estratégias de merge
Aprenda as estratégias de merge do Git — ort, recursive, resolve, octopus, ours e subtree — além de fast-forward, squash e merges explícitos, com exemplos.

Estratégias de Merge do Git
Quando o seu trabalho em um branch está concluído e pronto para ser combinado com a linha principal de desenvolvimento, o Git precisa decidir como unir os dois históricos. O algoritmo utilizado para isso é chamado de estratégia de merge.
Uma estratégia de merge recebe dois (ou mais) ponteiros de branch e produz um único resultado. Na maioria das vezes, você nunca precisa nomear uma estratégia explicitamente — o comando git merge escolhe um padrão adequado com base em quantos branches você está mesclando e se os históricos divergiram. Quando você precisar de controle, passe -s <estratégia> (e opcionalmente -X <opção-de-estratégia> para ajuste fino):
git merge -s recursive featureEsta página cobre dois conceitos relacionados que são fáceis de confundir:
- Estratégias de merge (
-s): o algoritmo que calcula a árvore mesclada —ort,recursive,resolve,octopus,ours,subtree. - Tipos de merge: o tipo de resultado que você obtém — um commit de merge explícito, um fast-forward ou um squash.
Você quase nunca precisa escolher uma estratégia manualmente. Os padrões estão corretos para a grande maioria dos merges; recorra a -s ou -X apenas quando encontrar um problema específico que eles resolvam.
Algoritmos de estratégia de merge
ort (padrão)
git merge -s ort featureort ("Ostensibly Recursive's Twin") é a estratégia de merge padrão para dois heads desde o Git 2.34 (2021). É uma reescrita mais rápida e precisa da estratégia recursive mais antiga e produz o mesmo tipo de resultado: um merge 3-way que lida com renomeações e mescla recursivamente múltiplos ancestrais comuns em um único ancestral virtual.
Por ser o padrão, você obtém ort automaticamente ao executar um merge simples:
git checkout main
git merge featurerecursive
git merge -s recursive featureA estratégia 3-way original para mesclar dois branches, e o padrão antes do Git 2.34. Pode detectar e seguir renomeações, mas não pode usar cópias de arquivos detectadas. Raramente você precisará solicitá-la pelo nome agora — ort a substitui — mas ainda está disponível por compatibilidade.
resolve
git merge -s resolve featureresolve realiza um único merge 3-way entre exatamente dois heads (o branch atual e o que você nomeia). Não tenta ser inteligente com múltiplas bases de merge, o que a torna rápida e previsível, mas pode mesclar incorretamente em um histórico "criss-cross" onde dois branches foram mesclados entre si anteriormente. Use-a apenas quando o merge recursive/ort produzir um resultado que você queira verificar com um algoritmo mais simples.
octopus
git merge -s octopus topic-a topic-b topic-coctopus é a estratégia padrão quando você mescla mais de dois branches de uma vez. Ela agrupa várias pontas de branch em um único commit de merge, o que é conveniente para unir um conjunto de branches de tópico independentes. Ela deliberadamente recusa qualquer merge que exigiria resolução manual de conflitos — merges octopus devem ser limpos; se houver um conflito, você deve mesclar os branches individualmente.
ours
git merge -s ours obsolete-branchA estratégia ours registra um commit de merge que tem o outro branch como pai, mas mantém a árvore do seu branch atual completamente inalterada — todas as alterações do outro branch são descartadas. O uso típico é marcar um branch como "mesclado" para fins históricos (para que merges futuros saibam sobre ele) enquanto ignora seu conteúdo real, por exemplo ao aposentar um branch de longa duração cujo trabalho não é mais desejado.
Não confunda a estratégia ours (-s ours, que descarta completamente o conteúdo do outro branch) com a opção de estratégia ours (-X ours, que mantém apenas o seu lado nas linhas que realmente conflitam). Elas se comportam de forma muito diferente.
subtree
git merge -s subtree project-bsubtree é uma variante do algoritmo recursive/ort para o caso em que uma árvore é um subdiretório (uma "subárvore") da outra. Antes de mesclar, o Git desloca os caminhos de uma árvore para que as duas se alinhem e depois mescla normalmente. Este é o mecanismo por trás de incorporar um projeto em uma subpasta de outro. Para o trabalho diário com subárvores, o comando de nível mais alto git subtree geralmente é mais fácil.
Tipos de merge: como o resultado se parece
A estratégia decide como as árvores são combinadas; o tipo de merge descreve o formato do histórico que resulta.
Merge fast-forward
Quando o branch no qual você está mesclando não se moveu desde que o outro branch foi criado, não há nada a combinar — o Git pode simplesmente avançar o ponteiro do branch para o commit mais recente. Nenhum novo commit é criado e o histórico permanece perfeitamente linear. Este é o comportamento padrão do Git sempre que é possível:
git checkout main
git merge feature
# Output (when main is an ancestor of feature):
# Updating a1b2c3d..d4e5f6a
# Fast-forward
# app.js | 3 +++
# 1 file changed, 3 insertions(+)Para manter um registro explícito do merge mesmo quando um fast-forward é possível, force um commit de merge com --no-ff:
git merge --no-ff featureCommit de merge explícito (3-way)
Quando ambos os branches têm novos commits — seus históricos divergiram — o Git cria um novo commit de merge com dois pais. Isso é "explícito" porque o commit é visível no histórico e registra exatamente onde e quando os branches se uniram:
git checkout main
git merge feature
# Output (when histories diverged):
# Merge made by the 'ort' strategy.
# app.js | 5 +++++
# 1 file changed, 5 insertions(+)Se os dois branches alteraram as mesmas linhas, o merge para com um conflito que você deve resolver manualmente — veja conflitos de merge.
Squash merge
Um squash merge recolhe todos os commits do branch de origem em um único novo commit no branch atual. Ele não cria um commit de merge e não registra o branch de origem como pai; portanto, os commits individuais do branch de origem nunca aparecem no histórico do destino:
git checkout main
git merge --squash feature
# Changes are staged but NOT committed yet:
git commit -m "Add feature X"Isso mantém o histórico do branch principal organizado — um commit por funcionalidade — ao custo de perder o log detalhado de commits do branch de funcionalidade. É uma política popular para pull requests. Para reescrever commits dentro de um branch, veja rebase interativo.
Opções de estratégia (-X)
As estratégias ort/recursive aceitam opções extras por meio da flag -X (note o X maiúsculo, separado de -s). Por exemplo, para resolver automaticamente conflitos em favor do seu lado:
git merge -X ours featureAs opções disponíveis são:
| Opção | Efeito |
|---|---|
ours | Resolve automaticamente os hunks conflitantes favorecendo o nosso lado. Alterações não conflitantes da outra árvore ainda são mescladas. (Diferente de -s ours, que descarta o outro lado completamente.) |
theirs | O oposto de ours: resolve conflitos automaticamente em favor da outra árvore. Não existe uma estratégia theirs separada, apenas esta opção. |
patience | Gasta tempo extra combinando linhas para evitar mesclagens incorretas causadas por linhas correspondentes sem importância. |
diff-algorithm=<algo> | Instrui o merge a usar um algoritmo de diff diferente (ex.: histogram, minimal, patience). |
ignore-space-change / ignore-all-space | Ignora diferenças apenas de espaços em branco ao detectar conflitos. Alterações de espaço em branco misturadas com alterações reais não são ignoradas. |
renormalize | Executa um check-out e check-in virtual de todos os estágios de arquivo, útil quando filtros de fim de linha ou smudge/clean foram alterados. |
no-renormalize | Desativa a opção renormalize. |
no-renames | Desativa a detecção de renomeações durante o merge. |
find-renames=<n> | Ativa a detecção de renomeações com um limiar de similaridade de n% (padrão 50%). |
subtree=<path> | Como a estratégia subtree, mas permite especificar o prefixo de caminho que deve ser deslocado para alinhar as árvores. |
Como escolher
Para o trabalho diário, você não escolhe uma estratégia — deixe o Git usar ort, e decida apenas o resultado que deseja:
- Quer o histórico mais simples e linear quando possível? Use apenas
git merge(fast-forward automático). - Quer que cada merge seja registrado como um commit? Adicione
--no-ff. - Quer um commit limpo por funcionalidade no
main? Use--squash. - Unindo vários branches de tópico finalizados de uma vez? Um
git merge a b csimples usaoctopus.
Se preferir replicar seus commits sobre o branch de destino em vez de mesclar, veja git rebase. Para trazer um único commit de outro branch, use git cherry-pick.