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


76

Quando comecei a usar o git, fiz apenas um git inite comecei a chamar adde commit. Agora estou começando a prestar atenção e posso ver que meus commits estão aparecendo como cowens@localmachine, e não no endereço que eu quero. Parece que está definindo GIT_AUTHOR_EMAILe GIT_COMMITTER_EMAILfará o que eu quero, mas ainda tenho esses commit antigos com o endereço de e-mail / nome errado. Como posso corrigir as confirmações antigas?


4
Para nossos futuros leitores: Perguntas sobre o uso gitpara finalidades semelhantes a essa são mais solicitadas no Stack Overflow .
Michael Hampton

Respostas:


82

Você pode voltar e corrigir todos os seus commit 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 nos documentos do git


11
bem, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"' é muito mais simples, obrigado. Esta seria a resposta aceita se eu pudesse alterá-la (parece que há um erro com a falha do servidor).
Chas. Owens

7
Observe que as linhas de exportação NÃO devem ter espaços nos dois lados do sinal de igual. Ou seja, eles devem ficar assim: export GIT_AUTHOR_EMAIL = "(email correto)";
Andy Balaam

1
Agora, como eu faria isso no Windows?
Carsten Schmitz

2
@Deckard: salve o script em um arquivo de texto como fixcommits.sh, execute o Git Bash e execute o script. Eu coloquei o arquivo de script na raiz do meu repo, em seguida, navegar para essa pasta no Git Bash, então eu corri o script com ./fixcommits.sh
Avalanchis

2
Adendo 1 Este formato de comando não estava funcionando para mim, mas se / então funcionou:if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
Josh M.

28

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 terminar com um arquivo .mailmap como este (digamos):

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

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

Isso é incrível. Eu o recompensaria se tivesse mais representante. Obrigado :)
pistache

9

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 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

Me pegou no caminho certo, mas precisava de comando: stackoverflow.com/a/28536828/307 em vez do uso --author
Brett Veenstra

5

Para seguir a resposta de jedberg: Você pode usar rebase -ie optar por editar os commits em questão. Se você usar git commit --amend --author <AUTHOR DETAILS>e, em seguida, git rebase continuepoderá percorrer e corrigir o histórico.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.