Rebase é uma operação do Git que move commits de um branch para o topo de outro, criando um histórico linear sem commits de merge desnecessários. Ao contrário da mesclagem, o rebase reescreve o histórico: cada commit movido recebe um novo hash porque seu pai muda. De acordo com a documentação do Git (2026), o rebase é usado para sincronizar branches de feature com o estado atual do main antes de criar um pull request. O comando git rebase é uma das principais ferramentas para manter um histórico limpo em projetos que usam Git Flow.
Pontos Principais
Rebase é um comando Git que rebaseia o branch atual sobre um especificado: pega todos os commits do branch atual, salva-os temporariamente, move o ponteiro do branch para o commit alvo e aplica sequencialmente os commits salvos sobre ele. O resultado — o histórico parece que o desenvolvedor trabalhou diretamente a partir do último commit do branch alvo.
A sintaxe básica: git rebase main — estando em um branch de feature, este comando move todos os commits da feature para o topo do main. O Git usa uma estratégia de merge de três vias para cada commit individualmente. Se o commit A já estiver presente no branch alvo (determinado pelo hash), o Git o pula automaticamente, evitando alterações duplicadas.
Rebase também suporta o modo onto para mover um subconjunto de commits: git rebase --onto target start end — esta forma permite extrair um intervalo de commits de um branch e aplicá-los sobre outro. Por exemplo, git rebase --onto main feature~3 feature move os últimos três commits do branch feature sobre o main.
# Switch to feature branch
git checkout feature
# Rebase feature onto main
git rebase main
# After successful rebase — history is linear
git log --oneline --graph
# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD
Rebase e merge resolvem a mesma tarefa — combinar alterações de branches diferentes — mas fazem isso de maneiras fundamentalmente diferentes. Merge preserva o histórico completo de mesclagens criando um commit de merge com dois pais. Rebase reescreve o histórico, tornando-o linear. A escolha entre eles depende do fluxo de trabalho da equipe e das regras de gerenciamento do repositório.
A principal diferença é como o fato da mesclagem é registrado. Merge preserva: "neste ponto mesclamos feature no main" — isso é informativo para o histórico do projeto, mas polui o log com mesclagens frequentes. Rebase mostra: "os commits da feature foram feitos sequencialmente a partir do último estado do main" — é limpo, mas esconde o fato de que o desenvolvimento foi feito em paralelo.
A segunda diferença é o tratamento de conflitos. Com merge, os conflitos são resolvidos uma vez e a solução é registrada no commit de merge. Com rebase, podem ocorrer conflitos para cada commit movido, cada um exigindo resolução separada. Isso é mais trabalhoso, mas permite um controle mais preciso sobre quais alterações chegam à versão final.
| Critério | Rebase | Merge |
|---|---|---|
| Histórico | Linear, sem commits de merge | Não linear, com commits de merge |
| Hashes dos commits | Reescritos (novos) | Originais preservados |
| Conflitos | Para cada commit separadamente | Uma vez no commit de merge |
| Branches públicos | Proibido | Permitido |
| Comando de desfazer | git rebase --abort | git merge --abort |
Rebase interativo (git rebase -i) é um modo onde o Git abre um editor com uma lista de commits e ações disponíveis para cada um. O desenvolvedor pode reescrever o histórico antes de enviar para um repositório remoto. Esta é a ferramenta principal para manter commits limpos em um branch de feature.
Comandos disponíveis no modo interativo: pick (manter o commit como está), reword (alterar a mensagem do commit), edit (parar para fazer alterações), squash (combinar com o commit anterior, mantendo ambas as mensagens), fixup (combinar, descartando a mensagem), drop (excluir commit). Cada comando é colocado antes do hash do commit no editor aberto.
Squash e fixup são os comandos mais usados para combinar commits. Se um desenvolvedor fez 5 pequenos commits de correção durante o trabalho, o squash os mescla em um único commit lógico com uma mensagem significativa. Fixup é útil para corrigir erros de digitação: as alterações vão para o commit anterior sem manter sua própria mensagem.
# Open editor for last 4 commits
git rebase -i HEAD~4
# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# After saving — Git performs rebase
# and opens editor for squashed commit message
# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash
A flag --autosquash organiza automaticamente fixup/squash para commits cujas mensagens começam com fixup! ou squash!. Isso acelera o trabalho se o desenvolvedor pré-marca os commits para combinação posterior. A flag --committer-date-is-author-date preserva a data original do commit ao rebasear — útil para manter a ordem cronológica no histórico.
Conflitos durante o rebase ocorrem quando o Git não consegue aplicar automaticamente um commit movido devido a contradições com as alterações no branch alvo. Ao contrário do merge, onde o conflito é resolvido uma vez, com rebase cada commit pode causar um conflito e deve ser resolvido sequencialmente para cada commit do mais antigo ao mais novo.
Quando ocorre um conflito, o Git pausa o rebase e informa qual commit causou o problema. O desenvolvedor abre o arquivo em conflito (o Git marca as áreas de conflito com marcadores <<<<<<<, =======, >>>>>>>), edita-o, adiciona-o ao índice (git add) e continua o rebase com git rebase --continue. Se nenhuma solução for encontrada — git rebase --abort cancela completamente o rebase.
Dica: com múltiplos conflitos, é mais eficiente usar git mergetool, que abre um editor visual para resolver conflitos. Você também pode pular o commit problemático (git rebase --skip), mas isso remove suas alterações do histórico final, o que raramente é a decisão correta.
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Check status
git status
# both modified: file.txt
# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue
# If uncertain — abort
git rebase --abort
A regra de ouro do rebase: nunca rebaseie commits que já foram enviados para um repositório remoto e estão disponíveis para outros desenvolvedores. Como o rebase reescreve os hashes dos commits, os colegas encontrarão conflitos ao tentar sincronizar — seu histórico local divergirá do histórico remoto reescrito.
Uma situação em que o rebase é estritamente proibido: se alguém já criou um branch com base em seus commits (por exemplo, um colega criou um branch a partir do seu branch de feature), reescrever o histórico quebrará o trabalho dele. Nesses casos, use merge. Também não é recomendado fazer rebase pouco antes do prazo final — um erro durante a resolução de conflitos pode levar mais tempo do que o esperado e bloquear o lançamento.
Exceção: se o branch for usado por apenas um desenvolvedor (branch de feature pessoal, não publicado ou publicado em modo rascunho), o rebase antes do push é uma prática padrão. Após a publicação e início do trabalho colaborativo — apenas merge. GitHub e GitLab oferecem por padrão o squash merge como um compromisso: ele combina commits em um, mas não reescreve o histórico do branch alvo.
Equipes modernas usam com mais frequência um fluxo de trabalho orientado a rebase combinado com GitHub Flow. O processo é assim: o desenvolvedor cria um branch de feature a partir do main, trabalha nele, sincroniza periodicamente via git rebase main e, antes de criar um pull request, realiza um rebase interativo para limpar o histórico.
Após criar um PR (se for necessário puxar novas alterações do main), usa-se git pull --rebase main em vez de um git pull comum. Isso puxa as alterações sem criar um commit de merge desnecessário. Git pull com a flag --rebase equivale a git fetch + git rebase — o Git primeiro baixa novos commits e depois rebaseia as alterações locais sobre eles.
O Git permite configurar rebase como comportamento padrão para pull: git config --global pull.rebase true. Após essa configuração, git pull sempre faz rebase em vez de merge. Se um pull comum for necessário — usa-se git pull --no-rebase. Muitas equipes também habilitam autostash: git config --global rebase.autoStash true — isso oculta automaticamente alterações não commitadas antes do rebase e as restaura depois.
Perguntas Frequentes
Fazer rebase significa executar git rebase: mover commits do branch atual para o topo de outro. Como resultado, o histórico se torna linear, cada commit recebe um novo hash e commits de merge não são criados. O comando é usado para sincronizar branches sem pontos de mesclagem desnecessários no log.
Merge cria um commit de merge com dois pais, preservando o histórico paralelo e os hashes originais. Rebase reescreve o histórico — os commits recebem novos hashes e o histórico se torna linear. Merge é mais seguro para branches públicos, rebase fornece um log mais limpo.
O comando git rebase -i HEAD~N abre um editor com os últimos N commits. Para cada commit você pode escolher uma ação: pick (manter), reword (renomear), edit (modificar), squash (combinar com o anterior), fixup (combinar sem mensagem), drop (excluir). Após salvar, o Git aplica as alterações escolhidas.
Rebase reescreve os hashes dos commits, tornando o histórico incompatível com cópias dos mesmos commits nas máquinas de outros desenvolvedores. Se um colega já obteve seus commits via git pull e depois você os rebaseou, o git push dele será rejeitado e o git pull criará commits duplicados e conflitos.
Antes da conclusão — git rebase --abort cancela completamente. Após a conclusão, é possível restaurar o estado anterior via git reflog — encontre o hash do commit antes do rebase e execute git reset --hard para ele. O Reflog armazena o histórico de movimentos do HEAD por 30 dias por padrão.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também