Como alterar vários commits no Git para alterar o autor

180

Fiz uma série de confirmações no Git e agora percebo que esqueci de definir corretamente meu nome de usuário e propriedades de email de usuário (nova máquina). Ainda não enviei essas confirmações para o meu repositório, então como posso corrigi-las antes de fazê-lo (apenas as três confirmações mais recentes no ramo mestre)?

Eu estive olhando git resete git commit -C <id> --reset-author, mas acho que não estou no caminho certo.

pauldoo
fonte
1
Outro motivo para você querer alterar a propriedade de email é este erro do github: remote: error: GH007: Your push would publish a private email address.... `! [remoto rejeitado] master -> master (push recusado devido a restrições de privacidade de email) `.
craq 18/09/09
Consulte também stackoverflow.com/q/750172/1340631 .
scai 20/04

Respostas:

232

Rebase / alterar parece ineficiente quando você tem o poder de ramificação do filtro na ponta dos dedos:

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

(divida em linhas para maior clareza, mas não é necessário)

Inspecione o resultado quando terminar, para garantir que você não alterou nada que não pretendia!

Cascabel
fonte
mente explicando isso um pouco mais? não sei o ramo filtro é
max pleaner
1
@maxpleaner git filter-branch --helpé bastante simples :)
alediaferia
3
consulte também help.github.com/articles/changing-author-info , que também adiciona--tag-name-filter cat ao a filter-branchfim de migrar tags para o novo histórico. Ele também usa --branches --tagsem vez de --all, que só reescreve ramo e etiqueta história e folhas outro refssozinho (embora isso provavelmente não faz muita diferença a não ser por exemplo, você estiver usando git-notes)
Tobias KIENZLER
12
para fazer isso apenas nos dois últimos commits, substitui -- --allporHEAD~1..HEAD
nmz787 30/03
1
@ nmz787 Quantos logs são mostrados se você o fizer git log HEAD~2..HEAD?
Jona
148

A abordagem de rebase interativa é bastante agradável quando usada em conjunto com o exec. Você pode executar qualquer comando do shell em uma confirmação específica ou em todas as confirmações na rebase.

Primeiro, defina as configurações do autor do git

git config --global user.name "John Doe"
git config --global user.email [email protected]

Em seguida, redefinir o autor para todas as confirmações após o SHA especificado

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

Isso abrirá seu editor para confirmar as alterações. Tudo o que você precisa fazer aqui é salvar e sair e ele passará por cada confirmação e executará o comando especificado no sinalizador -x.

Pelo comentário de @ Dave abaixo, você também pode alterar o autor, mantendo os registros de data e hora originais com:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Alex
fonte
3
Obrigado por me apresentar a opção -x. É muito incrível! para a opção -i, usei HEAD ~ 4 para corrigir meu endereço de email nos meus últimos 4 commits. funcionou como um encanto.
Brad Hein
2
Isso é muito mais simples do que filter-branchse você apenas deseja corrigir seus últimos commits :). Observe, no entanto, que isso altera o carimbo de data / hora das confirmações.
luator
24
Para alterar o autor, mas manter os registros de data e hora originais, usegit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Dave
2
O @Connor git logtambém mostrou autoria antiga para mim, mas o status git identificou corretamente os novos commits e após o push forçado, eles foram como eu pretendia.
Dan M.
6
Para rebase de todas as confirmações, incluindo o uso raiz: em git rebase -i --root …vez de passar um SHA.
precisa saber é o seguinte
80

Para alterar o autor apenas para o último commit:

git commit --amend --author 'Author Name <[email protected]>' --no-edit

Suponha que você queira alterar apenas o autor para os últimos N commit:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

NOTAS

  • a --no-editbandeira garante que git commit --amendnão solicite uma confirmação extra
  • quando você usa git rebase -i, você pode selecionar manualmente os commits onde alterar o autor,

o arquivo que você editar ficará assim:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
Chris Maes
fonte
1
para todos os commits da raiz. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit"
Ashish Negi
1
Eu recomendo adicionar a opção --rebase-merges(curta -r), para manter intacta a topologia do seu ramo, se ele contiver algumas mesclagens.
donquixote
4

Este método foi documentado pelo github para esse propósito. Os passos são:

  1. Abra o terminal e fazer um nu clone de sua repo
git clone --bare https://github.com/user/repo.git
cd repo
  1. Editar o script a seguir (substituindo OLD_EMAIL, CORRECT_EMAILe CORRECT_NAME)
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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. Copie / cole o script no seu terminal e pressione enter para executá-lo.
  2. Envie suas alterações git push --force --tags origin 'refs/heads/*'e pronto!
stevec
fonte
Eu segui as mesmas instruções no GitHub que você referenciou e o GitHub parece agora. No entanto, sou um novato do Git e não sei como sincronizar meu repositório local depois disso. Quando puxo, recebo o mesmo erro "recusando-se a mesclar histórias não relacionadas" mencionado em outra resposta. Eu acho que preciso me refazer contra esse novo histórico de consolidação, mas eu apreciaria muito etapas mais específicas.
enigment
@enigment se você está feliz com o repo como está no github, você pode excluir (ou talvez mudar para outro local) a pasta que você tem localmente e simplesmente clone de github
stevec
Obrigado, eu sei, mas isso não parece o caminho idiomático do GitHub / Git.
enigment
0

Se você não se sentir seguro quanto à degradação e alteração, poderá fazê-lo dessa maneira. Ao mesmo tempo, você também definiria a configuração global que provavelmente pretendia fazer de qualquer maneira.

git reset HEAD~ (desfazer a última confirmação)

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

git config --global user.email [email protected]

git commit -m "message"

Edison
fonte