Introducción
Un merge combina dos líneas de desarrollo. El caso más común es traer un branch de feature de vuelta a main. Esta página recorre un merge limpio, un fast-forward y un merge con conflictos.
Configuración inicial
git switch -c feature/greeting
echo "hello world" > greeting.txt
git add greeting.txt
git commit -m "Add greeting"
git switch main
git merge feature/greeting
Si main no se ha movido desde que se creó el branch, Git hace fast-forward: simplemente mueve el puntero de main a la punta de feature/greeting. No se crea merge commit.
Merges three-way reales
Si ambos branches tienen commits nuevos, Git crea un merge commit con dos padres:
git switch main
echo "main change" >> notes.txt
git commit -am "Update notes on main"
git merge feature/greeting
# Merge made by the 'ort' strategy.
El primer padre del merge commit es el HEAD previo de main; su segundo padre es la punta del branch mergeado.
Forzando un merge commit
Para preservar el historial visiblemente incluso cuando el fast-forward es posible:
git merge --no-ff feature/greeting -m "Merge feature/greeting"
Conflictos
Si ambos lados editaron las mismas líneas, Git se detiene y escribe marcadores de conflicto:
<<<<<<< HEAD
line from main
=======
line from feature
>>>>>>> feature/greeting
Resuelve editando el archivo, luego:
git add notes.txt
git status
git commit # usa el mensaje de merge preparado
Abortando
Si cambias de opinión a mitad de un merge:
git merge --abort
Esto restaura el árbol de trabajo al estado pre-merge.
Inspeccionando el resultado
git log --oneline --graph --decorate -n 10
El grafo muestra la forma de diamante creada por el merge.
Inspeccionando un merge
Los merge commits tienen dos padres, así que los diffs requieren manejo explícito. git show en un merge muestra por defecto un "diff combinado" que destaca solo los cambios que conflictan con ambos padres:
git show HEAD # diff combinado
git show -m HEAD # diff contra cada padre por separado
git show --first-parent HEAD # contra el primer padre solamente
git log --merges --oneline # solo merge commits
git log --no-merges --oneline # excluyendo merge commits
Para arqueología de código, --first-parent en un branch de larga duración revela la historia de integración: cuándo aterrizó cada feature, en orden cronológico de tronco.
Errores comunes
Editar archivos durante un merge pero olvidar hacerles git add, así que git commit sigue quejándose de paths no resueltos. Siempre ejecuta git status después de editar. Resolver eliminando los marcadores de conflicto pero dejando texto obsoleto de un lado; compila y ejecuta tests antes de commitear el merge. Usar --no-ff en cada merge en un repo de movimiento rápido, contaminando el historial con merge commits vacíos. Finalmente, entrar en pánico en el prompt y ejecutar git reset --hard a mitad del merge; git merge --abort es más seguro porque sabe sobre ORIG_HEAD.