Git, riscrivi i nomi utente e le e-mail di commit precedenti


170

Ho impegnato un sacco di commit in un progetto su Github, tuttavia mi sono reso conto di non aver impostato l'e-mail corretta e il nome completo del committer sul computer che sto attualmente utilizzando per effettuare i miei commit e quindi l'avatar e l'indirizzo e-mail degli utenti non sono lì.

Come posso riscrivere tutte le email e i nomi utente di commit precedenti?



L'ho riscontrato dopo aver modificato l'indirizzo e-mail sul mio account GitHub. Oltre a inviare le modifiche al codice dal repository git locale utilizzando l'interfaccia della riga di comando git (e non l'interfaccia desktop GitHub), ho anche modificato il testo e i file gestiti direttamente dal repository git remoto utilizzando l'interfaccia web GitHub. Il nuovo indirizzo e-mail si è propagato solo agli commit risultanti da queste ultime azioni e non dalla prima.
Robert John,

Risposte:


243

È possibile aggiungere questo alias:

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "

Per modificare il nome dell'autore:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

o l'e-mail solo per gli ultimi 10 commit:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

Alias:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f "

Fonte: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig


13
Anche git change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"per modificare l'e-mail del committer.
Laurent,

19
risolto per "eval: [[: not found" su ubuntu e aggiungi una confermachange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
qxo

9
git: 'change-commit' non è un comando git. Vedi 'git --help'. Significa che non hai aggiunto l'alias alla tua configurazione git. es. git config -e
Wayne

2
Questo ha appena fatto duplicati di tutti gli commit con l'e-mail che volevo cambiare. Non sembra riscrivere la storia. La soluzione di Olivier Verdier ha funzionato per me.
Jake Wilson,

6
Farlo due volte di seguito con input diversi porta a:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti

98

Vedi qui :

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

4
questo non cambierebbe il nome dell'autore per tutti gli commit (tutta la storia) della filiale?
hasen

2
Sì, ciò cambierebbe tutti gli commit nelle informazioni sul nuovo autore.
ewall,

9
Si prega di contrassegnare le domande come duplicati anziché copiare incollando la risposta.
givanse

2
cosa succede se non ho specificato un vecchio nome o una vecchia e-mail? git dice "
identificativo

Ho eseguito questo comando e ora il mio repository non può eseguire il push o il pull dal server git.
Gesù H

46

Se hai già trasferito alcuni dei tuoi commit nel repository pubblico, non vuoi farlo, o farebbe una versione alternativa della storia del master che altri potrebbero aver usato. "Non attraversare i corsi d'acqua ... Sarebbe male ..."

Detto questo, se sono solo i commit che hai fatto al tuo repository locale, allora risolvi questo problema prima di passare al server. Puoi utilizzare il git filter-branchcomando con l' --commit-filteropzione, quindi modifica solo i commit che corrispondono alle tue informazioni errate, in questo modo:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

5
Funziona perfettamente mentre la risposta contrassegnata in verde no
jmary

Successivamente, si potrebbe voler cancellare il backup con git update-ref -d refs/original/refs/heads/master, vedere < stackoverflow.com/a/7654880/333403 >.
cknoll,

Cordiali saluti: Se hai più nomi / e-mail errati potrebbe essere necessario eseguirlo più volte. Se ciò accade, ti lamenterà con questo errore: A previous backup already exists in refs/original/In tal caso, -feseguilo nuovamente con la nuova e-mail e aggiungi un prima del filtro --commit. Usalo a tua discrezione. Di solito -fè una cosa pericolosa da fare senza sapere cosa sta facendo.
Chuck,

19

Dopo aver applicato la risposta di Olivier Verdier:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... per inviare la cronologia modificata sul repository originale utilizzare:

git push origin +yourbranch

Il comando sopra (nota il plus) forza la riscrittura della cronologia anche sul repository originale. Usare con cautela!


Ha funzionato per me, anche riscritto correttamente la storia sull'origine.
Xeverous,

10
Questo riscriverà TUTTI i commit, indipendentemente da chi lo ha creato. Usare con cautela.
Bhavin Doshi,

14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

questo ha funzionato totalmente per me. Dopo git push, assicurati di vedere l'aggiornamento sul portale web di git. Se il commit non era ancora collegato al mio account, mostrava l'anteprima predefinita accanto al commit e non si rifletteva sul grafico della cronologia dei miei contributi, vai all'URL del commit e aggiungi .patch alla fine dell'URL e verifica il nome e l'email sono corretti.


Sebbene ciò possa teoricamente rispondere alla domanda, sarebbe preferibile includere qui le parti essenziali della risposta e fornire il collegamento come riferimento.
jhpratt,

1
Questo è l'unico che riscrive tutti i rami.
Bruno Zell,

6

Per coloro che desiderano semplicemente la versione semplice di copia e incolla (oltre all'aggiornamento di e-mail e nomi):

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5
-bash:! f: evento non trovato
Saiyine,

Molto probabilmente un problema con un terminale che fuoriesce automaticamente dalle cose
Andrei Savin,

3

Considerando che l'uso di nongit-filter-branch è desiderato , fare la stessa cosa in git-filter-repo (potrebbe essere necessario installarlo prima con pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

Se il repository è originale, senza telecomando, dovrai aggiungere --forceper forzare la riscrittura. (Potresti voler creare un backup del tuo repository prima di farlo.)

Se non si desidera conservare i riferimenti (verranno visualizzati nella cronologia delle filiali della GUI di Git), sarà necessario aggiungere --replace-refs delete-no-add.

Per funzionalità più avanzate, vedere "Filtro di nomi ed e-mail" .

PS rubato e migliorato da https://stackoverflow.com/a/59591928/714907 .

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.