¿Cómo edito el historial de git para corregir una dirección / nombre de correo electrónico incorrecto [cerrado]

76

Cuando comencé a usar git solo hice un git inity comencé a llamar addy commit. Ahora estoy empezando a prestar atención y puedo ver que mis confirmaciones se muestran como cowens@localmachine, en lugar de la dirección que quiero. Parece como si estuviera configurando GIT_AUTHOR_EMAILy GIT_COMMITTER_EMAILhará lo que quiero, pero todavía tengo esas confirmaciones antiguas con la dirección de correo electrónico / nombre incorrectos. ¿Cómo puedo corregir las confirmaciones anteriores?

Chas Owens
fuente
44
Para nuestros futuros lectores: las preguntas sobre el uso gitpara fines similares a este se hacen mejor en Stack Overflow .
Michael Hampton
Aquí está la pregunta más cercana en stackoverflow.com.
naught101

Respuestas:

82

Puede regresar y arreglar todas sus confirmaciones con una sola llamada a git filter-branch. Esto tiene el mismo efecto que rebase, pero solo necesita hacer un comando para arreglar todo su historial, en lugar de arreglar cada confirmación individualmente.

Puede corregir todos los correos electrónicos incorrectos con este comando:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

Más información está disponible en los documentos de git

andy
fuente
11
bueno, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "[email protected]"; GIT_AUTHOR_NAME = "Foo"' es mucho más simple, gracias. Esta sería la respuesta aceptada si pudiera cambiarla (parece que hay un error con la falla del servidor).
Chas. Owens
77
Tenga en cuenta que las líneas de exportación NO deben tener espacios a ambos lados del signo igual. Es decir, deberían verse así: export GIT_AUTHOR_EMAIL = "(correo electrónico correcto)";
Andy Balaam el
1
Ahora, ¿cómo haría esto en Windows?
Carsten Schmitz
2
@Deckard: guarde el script en un archivo de texto como fixcommits.sh, luego ejecute Git Bash y ejecute el script. Puse el archivo de script en la raíz de mi repositorio, luego navegué a esa carpeta en Git Bash, luego ejecuté el script con ./fixcommits.sh
Avalanchis
2
Anexo 1 Este formato de comando no funcionaba para mí, pero si / luego lo hizo:if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
Josh M.
28

El comando filter-branch de Git es poderoso, pero es terriblemente difícil de usar para cualquier cosa que no sea trivial, como por ejemplo, si tiene que corregir más de un autor.

Aquí hay una alternativa que encontré útil, que utiliza la función .mailmap descrita en la página de manual de git-shortlog. Esto proporciona un mecanismo de mapeo de autores que podemos usar con la función de formateo de git log. Podemos usarlo para generar los comandos para elegir y enmendar, enmendar una secuencia de confirmaciones con nombre.

Por ejemplo, suponga que desea corregir la autoría en una rama $ BRANCH, comenzando en commit $ START.

Debe crear un archivo .mailmap en el directorio superior de su repositorio que asigna los nombres de autor existentes a los correctos. Puede obtener una lista de los nombres de autor existentes con:

git shortlog -se

Debe terminar con un archivo .mailmap como este (por ejemplo):

You <[email protected]>   cowens@localmachine
You <[email protected]>   root@localmachine

Ahora puede usar la función de formateo de git log para generar los comandos para reescribir $ BRANCH como $ BRANCH2.

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

El primer comando crea una nueva rama vacía que brota del commit $ START. Para cada confirmación entre $ START y luego el final de $ BRANCH, el segundo comando cherry selecciona la confirmación original al final de la rama actual $ BRANCH2, y la modifica para establecer el autor correctamente.

Esto también es generalmente aplicable: ponga esto en su ~ / .gitconfig:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

Entonces, cuando necesita corregir autores, ahora solo necesita generar un archivo .map y hacer:

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

La referencia de sucursal original se puede reasignar a la nueva, y se puede eliminar la nueva:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2
wu-lee
fuente
Esto es asombroso Te recompensaría si tuviera más reputación. Gracias :)
pistache
9

Combinando la respuesta de ¿Cómo soluciono la metainformación en el primer commit en git?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo [email protected]"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo [email protected]"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root
Chas Owens
fuente
Me puso en el camino correcto, pero necesitaba el comando de: stackoverflow.com/a/28536828/307 en lugar del uso del autor
Brett Veenstra
5

Para seguir la respuesta de jedberg: puede usar rebase -iy elegir editar los commits en cuestión. Si usa git commit --amend --author <AUTHOR DETAILS>y luego git rebase continuepuede revisar y corregir el historial.

Chealion
fuente