Rebase: reescrevendo o histórico
1. Fundamentos do Rebase
O git rebase é uma ferramenta poderosa que permite reescrever o histórico de commits de um repositório Git. Diferentemente do merge, que cria um commit de fusão explícito, o rebase reaplica commits de uma branch sobre outra base, resultando em um histórico linear e mais limpo.
O mecanismo interno do rebase funciona da seguinte forma: ele identifica os commits que estão na branch atual mas não estão na branch alvo, "desfaz" temporariamente esses commits, move o ponteiro da branch para o commit mais recente da branch alvo e, em seguida, reaplica cada commit um a um sobre essa nova base.
Casos de uso típicos incluem:
- Rebase: quando você quer manter um histórico linear e limpo, especialmente em branches de feature antes de integrá-las
- Merge: quando você precisa preservar o contexto de que uma branch foi integrada em outra, ou em branches compartilhadas com múltiplos colaboradores
2. Rebase Básico: Linearizando o Histórico
A sintaxe básica do rebase é simples. Suponha que você tenha uma branch feature com dois commits e deseja integrá-la na main:
# Na branch feature
git checkout feature
git rebase main
Exemplo prático completo:
# Criando cenário de exemplo
git init rebase-exemplo
cd rebase-exemplo
echo "versão 1" > arquivo.txt
git add arquivo.txt
git commit -m "Commit inicial na main"
git checkout -b feature
echo "feature trabalho 1" >> arquivo.txt
git commit -am "Adiciona primeira funcionalidade"
echo "feature trabalho 2" >> arquivo.txt
git commit -am "Adiciona segunda funcionalidade"
git checkout main
echo "correção urgente" >> arquivo.txt
git commit -am "Correção na main"
# Rebase da feature sobre a main
git checkout feature
git rebase main
# Verificando o resultado
git log --graph --oneline --all
O resultado será um histórico linear onde os commits da feature aparecem após o commit mais recente da main, como se tivessem sido feitos sequencialmente.
3. Rebase Interativo: Controle Total sobre os Commits
O rebase interativo oferece controle granular sobre cada commit. Inicie-o com:
git rebase -i HEAD~3
Isso abrirá um editor com uma lista de commits e comandos disponíveis:
pick a1b2c3d Primeiro commit
pick e4f5g6h Segundo commit
pick i7j8k9l Terceiro commit
Os principais comandos são:
- pick: mantém o commit como está
- reword: altera apenas a mensagem do commit
- edit: pausa o rebase para modificar o conteúdo do commit
- squash: mescla o commit com o anterior e permite editar a mensagem combinada
- fixup: mescla o commit com o anterior descartando sua mensagem
- drop: remove o commit do histórico
4. Squash e Fixup: Limpeza de Commits
Suponha que você tenha uma série de commits "sujos" que deseja limpar:
git log --oneline
# Saída:
# d4e5f6g Correção final
# c3d4e5f Ajuste no código
# b2c3d4e WIP: implementação inicial
# a1b2c3d Commit inicial
Para transformar esses commits em um único commit limpo:
git rebase -i a1b2c3d
No editor, reorganize para:
pick a1b2c3d Commit inicial
pick b2c3d4e WIP: implementação inicial
squash c3d4e5f Ajuste no código
fixup d4e5f6g Correção final
Com squash, você poderá editar a mensagem combinada. Com fixup, a mensagem do commit é descartada automaticamente.
5. Reordenando e Editando Commits
Para reordenar commits, basta alterar a ordem das linhas no editor do rebase interativo:
pick c3d4e5f Ajuste no código
pick b2c3d4e WIP: implementação inicial
pick d4e5f6g Correção final
Para editar uma mensagem de commit, use reword:
reword b2c3d4e WIP: implementação inicial
O Git abrirá o editor para que você modifique a mensagem.
Para modificar o conteúdo de um commit, use edit:
edit b2c3d4e WIP: implementação inicial
Quando o rebase pausar, faça as alterações necessárias, adicione os arquivos e execute:
git commit --amend
git rebase --continue
6. Conflitos Durante o Rebase
Durante o rebase, cada commit é reaplicado individualmente, o que significa que conflitos podem surgir em qualquer um deles. O Git pausa o rebase no commit problemático:
git rebase main
# Conflito ao reaplicar commit "Adiciona primeira funcionalidade"
Para resolver:
1. Edite os arquivos conflitantes
2. Use git mergetool para uma interface visual (opcional)
3. Adicione os arquivos resolvidos: git add arquivo.txt
4. Continue o rebase: git rebase --continue
Se necessário:
- git rebase --abort: retorna ao estado anterior ao rebase
- git rebase --skip: pula o commit problemático (remove-o do histórico)
7. Cuidados e Boas Práticas
A regra de ouro do rebase: nunca faça rebase em commits que já foram enviados para um repositório remoto compartilhado. Reescrever o histórico público causa confusão e problemas de sincronização para outros desenvolvedores.
Diferenças importantes:
- Rebase: ideal para branches locais e de feature antes do merge
- Merge: recomendado para branches compartilhadas e para preservar o contexto de integração
Antes de fazer push, verifique o histórico:
git log --oneline
git diff main..feature
Configure o pull com rebase automático:
git config --global pull.rebase true
8. Recuperação e Cenários Avançados
Se um rebase der errado, o git reflog é seu salva-vidas:
git reflog
# Encontre o commit anterior ao rebase
git reset --hard HEAD@{2}
O rebase com --onto permite mover uma sequência de commits para outra base:
# Move commits do branch feature para uma nova base
git rebase --onto main feature~3 feature
Para atualizar sua branch com a main usando rebase:
git pull --rebase origin main
Isso evita commits de merge desnecessários e mantém o histórico linear.
O rebase é uma ferramenta essencial para manter um histórico Git limpo e compreensível. Quando usado corretamente, especialmente em branches locais e de feature, ele transforma um histórico caótico de desenvolvimento em uma narrativa clara e profissional das mudanças no código.
Referências
- Documentação Oficial do Git - Rebase — Referência completa sobre o comando rebase, incluindo todas as opções e flags disponíveis
- Atlassian Git Tutorial - Merging vs. Rebasing — Guia prático comparando merge e rebase com exemplos visuais e casos de uso
- Git SCM Book - Rebasing — Capítulo oficial do livro Pro Git explicando os fundamentos e práticas recomendadas de rebase
- GitHub Blog - Git Rebase: A Guide for Beginners — Tutorial introdutório do GitHub com exemplos passo a passo para iniciantes
- Git Rebase Interactive Mode - FreeCodeCamp — Artigo detalhado sobre o modo interativo do rebase com squash, fixup e reword
- Stack Overflow - How to Recover from a Git Rebase — Discussão comunitária sobre cenários de recuperação após rebase mal-sucedido
- GitLab Documentation - Rebase and Merge Strategies — Documentação do GitLab sobre estratégias de rebase e merge em fluxos de trabalho colaborativos