← Git

Ramas

¿Qué es un merge y cuál es la diferencia entre un fast-forward y un merge commit?

Ver respuesta — intenta responderla en voz alta primero

Un merge integra los cambios de una rama en otra. Si la rama destino no avanzó desde que se creó la otra, Git hace un fast-forward: solo mueve el puntero hacia adelante, sin crear un commit nuevo. Si ambas ramas avanzaron por separado, Git crea un merge commit que une las dos historias y tiene dos padres.

Trabajaste en una rama feature y ya quieres llevar esos cambios a main. Te paras en main y haces git merge feature. Hay dos escenarios:

  • Fast-forward: main no recibió commits nuevos mientras trabajabas en feature. Como la historia es lineal, Git simplemente adelanta el puntero de main hasta el último commit de feature. No se crea ningún commit de merge.
  • Merge commit (three-way merge): tanto main como feature recibieron commits distintos. Git no puede solo adelantar el puntero, así que crea un commit especial de merge con dos padres (el último de cada rama) para unir ambas historias. Aquí es donde pueden aparecer conflictos si las dos ramas tocaron las mismas líneas.
# Estoy en feature y quiero integrarla a main
git switch main
git merge feature

# Caso fast-forward (main no avanzó):
# Salida: Updating 1a2b3c4..5d6e7f8
#         Fast-forward
# No se crea commit nuevo, solo se adelanta el puntero

# Caso merge commit (ambas ramas avanzaron):
# Salida: Merge made by the 'ort' strategy.
# Se crea un commit de merge con dos padres

# Forzar SIEMPRE un merge commit, aunque se pueda hacer fast-forward
git merge --no-ff feature
# Útil para dejar registrado en el historial que existió una rama

# Después de mergear, borrar la rama
git branch -d feature

Creer que un merge siempre crea un commit de merge. No: si es fast-forward, no se crea ningún commit, solo se mueve el puntero, y el historial queda lineal. Otro error es olvidar que el merge se ejecuta desde la rama destino: hay que estar parado en main (o donde quieras integrar) y mergear la otra rama hacia ahí.

"Un merge integra los cambios de una rama en otra. Me paro en la rama destino, por ejemplo main, y hago git merge feature. Si main no avanzó desde que salió feature, Git hace un fast-forward: solo adelanta el puntero, sin commit nuevo. Si ambas ramas avanzaron por separado, crea un merge commit con dos padres para unir las historias, y ahí es donde pueden aparecer conflictos. A veces uso --no-ff para forzar el merge commit y dejar registrado que hubo una rama."

Reto rápido

Creaste feature desde main, hiciste 2 commits en feature y main no cambió nada mientras tanto. Haces git merge feature desde main. ¿Se crea un merge commit?

Ver respuesta

No. Como main no avanzó, la historia es lineal y Git hace un fast-forward: simplemente adelanta el puntero de main hasta el último commit de feature, sin crear ningún commit de merge. Si quisieras forzar un merge commit de todos modos, usarías git merge --no-ff feature.