Merge es una operación de fusión de ramas en Git que combina cambios de dos líneas de desarrollo diferentes en una rama destino. A diferencia de rebase, merge conserva el historial completo de ramificación creando un commit de merge especial con dos padres. Según la documentación oficial de Git (2026), merge es la forma más segura de unir ramas porque no reescribe el historial y permite rastrear cuándo y qué ramas se fusionaron. Es la opción estándar para la fusión en ramas públicas como main, develop y release.
Puntos clave
Merge es el comando git merge que combina los cambios de la rama especificada en la rama actual. Git encuentra el ancestro común (commit base), calcula el diff de cada rama respecto al ancestro y crea un commit de merge que contiene el conjunto combinado de cambios. El resultado es que la rama destino recibe todos los cambios de la rama fusionada.
Sintaxis: estando en la rama destino (por ejemplo, main), ejecuta git merge feature. Git crea automáticamente un commit de merge si no hay conflictos. El mensaje predeterminado del commit de merge es: “Merge branch 'feature' into main”. Puedes cambiar el mensaje con la bandera -m o editarlo en el editor abierto.
Merge es una operación no destructiva. A diferencia de rebase, merge no toca los commits existentes: conservan los mismos hashes, autores y fechas. Esto hace que merge sea la única forma segura de fusionar ramas en las que varios desarrolladores trabajan simultáneamente. Si algo sale mal, merge se puede cancelar con git merge --abort.
# Cambiar a la rama destino
git checkout main
# Fusionar rama de funcionalidad
git merge feature
# Resultado — commit de merge con dos padres
git log --oneline --graph
# Merge con mensaje personalizado
git merge feature -m "feat: integrate authentication module"
Git admite tres modos de fusión que se eligen según el resultado deseado. El merge regular (predeterminado) crea un commit de merge. El squash merge combina todos los commits de la rama de funcionalidad en uno solo. Fast-forward mueve el puntero de la rama sin crear un commit, si es posible. La elección del modo depende del flujo de trabajo del equipo y las reglas del historial.
Merge regular (--no-ff) — crea un commit de merge incluso si la fusión se pudiera realizar como fast-forward. Se recomienda para la rama main: un commit de merge marca claramente el punto de integración de la funcionalidad y permite revertir todos los cambios de la rama de funcionalidad con un solo revert del commit de merge. GitHub usa este modo por defecto al fusionar PR con el botón Merge.
Squash merge (--squash) — agrupa todos los commits de la rama de funcionalidad en un único commit en la rama destino. Útil cuando el historial preliminar de la rama de funcionalidad no debe contaminar main. Inconveniente: se pierde el vínculo con los commits originales — no se puede ver cómo se desarrolló la funcionalidad paso a paso. GitHub usa este modo al seleccionar “Squash and merge” en un PR.
Fast-forward (--ff) — si la rama destino no tiene commits nuevos desde que se bifurcó la rama de funcionalidad, Git simplemente mueve el puntero hacia adelante sin crear un commit de merge. El historial permanece lineal. La bandera --no-ff fuerza un commit de merge, mientras que --ff-only dará error si fast-forward no es posible.
# Forzar commit de merge (recomendado para main)
git merge --no-ff feature
# Squash merge — todos los commits en uno
git merge --squash feature
git commit -m "feat: add authentication"
# Fast-forward solo si es posible
git merge --ff-only feature
# Cancelar merge conflictivo
git merge --abort
Las estrategias de fusión determinan el algoritmo que Git utiliza para combinar cambios. Cada estrategia es adecuada para diferentes escenarios. Git selecciona automáticamente la estrategia apropiada, pero los desarrolladores pueden especificarla explícitamente con la bandera --strategy. Comprender las estrategias ayuda a predecir el comportamiento de Git en fusiones complejas.
Recursive — la estrategia predeterminada para fusionar dos ramas. Git encuentra el ancestro común, calcula los cambios en cada rama y los fusiona. Si se encuentra un ancestro común, recursive maneja correctamente los cambios de nombre y las adiciones de archivos. Durante los conflictos, recursive puede usar opciones adicionales: ours (elegir automáticamente nuestra versión) y theirs (elegir la suya).
Octopus — para fusionar más de dos ramas simultáneamente: git merge feature1 feature2 feature3. Octopus no admite resolución de conflictos — todos los conflictos deben resolverse antes de invocar el comando. Se usa raramente, principalmente para fusionar varias ramas independientes que se garantiza que no entren en conflicto (por ejemplo, diferentes módulos).
| Estrategia | Número de ramas | Resolución de conflictos |
|---|---|---|
| Recursive | 2 | Automática + opciones ours/theirs |
| Octopus | 3+ | No — todos los conflictos deben resolverse de antemano |
| Ours | Cualquiera | Siempre elige nuestra versión, ignora cambios ajenos |
| Subtree | 2 | Para fusiones de subárboles (subtree merge) |
Ours — una estrategia especial que ignora completamente los cambios de la rama fusionada y conserva el contenido actual de la rama destino. Se crea un commit de merge, pero el contenido permanece sin cambios. Útil cuando necesitas registrar en el historial el hecho de la fusión pero en realidad rechazar todos los cambios de la otra rama.
El conflicto de merge ocurre cuando las mismas líneas de un archivo se modificaron de forma diferente en ambas ramas. Git no puede determinar automáticamente qué versión es correcta y pausa el merge. También puede surgir un conflicto cuando un archivo se renombra en una rama y se modifica en otra, o cuando el mismo archivo se elimina y modifica simultáneamente.
Proceso de resolución: Git marca los archivos en conflicto con marcadores. El archivo muestra secciones con <<<<<<< HEAD (nuestra versión), ======= (separador) y >>>>>>> feature (su versión). El desarrollador edita manualmente la sección en conflicto, selecciona las líneas deseadas de ambas versiones, elimina los marcadores, guarda el archivo y lo añade al índice con git add.
Para la resolución visual de conflictos, Git admite mergetool — una herramienta externa de comparación. Herramientas mergetool populares: Meld, KDiff3, Beyond Compare, VS Code (editor de conflictos integrado). Mergetool muestra tres paneles: nuestra versión, su versión y el resultado. El desarrollador selecciona visualmente los bloques de código para incluirlos en el archivo final.
# Iniciar merge y detectar conflicto
git merge feature
# CONFLICTO (contenido): Conflicto de merge en src/main.swift
# Ver archivos en conflicto
git status
# Abrir mergetool visual
git mergetool
# Después de resolver — add y commit
git add src/main.swift
git commit
# Cancelar merge
git merge --abort
Merge es preferible a rebase en varias situaciones clave. Primera: al trabajar con ramas públicas accesibles a otros desarrolladores. Merge no reescribe el historial, por lo que los compañeros pueden sincronizarse de forma segura. Hacer rebase en una rama pública crea un historial divergente y causa conflictos a todos los que ya tienen los commits antiguos.
Segunda situación: al finalizar una rama de funcionalidad. La mayoría de los equipos prefieren merge (con la bandera --no-ff) en main para registrar el momento de integración de la funcionalidad. Esto simplifica la navegación por el historial y permite revertir fácilmente toda una funcionalidad con un solo git revert del commit de merge. GitHub Flow por defecto ofrece tres opciones de merge: merge simple, squash merge y rebase merge.
Tercera situación: al trabajar con un pull request revisado. GitHub y GitLab ofrecen un botón de merge con diferentes opciones. Merge (Create a merge commit) — historial completo con un commit de merge. Squash and merge — historial limpio sin detalles de desarrollo. Rebase and merge — historial lineal sin commit de merge, pero con reescritura de commits. La elección depende de las reglas del equipo.
Primera regla: estar siempre en la última versión de la rama destino antes de fusionar. Ejecuta git checkout main && git pull antes de fusionar la rama de funcionalidad. Esto minimiza los conflictos y garantiza que el commit de merge contenga todos los cambios más recientes. Si la rama destino ha avanzado significativamente, primero ejecuta git merge main dentro de la rama de funcionalidad para resolver conflictos en su contexto.
Segunda regla: probar el código después del merge. La fusión puede cambiar el comportamiento incluso si no hubo conflictos. El pipeline de CI/CD debe ejecutar pruebas en el commit de merge antes de enviarlo a producción. Algunos equipos usan merge gates — comprobaciones obligatorias que bloquean el merge hasta que se superen.
Tercera regla: documentar los commits de merge. El mensaje estándar “Merge branch 'feature' into main” es poco útil. Se recomienda añadir una descripción de lo que se fusionó: “Merge authentication module: login, registration, password recovery”. Esto simplifica el análisis del historial y la búsqueda de regresiones. En proyectos grandes, los commits de merge se generan automáticamente a partir del título del PR.
Preguntas frecuentes
Fusionar significa ejecutar git merge para combinar cambios de una rama en otra. El resultado es un commit de merge que registra el evento de fusión y contiene cambios de ambas ramas. Esta es la forma principal de integrar ramas de funcionalidad en main, develop o release en Git Flow.
Squash merge combina todos los commits de la rama de funcionalidad en un único commit en la rama destino, perdiendo el historial de desarrollo intermedio. El merge regular crea un commit de merge conservando todos los commits de la rama de funcionalidad. Squash merge proporciona un historial limpio pero no permite rastrear el desarrollo paso a paso de la funcionalidad.
Abre el archivo en conflicto, busca las secciones con los marcadores <<<<<<< HEAD y >>>>>>>. Edita el contenido, conservando las líneas necesarias de ambas versiones, elimina los marcadores. Guarda el archivo, ejecuta git add y git commit. Puedes usar git mergetool para la resolución visual.
Merge se usa siempre para ramas públicas (main, develop, release) porque no reescribe el historial. Rebase se aplica en ramas de funcionalidad personales antes de su publicación. Una vez que una rama ha pasado a formar parte del repositorio compartido y los compañeros han accedido a ella, solo se permite merge.
Antes de que el merge se complete (durante un conflicto) — git merge --abort cancela el merge por completo. Después de completado — git revert <merge-commit-hash> -m 1 crea un commit de reversión. La bandera -m 1 especifica qué rama padre conservar (la destino). Git revert es más seguro que git reset para ramas publicadas.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también