Como alterar o autor da confirmação para uma confirmação específica?

Respostas:

3567

Rebase interativo fora de um ponto anterior no histórico que o commit que você precisa modificar ( git rebase -i <earliercommit>). Na lista de confirmações que estão sendo reformuladas, altere o texto de pickpara editpróximo ao hash do que você deseja modificar. Então, quando o git solicitar que você altere o commit, use o seguinte:

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

Por exemplo, se seu histórico de confirmação estiver A-B-C-D-E-Fcom Fas HEADe você desejar alterar o autor de Ce D, então você ...

  1. Especifique git rebase -i B( aqui está um exemplo do que você verá após executar o git rebase -i Bcomando )
    • se você precisar editar A, usegit rebase -i --root
  2. Mude as linhas para ambos Ce Dde pickparaedit
  3. Saia do editor (para o vim, pressione Esc e digite :wq).
  4. Uma vez iniciado o rebase, ele primeiro pausa em C
  5. Você poderia git commit --amend --author="Author Name <[email protected]>"
  6. Então git rebase --continue
  7. Pararia novamente às D
  8. Então você faria git commit --amend --author="Author Name <[email protected]>"novamente
  9. git rebase --continue
  10. A recuperação seria concluída.
  11. Use git push -fpara atualizar sua origem com as confirmações atualizadas.
Âmbar
fonte
90
Boa resposta, mas para iniciantes: primeiro encontrar um commit anterior a que você gostaria de mudar, em seguida, executargit rebase -i <commit>
Mathew Byrne
47
Se você não sabe em qual editor está, a resposta é provável vim. Para salvar e sair, digite Esc: wq Enter. Por outro lado, se for Nano e você vir coisas como "WriteOut: ^ O" ao longo da parte inferior, use Ctrl + O, Enter, Ctrl + X.
22612 Amber
30
e se você quiser modificar o primeiro commit? Qual é o hash de confirmação anterior, então?
Brenden
219
Use a --no-editopção git commit --amend --reset-author --no-editnão abre um editor. Disponível desde o git 1.7.9.
5lava
51
@Brenden para modificar a primeira cometer no projeto, o usogit rebase -i --root
Noah Passalacqua
488

A resposta aceita para essa pergunta é um uso maravilhosamente inteligente de rebase interativa, mas infelizmente exibe conflitos se o commit em que estamos tentando mudar o autor costumava estar em um ramo que foi posteriormente incorporado. Mais geralmente, ele não funciona ao lidar com histórias confusas.

Como estou apreensivo com a execução de scripts que dependem da configuração e da configuração de variáveis ​​de ambiente para reescrever 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 está funcionando, ao contrário da resposta vinculada. Assuma, por clareza da exposição, que 03f482d6é o commit cujo autor estamos tentando substituir e 42627abeé o commit com o novo autor.

  1. Faça o checkout do commit que estamos tentando modificar.

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

    git commit --amend --author "New Author Name <New Author Email>"
    

    Agora, temos um novo commit com hash assumido 42627abe.

  3. Faça o checkout do ramo original.

  4. Substitua o commit antigo pelo novo localmente.

    git replace 03f482d6 42627abe
    
  5. Reescreva todas as confirmações futuras com base na substituição.

    git filter-branch -- --all
    
  6. Remova a substituição para limpeza.

    git replace -d 03f482d6
    
  7. Empurre o novo histórico (use somente --force se o abaixo falhar e somente após verificar a sanidade com git loge / ou git diff).

    git push --force-with-lease
    

Em vez de 4-6, você pode apenas refazer o novo commit:

git rebase -i 42627abe
merlin2011
fonte
9
Por favor, coloque uma nota lá para re-checkout seu ramo original após o passo 2.
Benjamin Riggs
42
Parece uma alternativa muito clara ao horrível git rebase -i. Nunca ouvi falar disso git replaceantes. 1
FractalSpace
3
Para limpar as refs / original / ... de backup veja aqui
alexis
5
Eu recomendo usar em --force-with-leasevez de -f. É mais seguro.
Jay Bazuzi
11
AVISO: esteja ciente de que git filter-branch -- --allestá alterando confirmações em todas as ramificações em que a confirmação original estava. Se você não possui credenciais suficientes (ou simplesmente não deseja alterar o histórico de ramificações de outras pessoas), é bom ter cuidado com esta resposta.
Ribamar
225

A documentação do Github contém um script que substitui as informações do commit de todos os commits em uma ramificação .

  • Execute o seguinte script do terminal depois de alterar os valores das variáveis

    #!/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
    
  • Envie o histórico corrigido para o GitHub:

    git push --force --tags origin 'refs/heads/*'
    

    OU se você deseja enviar referências selecionadas dos ramos, use

    git push --force --tags origin 'refs/heads/develop'
    
