estrategias de merge
Aprende las estrategias de merge en Git — ort, recursive, resolve, octopus, ours y subtree — además de fast-forward, squash y merges explícitos, con ejemplos.

Estrategias de Merge en Git
Cuando el trabajo en una rama está completo y listo para combinarse con la línea principal de desarrollo, Git debe decidir cómo unir las dos historias. El algoritmo que utiliza para esto se denomina estrategia de merge.
Una estrategia de merge toma dos (o más) puntas de rama y produce un único resultado. La mayor parte del tiempo nunca se nombra una estrategia de forma explícita — el comando git merge elige un valor predeterminado sensato según cuántas ramas se están fusionando y si sus historias han divergido. Cuando necesitas control, pasa -s <estrategia> (y opcionalmente -X <opción-de-estrategia> para ajuste fino):
git merge -s recursive featureEsta página cubre dos ideas relacionadas que es fácil confundir:
- Estrategias de merge (
-s): el algoritmo que calcula el árbol fusionado —ort,recursive,resolve,octopus,ours,subtree. - Tipos de merge: el tipo de resultado que obtienes — un commit de merge explícito, un fast-forward o un squash.
Casi nunca necesitas elegir una estrategia manualmente. Los valores predeterminados son correctos para la gran mayoría de los merges; recurre a -s o -X solo cuando encuentres un problema específico que resuelvan.
Algoritmos de estrategia de merge
ort (predeterminado)
git merge -s ort featureort ("Ostensibly Recursive's Twin") ha sido la estrategia de merge predeterminada para dos cabezas desde Git 2.34 (2021). Es una reescritura más rápida y correcta de la antigua estrategia recursive y produce el mismo tipo de resultado: un merge de 3 vías que maneja renombrados y fusiona recursivamente múltiples ancestros comunes en un único ancestro virtual.
Dado que es la predeterminada, obtienes ort automáticamente al ejecutar un merge simple:
git checkout main
git merge featurerecursive
git merge -s recursive featureLa estrategia original de 3 vías para fusionar dos ramas, y la predeterminada antes de Git 2.34. Puede detectar y seguir renombrados, pero no puede usar copias de archivos detectadas. Raramente necesitas solicitarla por nombre ahora — ort la reemplaza — pero sigue disponible por compatibilidad.
resolve
git merge -s resolve featureresolve realiza un único merge de 3 vías entre exactamente dos cabezas (la rama actual y la que se nombra). No intenta ser inteligente con múltiples bases de merge, lo que la hace rápida y predecible, pero puede producir un merge incorrecto en un historial de "criss-cross" donde dos ramas se fusionaron entre sí previamente. Úsala solo cuando el merge con recursive/ort produce un resultado que quieres verificar con un algoritmo más simple.
octopus
git merge -s octopus topic-a topic-b topic-coctopus es la estrategia predeterminada cuando fusionas más de dos ramas a la vez. Agrupa varias puntas de rama en un único commit de merge, lo cual es conveniente para unir un conjunto de ramas de tema independientes. Deliberadamente rechaza cualquier merge que necesite resolución manual de conflictos — los merges octopus están diseñados para ser limpios, por lo que si hay un conflicto deberías fusionar las ramas individualmente en su lugar.
ours
git merge -s ours obsolete-branchLa estrategia ours registra un commit de merge que tiene la otra rama como padre, pero mantiene el árbol de tu rama actual completamente sin cambios — todos los cambios de la otra rama se descartan. El uso típico es marcar una rama como "fusionada" por motivos históricos (para que los merges futuros la tengan en cuenta) ignorando su contenido real, por ejemplo al retirar una rama de larga duración cuyo trabajo ya no se desea.
No confundas la estrategia ours (-s ours, que descarta completamente el contenido de la otra rama) con la opción de estrategia ours (-X ours, que conserva tu lado solo para las líneas que realmente entran en conflicto). Se comportan de manera muy diferente.
subtree
git merge -s subtree project-bsubtree es una variante del algoritmo recursive/ort para el caso en que un árbol es un subdirectorio (un "subtree") del otro. Antes de fusionar, Git desplaza las rutas de un árbol para que los dos se alineen y luego fusiona de forma normal. Esta es la maquinaria detrás de incorporar un proyecto en una subcarpeta de otro. Para el trabajo cotidiano con subtree, el comando de nivel superior git subtree suele ser más fácil.
Tipos de merge: el aspecto del resultado
La estrategia decide cómo se combinan los árboles; el tipo de merge describe la forma del historial que surge al final.
Merge fast-forward
Cuando la rama en la que estás fusionando no se ha movido desde que se creó la otra rama, no hay nada que combinar — Git simplemente puede deslizar el puntero de la rama hacia adelante hasta el último commit. No se crea ningún commit nuevo y el historial permanece perfectamente lineal. Este es el comportamiento predeterminado de Git cuando es posible:
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 mantener un registro explícito del merge incluso cuando es posible un fast-forward, fuerza un commit de merge con --no-ff:
git merge --no-ff featureCommit de merge explícito (3 vías)
Cuando ambas ramas tienen nuevos commits — sus historias han divergido — Git crea un commit de merge completamente nuevo con dos padres. Es "explícito" porque el commit es visible en el historial y registra exactamente dónde y cuándo se unieron las ramas:
git checkout main
git merge feature
# Output (when histories diverged):
# Merge made by the 'ort' strategy.
# app.js | 5 +++++
# 1 file changed, 5 insertions(+)Si las dos ramas cambiaron las mismas líneas, el merge se detiene con un conflicto que debes resolver manualmente — consulta conflictos de merge.
Merge squash
Un merge squash colapsa todos los commits de la rama de origen en un único commit nuevo en la rama actual. No crea un commit de merge y no registra la rama de origen como padre, por lo que los commits individuales de la rama de origen nunca aparecen en el historial de destino:
git checkout main
git merge --squash feature
# Changes are staged but NOT committed yet:
git commit -m "Add feature X"Esto mantiene el historial de la rama principal ordenado — un commit por característica — a costa de perder el registro detallado de commits de la rama de la característica. Es una política popular para pull requests. Para reescribir commits dentro de una rama en su lugar, consulta rebase interactivo.
Opciones de estrategia (-X)
Las estrategias ort/recursive aceptan opciones adicionales a través del indicador -X (nota la X mayúscula, separada de -s). Por ejemplo, para resolver automáticamente los conflictos a favor de tu lado:
git merge -X ours featureLas opciones disponibles son:
| Opción | Efecto |
|---|---|
ours | Resuelve automáticamente los fragmentos en conflicto favoreciendo nuestro lado. Los cambios no conflictivos del otro árbol aún se fusionan. (A diferencia de -s ours, que descarta el otro lado por completo.) |
theirs | Lo opuesto a ours: resuelve automáticamente los conflictos a favor del otro árbol. No existe una estrategia theirs separada, solo esta opción. |
patience | Invierte tiempo adicional haciendo coincidir líneas para evitar merges incorrectos causados por líneas de coincidencia sin importancia. |
diff-algorithm=<algo> | Indica al merge que use un algoritmo diff diferente (p. ej., histogram, minimal, patience). |
ignore-space-change / ignore-all-space | Ignora las diferencias solo de espacios en blanco al detectar conflictos. Los cambios de espacios en blanco mezclados con cambios reales no se ignoran. |
renormalize | Ejecuta un check-out y check-in virtual de todas las etapas de archivos, útil cuando cambiaron los filtros de fin de línea o smudge/clean. |
no-renormalize | Desactiva la opción renormalize. |
no-renames | Desactiva la detección de renombrados durante el merge. |
find-renames=<n> | Activa la detección de renombrados con un umbral de similitud de n% (predeterminado 50%). |
subtree=<path> | Similar a la estrategia subtree, pero permite especificar el prefijo de ruta que debe desplazarse para alinear los árboles. |
Cómo elegir
Para el trabajo diario no eliges una estrategia en absoluto — deja que Git use ort, y decide solo el resultado que deseas:
- ¿Quieres el historial más simple y lineal cuando sea posible? Solo usa
git merge(hace fast-forward automáticamente). - ¿Quieres que cada merge quede registrado como un commit? Agrega
--no-ff. - ¿Quieres un commit limpio por característica en
main? Usa--squash. - ¿Uniendo varias ramas de tema terminadas a la vez? Un simple
git merge a b cusaoctopus.
Si prefieres reproducir tus commits encima de la rama de destino en lugar de fusionar, consulta git rebase. Para traer un único commit de otra rama, usa git cherry-pick.