Cómo cambiar el correo electrónico del autor en el momento de la confirmación con ganchos

La pregunta lo dice todo.

Quiero darles privacidad a mis usuarios al ofuscar sus direcciones de correo electrónico reales en commits por mis propios alias. ¿Hay algún gancho que pueda ayudarme a hacer esto?

Podrías conseguir que cambien la propiedad user.email en su repository local.

 git config user.email email@server.com 

No importa qué más ocurra, si cambia algo, incluso un solo carácter en el nombre de usuario y / o correo electrónico, en algún compromiso, obtendrá un compromiso nuevo y diferente. (Esto se debe a que el ID de confirmación consiste en una sum de verificación criptográfica del contenido de la confirmación. Entonces, de acuerdo, si puede romper la cryptography, puede get dos confirmaciones diferentes que tendrían la misma ID. Git completamente roto, y probablemente también haya ganado un premio Turing o un premio Nobel. :-))

El "gancho de trabajo" al que se ha vinculado en los comentarios sobre otra respuesta es probablemente su mejor opción. Este problema se networkinguce a una cosa: no puede realizar ningún cambio en una confirmación publicada (sin causar problemas a los consumidores de esa publicación), pero puede hacer los cambios que desee en una confirmación privada siempre que "sepa lo que 're doing'. El uso de git commit --amend --author "$user <$email>" -C HEAD por cada confirmación, a medida que ingresan a su copy del repository, garantiza que usted reemplace una confirmación no publicada con una nueva, ligeramente diferente commit inédito. (Supongo que has puesto esto en el gancho post-commit).

No estoy seguro de qué parte no está contento, tal vez el [ -n "$richo_git_rewrite" ] && exit 0 ? Ese es un método bastante inteligente para detectar recursiones. Una alternativa es omitir la detección de recursion, y en su lugar comparar el usuario existente y el correo electrónico en la confirmación con los deseados.

Aquí hay un script que hace eso (excepto que usé la variable env SWITCHY = true para hacer mi testing):

 #! /bin/sh # first, pick which git config variables to get if ${SWITCHY-false}; then config=user.work else config=user fi # next, find out if they're set can_rewrite=false target_author=$(git config --get $config.name) && target_email=$(git config --get $config.email) && can_rewrite=true # If they ARE set, we can "rewrite" (replace) the commit; # if not, we can't. Just because we can, though, does not # mean we should. Find out if the current author and email # differ from the desinetworking ones. if $can_rewrite; then current_author=$(git log --pretty=format:%an HEAD -n 1) current_email=$(git log --pretty=format:%ae HEAD -n 1) if [ "$current_author" != "$target_author" -o \ "$current_email" != "$target_email" ]; then # may want --allow-empty here, if you're allowing empty commits # at all, otherwise empty ones don't get the rewrite done git commit --amend --author "$target_author <$target_email>" -C HEAD fi fi 

Nota: deberá establecer este mismo enlace en los hooks/post-merge , para get fusiones modificadas con el nombre y el correo electrónico actualizados. Y, por supuesto, puedes simplificar un poco el gancho (no necesitas una variable can_rewrite real, solo haz las dos operaciones de configuration de git con && s y continúa con otra && ). También tendría sentido tener más que solo usuario vs usuario.trabajo, tal vez usuario vs usuario.ModoA vs usuario.ModeB, etc., y puede expulsarlo de cualquier testing que desee (variables env, presencia o ausencia de commands, etc.)


OK, por comentarios, aquí hay un gancho precompromiso. Lamentablemente, no funciona con git merge (el enlace de precompilation se ejecuta y se queja y luego se envía la confirmación de fusión).

 #! /bin/sh fatal() { echo "$@" 1>&2 exit 1 } # pick which git config variables to get if ${SWITCHY-false}; then config=user.work else config=user fi # tn, te = target author name/email # an, ae = what git will use for author name/email tn=$(git config --get $config.name) || exit 0 te=$(git config --get $config.email) || exit 0 an=${GIT_AUTHOR_NAME-$(git config --get user.name)} || fatal "no author name set" ae=${GIT_AUTHOR_EMAIL-$(git config --get user.email)} || fatal "no author email set" [ "$an" = "$tn" -a "$ae" = "$te" ] || fatal "git will use author $an <$ae> but you want them as $tn <$te> fix your environment variables and try again" 

Puede combinar este gancho precompromiso con un gancho de reescritura de la postcombinación ( eww :-)). No intenté una confirmación conflictiva, pero es de suponer que el enlace de precompilation atrapará mermas conflictivas que requieren que hagas tu propia confirmación.

(También vale la pena señalar que este enlace precompromiso no mira el tree o índice de trabajo, por lo que no tiene la falla habitual de "verificar el tree de trabajo pero comprometer el índice").

http://progit.org/book/ch6-4.html explica cómo reescribir la historia. Cerca de la parte inferior, no hay este command

 git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; then GIT_AUTHOR_NAME="Scott Chacon"; GIT_AUTHOR_EMAIL="schacon@example.com"; git commit-tree "$@"; else git commit-tree "$@"; fi' HEAD 

que cambia todas las confirmaciones de schacon@localhost de schacon@example.com .

Advertencia: esto cambia TODAS las identificaciones de compromiso desde el primer cambio de correo electrónico en adelante.