it-swarm-pt.tech

Como edito o histórico do git para corrigir um endereço / nome de email incorreto

Quando comecei a usar o git, fiz um git init e começou a chamar add e commit. Agora estou começando a prestar atenção e posso ver que meus commits estão aparecendo como [email protected], em vez do endereço que eu quero. Parece que a configuração GIT_AUTHOR_EMAIL e GIT_COMMITTER_EMAIL farei o que eu quero, mas ainda tenho esses commit antigos com o endereço/nome de email errado. Como posso corrigir os commits antigos?

76
Chas. Owens

Você pode voltar e corrigir todos os seus commits com uma única chamada para git filter-branch. Isso tem o mesmo efeito que o rebase, mas você só precisa executar um comando para corrigir todo o seu histórico, em vez de corrigir cada confirmação individualmente.

Você pode corrigir todos os emails errados com este 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

Mais informações estão disponíveis no git docs

82
andy

O comando filter-branch do Git é poderoso, mas é terrivelmente difícil de usar para algo não trivial, como por exemplo, se você tiver mais de um autor para corrigir.

Aqui está uma alternativa que eu achei útil, que usa o recurso .mailmap descrito na página de manual do git-shortlog. Isso fornece um mecanismo de mapeamento de autor que podemos usar com o recurso de formatação do git log. Podemos usá-lo para gerar os comandos para escolher e alterar, alterar uma sequência nomeada de confirmações.

Por exemplo, suponha que você queira corrigir a autoria em uma filial $ BRANCH, iniciando em uma confirmação $ START.

Você precisa criar um arquivo .mailmap no diretório superior do seu repositório, que mapeia os nomes de autores existentes para os nomes corretos. Você pode obter uma lista dos nomes de autores existentes com:

git shortlog -se

Você precisa acabar com um arquivo .mailmap como este (digamos):

You <[email protected]>   [email protected]
You <[email protected]>   [email protected]

Agora você pode usar o recurso de formatação do git log para gerar os comandos para reescrever $ BRANCH como $ BRANCH2.

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

O primeiro comando cria uma nova ramificação vazia surgindo do commit $ START. Para cada confirmação entre $ START e o final de $ BRANCH, o segundo comando seleciona o commit original no final do ramo atual $ BRANCH2 e o altera para definir o autor corretamente.

Isso também é geralmente aplicável - coloque isso no seu ~/.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" '

Portanto, quando você precisar corrigir os autores, agora precisará gerar um arquivo .map e fazer:

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

A ref original da ramificação pode ser reatribuída para a nova e a nova excluída:

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

Combinando a resposta de Como faço para corrigir as metainformações no primeiro commit no 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

Para seguir a resposta de jedberg: Você pode usar rebase -i e escolha editar os commits em questão. Se você usar git commit --amend --author <AUTHOR DETAILS> e depois git rebase continue você pode analisar e corrigir o histórico.

5
Chealion