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
| Aspecto | Merge | Rebase |
|---|---|---|
| Historial | Preserva la forma real del trabajo (ramas y puntos de integración) | Linealiza reescribiendo commits (historia “limpia”) |
| Colaboración | Seguro para ramas publicadas; no cambia SHAs existentes | Peligroso si ya publicaste esos commits; cambia SHAs |
| Contexto | Muestra claramente cuándo y por qué se integró | Oculta el momento de integración (no hay merge commit) |
| Uso típico | Integrar en rama principal o en ramas compartidas | Preparar 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.
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
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---ESi 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/loginSi 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/login4) 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 --abortEsto 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 fetchy/ogit pullen 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/mainGit 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 --skip4) Cancelar el rebase y volver atrás
Si el rebase se complica o no era lo que querías:
git rebase --abortVuelves 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 reflogVerá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/loginPara 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
featurelocalmente. - Antes de publicar/abrir PR, haces
git rebase origin/mainpara 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:
rebasesobremainpara linearizar y resolver conflictos antes de publicar.
git switch feature/login git fetch origin git rebase origin/mainEscenario B: rama compartida con más personas trabajando
- Recomendación: evita rebase; usa
mergepara integrar cambios sin reescribir SHAs.
git switch feature/team-work git fetch origin git merge origin/mainEscenario 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/loginEscenario D: hiciste rebase y ahora tu rama “se rompió” o te arrepentiste
- Recomendación: usa
git rebase --abortsi aún estás en el proceso; si ya terminó, usagit reflogy vuelve congit 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)