Integración de cambios en Git: merge, rebase y decisiones correctas

Capítulo 4

Tiempo estimado de lectura: 8 minutos

+ Ejercicio

Merge y rebase: dos formas de integrar cambios

Cuando dos líneas de trabajo han avanzado (por ejemplo, tu rama de funcionalidad y la rama principal), necesitas integrar cambios. En Git, las dos herramientas más comunes son merge y rebase. Ambas pueden terminar con el mismo contenido final en tu proyecto, pero difieren en cómo queda el historial y en cómo se colabora.

Qué cambia realmente: el historial

  • Merge integra dos historiales tal como ocurrieron y, si hace falta, crea un merge commit que deja evidencia explícita del punto de integración.
  • Rebase “recoloca” tus commits sobre otra base, reescribiendo el historial para que parezca lineal (como si hubieras trabajado desde el último estado de la rama destino).

Comparación práctica: impacto en colaboración e historial

AspectoMergeRebase
HistorialPreserva la forma real del trabajo (ramas y puntos de integración)Linealiza reescribiendo commits (historia “limpia”)
ColaboraciónSeguro para ramas publicadas; no cambia SHAs existentesPeligroso si ya publicaste esos commits; cambia SHAs
ContextoMuestra claramente cuándo y por qué se integróOculta el momento de integración (no hay merge commit)
Uso típicoIntegrar en rama principal o en ramas compartidasPreparar tu rama local antes de compartir o antes de abrir PR

Regla de oro: no reescribas historial publicado

Si una rama ya fue compartida (por ejemplo, la subiste a GitHub y alguien más puede basarse en ella), evita rebase sobre esa rama. Reescribir historial cambia los identificadores (SHAs) de los commits, lo que puede causar divergencias y trabajo duplicado en el equipo.

En ramas compartidas, prefiere merge o, si tu flujo lo permite, rebase solo en tu rama local antes de publicarla.

Cuándo elegir merge

  • Para preservar contexto de integración: quieres ver en el historial el “momento” en que se unieron dos trabajos.
  • En ramas publicadas o colaborativas: minimiza fricción porque no reescribe commits existentes.
  • Para mantener trazabilidad: útil cuando el equipo revisa el historial para entender cómo se integraron features.

Diagrama conceptual (merge con merge commit)

Imagina este historial (cada letra es un commit):

main:    A---B---C---------F   (merge commit F integra feature) feature:       D---E----/

Aquí, F es un commit especial que tiene dos padres: uno en main (C) y otro en feature (E). El historial conserva que hubo dos líneas paralelas y luego una integración.

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

Cuándo elegir rebase

  • Para linearizar trabajo local antes de compartir: tu rama aún es tuya (no publicada) y quieres un historial más fácil de leer/revisar.
  • Para evitar merges repetitivos en una rama de feature: en vez de “traer main” con merges frecuentes, rebasas tu trabajo encima de la versión más reciente.
  • Antes de abrir un Pull Request (si tu equipo lo recomienda): facilita la revisión al presentar commits en una línea continua.

Diagrama conceptual (rebase reescribe historial)

Situación inicial:

main:    A---B---C feature:       D---E

Si main avanza a G y luego rebasas feature sobre main:

main:    A---B---C---G feature:                D'---E'   (D y E reescritos como D' y E')

Los commits D y E “cambian de identidad” (por eso aparecen como D' y E'). El contenido puede ser equivalente, pero el historial es nuevo.

Guía paso a paso: hacer merge con seguridad

1) Preparación: estado limpio y actualizado

  • Verifica que no tengas cambios sin guardar: git status
  • Actualiza referencias remotas (si trabajas con remoto): git fetch

2) Merge típico: integrar una rama en otra

Ejemplo: integrar feature/login dentro de main.

git switch main git pull   # si usas remoto y quieres main al día git merge feature/login

Si no hay conflictos, Git creará un merge commit (o hará fast-forward si aplica, según el caso y configuración).

3) Forzar que quede evidencia de integración (merge commit)

Si quieres siempre un merge commit (útil para preservar contexto), incluso cuando podría ser fast-forward:

git merge --no-ff feature/login

4) Si hay conflictos: pausar, resolver y continuar

Durante un conflicto, Git pausa el merge. Pasos:

  • Ver archivos en conflicto: git status
  • Abrir y resolver marcadores (<<<<<<<, =======, >>>>>>>)
  • Marcar como resuelto: git add <archivo>
  • Finalizar el merge: git commit (Git propondrá el mensaje de merge)

5) Si necesitas cancelar el merge

Si estás en medio de un merge con conflictos y decides volver al estado anterior:

git merge --abort

Esto intenta restaurar el estado previo al merge.

Guía paso a paso: hacer rebase con seguridad

0) Checklist antes de rebase

  • Idealmente, que tu rama sea local o no compartida.
  • Estado limpio: git status
  • Actualiza la rama base: git fetch y/o git pull en la rama base.

