Como alterar o autor de confirmação para um commit específico?

Eu quero mudar o autor de um commit específico no histórico. Não é o último commit.

Eu sei sobre esta questão – Como faço para mudar o autor de um commit no git?

Mas estou pensando em algo, onde identifico o commit por hash ou short-hash.

Rebase interativa fora de um ponto anterior no histórico que o commit que você precisa modificar ( git rebase -i ). Na lista de confirmações que estão sendo realocadas, altere o texto de pick para edit ao lado do hash do que você deseja modificar. Então, quando o git solicitar que você altere o commit, use isto:

 git commit --amend --author="Author Name " 

Por exemplo, se o seu histórico de ABCDEF é ABCDEF com F como HEAD , e você quer mudar o autor de C e D , então você …

  1. Especifique git rebase -i B ( aqui está um exemplo do que você verá depois de executar o comando git rebase -i B )
    • se você precisar editar A , use git rebase -i --root
  2. mudar as linhas para C e D de pick para edit
  3. Uma vez iniciado o rebase, primeiro ele faria uma pausa em C
  4. Você iria git commit --amend --author="Author Name "
  5. Então git rebase --continue
  6. Pararia de novo em D
  7. Então você iria git commit --amend --author="Author Name " novamente
  8. git rebase --continue
  9. O rebase seria concluído.

A resposta aceita para essa pergunta é um uso maravilhosamente inteligente do rebase interativo, mas, infelizmente, exibe conflitos se o commit que estamos tentando mudar o autor costumava ser em uma ramificação que foi posteriormente mesclada. Mais geralmente, ele não funciona ao lidar com histórias confusas.

Como estou apreensivo sobre a execução de scripts que dependem da configuração e desconfiguração de variables ​​de ambiente para rewrite o histórico do git, estou escrevendo uma nova resposta baseada neste post, que é semelhante a essa resposta, mas é mais completa.

O seguinte é testado e funcionando, ao contrário da resposta vinculada. Suponha, por clareza de exposição, que 03f482d6 é o commit cujo autor estamos tentando replace, e 42627abe é o commit com o novo autor.

  1. Confira o commit que estamos tentando modificar.

     git checkout 03f482d6 
  2. Faça o autor mudar.

     git commit --amend --author "New Author Name " 

    Agora temos um novo commit com hash assumido como sendo 42627abe .

  3. Finalize a ramificação original.

  4. Substitua a confirmação antiga pela nova localmente.

     git replace 03f482d6 42627abe 
  5. Reescreva todos os commits futuros com base na substituição.

     git filter-branch -- --all 
  6. Remova o substituto para limpeza.

     git replace -d 03f482d6 
  7. Empurre o novo histórico (use somente –force se o abaixo falhar, e somente após verificação de git log com git log e / ou git diff ).

     git push --force-with-lease 

Em vez de 4-6 você pode apenas rebase para novo commit:

 git rebase -i 42627abe 

A documentação do Github contém um script que substitui as informações do committer de todas as confirmações em uma ramificação .

 #!/bin/sh git filter-branch --env-filter ' OLD_EMAIL="your-old-email@example.com" CORRECT_NAME="Your Correct Name" CORRECT_EMAIL="your-correct-email@example.com" 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 

Você pode alterar o autor do último commit usando o comando abaixo.

git commit --amend --author="Author Name "

No entanto, se você quiser alterar mais de um nome de autor comete, é um pouco complicado. Você precisa iniciar um rebase interativo e marcar commits como edit e, em seguida, alterá-los um por um e finalizar.

Comece rebasing com git rebase -i . Ele vai te mostrar algo assim.

http://sofpt.miximages.com/git/2908150343-77gex.png

Altere a palavra-chave pick para edit para os commits que você deseja alterar o nome do autor.

http://sofpt.miximages.com/git/2908150344-ii246.png

Em seguida, feche o editor. Para os iniciantes, pressione Escape e digite :wq e pressione Enter .

Então você verá seu terminal como se nada tivesse acontecido. Na verdade você está no meio de um rebase interativo. Agora é hora de alterar o nome do autor do commit usando o comando acima. Ele irá abrir o editor novamente. Saia e continue rebase com git rebase --continue . Repita o mesmo para a contagem de commits que você deseja editar. Você pode certificar-se de que o rebase interativo tenha terminado quando você receber o No rebase in progress? mensagem.

  • Redefina seu email para a configuração globalmente:

    git config --global user.email example@email.com

  • Agora redefina o autor do seu commit sem edição necessária:

    git commit --amend --reset-author --no-edit