olivieradam666
fonte
12
Isso muda em todas as confirmações, não apenas uma. Engraçado, eu fiz isso há menos de 30 minutos.
22415 Artjom B.
Quando encontrei essa resposta depois de ler as anteriores, achei que valeria a pena tentar e pronto, ele fez o trabalho. No entanto, no meu caso, ele mudou o nome do commit apenas no commit inicial. A propósito, antes de tentar idéias desde a primeira resposta. Talvez isso tenha afetado o sistema de alguma forma.
Ruslan Gerasimov
2
Observe que, se você evitar usar clone/ push, terá um espaço para nome de backup refs/original/. Não consegui encontrar uma maneira de remover esse espaço de nomes de forma inteligente, então acabei excluindo o diretório .git/refs/original, que funcionou.
VasiliNovikov 18/01/19
Por que isso resulta em alterações no repositório se, por exemplo, OLD_EMAIL não corresponder a nada? Por alguma razão, alguns (mas não todos!) Cometem alteração de hashes.
MJS
1
Meu caso de uso para esta resposta é: Eu tenho duas contas no Github, uma que usei involuntariamente para confirmar. Esse script ajudou a corrigir todos os meus commits, renomeando o e-mail / nomes incorretos do committer. É claro que, se eu tenho confirmado com o usuário errado, digamos, da 50ª para a 500ª, haverá 450 confirmações divergentes. De qualquer forma, depois de executar o script, como o @andrej apontou, você precisará git push -fforçar as alterações no repo.
LWY
168
  • Redefina seu email para a configuração globalmente:

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

  • Agora redefina o autor do seu commit sem a necessidade de edição:

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

pravbeatle
fonte
2
Não, não é. Olhe para o OP: It's not last commit.Então, como eles iriam amend?
underscore_d
2
Isso é ótimo, é uma pena que seja o último commit apenas. Felizmente, eu precisava dos dois últimos, felizmente, então git reset HEAD~executei as linhas sugeridas e executei o próximo commit manualmente novamente. Funcionou bem!
Matt Fletcher
2
Obrigado! O --reset-author fez o truque para mim, pois sem ele o autor muda, mas o "commiter" permanece com os detalhes do autor antigo.
Lucas P.
9
Para corrigir meus últimos seis commits: Primeiro defina o autor correto para o repositório Git atual usando git config --local user.name FirstName LastName e git config --local user.email [email protected]. Em seguida, aplique nos últimos seis commits usando git rebase --onto HEAD~6 --exec "git commit --amend --reset-author --no-edit" HEAD~6. Por fim, envie-o para o repositório Git remoto usando git push --force-with-lease.
olibre
@olibre funciona como um encanto, obrigado.
Bruno Gasparotto
88

Você pode alterar o autor da última confirmação usando o comando abaixo.

git commit --amend --author="Author Name <[email protected]>"

No entanto, se você quiser alterar mais de um nome de autor, é um pouco complicado. Você precisa iniciar uma nova reformulação interativa, marcar as confirmações como editar, alterá-las uma a uma e terminar.

Comece a rebasear com git rebase -i. Isso mostrará algo assim.

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

Altere a pickpalavra-chave para editpara as confirmações nas quais deseja alterar o nome do autor.

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

Depois feche o editor. Para os iniciantes, pressione Escapee digite :wqe 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 abrirá o editor novamente. Saia e continue com o rebase git rebase --continue. Repita o mesmo para a contagem de confirmação que você deseja editar. Você pode ter certeza de que o rebase interativo terminou quando receber a No rebase in progress?mensagem.

Fatih Acet
fonte
Você pode atualizar suas fotos?
Shimmy Weitzhandler
1
Se você tem vários commits para alterar, em vez de editá-los individualmente, também pode deixar a pickação e adicionar após cada linhaexec git commit --no-edit --amend --author="MyNewAuthor <[email protected]>"
Pierre-Olivier Vares
60

As respostas na pergunta à qual você vinculou são boas e abrangem sua situação (a outra pergunta é mais geral, pois envolve a reescrita de várias confirmações).

Como desculpa para experimentar git filter-branch, escrevi um script para reescrever o Nome do Autor e / ou o 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 <branch-to-rewrite> is not provided or is empty HEAD will be used.
#     Use "--all" or a space separated list (e.g. "master next") to rewrite
#     multiple branches.
#
#     If <new-name> (or <new-email>) is not provided or is empty, the normal
#     user.name (user.email) Git configuration value will be used.
#

