Come modificare diversi commit in Git per cambiare autore


180

Ho eseguito una serie di commit in Git e ora mi rendo conto di aver dimenticato di impostare correttamente il mio nome utente e le proprietà e-mail dell'utente (nuova macchina). Non ho ancora inviato questi commit al mio repository, quindi come posso correggerli prima di farlo (solo gli ultimi 3 commit sul ramo master)?

Ho guardato git resete git commit -C <id> --reset-author, ma non credo di essere sulla strada giusta.


1
Un altro motivo per cui potresti voler cambiare la proprietà email è questo errore github: remote: error: GH007: Your push would publish a private email address.... `! [remoto rifiutato] master -> master (push rifiutato a causa delle restrizioni sulla privacy delle e-mail) `.
craq,

Risposte:


232

Il rifacimento / modifica sembra inefficiente, quando hai il potere del filtro-ramo a portata di mano:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(diviso in più righe per chiarezza, ma non necessario)

Assicurati di ispezionare il risultato quando hai finito, per assicurarti di non aver cambiato nulla che non volevi!


ti dispiace spiegarlo un po 'di più? non sono sicuro di cosa sia il ramo del filtro
massimo pleaner

1
@maxpleaner git filter-branch --helpè piuttosto semplice :)
alediaferia,

3
consultare anche help.github.com/articles/changing-author-info , che si aggiunge anche --tag-name-filter cata filter-branchper migrare i tag nella nuova cronologia. Utilizza anche --branches --tagsinvece di --all, che riscrive solo la cronologia dei rami e dei tag e ne lascia refssolo altri (anche se questo probabilmente non fa molta differenza a meno che non si stia usando ad esempio git-notes)
Tobias Kienzler

12
per eseguire questa operazione solo negli ultimi due commit, ho sostituito -- --allconHEAD~1..HEAD
nmz787

1
@ nmz787 Quanti registri vengono visualizzati se lo fai git log HEAD~2..HEAD?
Jona,

148

L'approccio di rebase interattivo è piuttosto carino se usato insieme a exec. È possibile eseguire qualsiasi comando shell contro un commit specifico o tutti i commit nel rebase.

Innanzitutto imposta le impostazioni dell'autore git

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

Quindi reimpostare l'autore per tutti i commit dopo il dato SHA

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

Verrà visualizzato l'editor per confermare le modifiche. Tutto quello che devi fare qui è salvare ed uscire e passerà attraverso ogni commit ed eseguirà il comando specificato nel flag -x.

Per il commento di @ Dave di seguito, puoi anche modificare l'autore mantenendo i timestamp originali con:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"

3
Grazie per avermi introdotto all'opzione -x. È davvero fantastico! per l'opzione -i ho usato HEAD ~ 4 per correggere il mio indirizzo e-mail negli ultimi 4 commit. ha funzionato come un fascino.
Brad Hein,

2
Questo è molto più semplice che filter-branchse vuoi solo correggere i tuoi ultimi commit :). Si noti tuttavia che ciò modifica il timestamp dei commit.
Luator,

24
Per modificare l'autore ma mantenere i timestamp originali, utilizzaregit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"
Dave,

2
Anche @Connor git logha mostrato per me una vecchia paternità, ma lo stato git ha identificato correttamente i nuovi commit e, dopo la spinta forzata, erano come intendevo.
Dan M.

6
Per reimpostare tutti i commit incluso l'uso root: git rebase -i --root …invece di passare un SHA.
gfullam,

80

Per modificare l'autore solo per l'ultimo commit:

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

Supponiamo di voler modificare l'autore solo per gli ultimi N commit:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

APPUNTI

  • la --no-editbandiera si assicura git commit --amendche non richieda una conferma aggiuntiva
  • quando lo usi git rebase -i, puoi selezionare manualmente i commit dove cambiare l'autore,

il file modificato sarà simile al seguente:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

1
per tutti i commit dalla radice. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit"
Ashish Negi

1
Consiglio di aggiungere un'opzione --rebase-merges(breve -r), per mantenere intatta la topologia del ramo se contiene alcune fusioni.
donquixote,

4

Questo metodo è stato documentato da Github proprio per questo scopo. I passaggi sono:

  1. Apri il terminale e crea un clone nudo del tuo repository
git clone --bare https://github.com/user/repo.git
cd repo
  1. Modificare il seguente script (che sostituisce OLD_EMAIL, CORRECT_EMAILe CORRECT_NAME)
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
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
  1. Copia / incolla lo script nel tuo terminale e premi invio per eseguirlo.
  2. Spingi le modifiche con git push --force --tags origin 'refs/heads/*'e il gioco è fatto!

Ho seguito le stesse istruzioni su GitHub a cui hai fatto riferimento e GitHub sembra proprio ora. Tuttavia, sono un novellino di Git e non sono sicuro di come sincronizzare il mio repository locale dopo il backup. Quando tiro ho lo stesso errore "rifiutare di unire storie non correlate" menzionato in un'altra risposta. Penso che dovrei ribellarmi a quella nuova cronologia di commit, ma apprezzerei molto i passaggi più specifici.
enigment

@enigment se sei soddisfatto del repository com'è su github, puoi eliminare (o forse spostarti in un'altra posizione) la cartella che hai localmente e semplicemente clonare da github
stevec

Grazie, lo so, ma non sembra il modo idiomatico GitHub / Git.
enigment


0

Se non ti senti sicuro riguardo al debasing e alla modifica, puoi farlo in questo modo. Allo stesso tempo, dovresti anche impostare la configurazione globale che probabilmente intendevi fare comunque.

git reset HEAD~ (annulla ultimo commit)

git config --global user.name "Your Name"

git config --global user.email you@example.com

git commit -m "message"

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.