¿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:
mainno recibió commits nuevos mientras trabajabas enfeature. Como la historia es lineal, Git simplemente adelanta el puntero demainhasta el último commit defeature. No se crea ningún commit de merge. - Merge commit (three-way merge): tanto
maincomofeaturerecibieron 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 hagogit merge feature. Simainno 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-ffpara forzar el merge commit y dejar registrado que hubo una rama."
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.