Comparação

Git merge vs rebase: qual escolher para o seu time

Atualizado: · Skillaria.Top

Tanto o merge quanto o rebase integram as mudanças de branches, mas tratam o histórico de formas diferentes: o merge preserva o histórico como ele aconteceu e adiciona um commit de merge, enquanto o rebase reescreve seus commits sobre uma nova base e deixa o histórico linear. Regra prática: rebase para organizar seus commits ainda não publicados, merge para integrar trabalho pronto em branches compartilhadas.

Resumindo: qual a diferença entre merge e rebase

A discussão "merge vs rebase" não é sobre qual comando é melhor, e sim sobre que histórico do projeto você quer ver. Os dois comandos chegam ao mesmo código no final. O que muda é o caminho que fica registrado no log.

  • Merge junta duas linhas de histórico e registra honestamente que o trabalho foi feito em paralelo. Os commits existentes não mudam; é adicionado um commit de merge com dois pais.
  • Rebase reescreve seus commits como se você tivesse começado a partir da versão mais recente da branch base. O histórico vira uma linha reta, mas os commits ganham novos hashes.

A mecânica de cada comando — flags, resolução de conflitos, modo interativo — está em artigos separados. Aqui o foco é só a escolha da estratégia.

Como fica o histórico em cada caso

Situação inicial: você criou a branch feature, fez dois commits e, nesse meio-tempo, entraram dois commits de outras pessoas na main.

          D---E        feature
         /
A---B---C---F---G      main

Depois de git merge feature na main:

          D---E
         /     \
A---B---C---F---G---M  main

Depois de git rebase main na feature e de um fast-forward da main:

A---B---C---F---G---D'---E'   main

No primeiro caso, o histórico mostra que a feature foi desenvolvida em paralelo e quando ela foi integrada. No segundo, o histórico se lê como uma narrativa sequencial, mas o fato de ter havido trabalho paralelo desaparece: D' e E' são commits novos, criados no momento do rebase.

Tabela comparativa: merge vs rebase

Critériogit mergegit rebase
Commits existentesNão mudamSão recriados com novos hashes
Formato do históricoGrafo ramificado com commits de mergeLinear
Segurança em branches compartilhadasSempre seguroPerigoso para commits já publicados
Precisa de force pushNãoSim, se a branch já está no servidor
ConflitosResolvidos uma vez, no commit de mergePodem aparecer em cada commit reaplicado
Contexto de "de onde veio"PreservadoPerdido
Reverter uma feature inteiraUm único git revert -m 1 do commit de mergeRevert de cada commit ou de um intervalo
Facilidade com git bisect e git logGrafo mais difícil de lerMais simples: uma única linha reta
Curva de aprendizadoBaixaMais alta, exige entender reescrita de histórico
Limpeza de commits (squash, reword)Só --squash da branch inteiraFlexível com rebase -i

Prós e contras do merge

Prós

  • Não destrói o histórico. Tudo o que foi publicado continua no lugar. Ninguém do time vai precisar consertar nada depois da sua ação.
  • O conflito é resolvido uma vez só. Mesmo que a branch tenha 30 commits, você lida com o estado final, e não com cada passo.
  • O contexto é preservado. Pelo commit de merge dá para ver qual tarefa entrou na branch principal e quando, e é fácil reverter tudo de uma vez.

Contras

  • Grafo poluído. Com sincronizações frequentes, o histórico se enche de commits "Merge branch 'main' into feature", e o git log --graph vira um mapa de linhas de trem.
  • Commits de rascunho vão para o histórico. "wip", "fix", "mais um fix" ficam para sempre na branch principal se não forem condensados.

Prós e contras do rebase

Prós

  • Histórico linear e legível. Cada commit fica no seu lugar, o git log se lê como uma lista de mudanças e o git bisect encontra com mais facilidade o commit que introduziu o bug.
  • Dá para organizar os commits antes do review: juntar, renomear, reordenar.
  • Sem commits técnicos de merge gerados pela sincronização com a branch principal.

Contras

  • Reescreve o histórico. Fazer rebase de uma branch compartilhada já publicada quebra o trabalho de todo mundo que a baixou.
  • Exige force push em branches que estão no servidor, ou seja, disciplina e --force-with-lease.
  • Conflitos repetidos. O mesmo trecho pode gerar conflito em vários commits seguidos.
  • Commits intermediários podem não compilar. Depois de mudar de base, ninguém testou os commits antigos no novo contexto.

Quando usar cada um

Rebase para o seu trabalho local

Você atualiza sua branch antes de enviar — git pull --rebase. Prepara a branch para o review e quer eliminar commits de rascunho — git rebase -i. Sua feature branch pessoal ficou atrás da main — git rebase origin/main. Em todos esses casos, são reescritos commits que só você viu (ou que pertencem só a você).

Merge para branches compartilhadas e integração

Uma feature pronta entra na main ou na develop. Várias pessoas trabalham na mesma branch. É preciso integrar a branch de release de volta na principal. Aqui o importante é não mexer em commits já publicados, e o merge é a única opção correta.

Uma regra simples de escolha

Se os commits só existem na sua máquina, pode usar rebase. Se alguém já os baixou, só merge.

Fluxos comuns para o time

FluxoComo funcionaPara quem
Só mergeFeatures entram com --no-ff, sincronização com git merge mainIniciantes em Git, times que valorizam a cronologia completa e reverts simples
Rebase + mergeAntes de integrar, a branch é rebaseada na main, depois vem um commit de merge com --no-ffTimes que querem histórico limpo e também os limites de cada feature
Rebase + fast-forwardA branch é rebaseada e integrada por fast-forward; histórico totalmente linearTimes pequenos com commits atômicos e bem cuidados
Squash mergeCada pull request vira um único commit na mainTimes com tarefas curtas, em que o histórico detalhado da branch não importa

