Comparación

Git merge vs rebase: cuál elegir para tu equipo

Actualizado: · Skillaria.Top

Tanto merge como rebase integran los cambios de dos ramas, pero tratan el historial de forma distinta: merge lo conserva tal cual y añade un commit de fusión, y rebase reescribe tus commits sobre la nueva base y deja un historial lineal. Regla práctica: rebase para ordenar tus commits aún no publicados, merge para integrar el trabajo terminado en las ramas compartidas.

En resumen: diferencia entre merge y rebase

El debate «git merge vs rebase» no va realmente de qué comando es mejor, sino de qué historial del proyecto quieres ver. Ambos comandos llevan al mismo código final. Lo que cambia es el camino que queda registrado en el log.

  • Merge une dos líneas del historial y deja constancia honesta de que el trabajo avanzó en paralelo. Los commits existentes no cambian y se añade un merge commit con dos padres.
  • Rebase reescribe tus commits como si hubieras empezado a trabajar desde la versión más reciente de la rama base. El historial queda como una línea recta, pero los commits reciben hashes nuevos.

La mecánica de cada comando (opciones, resolución de conflictos, modo interactivo) la explicamos en artículos aparte. Aquí nos centramos solo en elegir la estrategia.

Cómo queda el historial en cada caso

Situación de partida: creaste feature, hiciste dos commits y, mientras tanto, en main aparecieron dos commits de otras personas.

          D---E        feature
         /
A---B---C---F---G      main

Después de git merge feature en main:

          D---E
         /     \
A---B---C---F---G---M  main

Después de git rebase main en feature y del fast-forward de main:

A---B---C---F---G---D'---E'   main

En el primer caso el historial muestra que la funcionalidad se desarrolló en paralelo y cuándo se integró. En el segundo, el historial se lee como un relato secuencial, pero el hecho del trabajo en paralelo desaparece: D' y E' son commits nuevos creados en el momento del rebase.

Tabla comparativa: git merge vs rebase

Criteriogit mergegit rebase
Commits existentesNo cambianSe recrean con hashes nuevos
Forma del historialGrafo ramificado con merge commitsLineal
Seguridad en ramas compartidasSiempre seguroPeligroso con commits publicados
¿Hace falta force push?NoSí, si la rama ya está en el servidor
ConflictosSe resuelven una vez, en el merge commitPueden aparecer en cada commit que se traslada
Contexto de «de dónde viene»Se conservaSe pierde
Revertir una funcionalidad completaUn solo git revert -m 1 del merge commitRevert de cada commit o de un rango
Comodidad con git bisect y git logGrafo más difícil de leerMás sencillo: una sola línea recta
Curva de aprendizajeBajaMás alta, hay que entender la reescritura del historial
Limpieza de commits (squash, reword)Solo --squash de todo a la vezFlexible con rebase -i

Ventajas y desventajas de merge

Ventajas

  • No destruye el historial. Todo lo publicado sigue en su sitio. Tus compañeros no tendrán que arreglar nada después de lo que hagas.
  • El conflicto se resuelve una sola vez. Aunque la rama tenga 30 commits, trabajas con el estado final, no con cada paso.
  • Se conserva el contexto. Por el merge commit se ve qué tarea entró en la rama principal y cuándo, y es fácil revertirla entera.

Desventajas

  • Grafo ruidoso. Con sincronizaciones frecuentes, el historial se llena de commits «Merge branch 'main' into feature» y git log --graph acaba pareciendo un mapa de vías de tren.
  • Los commits de borrador acaban en el historial. «wip», «fix», «otro fix» se quedan para siempre en la rama principal si no se combinan.

Ventajas y desventajas de rebase

Ventajas

  • Historial lineal y legible. Cada commit está en su sitio, git log se lee como una lista de cambios y git bisect encuentra más fácilmente el commit que introdujo el error.
  • Posibilidad de ordenar los commits antes de la revisión: combinarlos, renombrarlos, reordenarlos.
  • Sin merge commits técnicos por sincronizarse con la rama principal.

Desventajas

  • Reescribe el historial. Hacer rebase de una rama compartida ya publicada rompe el trabajo de todos los que la descargaron.
  • Exige force push en las ramas que están en el servidor, y por tanto disciplina y --force-with-lease.
  • Conflictos repetidos. El mismo fragmento puede entrar en conflicto en varios commits seguidos.
  • Puede que los commits intermedios no compilen. Tras trasladarlos a la nueva base, nadie ha probado esos commits antiguos en el nuevo entorno.

Cuándo usar cada uno

Rebase para tu trabajo local

Actualizas tu rama antes de subirla: git pull --rebase. Preparas la rama para revisión y quieres quitar los commits de borrador: git rebase -i. Tu rama de feature personal se ha quedado atrás respecto a main: git rebase origin/main. En todos estos casos se reescriben commits que solo has visto tú (o que solo te pertenecen a ti).

Merge para ramas compartidas e integración

Una funcionalidad terminada se integra en main o develop. Varias personas trabajan en la misma rama. Hay que fusionar una rama de release de vuelta en la principal. Aquí lo importante es no tocar los commits ya publicados, y merge es la única opción correcta.

Una regla sencilla para decidir

Si los commits solo los tienes tú, puedes hacer rebase. Si alguien ya los ha descargado, solo merge.

Flujos de trabajo habituales para un equipo

FlujoCómo funcionaPara quién
Solo mergeLas funcionalidades se integran con --no-ff y la sincronización se hace con git merge mainEquipos que empiezan con Git, o donde importan la cronología completa y los reverts sencillos
Rebase + mergeAntes de integrar, la rama se rebasa sobre main y luego se crea un merge commit con --no-ffEquipos que quieren un historial limpio y también los límites de cada funcionalidad
Rebase + fast-forwardLa rama se rebasa y se integra por fast-forward; el historial es completamente linealEquipos pequeños con commits atómicos y cuidados
Squash mergeCada pull request se convierte en un único commit en mainEquipos con tareas cortas en los que no hace falta el historial detallado de la rama

En GitHub y GitLab estos flujos corresponden a los botones «Create a merge commit», «Rebase and merge» y «Squash and merge». Lo mejor es permitir en la configuración del repositorio solo la opción elegida, para que el historial no se convierta en una mezcla de estilos.

Configuración que fija la elección

# pull sin merge commits innecesarios
git config --global pull.rebase true

# o bien: pull solo por fast-forward; si no, error y decides tú
git config --global pull.ff only

# siempre un merge commit al integrar funcionalidades
git config --global merge.ff false

Cuidado con merge.ff false: también afecta a git pull en modo merge. Muchos prefieren no activarlo de forma global y escribir --no-ff explícitamente al integrar una funcionalidad.

Ejemplo: la misma tarea en los dos estilos

Veamos un caso real. Llevas tres días desarrollando la funcionalidad de pagos en la rama feature/payment y, mientras tanto, en main se han integrado cinco tareas de otros. Antes del pull request tienes que traer el main actualizado y comprobar que todo funciona.

Opción con merge

git switch feature/payment
git fetch origin
git merge origin/main
# conflictos resueltos una sola vez, git add, git commit
git push

La rama recibe el commit «Merge remote-tracking branch 'origin/main' into feature/payment». El push es normal y los compañeros que siguen la rama no notan nada. Si te sincronizas así cada día, la rama tendrá tres commits de este tipo, y llegarán a main junto con la funcionalidad si se integra sin squash.

Opción con rebase

git switch feature/payment
git fetch origin
git rebase origin/main
# los conflictos se resuelven sobre la marcha, en cada commit: git add, git rebase --continue
git rebase -i origin/main      # opcional: combinar los commits de borrador
git push --force-with-lease

