Come posso modificare la cronologia di git per correggere un indirizzo / nome email errato [chiuso]


76

Quando ho iniziato a usare git ho appena fatto una git inite ho iniziato a chiamare adde commit. Ora sto iniziando a prestare attenzione e vedo che i miei impegni si stanno manifestando come cowens@localmachine, piuttosto che l'indirizzo che desidero. Sembra che l'impostazione GIT_AUTHOR_EMAILe GIT_COMMITTER_EMAILfarà quello che voglio, ma ho ancora quei vecchi commit con l'indirizzo / nome email errato. Come posso correggere i vecchi commit?


4
Per i nostri futuri lettori: le domande sull'uso gitper scopi simili a questo sono meglio poste su Stack Overflow .
Michael Hampton

Ecco la domanda più vicina su stackoverflow.com.
naught101

Risposte:


82

Puoi tornare indietro e correggere tutti i tuoi commit con una sola chiamata per git filter-branch. Questo ha lo stesso effetto di rebase, ma devi solo eseguire un comando per correggere tutta la cronologia, invece di correggere ogni commit singolarmente.

Puoi correggere tutte le e-mail sbagliate con questo 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

Maggiori informazioni sono disponibili nei documenti git


11
bene, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"' è molto più semplice, grazie. Questa sarebbe la risposta accettata se potessi cambiarla (sembra che ci sia un bug con Server Fault).
Chas. Owens,

7
Si noti che le linee di esportazione NON devono avere spazi su entrambi i lati del segno di uguale. Vale a dire che dovrebbero apparire così: export GIT_AUTHOR_EMAIL = "(email corretta)";
Andy Balaam,

1
Ora, come lo farei su Windows?
Carsten Schmitz,

2
@Deckard: salva lo script in un file di testo come fixcommits.sh, quindi esegui Git Bash ed esegui lo script. Ho inserito il file di script nella radice del mio repository, quindi sono passato a quella cartella in Git Bash, quindi ho eseguito lo script con ./fixcommits.sh
Avalanchis il

2
Addendum 1 Questo formato di comando non funzionava per me, ma se / allora ha fatto:if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
Josh M.

28

Il comando filtro-ramo di Git è potente, ma è terribilmente ingombrante da usare per qualsiasi cosa non banale, come ad esempio se hai più di un autore da correggere.

Ecco un'alternativa che ho trovato utile, che utilizza la funzione .mailmap descritta nella manpage git-shortlog. Questo fornisce un meccanismo di mappatura dell'autore che possiamo usare con la funzione di formattazione di git log. Possiamo usarlo per generare i comandi per selezionare e modificare e modificare una sequenza denominata di commit.

Ad esempio, supponiamo di voler correggere la paternità su un ramo $ BRANCH, iniziando da un commit $ START.

È necessario creare un file .mailmap nella directory superiore del repository che associ i nomi degli autori esistenti a quelli corretti. Puoi ottenere un elenco dei nomi degli autori esistenti con:

git shortlog -se

Devi finire con un file .mailmap come questo (diciamo):

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

Ora puoi usare la funzione di formattazione di git log per generare i comandi per riscrivere $ BRANCH come $ BRANCH2.

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

Il primo comando crea un nuovo ramo vuoto che nasce dal commit $ START. Per ogni commit tra $ START e quindi la fine di $ BRANCH, il secondo comando cherry seleziona il commit originale alla fine del ramo $ $ BRANCH2 corrente e lo modifica per impostare correttamente l'autore.

Questo è anche generalmente applicabile - inseriscilo nel tuo ~ / .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" '

Quindi, quando è necessario correggere gli autori, ora è necessario generare un file .map ed eseguire:

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

Il ref di filiale originale può essere riassegnato a quello nuovo e quello nuovo cancellato:

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

Questo e spettacolare. Ti ricompenserei se avessi più rappresentante. Grazie :)
pistache il

9

Combinazione della risposta da Come posso correggere la metainformazione sul primo commit in 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 foo@example.com"
# (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 foo@example.com"
# (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

Mi ha portato sulla strada giusta, ma avevo bisogno del comando da: stackoverflow.com/a/28536828/307 invece dell'uso --author
Brett Veenstra

5

Per seguire la risposta di jedberg: è possibile utilizzare rebase -ie scegliere di modificare i commit in questione. Se si utilizza git commit --amend --author <AUTHOR DETAILS>e quindi git rebase continueè possibile esaminare e correggere la cronologia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.