No GitHub e no GitLab, esses fluxos correspondem aos botões "Create a merge commit", "Rebase and merge" e "Squash and merge". O ideal é permitir nas configurações do repositório apenas a opção escolhida, para o histórico não virar uma mistura de estilos.

Configurações que reforçam a escolha

# pull sem commits de merge desnecessários
git config --global pull.rebase true

# ou: pull só por fast-forward, senão dá erro e você decide
git config --global pull.ff only

# sempre criar commit de merge ao integrar features
git config --global merge.ff false

Cuidado com merge.ff false: ele também afeta o git pull no modo merge. Muita gente prefere não defini-lo globalmente e passar --no-ff explicitamente ao integrar uma feature.

Exemplo: a mesma tarefa nos dois estilos

Vamos a um cenário real. Você passa três dias desenvolvendo a feature de pagamento na branch feature/payment, e nesse período entram cinco tarefas de outras pessoas na main. Antes do pull request, você precisa trazer a main atualizada e conferir se tudo funciona.

Opção com merge

git switch feature/payment
git fetch origin
git merge origin/main
# conflitos resolvidos uma vez: git add, git commit
git push

A branch ganhou o commit "Merge remote-tracking branch 'origin/main' into feature/payment". O push é normal, e quem estava acompanhando a branch não percebe nada. Se você sincronizar assim todo dia, a branch terá três commits desses, e eles vão parar na main junto com a feature se a integração for feita sem squash.

Opção com rebase

git switch feature/payment
git fetch origin
git rebase origin/main
# conflitos resolvidos no caminho, commit a commit: git add, git rebase --continue
git rebase -i origin/main      # opcional: juntar commits de rascunho
git push --force-with-lease

A branch parece ter sido criada hoje de manhã a partir da main atualizada, sem commits sobrando, e o revisor consegue ler as mudanças passo a passo com mais facilidade. O preço é o push forçado e a necessidade de garantir que ninguém mais esteja commitando nessa branch.

O que a main vai mostrar no final

Na integração via pull request, a diferença se mantém. O estilo merge gera um grafo com ramificações e merges de sincronização; o estilo rebase gera uma sequência limpa de commits da feature, que pode ser integrada por fast-forward ou com um único commit de merge. O código será o mesmo, desde que os conflitos sejam resolvidos da mesma forma.

Como decidir em equipe

Responda a algumas perguntas. Várias pessoas trabalham na mesma branch? Se sim, rebase está fora de questão para essa branch. Qual é a experiência do time com Git? Se há muitos iniciantes, comece com merge e squash merge, que perdoam erros. Vocês precisam da cronologia completa para auditoria e análise de incidentes? Então commits de merge das features são úteis. Um git log legível e o uso frequente de git bisect são importantes? Então ponto para o rebase e o histórico linear.

Registre a decisão no CONTRIBUTING ou no README do repositório e ative a proteção da branch principal: proibir force push, exigir pull request, definir o método de merge permitido. Uma regra garantida pelas configurações funciona muito melhor do que qualquer combinado verbal.

Equívocos comuns

  • "Rebase é coisa de avançado, merge é para iniciante". Não: são ferramentas diferentes para tarefas diferentes. Desenvolvedores experientes usam as duas.
  • "Commits de merge são lixo". Os de sincronização, sim, muitas vezes são ruído. Mas o commit de merge que integra uma feature é um ponto útil: por ele se enxerga e se reverte uma tarefa inteira.
  • "Com rebase há menos conflitos". Os conflitos são os mesmos, porque as mesmas linhas foram alteradas. O rebase só os distribui pelos commits, enquanto o merge resolve tudo de uma vez.
  • "O rebase perde commits". Os commits antigos continuam no git reflog e podem ser recuperados até o garbage collector removê-los.

Conclusão

Escolher entre merge vs rebase é escolher entre uma cronologia fiel e um histórico linear e legível. O merge é seguro e preserva o contexto; o rebase traz limpeza, mas reescreve commits. A prática mais confiável é combinar os dois: rebasear e limpar sua branch enquanto ela é só sua, e integrar o trabalho pronto nas branches compartilhadas via merge ou squash, conforme as regras do time. O essencial é combinar o fluxo e fixá-lo nas configurações do repositório. As duas estratégias e o trabalho com branches em equipe são praticados no curso de Git.

Perguntas frequentes

O que usar no git pull: merge ou rebase?

Para atualizar a branch local, o rebase é mais prático: seus commits não publicados ficam por cima dos remotos mais recentes, sem commit de merge extra. Ative com git config --global pull.rebase true.

Dá para misturar merge e rebase no mesmo projeto?

Sim, e essa é a abordagem mais comum: rebase nas suas branches, merge nas compartilhadas. O importante é que todo o time conheça a regra.

O que um iniciante deve escolher?

Comece com merge: ele não reescreve o histórico e é mais difícil quebrar algo. Aprenda rebase nas suas branches locais depois de entender reflog e force push.

A estratégia escolhida muda o código final?

Não. Com os conflitos resolvidos da mesma forma, o estado final dos arquivos é idêntico. Só muda o histórico de commits registrado.

Qual a diferença entre squash merge e rebase?

O squash merge condensa a branch inteira em um único commit novo na branch principal, enquanto o rebase reaplica cada commit separadamente. Os dois geram histórico linear, mas o squash perde o detalhamento passo a passo.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso