Resolución de historias divergidas: Estrategias de Git Merge vs. Rebase

Compara git merge y git rebase para ramas divergidas, manejo de conflictos, historial compartido y elección de un flujo de trabajo seguro para el equipo.

Resolución de historias divergidas: Estrategias de Git Merge vs. Rebase

Tanto git merge como git rebase ayudan cuando tu rama ha divergido de otra. La diferencia radica en cómo preservan el historial, y elegir la incorrecta puede dificultar la colaboración más de lo necesario.

No necesitas un historial perfecto para cada cambio. Sí necesitas una estrategia que tu equipo entienda y que mantenga estables las ramas compartidas.

Qué significa una historia divergida

Una historia divergida ocurre cuando dos ramas tienen commits diferentes después de un punto de partida común. Por ejemplo, creaste feature/log-cleanup desde main el lunes. El martes, alguien fusionó una corrección de seguridad en main. Ahora tu rama y main tienen cada una commits que la otra no tiene.

Puedes ver esto con:

git log --oneline --graph --decorate --all

También puedes ver que Git te dice que tu rama y la rama remota han divergido. Eso significa que ambos lados tienen commits únicos. Git necesita que decidas cómo combinarlos.

Las dos herramientas normales son merge y rebase:

git merge main

o:

git rebase main

Ambas pueden producir el mismo contenido final de archivo. El historial se verá diferente.

Cómo funciona Git Merge

Merge combina historiales sin reescribir commits existentes. Si tu rama y main avanzaron, Git crea un commit de fusión que une las dos líneas de trabajo.

Un flujo típico se ve así:

git switch feature/log-cleanup
git fetch origin
git merge origin/main

Si no hay conflictos, Git crea un commit de fusión o avanza rápido cuando es posible. Si hay conflictos, Git se detiene y te pide que los resuelvas.

Merge es bueno cuando quieres preservar la forma real de la colaboración. Muestra que el trabajo ocurrió en paralelo y se combinó después. Esto puede ser útil para ramas de larga duración, ramas de lanzamiento y ramas de características compartidas.

La desventaja es que las fusiones frecuentes pueden agregar ruido. Una rama con muchos commits de "fusionar main en feature" puede ser más difícil de escanear. Eso no significa que esté mal, pero puede hacer que el historial sea menos ordenado.

Usa merge cuando:

  • La rama es compartida con otros desarrolladores.
  • Quieres evitar reescribir el historial de commits.
  • Tu equipo valora un registro exacto de los puntos de integración.
  • Estás actualizando una rama de lanzamiento o una rama protegida.

Para una rama ya enviada y utilizada por otros, merge suele ser la opción predeterminada más segura.

Cómo funciona Git Rebase

Rebase mueve los commits de tu rama para que aparezcan sobre un nuevo commit base. En lugar de mostrar dos líneas divergidas unidas por un commit de fusión, el historial de la rama se vuelve lineal.

Un flujo típico se ve así:

git switch feature/log-cleanup
git fetch origin
git rebase origin/main

Git reproduce tus commits uno por uno sobre el último main. Si aparece un conflicto, Git se detiene en el commit que no se puede reproducir. Después de arreglar el conflicto, continúa con:

git add <archivos-arreglados>
git rebase --continue

Si el rebase se vuelve confuso, puedes deshacerlo:

git rebase --abort

Rebase es útil para ramas locales y privadas porque mantiene el historial fácil de leer. Los revisores pueden ver tus commits como si se hubieran construido sobre el último main desde el principio.

Usa rebase cuando:

  • La rama es tuya y no compartida.
  • Quieres un historial de commits limpio y lineal.
  • Estás preparando una rama antes de abrir una solicitud de extracción.
  • Tu equipo prefiere explícitamente ramas de características con rebase.

La regla principal es simple: no hagas rebase de commits públicos a menos que tu equipo lo espere. Rebase reescribe los hashes de los commits. Si alguien más basó su trabajo en tus commits antiguos, tu reescritura puede causarles confusión.

Para más herramientas cotidianas del historial de Git, consulta explorando el historial del proyecto.

Manejo de conflictos durante Merge o Rebase

Los conflictos ocurren cuando Git no puede combinar cambios automáticamente. Son comunes en archivos ocupados como manifiestos de despliegue, archivos de bloqueo de dependencias y archivos de configuración compartidos.

Comienza verificando el estado:

git status

Abre los archivos en conflicto y busca los marcadores de conflicto:

<<<<<<< HEAD
versión de la rama actual
=======
versión entrante
>>>>>>> nombre-de-la-rama

Tu trabajo es reemplazar el bloque marcado con el contenido final que realmente deseas. No mantengas los marcadores.

Después de editar, agrega el archivo:

git add ruta/al/archivo

Para un merge, termina con:

git commit

Para un rebase, continúa con:

git rebase --continue

Ejecuta pruebas o al menos el comando de validación relevante después de resolver conflictos. Un archivo puede estar sintácticamente limpio pero lógicamente incorrecto. Por ejemplo, dos cambios en YAML de Kubernetes pueden fusionarse sin conflicto mientras aún definen puertos duplicados o etiquetas no coincidentes.

Elegir una estrategia de equipo

La mejor estrategia es la que crea un historial predecible para tu proyecto. Muchos equipos usan rebase para ramas de características privadas y commits de fusión para solicitudes de extracción. Otros comprimen todo el trabajo de una característica en un solo commit. Algunos equipos de infraestructura prefieren commits de fusión porque muestran exactamente cuándo se integraron las ramas.

Elige una regla y documéntala. Una política simple podría ser:

  • Haz rebase de tu propia rama de características antes de la revisión.
  • Nunca hagas rebase de main, ramas de lanzamiento o ramas compartidas.
  • Usa commits de fusión para solicitudes de extracción aprobadas.
  • Usa fusión comprimida para correcciones pequeñas y de un solo propósito.

Esto evita debates sobre el estilo de Git durante el trabajo urgente. También facilita la automatización porque CI, notas de lanzamiento y herramientas de despliegue pueden confiar en un historial consistente.

Cuándo pedir ayuda

Pregunta antes de hacer push forzado después de un rebase en una rama que otros puedan usar. También pregunta cuando un conflicto toque configuraciones de seguridad, migraciones de base de datos, archivos de despliegue de producción o archivos de bloqueo generados que no entiendes.

Si un merge o rebase se enreda, detente e inspecciona el estado con git status. Generalmente puedes abortar y volver al estado anterior con git merge --abort o git rebase --abort. Eso es mejor que probar comandos aleatorios hasta que el árbol de trabajo se vea limpio.

Merge y rebase resuelven el mismo problema general, pero cuentan historias diferentes. Merge preserva cómo se unió el trabajo. Rebase crea una línea más limpia de commits. Usa cada uno donde encaje, y tu historial de Git seguirá siendo útil en lugar de convertirse en una fuente de riesgo.