Como edito uma mensagem de confirmação incorreta no git (enviada por mim)?

152

Quero modificar uma mensagem de confirmação mais profunda na história e enviei muitas novas confirmações.

Como altero a mensagem de confirmação? É possível?

Mehdi Raash
fonte

Respostas:

125

A mensagem de Linus Torvalds pode responder à sua pergunta:

Modificar / editar mensagens de confirmação antigas

Resposta curta: você não pode (se pressionado).


extrato (Linus se refere ao BitKeeper como BK):

Nota lateral, apenas por interesse histórico: em BK você poderia.

E se você está acostumado (como eu), foi realmente bastante prático. Eu aplicaria uma bomba de remendo de Andrew, notaria que algo estava errado e a editaria antes de empurrá-la para fora.

Eu poderia ter feito o mesmo com o git. Teria sido fácil o suficiente fazer com que apenas a mensagem de confirmação não fizesse parte do nome e ainda assim garantir que o histórico não foi tocado e permitir a coisa "corrigir comentários mais tarde".

Mas eu não fiz.

Parte disso é puramente "consistência interna". O Git é simplesmente um sistema mais limpo , graças a tudo ser protegido por SHA1 e a todos os objetos serem tratados da mesma forma, independentemente do tipo de objeto. Sim, existem quatro tipos diferentes de objetos, e todos são realmente diferentes, e não podem ser usados ​​da mesma maneira, mas ao mesmo tempo, mesmo que sua codificação possa ser diferente no disco, conceitualmente todos funcionam exatamente o mesmo.

Mas a consistência interna não é realmente uma desculpa para ser inflexível, e claramente seria muito flexível se pudéssemos corrigir os erros depois que eles acontecessem. Portanto, esse não é um argumento muito forte.

A verdadeira razão pela qual o git não permite alterar a mensagem de confirmação acaba sendo muito simples: dessa forma, você pode confiar nas mensagens. Se você permitir que as pessoas as alterem posteriormente, as mensagens não são inerentemente muito confiáveis.


Para concluir, você pode reescrever o histórico de consolidação local para refletir o que deseja, conforme sugerido por sykora (com algumas alterações e redefinições --hard, gasp!)

No entanto, depois de publicar seu histórico revisado novamente (com a git push origin +master:master, o +sinal forçando a ocorrência do envio, mesmo que não resulte em uma confirmação "de avanço rápido") ... você pode ter problemas .

Extraia desta outra questão SO:

Na verdade, uma vez empurrei o --force para o repositório git.git e fui repreendido por Linus BIG TIME. Isso criará muitos problemas para outras pessoas. Uma resposta simples é "não faça".

VonC
fonte
boa resposta. Você sabe se agora você pode alterar as mensagens de envio já enviadas nas versões mais recentes do git? Alguma coisa mudou desde que foi publicada em '09?
David West
@ David David O mesmo princípio é válido: você pode reescrever sua história e forçar um empurrão.
VonC
2
Para tornar as coisas mais específicas, se você alterar / refazer as confirmações, seus identificadores de confirmação (hashes hexadecimais no índice git) mudam inevitavelmente; significa que as confirmações editadas são tratadas de maneira diferente das confirmações antigas na história do git VCS. Dito isto, se os membros da sua equipe de desenvolvimento, infelizmente, já tiverem retirado os commits antigos, eles são obrigados a extrair os editados, os novos commits e a fazer uma fusão entre o antigo e o novo em suas cópias de trabalho locais.
Shigerello
1
É melhor empurrar os commits editados de novo para conveniência dos seus colegas, removendo assim a necessidade de mesclagem nas cópias de trabalho dos colegas.
Shigerello
28

Atualmente, uma substituição do git pode fazer o truque.

Em detalhes: criar uma ramificação de trabalho temporária

git checkout -b temp

Redefinir para confirmar para substituir

git reset --hard <sha1>

Alterar o commit com a mensagem certa

git commit --amend -m "<right message>"

Substitua o antigo commit pelo novo

git replace <old commit sha1> <new commit sha1>

volte para o ramo onde você estava

git checkout <branch>

remover ramo temporário

git branch -D temp

empurrar

guess

feito.

