web-dev-qa-db-fra.com

Comment modifier l'historique de git pour corriger une adresse e-mail / un nom incorrect

Quand j'ai commencé à utiliser git, je viens de faire un git init et a commencé à appeler add et commit. Maintenant, je commence à faire attention et je peux voir que mes commits apparaissent comme cowens@localmachine, plutôt que l'adresse que je veux. Il semble que le paramètre GIT_AUTHOR_EMAIL et GIT_COMMITTER_EMAIL fera ce que je veux, mais j'ai toujours ces anciens commits avec la mauvaise adresse e-mail/le mauvais nom. Comment puis-je corriger les anciens commits?

76
Chas. Owens

Vous pouvez revenir en arrière et corriger tous vos commits avec un seul appel à git filter-branch. Cela a le même effet que rebase, mais vous n'avez qu'à exécuter une seule commande pour corriger tout votre historique, au lieu de corriger chaque commit individuellement.

Vous pouvez corriger tous les mauvais e-mails avec cette commande:

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

Plus d'informations sont disponibles sur le git docs

82
andy

La commande filter-branch de Git est puissante, mais elle est horriblement difficile à utiliser pour tout ce qui n'est pas trivial, comme par exemple, si vous avez plus d'un auteur à corriger.

Voici une alternative que j'ai trouvée utile, qui utilise la fonctionnalité .mailmap décrite dans la page de manuel git-shortlog. Cela fournit un mécanisme de mappage d'auteur que nous pouvons utiliser avec la fonction de formatage de git log. Nous pouvons l'utiliser pour générer les commandes permettant de sélectionner et de modifier, d'amender une séquence nommée de validations.

Par exemple, supposons que vous vouliez corriger la paternité d'une branche $ BRANCH, en commençant par un commit $ START.

Vous devez créer un fichier .mailmap dans le répertoire supérieur de votre référentiel qui mappe les noms d'auteurs existants aux bons. Vous pouvez obtenir une liste des noms d'auteurs existants avec:

git shortlog -se

Vous devez vous retrouver avec un fichier .mailmap comme celui-ci (par exemple):

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

Vous pouvez maintenant utiliser la fonction de formatage de git log pour générer les commandes pour réécrire $ BRANCH en $ BRANCH2.

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

La première commande crée une nouvelle branche vide germant à partir de la validation $ START. Pour chaque commit entre $ START et ensuite la fin de $ BRANCH, la deuxième commande cherry sélectionne le commit d'origine à la fin de la branche courante $ BRANCH2 et la modifie pour définir correctement l'auteur.

Ceci est également généralement applicable - mettez ceci dans votre ~/.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" '

Donc, lorsque vous devez corriger les auteurs, vous devez maintenant générer un fichier .map et faire:

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

La référence de branche d'origine peut être réaffectée à la nouvelle et la nouvelle supprimée:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2
28
wu-lee

Combiner la réponse de Comment puis-je corriger la métainformation sur le premier commit dans 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
9
Chas. Owens

Pour suivre la réponse de jedberg: Vous pouvez utiliser rebase -i et choisissez de modifier les commits en question. Si tu utilises git commit --amend --author <AUTHOR DETAILS> et alors git rebase continue vous pouvez parcourir et corriger l'historique.

5
Chealion