O rebase interativo é às vezes chamado de “Swiss Army Knife” de Git – porque ele contém tantas ferramentas diferentes, para tantos casos de uso diferentes! Entretanto, há um caso de uso principal e abrangente: limpeza do seu histórico de commit local.
Mente a palavra “local”: ela só deve ser usada para limpar o seu próprio histórico de commit local, por exemplo, antes de integrar um dos seus ramos de características em um ramo de equipe. Em contraste, ele NÃO deve ser usado no histórico de commit que já foi empurrado e compartilhado em um repositório remoto. Rebase interativo é uma daquelas ferramentas que “reescrevem” o histórico de Git – e você não deve fazer isso em commits que já foram compartilhados com outros.
Com esta pequena mensagem de aviso fora do caminho, vamos ver alguns exemplos práticos!
Nota: para facilitar a visualização dos cenários e fluxos de trabalho neste post, eu tenho usado a GUI “Torre” do desktop Git em algumas das minhas telas.
Corrigindo uma mensagem de commit antiga
Algumas vezes você nota um erro de digitação em uma mensagem de commit antiga – ou você esqueceu de mencionar algo na descrição que é digno de nota. Se estivéssemos a falar da última submissão, poderíamos simplesmente ter usado a opção --amend
do comando git commit
. Mas para commits antigos você terá que usar o rebase interativo para mudá-los após o fato.
Aqui está um exemplo de uma mensagem de commit que deu horrivelmente errado que queremos corrigir:
Uma mensagem de commit ruim que precisa de correção
O primeiro passo em qualquer sessão de rebase interativa é determinar qual parte do histórico de commit que você quer manipular. Para novamente tomar o exemplo acima: para mudar esta má submissão temos que iniciar a sessão na sua submissão pai.
Iniciando a nossa sessão de rebase interativa
Agora podemos alimentar este hash de inicialização da submissão com o comando rebase interativa:
$ git rebase -i 0023cddd
A janela do editor irá agora abrir, contendo uma lista das submissões que você acabou de selecionar para manipulação. E não se surpreenda porque eles estão na ordem reversa: em uma sessão de rebase interativa, Git reaplicará as antigas commits, item após item – o que significa que reverter a ordem está correto da perspectiva de Git.
Janela do editor com as commits selecionadas
Uma outra coisa importante a notar sobre esta janela do editor: você não executa as manipulações reais aqui! Ou, neste exemplo concreto, você NÃO vai em frente e muda a mensagem de commit aqui. Em vez disso, você apenas marca o commit que você quer alterar com uma palavra-chave de ação. No nosso caso, porque queremos mudar a mensagem de commit, marcamos a linha com “reword”. Se depois guardares e fechares esta janela do editor, abrirá uma nova, contendo a mensagem de submissão antiga. Agora é a hora de finalmente fazer suas alterações:
Finalmente, podemos fazer nossas alterações
Após salvar e fechar mais uma vez, a sessão de rebase interativo está completa e nossa antiga mensagem de commit foi corrigida!
Combinando múltiplos commits em um
Outro caso de uso para rebase interativo é quando você quer combinar múltiplos comentários antigos em um. Embora, é claro, a regra de ouro do controle de versão se aplica: na maioria das situações, é benéfico criar mais e menores commits ao invés de alguns grandes. No entanto, como com tudo, podemos descobrir que exageramos e agora queremos fundir dois ou mais commits antigos em um só.
Para fazer um exemplo concreto, digamos que queremos combinar as seguintes commits selecionadas em uma única:
Vamos combinar várias commits em uma
Apenas como no nosso primeiro caso, começamos por iniciar a sessão de rebase interativa pelo menos na commit pai da que queremos manipular.
$ git rebase -i 2b504bee
Again, uma janela do editor irá abrir, listando a parte do nosso histórico de commit que queremos manipular:
Marcar linhas com “squash”
A palavra-chave action que vamos usar aqui chama-se “squash”. E há apenas uma informação importante que você precisa saber sobre squash para poder usá-lo: a linha que marcarmos com a palavra-chave “squash” será combinada com a linha diretamente acima. É por isso que, como podem ver no meu screenshot acima, marquei a linha #2 com “squash” para a combinar com a linha #1.
Agora podemos salvar e fechar a janela do editor e novamente assistir e uma nova janela aparece: agora pedimos para fornecer uma mensagem de commit para o novo commit que é criado ao combinar aqueles dois antigos.
Entrar uma nova mensagem para a nova submissão, squashed commit
Após salvar e fechar esta janela do editor, você verá que foi criada uma nova submissão que contém os conjuntos de alterações de ambas as antigas submissões. Voila!
Fixando um erro
Outro caso de uso para rebase interativo é quando você encontrou um erro em uma de suas commits anteriores. E não importa o que exatamente você estragou: você poderia ter esquecido de adicionar uma certa mudança, deveria ter apagado um arquivo, ou simplesmente introduzido um erro de digitação…
A tendência natural, em tal situação, é simplesmente criar um novo commit que corrija o erro. Mas por outro lado, isto vai estragar a nossa história de commit: fazer um commit original, e depois adicionar um “band-aid” commit apenas para corrigir alguns erros… é uma forma confusa de trabalhar. Seu histórico de commits logo se tornará difícil de entender, porque está repleto de todos aqueles pequenos “quick fix commits”!
Aqui é onde o “fixup”, uma das ferramentas que vem com o rebase interativo, vem muito a mão. Fixup pega essa “quick fixup” commit, aplica suas alterações na commit original (corrigindo-a assim), e então se livra da band-aid commit:
Como “fixup” funciona
Depois de terminarmos, parece que nunca houve um problema com a nossa commit original! Então vamos caminhar através disto usando um exemplo prático.
O primeiro passo é fazer o que for necessário para corrigir o problema: isto pode significar adicionar um novo arquivo, fazer alterações nos existentes, apagar arquivos obsoletos… você “apenas” precisa produzir as alterações que corrigem o erro.
O próximo passo é submeter essas alterações ao repositório – mas com um pequeno extra: ao fazer o commit, vamos usar a bandeira --fixup
e dizer ao Git o hash de commit do nosso commit ruim:
$ git add corrections.txt$ git commit --fixup 2b504bee
Quando você agora der uma olhada no histórico de commit, você verá que um commit de aparência bastante comum foi criado – provavelmente não a magia e fogos de artifício que você esperaria. Mas se você der uma olhada mais de perto, você verá que algo está acontecendo: a nova submissão foi automaticamente preparada com “fixup !” e o assunto da nossa má submissão.
A submissão original e a correção da submissão
O terceiro passo agora é iniciar a sessão de rebase interativa. Mais uma vez, escolhemos o pai da nossa má submissão como ponto de partida…
$ git rebase -i 0023cddd --autosquash
$ git rebase -i 0023cddd --autosquash
… e como segunda parte do molho secreto, estamos a usar a bandeira --autosquash
. Esta opção garante que não temos de fazer nada na janela do editor que está agora aberta. Dê uma olhada na situação:
A nossa correção de commit está marcada como “fixup” e ordenada na posição certa
Você verá que Git automaticamente fez duas coisas para nós:
- Marcou a nossa correção de commit como “fixup”.”
- Reordenou as linhas para que nosso band-aid commit apareça diretamente abaixo do nosso bad commit. Isto é porque o fixup funciona exatamente como o squash no qual ele combina com a linha acima.
Em outras palavras: não há nada mais a fazer por nós além de salvar e fechar a janela do editor.
Vamos dar outra olhada no histórico de commit:
Um final feliz!
Não apenas o nosso commit originalmente ruim agora contém as mudanças do nosso commit do band-aid. Mas, além disso, o feio band-aid commit desapareceu da história do commit! Tudo é bom e limpo, como se nunca tivesse havido um problema!
Descubra o poder do rebase interativo
Existem muitos casos de uso para rebase interativo – e a maioria deles no departamento de “corrigir erros”. Para uma visão geral de outras coisas úteis que você pode fazer, eu recomendo o “First Aid Kit for Git” gratuito: é uma coleção de vídeos curtos (2-3 min por episódio) que ajudam você a aprender a desfazer erros usando rebase interativo e outras ferramentas de Git.
Editor’s note: Eu tive que usar rebase interativo ao rever este mesmo post! Um dos meus commits incluiu uma imagem que era maior que 1MB o que é contra as regras do projeto do site GitLab. Eu tive que voltar e corrigir esse commit para incluir uma imagem de tamanho correto em vez disso. Obrigado pela lição, universo! 😁
Mais dicas e truques de Git
- 15 Dicas de Git para melhorar seu fluxo de trabalho
- Como Git Partial Clone permite que você pegue apenas o arquivo grande que você precisa
- Git acontece! 6 Erros comuns de Git e como corrigi-los
Sobre o autor convidado
Tobias Günther é o CEO da Tower, o popular cliente desktop Git que ajuda mais de 100.000 desenvolvedores ao redor do mundo a serem mais produtivos com Git.
Cobrir imagem de David Taljat em Pexels