Johan
fonte
11
@Jonah: Estou recebendo uma mensagem "Tudo up-to-date" quando tento empurrar para o ramo remoto
Simon Kagwi
1
Como mencionado em outra resposta: use rebase -i com reword. E vai reescrever a história.
Sylvain
Obrigado pela solução que eu estava procurando. Você economiza meu tempo!
Tomasz Kuter
1
@ Jonah - Estou com um problema ... sua solução atualizou meus logs de consolidação localmente, mas não remotamente. Como empurrá-los para lá?
Tomasz Kuter
1
@ TomaszKuter, eu tive o mesmo problema que você. Minha mensagem de confirmação não foi atualizada remotamente. Eu o resolvi usando a seguinte ajuda do GitHub: help.github.com/articles/changing-a-commit-message . Siga a seção: Alterando a mensagem de mensagens de confirmação mais antigas ou múltiplas. É basicamente a resposta abaixo fornecida pelo usuário987419 Se você já alterou a mensagem de confirmação, poderá escolher e salvar sem precisar alterá-la novamente.
Evaldeslacasa
19

Você pode usar git rebase -i(contra o ramo de onde você ramificou) 'i' para interativo.

Substitua o pickpróximo ao comentário de confirmação com o qual deseja alterar r(ou reword), salve e saia e, ao fazer isso, você poderá fazer a edição.

git push mais uma vez e pronto!

Marcus
fonte
1
Isso não permite editar mensagens em confirmações de mesclagem. Isso é possível com alguma variante deste comando?
Andrew Mao
1
Tente o -pargumento de rebasequais preservas são mescladas.
Cactus
3
Eu gosto desse procedimento, mas não entendi direito a resposta no começo. No caso em que alguém precisa de ajuda com ele, o Githulb Ajuda página oferece boas informações sobre ele: help.github.com/articles/changing-a-commit-message
evaldeslacasa
15

Suponha que você tenha uma árvore como esta:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

Primeiro, checkoutum ramo temporário:

git checkout -b temp

Na tempramificação, reset --hardpara um commit que você deseja alterar sua mensagem (por exemplo, esse commit é 946992):

git reset --hard 946992

Use amendpara alterar a mensagem:

git commit --amend -m "<new_message>"

Depois disso, a árvore ficará assim:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Então, cherry-picktoda a cometer esse é antes de 946992partir masterpara tempe cometê-los, use amendse você deseja alterar as suas mensagens, bem como:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

A árvore agora fica assim:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Agora force o push do branch temp para controle remoto:

git push --force origin temp:master

A etapa final, exclua a ramificação masterno local, git fetch originpara extrair a ramificação masterdo servidor, depois alterne para ramificação mastere exclua a ramificação temp.

Agora, tanto o local quanto o remoto, terão todas as mensagens atualizadas.

Huy Vo
fonte
5

Em nossa loja, introduzi a convenção de adicionar tags anotadas com nomes reconhecíveis para confirmar com mensagens incorretas e usar a anotação como substituta.

Mesmo que isso não ajude as pessoas que executam comandos casuais "git log", ele nos fornece uma maneira de corrigir referências incorretas de rastreadores de erros nos comentários, e todas as minhas ferramentas de compilação e lançamento entendem a convenção.

Obviamente, essa não é uma resposta genérica, mas pode ser algo que as pessoas possam adotar em comunidades específicas. Tenho certeza que se for usado em uma escala maior, algum tipo de suporte de porcelana poderá surgir, eventualmente ...

Christian Goetze
fonte
3
"notas git" pode servir a um propósito semelhante
Christian Goetze
2

(De http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )

Como mudar compromete-se mais profundamente na história

Como o histórico no Git é imutável, a correção de qualquer coisa, exceto o commit mais recente (commit que não é cabeça de ramificação), requer que o histórico seja reescrito a partir do commit alterado e para a frente.

Você pode usar o StGIT para isso, inicializar a ramificação, se necessário, comprometendo-se com a confirmação que deseja alterar, acessá-la se necessário, fazer uma alteração e atualizar o patch (com a opção -e se desejar corrigir a mensagem de confirmação) e pressione tudo e stg cometem.

Ou você pode usar rebase para fazer isso. Crie uma nova ramificação temporária, rebobine-a para o commit que você deseja alterar usando git reset --hard, altere esse commit (seria o topo do cabeçalho atual) e depois rebase o branch em cima do commit alterado, usando git rebase --onto.

Ou você pode usar o git rebase --interactive, que permite várias modificações, como reordenação de patches, recolhimento, ...

Eu acho que isso deveria responder sua pergunta. No entanto, observe que, se você empurrou o código para um repositório remoto e as pessoas o retiraram, isso atrapalha o histórico de códigos e o trabalho que eles fizeram. Então faça com cuidado.

sykora
fonte
Boa resposta, em teoria, bem perigoso na prática: ver stackoverflow.com/questions/253055#432518
VonC
0

Se você estiver usando extensões Git: vá para a tela Confirmar, deve haver uma caixa de seleção que diz "Alterar confirmação" na parte inferior, como pode ser visto abaixo:

insira a descrição da imagem aqui

batsheva
fonte
@KrunalPandya sim, ou apenas pressione commit e push
batsheva