force=''
if test "x$1" = "x-f"; 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
Chris Johnsen
fonte
+1 obrigado. O repositório git do assembla.com não parece alterar todas as referências de autor na exibição da Web do repositório, mas os resultados de 'git pull / clone' parecem funcionar corretamente.
Johnny Utahh 31/10/12
Ótima solução, pois altera apenas o que se destina, e não outros campos, como data de confirmação.
Guillaume Lemaître
12
Documentação Github contém um script semelhante
olivieradam666
2
@ olivieradam666 que funciona como um encanto e é mais fácil de ler
fregante
@ olivieradam666 Obrigado. Você deve realmente adicionar isso como resposta, para que receba mais atenção.
Seane
44

Confirmar antes:

insira a descrição da imagem aqui

Para corrigir o autor de todas as confirmações, você pode aplicar o comando da resposta de @ Amber:

git commit --amend --author="Author Name <[email protected]>"

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

Nota: Para incluir um autor que contenha espaços como nome e endereço de e-mail, o autor deve estar entre aspas. Por exemplo:

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <[email protected]>\"" 4025621

ou adicione esse alias em ~/.gitconfig:

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

E então execute:

git reauthor 4025621 Eugen
Eugen Konkov
fonte
1
Para verificar se o comando funcionou conforme o esperado, revisei a saída de git shortlog -e -s.
Taylor Edmiston
5
Esta é a resposta que melhor serviu aos meus propósitos, obrigado. E como eu apenas queria ajustar meu endereço de e-mail, eu poderia executar com --exec = "git commit --amend --reset-author", depois de atualizar meu arquivo .git / config.
Dato
1
Eeh, não sei por que eu esqueci! Feito agora.
Dato
Ótima resposta e muito fácil de corrigir. Ame o apelido!
J_A_X 11/04/19
isso não me ajudou. agora eu tenho erro Continue Rebase Failed
Alexey Sh.
17

Há uma etapa adicional na resposta de Amber se você estiver usando um repositório centralizado:

git push -f para forçar a atualização do repositório central.

Cuidado para não haver muitas pessoas trabalhando no mesmo ramo, pois isso pode arruinar a consistência.

Fabian76
fonte
16

Ao fazer git rebase -iisso, há uma parte interessante no documento:

Se você deseja dobrar duas ou mais confirmações em uma, substitua o comando "pick"da segunda e as confirmações subsequentes por "squash"ou "fixup". Se os commits tiverem autores diferentes, o commit dobrado será atribuído ao autor do primeiro commit. A mensagem de confirmação sugerida para a confirmação dobrada é a concatenação das mensagens de confirmação da primeira confirmação e daquelas com o "squash"comando, mas omite as mensagens de confirmação de confirmações com o "fixup"comando.

  • Se você tem um histórico de A-B-C-D-E-F ,
  • e você deseja alterar confirmações Be D(= 2 confirmações),

então você pode fazer:

  • git config user.name "Correct new name"
  • git config user.email "[email protected]"
  • crie confirmações vazias (uma para cada confirmação):
    • 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ê desejará colocar uma confirmação vazia antes de cada confirmação para modificar
  • você vai querer mudar pickpara squashpara aqueles.

Exemplo do que 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 E-F 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 simplesmente remover as primeiras linhas.

dnozay
fonte
16

Como resposta à resposta de Eugen Konkov , para iniciar a partir do commit raiz, use --rootflag. A --no-editbandeira também é útil

git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"
korwalskiy
fonte
Isso funcionou e mudou em todos os commits.
SagarKapasi099
1
Obrigado pela resposta. Tinha que adicionar --interactive para fazê-lo funcionar. git rebase --root --interactive --exec "git commit --amend --author = 'name <email>' --no-edit"
Sreeragh AR
8

Encontre uma maneira de mudar o usuário rapidamente e não tenha efeito colateral para outras pessoas.

Maneira simples e clara:

git config user.name "New User"
git config user.email "[email protected]"

git log
git rebase -i 1f1357
# change the word 'pick' to 'edit', save and exit

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

git push --force-with-lease

operações detalhadas

  • mostre os logs de confirmação e descubra o ID de confirmação que antes da sua confirmação que você deseja alterar:
git log
  • O git rebase start do id de confirmação escolhido para o recente inversamente:
git config user.name "New User"
git config user.email "[email protected]"
git rebase -i 1f1357

# change word pick to edit, save and exit
edit 809b8f7 change code order 
pick 9baaae5 add prometheus monitor kubernetes
edit 5d726c3 fix liquid escape issue   
edit 3a5f98f update tags
pick 816e21c add prometheus monitor kubernetes
  • rebase será interrompido no próximo ID de confirmação, saída:
Stopped at 809b8f7...  change code order 
You can amend the commit now, with
  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue
  • confirme e continue sua recuperação até que seja bem-sucedida refs/heads/master.
# each continue will show you an amend message
# use git commit --amend --reset-author --no-edit to comfirm
# use git rebase --skip to skip
git commit --amend --reset-author --no-edit
git rebase --continue
git commit --amend --reset-author --no-edit
...
git rebase --continue
Successfully rebased and updated refs/heads/master.
  • git push para atualizar
