sviluppo-web-qa.it

Come posso modificare la cronologia di git per correggere un indirizzo / nome e-mail errato

Quando ho iniziato a usare git ho appena fatto un git init e ha iniziato a chiamare add e commit. Ora sto iniziando a prestare attenzione e vedo che i miei commit vengono visualizzati come [email protected], piuttosto che l'indirizzo che desidero. Sembra che l'impostazione GIT_AUTHOR_EMAIL e GIT_COMMITTER_EMAIL farà quello che voglio, ma ho ancora quei vecchi commit con l'indirizzo/nome email errato. Come posso correggere i vecchi commit?

76
Chas. Owens

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 email 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 su git docs

82
andy

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 <[email protected]>   [email protected]
You <[email protected]>   [email protected]

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 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
28
wu-lee

Combinando la risposta di 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 [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

Per seguire la risposta di jedberg: puoi usare rebase -i e scegli di modificare i commit in questione. Se usi git commit --amend --author <AUTHOR DETAILS> e poi git rebase continue puoi consultare e correggere la cronologia.

5
Chealion