Interactive rebase para limpeza de histórico antes do PR
1. Fundamentos do Interactive Rebase
O git rebase -i (modo interativo) é uma ferramenta poderosa que permite reescrever o histórico de commits antes de enviar um Pull Request. Diferente do rebase comum, que apenas move commits para uma nova base, o interactive rebase abre um editor onde você pode modificar, unir, reordenar ou excluir commits individualmente.
Pré-requisitos essenciais:
- Commits ainda não enviados para o repositório remoto compartilhado
- Branch atualizada com a base (geralmente main ou develop)
- Certifique-se de que ninguém mais está trabalhando na sua branch
# Verificando se há commits locais não compartilhados
git log origin/main..HEAD --oneline
2. Preparação para o Rebase Interativo
Antes de iniciar, identifique o commit base. Use git log ou git merge-base:
# Identificar quantos commits você fez
git log --oneline
# Encontrar o ponto de divergência com a branch base
git merge-base HEAD origin/main
Para iniciar o rebase interativo:
# Modo 1: especificando número de commits
git rebase -i HEAD~5
# Modo 2: usando hash do commit base
git rebase -i <commit-hash>
O editor será aberto com uma lista semelhante a esta:
pick a1b2c3d Implementa funcionalidade X
pick e4f5g6h Corrige bug na funcionalidade X
pick i7j8k9l Adiciona testes para funcionalidade X
pick m0n1o2p Ajusta formatação
pick q3r4s5t Remove debug temporário
3. Comandos Essenciais para Limpeza de Histórico
pick — Mantendo commits inalterados
Use pick (ou p) para commits que devem permanecer como estão. É o comando padrão.
squash e fixup — Unificando commits relacionados
squash (ou s) combina o commit com o anterior e permite editar a mensagem final. fixup (ou f) faz o mesmo, mas descarta a mensagem do commit sendo incorporado.
Cenário prático: Você fez vários commits de correção após implementar uma funcionalidade:
pick a1b2c3d Implementa funcionalidade X
fixup e4f5g6h Corrige bug na funcionalidade X
fixup i7j8k9l Ajusta formatação
pick m0n1o2p Adiciona testes
fixup q3r4s5t Remove debug temporário
Após salvar, o histórico mostrará apenas dois commits limpos.
reword — Renomeando mensagens de commit
Use reword (ou r) para melhorar mensagens confusas:
reword a1b2c3d "wip" → "Implementa validação de entrada do usuário"
pick e4f5g6h Adiciona testes unitários
4. Removendo e Reorganizando Commits
drop — Excluindo commits desnecessários
Commits de "wip", "teste" ou "debug" podem ser removidos:
pick a1b2c3d Implementa funcionalidade X
drop e4f5g6h commit de teste
pick i7j8k9l Adiciona testes
edit — Modificando conteúdo de um commit específico
Use edit (ou e) para pausar o rebase e alterar arquivos:
edit a1b2c3d Implementa funcionalidade X
pick e4f5g6h Adiciona testes
Quando o rebase pausar, faça as alterações e continue:
# Faça alterações nos arquivos
git add .
git commit --amend
git rebase --continue
Reordenando commits
Simplesmente mova as linhas no editor para criar uma sequência lógica:
# Antes (confuso)
pick i7j8k9l Adiciona testes
pick a1b2c3d Implementa funcionalidade X
pick e4f5g6h Corrige bug
# Depois (lógico)
pick a1b2c3d Implementa funcionalidade X
pick i7j8k9l Adiciona testes
pick e4f5g6h Corrige bug
5. Resolvendo Conflitos Durante o Rebase
Conflitos podem ocorrer ao reordenar ou fazer squash de commits. O Git pausa o rebase e indica os arquivos conflitantes.
Identificando conflitos:
git status
# Mostra arquivos em conflito (both modified)
Resolvendo manualmente:
Abra os arquivos conflitantes e edite as marcações <<<<<<<, =======, >>>>>>>. Após resolver:
git add <arquivo-resolvido>
git rebase --continue
Usando ferramenta visual:
git mergetool
# Configure previamente: git config merge.tool vimdiff
Opções de emergência:
# Para desistir do rebase
git rebase --abort
# Para pular um commit problemático
git rebase --skip
6. Boas Práticas e Validação Final
Verificando o histórico limpo
git log --oneline --graph --decorate --all
Exemplo de saída desejada:
* 1234567 (HEAD -> feature/nova-funcionalidade) Adiciona testes de integração
* 2345678 Implementa funcionalidade X com validação
* 3456789 Refatora módulo de autenticação
* 4567890 (origin/main) Último commit da main
Testando antes do PR
# Verificar diferenças com a base
git diff origin/main
# Executar testes automatizados
npm test # ou equivalente
Forçando o push com cautela
Nunca use --force em branches compartilhadas. Prefira:
git push --force-with-lease
Este comando verifica se sua branch remota não foi atualizada por outra pessoa, evitando sobrescrever trabalho alheio.
7. Cenários Comuns e Erros a Evitar
❌ Rebase em branches compartilhadas
Se outros desenvolvedores já fizeram checkout da sua branch, evite rebase. Use git revert para desfazer commits publicados.
❌ Squash excessivo
Agrupar commits muito diferentes (ex.: "implementa login" com "corrige cor do botão") dificulta revisões e bisect futuro.
Boa prática: Mantenha commits atômicos — cada commit deve representar uma mudança lógica única.
❌ Esquecer de atualizar a branch base
Sempre faça git pull origin main (ou rebase com a base) antes do rebase interativo para evitar conflitos desnecessários.
Fluxo completo recomendado:
# 1. Atualizar com a base
git checkout main
git pull origin main
git checkout feature/minha-feature
git rebase main
# 2. Limpar histórico
git rebase -i HEAD~N
# 3. Validar
git log --oneline --graph
git diff origin/main
npm test
# 4. Enviar
git push --force-with-lease
Com essas práticas, seus Pull Requests terão históricos limpos, facilitando a revisão por colegas e mantendo um registro claro das alterações no projeto.
Referências
-
Documentação oficial do Git - Rebase — Referência completa sobre o comando rebase, incluindo opções interativas e flags importantes.
-
Atlassian - Merging vs. Rebasing — Tutorial detalhado comparando merge e rebase, com exemplos práticos de interactive rebase.
-
Git SCM - Interactive Rebase — Capítulo do livro Pro Git sobre reescrita de histórico, incluindo squash, fixup e reordenação.
-
GitHub - About Git rebase — Guia do GitHub explicando quando e como usar rebase, com ênfase em Pull Requests.
-
Git Tower - Interactive Rebase Guide — Tutorial visual sobre interactive rebase, incluindo cenários comuns e resolução de conflitos.
-
FreeCodeCamp - Git Rebase Explained — Explicação acessível sobre rebase interativo com exemplos passo a passo para iniciantes.