Como faço para reformular a primeira mensagem do git commit?

116

Eu tenho uma árvore de trabalho contendo 3 commmits:

➜ ~ meuprojeto git: (mestre) git log

commit a99cce8240495de29254b5df8745e41815db5a75
Author: My Name <[email protected]>
Date:   Thu Aug 16 00:59:05 2012 +0200

    .gitignore edits

commit 5bccda674c7ca51e849741290530a0d48efd69e8
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:36:39 2012 +0200

    Create .gitignore file

commit 6707a66191c84ec6fbf148f8f1c3e8ac83453ae3
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:13:05 2012 +0200

    Initial commit (with a misleading message)

Agora eu desejo a rewordmensagem de commit do meu primeiro commit (6707a66)

➜ ~ meuprojeto git: (mestre) git rebase -i 6707

(... entrando no vim)

pick 5bccda6 Create .gitignore file
pick a99cce8 .gitignore edits

# Rebase 6707a66..a99cce8 onto 6707a66
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

Neste caso, desejo corrigir ( rewordem linguagem git) a mensagem de commit em questão:

Confirmação inicial (com uma mensagem enganosa)

… Para algo apropriado.

Sem surpresa, minha tentativa acima não teve sucesso, pois o primeiro commit obviamente não tem nenhum commit pai . (E quando você rebase, você precisa fazer referência ao próximo commit mais antigo antes daquele que você deseja reword, certo?)

A essência da minha pergunta, portanto, você pode conseguir isso por qualquer outro meio de fazê-lo?

Henrik
fonte
Ou você pode simplesmente deixá-lo para sempre como uma peculiaridade espalhafatosa do
Christopher de
4
possível duplicata de Mudando a mensagem do primeiro commit? (git)
Mark Longair de
^ É verdade ... Achei que tivesse pesquisado adequadamente esta questão em particular, mas é a mesma que a minha. Lá vai uma grande quantidade de aperfeiçoamento de redação da minha pergunta. :-P
Henrik
1
@hced: :) seus direitos autorais não vão para o lixo - vai ajudar outras pessoas a encontrar uma solução no futuro, mesmo que seja fechada como uma duplicata
Mark Longair
2
Qualquer pessoa que se deparar com esta questão pode encontrar minha resposta para Alterar a mensagem do primeiro commit? (git) para ser útil.

Respostas:

214

Faz git rebase -i --root

(aponte para em rootvez de apontar para um commit específico)

Desta forma, o primeiro commit também está incluído e você pode rewordfazer como qualquer outro commit.

A --rootopção foi introduzida no Git v1.7.12(2012). Antes, a única opção era usar filter-branchou --amend, que normalmente é mais difícil de fazer.

Nota: veja também esta pergunta e resposta semelhante .

florisla
fonte
12

Você sempre pode usar git filter-branch --msg-filter:

git filter-branch --msg-filter \
  'test $GIT_COMMIT = '$(git rev-list --reverse master |head -n1)' &&
echo "Nice message" || cat' master
fork0
fonte
1
fork0: Isso é ótimo, obrigado. Curioso, deve ser considerada prática "legítima", por falta de palavra melhor. Quer dizer, é comum / recomendado fazer assim? Além disso, você pode fazer isso uma e outra vez em casos com mensagens de confirmação incorretas? A razão para perguntar isso é porque eu fiz isso primeiro com o commit errado SHA-1, copiando seu snippet (o seu foi o commit mais recente, enquanto eu queria mudar o primeiro). Depois de usar o comando mais uma vez, desta vez com o SHA-1 correto (primeiro commit; 6707a66), ele vomitou em mim.
Henrik de
Bem, é comum :) E sim, você pode repetir. Se você apenas adicionar, -fele irá em frente e sempre reescreverá os commits do branch fornecido. O valor de referência do ramo da primeira vez foi salvo em refs/original/master, antes de você executar o comando.
fork0
Claro, você pode simplesmente remover (ou renomear) a referência salva.
fork0
2
Eu atualizei o código para ter certeza de que o erro com o ID de confirmação copiado não aconteça. Agora o código pode ser copiado e colado. Uma palavra de advertência , porém: não funciona corretamente se houver mais de um commit inicial (ou seja, quando você mesclou dois ou mais branches não relacionados)
fork0
3
@hced: Você deve estar ciente de que reescrever qualquer commit que seja considerado "histórico publicado" geralmente é uma má ideia. No seu caso, isso significaria que você geralmente não deveria fazer isso se alguém mais estivesse trabalhando em um commit que tinha seu commit root como ancestral.
Mark Longair de
12

A essência do pcreux tem uma boa maneira de reformular o primeiro commit:

# You can't use rebase -i here since it takes the parent commit as argument.
# You can do the following though:
git checkout FIRST_COMMIT_SHA && git commit --amend && git rebase HEAD master
Douglas
fonte
3
A partir do git 1.7.12 , git rebase -i --rooté o caminho a seguir, conforme sugerido por florisla.
Douglas