La rama parece haberse creado esta mañana a partir del main actualizado, no hay commits sobrantes y al revisor le resulta más fácil leer los cambios paso a paso. El precio es un push forzado y tener que asegurarse de que nadie más hace commits en esa rama.

Qué acabará viendo main

Al integrar mediante pull request, la diferencia se mantiene. El estilo merge dará un grafo con bifurcaciones y fusiones de sincronización; el estilo rebase, una cadena ordenada de commits de la funcionalidad que se puede integrar por fast-forward o con un único merge commit. El código será el mismo siempre que los conflictos se resuelvan igual.

Cómo decidir en equipo

Responde a unas cuantas preguntas. ¿Trabajan varias personas en la misma rama? Si es así, rebase queda descartado para esa rama. ¿Qué experiencia tiene el equipo con Git? Si entra gente nueva a menudo, empieza con merge y squash merge, que perdonan los errores. ¿Necesitáis la cronología completa para auditorías y análisis de incidentes? Entonces los merge commits de cada funcionalidad son útiles. ¿Os importa un git log legible y usáis git bisect con frecuencia? Entonces la balanza se inclina por rebase y un historial lineal.

Deja la decisión por escrito en el CONTRIBUTING o el README del repositorio y activa la protección de la rama principal: prohibir el force push, exigir pull request y fijar el método de fusión permitido. Una regla respaldada por la configuración funciona mejor que cualquier acuerdo verbal.

Mitos frecuentes

  • «Rebase es para expertos y merge para principiantes». No: son herramientas distintas para tareas distintas. Los desarrolladores con experiencia usan ambas.
  • «Los merge commits son basura». Los de sincronización, sí, a menudo son ruido. Pero el merge commit que integra una funcionalidad es un punto útil: ahí se ve toda la tarea y se puede revertir de una vez.
  • «Con rebase hay menos conflictos». Los conflictos son los mismos, porque cambian las mismas líneas. Rebase solo los reparte por commits, mientras que merge los resuelve de golpe.
  • «Rebase pierde commits». Los commits antiguos siguen en git reflog y se pueden recuperar mientras el recolector de basura no los elimine.

Conclusión

Elegir entre git merge vs rebase es elegir entre una cronología fiel y un historial lineal y legible. Merge es seguro y conserva el contexto; rebase aporta limpieza, pero reescribe los commits. La práctica más fiable es combinarlos: rebasar y limpiar tu rama mientras sea solo tuya, e integrar el trabajo terminado en las ramas compartidas con merge o squash según las reglas del equipo. Lo esencial es acordar un flujo y fijarlo en la configuración del repositorio. Ambas estrategias y el trabajo con ramas en equipo se practican en el curso de Git.

Preguntas frecuentes

¿Qué conviene usar con git pull, merge o rebase?

Para actualizar una rama local es más cómodo rebase: tus commits no publicados se colocan encima de los remotos recientes sin un merge commit extra. Se activa con git config --global pull.rebase true.

¿Se pueden combinar merge y rebase en el mismo proyecto?

Sí, y es el enfoque más habitual: rebase para tus ramas y merge para las compartidas. Lo importante es que todo el equipo conozca la regla.

¿Qué debería usar alguien que empieza?

Empieza con merge: no reescribe el historial y es más difícil romper algo. Aprende rebase en tus ramas locales cuando ya domines reflog y el force push.

¿La estrategia elegida afecta al código final?

No; si los conflictos se resuelven igual, el estado final de los archivos es idéntico. Solo cambia el historial de commits que queda registrado.

¿En qué se diferencia squash merge de rebase?

Squash merge comprime toda la rama en un único commit nuevo en la rama principal, mientras que rebase traslada cada commit por separado. Ambos dan un historial lineal, pero squash pierde el detalle paso a paso.

Aprende este tema en vídeo

Este tema se explica a fondo y con práctica en el curso «Git desde cero hasta desarrollador seguro».

Ir al curso