git push --force-with-lease
NOZUONOHIGH
fonte
5

Se a confirmação que você deseja alterar não for a última confirmação, siga as etapas abaixo. Se o seu commit estiver em uma ramificação diferente, primeiro mude para essa ramificação.

git checkout branch_name

Localize o commit antes do commit que você deseja alterar e encontre seu hash. Em seguida, emita o comando rebase.

git rebase -i -p hash de confirmação

Em seguida, um editor será aberto e digite 'edit' para as confirmações que você deseja alterar. Deixe outras pessoas com a opção padrão 'pick'. Uma vez alterado, digite a tecla 'esc' e wq! sair.

Em seguida, emita o comando git commit com a opção de alteração.

git commit --amend --author = "Nome de usuário e-mail" --no-edit

Em seguida, emita o seguinte comando.

git rebase --continuar

Depois que o autor da confirmação for atualizado no repositório local, envie as alterações para o repositório remoto.

ChannaB
fonte
Eu acho que essa é a maneira mais simples de fazer isso. Eu estava usando o comando reword e isso falha. Aprendi que preciso usar o comando de edição. Talvez a palavra-chave "editar" possa ser destacada. Obrigado pela resposta @ChannaB 👍
Berk
realmente fácil de seguir os passos. Obrigado!
Habiba
4

Há também uma abordagem preguiçosa para esse problema, especialmente se você tiver mais de um commit que deseja alterar. No meu caso, eu tinha uma nova ramificação com vários commits com um autor errado, então o que me ajudou:

Vá para o seu ramo original:

git checkout develop

Crie um novo ramo a partir dele:

git checkout -b myFeature develop 

Mesclar isso sem informações de confirmação como uma confirmação:

git merge --no-commit --squash branchWrongAuthor

Você também pode querer organizar mudanças:

git stage .

Mude o nome do autor e confirme as alterações:

git commit --amend --author "New Author Name <New Author Email>" -m "new feature added"

E é isso, você pode empurrar as mudanças.

git push

Você pode excluir a ramificação com um autor errado depois disso.

alexlz
fonte
4

Etapas para renomear o nome do autor após o envio da confirmação

  1. Primeiro digite "git log" para obter o ID de confirmação e mais detalhes
  2. git rebase i HEAD ~ 10 (10 é o total comprometido para exibir na rebase)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. Em seguida, digite "git rebase --continue" ou "git rebase --abort" conforme sua necessidade

    • agora sua janela rebase será aberta, clique na tecla "i" do teclado
    • você receberá uma lista de confirmações para 10 [porque passamos 10 confirmadas acima] Como abaixo

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. Agora você precisa adicionar o comando abaixo, logo abaixo do commit que você deseja editar, como abaixo

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <[email protected]>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <[email protected]>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <[email protected]>'

    1. É isso aí, agora basta pressionar ESC,: wq e está tudo pronto

    2. Em seguida, git push origin HEAD: FILIAL NOME -f [cuide de -f Force push]

    gosto git push -fougit push origin HEAD: dev -f

Kirtikumar A.
fonte
ótima resposta, você poderia atualizar o ponto 6 com um exemplo de git pushcomando?
Lukasz 'Severiaan' Grela 20/09/19
1
@ Lukasz'Severiaan'Grela editada, por favor verifique agora, Obrigado
Kirtikumar A.
3

Alterando seu nome e e-mail de responsável globalmente:

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

Alterando o nome e o email do responsável por repositório:

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

Alterando as informações do autor apenas para o próximo commit:

$ git commit --author="John Doe <[email protected]>"

Dica : Para outras situações e leia mais informações, leia a referência do post .

AmerllicA
fonte
2

Se o que você precisa mudar é o commit do AUTOR DO ÚLTIMO e nenhum outro está usando seu repositório, você pode desfazer seu último commit com:

git push -f origin last_commit_hash:branch_name 

altere o nome do autor do seu commit com:

git commit --amend --author "type new author here"

Saia do editor que abre e envie novamente seu código:

git push
pebox11
fonte
2

Para a mensagem de consolidação de mesclagem, descobri que não posso alterá-la usando rebase, pelo menos no gitlab. Ele mostra a mesclagem como uma confirmação, mas não posso me refazer à #sha. Achei que este post é útil.

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

Essas três linhas de código fizeram o trabalho de alterar a mensagem de confirmação de mesclagem (como autor).

Jason Liu
fonte
1

você pode usar esses comandos na página oficial do github

https://help.github.com/en/github/using-git/changing-author-info

aqui estão os comandos

#!/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

aqui você pode alterar o e-mail antigo para seu novo nome de usuário e endereço de e-mail.

Mudassir Khan
fonte