78 votes

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

Lorsque j'ai commencé à utiliser git, j'ai simplement fait un git init et j'ai commencé à appeler add et commit. Maintenant, je commence à faire attention et je peux voir que mes commits s'affichent sous cowens@localmachine, plutôt que l'adresse que je veux. Il semble que définir 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/nom. Comment puis-je corriger les anciens commits ?

4 votes

Pour nos futurs lecteurs : Les questions sur l'utilisation de git à des fins similaires à celles-ci sont mieux posées sur Stack Overflow.

0 votes

Voici la question la plus proche sur stackoverflow.com.

85voto

Jagmal Points 1205

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 besoin que d'une seule commande pour corriger toute votre historique, au lieu de corriger chaque commit individuellement.

Vous pouvez corriger tous les emails incorrects avec cette commande :

git filter-branch --env-filter '
    oldname="(ancien nom)"
    oldemail="(ancien email)"
    newname="(nouveau nom)"
    newemail="(nouvel 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 les docs git

13 votes

Eh bien, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="foo@example.com";GIT_AUTHOR_NAME="Foo"' est beaucoup plus simple, merci. Ce serait la réponse acceptée si je pouvais la modifier (il semble qu'il y ait un bug avec Server Fault).

0 votes

@Chas. Owens - Essayez de cliquer sur la coche à côté de ma réponse pour la désélectionner, puis sélectionnez celle d'Andy

0 votes

@Chealion C'est ce que j'essayais (Je suis sur Stack Overflow depuis quelques mois maintenant), mais cela ne fonctionnait pas. Je viens de réessayer et ça a marché. Bizarre.

28voto

wu-lee Points 381

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

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

Par exemple, supposez que vous voulez corriger l'auteur sur une branche $BRANCH, à partir d'un commit $START.

Vous devez créer un fichier .mailmap dans le répertoire racine de votre dépôt 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 finir avec un fichier .mailmap comme ceci (disons) :

You    cowens@localmachine
You    root@localmachine

Maintenant vous pouvez 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 à partir du commit $START. Pour chaque commit entre $START et la fin de $BRANCH, la deuxième commande opère un cherry-pick du commit original à la fin de la branche actuelle $BRANCH2, et l'amende pour définir correctement l'auteur.

Cela est également généralement applicable - placez 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 avez juste besoin de générer un .mapfile et de faire :

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

La référence de la branche originale peut être réaffectée à la nouvelle, et la nouvelle supprimée :

git checkout $BRANCH
git reset --hard $BRANCH2 # soyez prudent avec cette commande
git branch -d $BRANCH2

0 votes

C'est génial. Je te donnerais une prime si j'avais plus de réputation. Merci :)

9voto

Jeff Points 103

En combinant la réponse de Comment puis-je corriger les méta-informations sur le premier commit dans git?

### Corriger le premier commit ###
# créer une balise temporaire pour le commit le plus ancien afin que nous puissions le référencer
git tag root `git rev-list HEAD | tail -1`
# le vérifier sur sa propre branche temporaire
git checkout -b new-root root
# amender le commit
git commit --amend --author "Foo foo@example.com"
# (ou si vous avez défini les bonnes valeurs **config** git)
git commit --amend -C HEAD --reset-author
# maintenant que vous avez changé le message de commit, revenez à la branche d'origine
git checkout @{-1}
# et rebaser sur votre nouveau commit racine
git rebase --onto new-root root
### Corriger le reste des commits ###
git rebase -i root
# modifier le fichier pour lire "edit  pour chaque entrée
# amender le commit
git commit --amend --author "Foo foo@example.com"
# (ou si vous avez défini les bonnes valeurs **config** git)
git commit --amend -C HEAD --reset-author
# passer au commit suivant
git rebase --continue
# continuer à exécuter les deux dernières commandes jusqu'à ce que vous voyiez
# Successfully rebased and updated refs/heads/master.
### Nettoyer ###
# supprimer la branche temporaire que nous avons créée
git branch -d new-root
# supprimer la balise temporaire que nous avons créée
git tag -d root

0 votes

M'a remis sur la bonne voie, mais j'avais besoin de la commande de : stackoverflow.com/a/28536828/307 au lieu de l'utilisation de --author

5voto

Steven Murawski Points 6665

Pour suivre la réponse de jedberg : Vous pouvez utiliser rebase -i et choisir d'éditer les commits en question. Si vous utilisez git commit --amend --author

et ensuite git rebase continue vous pouvez parcourir et corriger l'historique.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X