Git rebase interativo: reorganizando commits antes de fazer push
1. O que é o rebase interativo e por que usá-lo antes do push
O rebase interativo (git rebase -i) é uma ferramenta poderosa do Git que permite reescrever o histórico de commits locais antes de enviá-los para um repositório remoto. Diferentemente do rebase comum, que simplesmente aplica commits sobre outra base, o modo interativo abre um editor onde você pode especificar ações para cada commit envolvido.
O conceito fundamental é que estamos trabalhando exclusivamente com commits que ainda não foram compartilhados via git push. Como esses commits existem apenas no repositório local, podemos reordená-los, combiná-los, editar suas mensagens ou até removê-los sem causar problemas para outros desenvolvedores.
As principais vantagens de reorganizar commits antes do push incluem:
- Histórico limpo: commits agrupados por funcionalidade, não por "tentativa e erro"
- Revisão facilitada: colegas entendem facilmente a evolução do código
- Mensagens significativas: cada commit conta uma história clara do desenvolvimento
A diferença crucial entre o rebase comum e o interativo está no controle granular. Enquanto git rebase apenas move commits para uma nova base, git rebase -i permite transformar cada commit individualmente.
2. Preparando o terreno: quando e como iniciar um rebase interativo
Antes de começar, identifique quais commits são elegíveis. A regra de ouro é: apenas commits que não foram enviados ao remoto. Use git log --oneline para visualizar o histórico local:
$ git log --oneline
a1b2c3d (HEAD -> feature/login) Adiciona validação de email
e4f5g6h Corrige estilo do botão de login
i7j8k9l Ajusta mensagem de erro
m0n1o2p Refatora função de autenticação
q3r4s5t (main) Versão inicial do projeto
Para iniciar o rebase interativo nos últimos 4 commits (todos locais), use:
$ git rebase -i HEAD~4
Ou, alternativamente, referenciando o commit base:
$ git rebase -i q3r4s5t
O editor será aberto com uma lista como esta:
pick a1b2c3d Adiciona validação de email
pick e4f5g6h Corrige estilo do botão de login
pick i7j8k9l Ajusta mensagem de erro
pick m0n1o2p Refatora função de autenticação
Cada linha representa um commit, e a palavra pick é a ação padrão que mantém o commit inalterado.
3. As operações principais do rebase interativo: pick, reword, squash, fixup
pick
Mantém o commit exatamente como está, preservando sua mensagem e alterações. É a ação padrão para commits que você não deseja modificar.
reword
Permite alterar apenas a mensagem do commit, sem modificar seu conteúdo. Útil para corrigir erros de digitação ou melhorar descrições:
pick a1b2c3d Adiciona validação de email
reword e4f5g6h Corrige estilo do botão de login
pick i7j8k9l Ajusta mensagem de erro
pick m0n1o2p Refatora função de autenticação
squash e fixup
Ambos combinam múltiplos commits em um único. A diferença está na mensagem final:
- squash: combina as mensagens, permitindo editar o resultado
- fixup: descarta a mensagem do commit sendo combinado, mantendo apenas a do commit anterior
Exemplo prático: unindo commits de ajustes:
pick a1b2c3d Adiciona validação de email
squash e4f5g6h Corrige estilo do botão de login
fixup i7j8k9l Ajusta mensagem de erro
pick m0n1o2p Refatora função de autenticação
Resultado: teremos 3 commits finais, sendo que o primeiro incorpora as alterações dos commits e4f5g6h e i7j8k9l com uma mensagem editável.
4. Reordenando e removendo commits com segurança
Para reordenar commits, simplesmente mova as linhas no editor. Por exemplo, para colocar a refatoração antes da validação:
pick m0n1o2p Refatora função de autenticação
pick a1b2c3d Adiciona validação de email
Para remover commits desnecessários, use drop ou simplesmente delete a linha:
pick a1b2c3d Adiciona validação de email
drop i7j8k9l Ajusta mensagem de erro
pick m0n1o2p Refatora função de autenticação
Cuidado com dependências: se o commit que você moveu depende de alterações de outro commit que ficou para trás, podem ocorrer conflitos. Por exemplo, se m0n1o2p usa uma função criada em a1b2c3d, reordená-los causará erro. Sempre analise as dependências lógicas entre os commits.
5. Editando commits no meio do histórico com edit
A ação edit pausa o rebase em um commit específico, permitindo modificar arquivos. O fluxo típico é:
- Marque o commit com
edit:
edit a1b2c3d Adiciona validação de email
pick m0n1o2p Refatora função de autenticação
-
Após salvar e fechar o editor, o Git para no commit
a1b2c3d. Faça as alterações necessárias nos arquivos. -
Adicione as mudanças e atualize o commit:
$ git add .
$ git commit --amend
- Continue o rebase:
$ git rebase --continue
Casos de uso comuns:
- Corrigir um bug introduzido em um commit antigo
- Adicionar um arquivo que foi esquecido em um commit específico
- Alterar a implementação de uma funcionalidade sem criar novos commits
6. Lidando com conflitos durante o rebase interativo
Conflitos surgem quando commits reordenados ou editados criam inconsistências no código. Por exemplo, se você moveu um commit que adiciona uma função para antes do commit que define uma variável que essa função utiliza.
Quando um conflito ocorre, o Git pausa o rebase e exibe:
$ git rebase --continue
error: could not apply a1b2c3d... Adiciona validação de email
Resolve all conflicts manually, mark them as resolved with "git add", and run "git rebase --continue".
Estratégia de resolução:
- Abra os arquivos conflitantes e resolva manualmente as diferenças
- Marque como resolvido:
$ git add arquivo-resolvido.js
- Continue o rebase:
$ git rebase --continue
Se a situação ficar complicada, você pode abortar tudo e retornar ao estado original:
$ git rebase --abort
7. Boas práticas e armadilhas comuns
Nunca faça rebase em commits já enviados ao remoto
Esta é a regra mais importante. Se outros desenvolvedores já têm seus commits, reescrever o histórico causará divergências e dores de cabeça. Use rebase interativo antes do git push.
Crie um branch de backup
Antes de iniciar um rebase complexo, crie um branch de segurança:
$ git branch backup-feature-login
Se algo der errado, você pode retornar facilmente:
$ git reset --hard backup-feature-login
Verifique o resultado final
Após o rebase, compare com o branch original:
$ git log --oneline --graph --all
Isso ajuda a visualizar se a reorganização ficou como esperado.
Evite rebase excessivo em branches colaborativos
Se várias pessoas trabalham no mesmo branch, o rebase frequente pode causar confusão. Prefira branches individuais e faça rebase apenas antes de mesclar.
Referências
- Documentação oficial do Git: git rebase — Referência completa sobre o comando rebase, incluindo todas as opções do modo interativo.
- Atlassian Git Tutorial: Git Rebase — Guia prático com exemplos detalhados de rebase interativo e boas práticas.
- GitHub Docs: About Git rebase — Explicação oficial do GitHub sobre rebase, com foco em fluxos de trabalho colaborativos.
- FreeCodeCamp: Git Rebase Explained — Tutorial acessível que cobre desde conceitos básicos até cenários avançados de rebase interativo.
- Git Tower: Interactive Rebase — Guia visual com exemplos práticos das operações pick, squash, reword e edit.