Na outra manhã eu estava passando por um monte de mudanças e dividindo-as em vários commits. Depois de alguns commits, vi um arquivo alterado que deveria ter incluído dois commits de volta. Você pode fazer um git commit --amend
para adicionar sua mudança em estágios ao commit anterior, mas adicionar isso a um commit mais atrás no histórico é um pouco mais complicado.
Mas não impossível. git rebase -i
é uma ferramenta que você pode usar, para o bem ou para o mal, para fazer todos os tipos de manipulação de histórico. Veja como você pode usá-lo para alterar um commit dois commits de volta.
Então, novamente, a situação é que você tem dois commits e uma mudança (to file1b
) que deveria ter entrado no primeiro commit.
$ git log --oneline
93c0d5c change to file2
9703cef change to file1a
A primeira coisa a fazer é comprometer sua mudança.
$ git add file1b
$ git commit -m "forgot to add this 2 commits ago"
$ git log --oneline
1a48423 forgot to add this 2 commits ago
93c0d5c change to file2
9703cef change to file1a
Agora inicie o rebase interativo selecionando o commit do qual iniciar a manipulação. Aqui, estamos começando com três commits anteriores.
$ git rebase -i HEAD~3
Você entrará em seu $EDITOR
e verá algo assim:
pick 9703cef change to file1a
pick 93c0d5c change to file2
pick 1a48423 forgot to add this 2 commits ago
Mude para ficar assim:
pick 9703cef change to file1a
squash 1a48423 forgot to add this 2 commits ago
pick 93c0d5c change to file2
(Mova o commit esquecido logo após o commit, deve-se adicionar dois, e mudar “pick” para “squash”.)
Quando você salvar e sair, o git o trará de volta ao seu $EDITOR
e pedirá que você edite sua mensagem de confirmação:
# This is a combination of 2 commits.
# The first commit's message is:
change to file1a
# This is the 2nd commit message:
forgot to add this 2 commits ago
Neste exemplo específico, posso me livrar da mensagem “esqueci …” e alterar a mensagem “mudar para arquivo1a”. Salve e saia, e git vai de squash comprometer 1a48423
em 9703cef
–making-los um commit.
Com o rebase interativo, o git permite que você altere o passado de maneiras que podem ser realmente perigosas. E você realmente não deveria fazer isso em commits já enviados para um controle remoto. Mas este é um caso em que acho que é extremamente valioso.