Git, reescreva nomes de usuário e emails de confirmação anteriores

170

Confirmei várias confirmações em um projeto no Github, mas percebi que não havia configurado o nome completo do e-mail e do committer no computador que estou usando atualmente para fazer minhas confirmações e, portanto, o avatar e o endereço de email dos usuários. não estão lá.

Como posso reescrever todos os emails e nomes de usuários confirmados no passado?

JP Silvashy
fonte
9
possível duplicata de Como altero o autor de uma confirmação no git?
givanse
Eu experimentei isso depois de alterar o endereço de email na minha conta do GitHub. Além de enviar alterações de código do repositório git local usando a interface da linha de comando git (e não a área de trabalho do GitHub), também editei o texto e os arquivos gerenciados diretamente do repositório remoto do git usando a interface da web GitHub. O novo endereço de email propagado apenas para as confirmações resultantes das últimas ações e não da primeira.
Robert John

Respostas:

243

Você pode adicionar este 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 "

Para alterar o nome do autor:

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

ou o email apenas dos últimos 10 confirmados:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" 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

brauliobo
fonte
13
Também git change-commits GIT_COMMITTER_EMAIL "[email protected]" "[email protected]"para alterar o email do committer.
precisa
19
fixa para "eval: [[: não encontrado" no ubuntu e adicionar um confirmchange-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-commits' não é um comando git. Veja 'git --help'. Significa que você não adicionou o alias à sua configuração do git. por exemplo, git config -e
Wayne
2
Isso apenas duplicou todos os commits com o email que eu queria alterar. Não parece reescrever o histórico. A solução da @Olivier Verdier funcionou para mim.
Jake Wilson
6
Fazê-lo duas vezes seguidas com diferentes leads entradas para:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti
98

Veja aqui :

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
Olivier Verdier
fonte
4
isso não mudaria o nome do autor para todos os commits (histórico inteiro) da ramificação?
hasen 27/05
2
Sim, isso mudaria todos os commits para as novas informações do autor.
ewall 28/05
9
Marque as perguntas como duplicadas em vez de copiar e colar a resposta.
givanse
2
e se eu não especificasse um nome antigo ou email antigo? git diz "ident vazio <> não permitido"
Griffan 10/04/2015
Executei este comando e agora meu repositório não envia ou extrai do servidor git.
Jesus H
46

Se você já enviou algumas de suas confirmações para o repositório público, não deseja fazer isso ou criaria uma versão alternativa do histórico do mestre que outras pessoas possam ter usado. "Não atravesse as correntes ... Seria ruim ..."

Dito isto, se foram apenas os commits que você fez no seu repositório local, corrija isso de qualquer maneira antes de enviar para o servidor. Você pode usar o git filter-branchcomando com a --commit-filteropção, para que apenas edite confirmações que correspondam às suas informações incorretas, assim:

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
ewall
fonte
5
Isso funciona perfeitamente, enquanto a resposta marcada em verde não era ...
jmary
Depois, é possível limpar o backup com git update-ref -d refs/original/refs/heads/master, consulte < stackoverflow.com/a/7654880/333403 >.
cknoll 23/03
FYI: Se você tiver vários nomes / e-mails incorretos, talvez seja necessário executá-lo várias vezes. Se isso acontecer, ele lamentará você com este erro: A previous backup already exists in refs/original/Nesse caso, execute-o novamente com o novo email e adicione um -fantes do --commit-filter. Use a seu próprio critério. Geralmente -fé algo perigoso de se fazer sem o conhecimento do que está fazendo.
Chuck
19

Depois de aplicar a resposta de 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

... para enviar o histórico alterado no repositório original, use:

git push origin +yourbranch

O comando acima (observe o sinal de mais) força a reescrita do histórico no repositório original também. Use com cuidado!

sarusso
fonte
Trabalhou para mim, também reescreveu corretamente a história na origem.
Xeverous 15/09
10
Isso vai reescrever TODAS as confirmações, independentemente de quem a criou. Use com cuidado.
Bhavin Doshi
14

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

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="[email protected]"
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

isso funcionou totalmente para mim. Após o git push, verifique a atualização no portal da web do git. Se o commit ainda não estava vinculado à minha conta, mostrava uma imagem em miniatura padrão ao lado do commit e não era refletida no gráfico de linha do tempo das minhas contribuições, vá para o URL do commit e anexe .patch no final do URL e verifique o nome e email estão corretos.

Jacccck
fonte
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência.
jhpratt
1
Este é o único que reescreve todos os ramos.
Bruno Zell
6

Para aqueles que querem apenas a versão fácil de copiar e colar (além de atualizar e-mails e nomes):

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 <[email protected]> <[email protected]> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <[email protected]> <[email protected]> -f
Nick Kuznia
fonte
5
! -bash: f: evento não encontrado
Saiyine
O mais provável é um problema com um terminal de coisas que escapam automaticamente
Andrei Savin
3

Considerando que o uso de nãogit-filter-branch é desejado , faça o mesmo no git-filter-repo (pode ser necessário instalá-lo primeiro pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"[email protected]", b"[email protected]")'

Se o repositório for original, sem controle remoto, você precisará adicionar --forcepara forçar a reescrita. (Você pode criar um backup do seu repositório antes de fazer isso.)

Se você não deseja preservar as referências (elas serão exibidas no histórico da ramificação da Git GUI), será necessário adicionar --replace-refs delete-no-add.

Para recursos mais avançados, consulte "Filtragem de nomes e e-mails" .

PS Roubado e aprimorado em https://stackoverflow.com/a/59591928/714907 .

Pugsley
fonte