As respostas na pergunta à qual você ligou são boas respostas e cobrem sua situação (a outra pergunta é mais geral, pois envolve rewrite vários commits).

Como desculpa para experimentar o git filter-branch , escrevi um script para rewrite o nome do autor e / ou e-mail do autor para um determinado commit:

 #!/bin/sh # # Change the author name and/or email of a single commit. # # change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]] # # If -f is supplied it is passed to "git filter-branch". # # If  is not provided or is empty HEAD will be used. # Use "--all" or a space separated list (eg "master next") to rewrite # multiple branches. # # If  (or ) is not provided or is empty, the normal # user.name (user.email) Git configuration value will be used. # force='' if test "x$1" = "xf"; then force='-f' shift fi die() { printf '%s\n' "$@" exit 128 } targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit" br="${2:-HEAD}" TARG_COMMIT="$targ" TARG_NAME="${3-}" TARG_EMAIL="${4-}" export TARG_COMMIT TARG_NAME TARG_EMAIL filt=' if test "$GIT_COMMIT" = "$TARG_COMMIT"; then if test -n "$TARG_EMAIL"; then GIT_AUTHOR_EMAIL="$TARG_EMAIL" export GIT_AUTHOR_EMAIL else unset GIT_AUTHOR_EMAIL fi if test -n "$TARG_NAME"; then GIT_AUTHOR_NAME="$TARG_NAME" export GIT_AUTHOR_NAME else unset GIT_AUTHOR_NAME fi fi ' git filter-branch $force --env-filter "$filt" -- $br 

Ao fazer o git rebase -i há este bit interessante no doc:

Se você quiser dobrar dois ou mais commits em um, substitua o comando "pick" pelo segundo commit e subseqüentes com "squash" ou "fixup" . Se os commits tiverem autores diferentes, o commit dobrado será atribuído ao autor do primeiro commit. A mensagem de commit sugerida para o commit dobrado é a concatenação das mensagens de commit do primeiro commit e daquelas com o comando "squash" , mas omite as mensagens de commit de commits com o comando "fixup" .

  • Se você tem um histórico de ABCDEF ,
  • e você quer mudar os commits B e D (= 2 commits),

então você pode fazer:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • crie commits vazios (um para cada commit):
    • você precisa de uma mensagem para fins de rebase
    • git commit --allow-empty -m "empty"
  • iniciar a operação de rebase
    • git rebase -i B^
    • B^ seleciona o pai de B
  • você vai querer colocar um commit vazio antes de cada commit para modificar
  • você vai querer mudar de pick para squash para aqueles.

Exemplo de qual git rebase -i B^ lhe dará:

 pick sha-commit-B some message pick sha-commit-C some message pick sha-commit-D some message pick sha-commit-E some message pick sha-commit-F some message # pick sha-commit-empty1 empty # pick sha-commit-empty2 empty 

mude isso para:

 # change commit B's author pick sha-commit-empty1 empty squash sha-commit-B some message # leave commit C alone pick sha-commit-C some message # change commit D's author pick sha-commit-empty2 empty squash sha-commit-D some message # leave commit EF alone pick sha-commit-E some message pick sha-commit-F some message 

Ele solicitará que você edite as mensagens:

 # This is a combination of 2 commits. # The first commit's message is: empty # This is the 2nd commit message: ...some useful commit message there... 

e você pode apenas remover as primeiras linhas.

Há um passo adicional para a resposta de Amber se você estiver usando um repository centralizado:

git push -f para forçar a atualização do repository central.

Tenha cuidado para que não haja muitas pessoas trabalhando no mesmo ramo, pois isso pode arruinar a consistência.

Confirme antes:

insira a descrição da imagem aqui

Para corrigir o autor de todos os commits, você pode aplicar o comando da resposta do @ Amber:

 git commit --amend --author="Author Name " 

Ou, para reutilizar seu nome e e-mail, basta escrever:

 git commit --amend --author=Eugen 

Confirme após o comando:

insira a descrição da imagem aqui

Por exemplo, para alterar tudo a partir de 4025621 :

insira a descrição da imagem aqui

Você deve executar:

 git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621 

ou adicione este alias em ~/.gitconfig :

 [alias] reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' -- 

E então corra:

 git reauthor 4025621 Eugen