1) Rebase de tu rama sobre main

Ejemplo: estás en feature/login y quieres rebasar sobre main actualizado.

git switch feature/login git fetch origin git rebase origin/main

Git tomará tus commits de feature/login y los aplicará uno por uno encima de origin/main.

2) Si hay conflictos: pausar, resolver y continuar

En rebase, Git se detiene en el commit que no pudo aplicar. Pasos:

  • Ver qué pasó: git status
  • Resolver conflictos en archivos
  • Marcar resueltos: git add <archivo>
  • Continuar rebase: git rebase --continue

3) Saltar un commit problemático (caso excepcional)

Si un commit no tiene sentido aplicarlo (por ejemplo, era un cambio temporal), puedes omitirlo:

git rebase --skip

4) Cancelar el rebase y volver atrás

Si el rebase se complica o no era lo que querías:

git rebase --abort

Vuelves al estado anterior al rebase.

Recuperación ante errores: volver a un estado anterior

Usar reflog para “deshacer” un rebase o un merge

git reflog registra movimientos de HEAD (incluye rebase). Si hiciste un rebase y luego te arrepientes, puedes volver al commit anterior.

git reflog

Verás entradas como:

abc1234 HEAD@{0}: rebase finished: returning to refs/heads/feature/login def5678 HEAD@{1}: rebase: pick ... 987aaaa HEAD@{2}: checkout: moving from main to feature/login

Para volver a un punto anterior (ejemplo HEAD@{2}):

git reset --hard HEAD@{2}

Precaución: --hard descarta cambios no confirmados. Úsalo cuando estés seguro o cuando tu working tree esté limpio.

Mantener una rama principal limpia: reglas y prácticas

1) Evita commits directos en main (si trabajas en equipo)

Una práctica común es que main solo reciba cambios integrados (por PR o revisiones). Esto reduce errores y mantiene el historial más consistente.

2) Integra en main con merge cuando quieras preservar contexto

Si tu equipo valora ver el punto de integración (por ejemplo, “feature X entró aquí”), usa merge con --no-ff al integrar ramas de funcionalidad.

3) Rebase solo para preparar tu rama antes de compartir

Flujo típico recomendado:

  • Trabajas en feature localmente.
  • Antes de publicar/abrir PR, haces git rebase origin/main para linearizar y resolver conflictos tú mismo.
  • Luego publicas la rama. Si ya la habías publicado y necesitas actualizarla tras un rebase, tendrás que hacer push forzado (ver siguiente punto), lo cual requiere coordinación.

4) Si reescribiste una rama publicada: push forzado con seguridad (solo si es imprescindible)

Si tu equipo permite rebase en ramas publicadas (por ejemplo, una rama de PR que solo tú usas), evita --force y prefiere:

git push --force-with-lease

--force-with-lease es más seguro porque falla si el remoto tiene commits nuevos que tú no tienes (protege contra pisar trabajo ajeno).

Escenarios comunes y decisión recomendada

Escenario A: tu rama local se quedó atrás de main y aún no la compartiste

  • Recomendación: rebase sobre main para linearizar y resolver conflictos antes de publicar.
git switch feature/login git fetch origin git rebase origin/main

Escenario B: rama compartida con más personas trabajando

  • Recomendación: evita rebase; usa merge para integrar cambios sin reescribir SHAs.
git switch feature/team-work git fetch origin git merge origin/main

Escenario C: integrar una feature terminada a main y quieres trazabilidad

  • Recomendación: merge con commit explícito (--no-ff).
git switch main git pull git merge --no-ff feature/login

Escenario D: hiciste rebase y ahora tu rama “se rompió” o te arrepentiste

  • Recomendación: usa git rebase --abort si aún estás en el proceso; si ya terminó, usa git reflog y vuelve con git reset --hard.

Mini-guía de verificación antes y después de integrar

Antes

  • git status (working tree limpio)
  • git log --oneline --decorate --graph --all (entender el estado del historial)
  • git fetch (tener referencias actualizadas)

Después

  • git log --oneline --decorate --graph --all (confirmar el resultado: merge commit o historial lineal)
  • Ejecutar pruebas o comandos de verificación del proyecto (según tu stack)

Ahora responde el ejercicio sobre el contenido:

Tienes una rama ya publicada y usada por otras personas. ¿Qué decisión es la más segura para integrar cambios sin reescribir el historial compartido?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

En ramas publicadas o colaborativas se debe evitar rebase porque reescribe el historial y cambia los SHAs, lo que puede causar divergencias. Merge integra manteniendo el historial tal como ocurrió y es más seguro para el equipo.

Siguiente capítulo

Conflictos en Git: diagnóstico, resolución y prevención

Arrow Right Icon
Portada de libro electrónico gratuitaGit y GitHub para programadores principiantes: control de versiones para proyectos
33%

Git y GitHub para programadores principiantes: control de versiones para proyectos

Nuevo curso

12 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.