Git merge vs rebase: diferencias, ejemplos y cuándo usar cada uno
Git merge vs rebase decide cómo se ve el historial de tu proyecto. Mira ambos sobre el mismo ejemplo con salida real del log, aprende la regla que evita desastres y copia un flujo de trabajo seguro para equipos.
- Merge une dos ramas con un nuevo commit de fusión y conserva el historial tal como ocurrió.
- Rebase reproduce tus commits encima de otra rama, lo que da una línea recta pero hashes nuevos.
- Nunca hagas rebase de commits que otras personas ya descargaron.
- Haz rebase de tu propia rama de funcionalidad antes de abrir un pull request y usa merge al llevarla a la rama principal.
Tu rama de funcionalidad va por detrás de main y necesitas el trabajo nuevo. Git merge vs rebase es la elección entre dos formas de conseguirlo, y ambas son correctas. Se diferencian en cómo queda el historial después.
Creamos un repositorio diminuto, ejecutamos ambos comandos y pegamos la salida real, para que compares el resultado en lugar de imaginarlo. ¿Nuevo en Git? Empieza con nuestro tutorial de Git para principiantes.
Qué hacen git merge y git rebase
git merge toma las puntas de dos ramas y las combina. Si ambas tienen commits nuevos, Git crea un commit de fusión con dos padres. Nada de lo que ya existe cambia.
git rebase toma los commits exclusivos de tu rama, los aparta, mueve tu rama a la punta de la otra y luego los reproduce uno a uno. Los commits reproducidos son commits nuevos con hashes nuevos, aunque sus cambios sean los mismos.
Git merge en la práctica
Nuestro punto de partida: el commit A en main, dos commits (F1, F2) en feature y un commit más (M1) añadido después a main. Ahora fusionamos main en feature.
git switch feature
git merge main
git log --oneline --graph
* f507aab Merge main into feature
|\
| * 8842fb5 M1
* | 082cc6a F2
* | 5a71e3c F1
|/
* 8766865 A
El gráfico muestra la historia real: dos líneas de trabajo que se unieron. Los commits originales F1 y F2 conservan sus hashes. El coste es un commit de fusión adicional y, en un proyecto activo, el gráfico se convierte en una telaraña.
Git rebase en la práctica
Mismo punto de partida, pero ahora hacemos rebase de feature sobre main.
git switch feature
git rebase main
git log --oneline --graph
* 1ff474b F2
* bf9149e F1
* 8842fb5 M1
* 8766865 A
El historial es una línea recta, como si hubieras empezado tu trabajo después de M1. Fíjate en los hashes: F1 era 5a71e3c y ahora es bf9149e, y F2 pasó de 082cc6a a 1ff474b. Git los reescribió, y por eso el rebase exige cuidado.
Merge vs rebase lado a lado
| Aspecto | Merge | Rebase |
|---|---|---|
| Forma del historial | Gráfico ramificado con commits de fusión | Una línea recta |
| Commits existentes | Sin cambios | Reescritos con hashes nuevos |
| Conflictos | Se resuelven una vez, en el commit de fusión | Puede haber que arreglarlos en cada commit reproducido |
| Seguro en ramas compartidas | Sí | No |
| Ideal para | Integrar trabajo terminado en main | Actualizar tu propia rama antes de la revisión |
Consejo: si no puedes decidir, pregunta quién más tiene tu rama. Si nadie, el rebase es seguro. Si un compañero la descargó, usa merge.
La regla de oro del rebase
No hagas rebase de commits que existen fuera de tu propio repositorio. Tras un rebase, tu rama ya no coincide con la copia del servidor, así que subirla exige un push forzado. Si un colega construyó trabajo sobre los commits antiguos, su historial ahora discrepa del tuyo, y arreglarlo es doloroso.
Hacer rebase de tu rama privada de funcionalidad está bien. Hacerlo de main o de cualquier rama que otros usen, no.
Un flujo de trabajo seguro para equipos
Esta rutina mantiene el historial limpio sin sorprender a nadie. También es lo que usan la mayoría de los equipos antes de su pipeline de CI, como el de nuestra guía de GitHub Actions CI/CD.
git switch feature
git fetch origin
git rebase origin/main # or: git pull --rebase
# fix conflicts, then: git add <file> && git rebase --continue
git push --force-with-lease # only on your own branch
--force-with-lease se niega a sobrescribir la rama del servidor si alguien ha subido cambios desde tu último fetch, algo que un --force normal destruiría sin avisar. Cuando se apruebe el pull request, fusiónalo en main.
Cómo deshacer un rebase fallido
Un rebase parece destructivo, pero los commits antiguos permanecen un tiempo en el reflog de Git, así que puedes volver atrás.
git reflog # find the commit before the rebase
git reset --hard HEAD@{5} # example position, check reflog first
Crea una rama de respaldo con git branch backup antes de cualquier rebase arriesgado y recuperar será un solo comando. ¿Ejecutas una base de datos o herramientas en contenedores? Mira nuestro tutorial de Docker para principiantes.
Para terminar
Merge conserva la verdad, rebase la mantiene ordenada. Usa rebase para refrescar tu propia rama, merge para entregarla y nunca reescribas un historial del que dependan otras personas.
Preguntas frecuentes
¿Qué diferencia hay entre git merge y git rebase?
Merge combina dos ramas con un commit de fusión y conserva todos los commits existentes. Rebase mueve tus commits encima de otra rama y los reescribe, lo que produce un historial lineal.
¿Debo usar merge o rebase?
Haz rebase de tu propia rama de funcionalidad para mantenerla al día y usa merge al entregarla en una rama compartida como main. Usa merge siempre que otros compartan la rama.
¿Es peligroso git rebase?
Es seguro en ramas privadas y arriesgado en compartidas, porque reescribe los hashes de los commits. Usa una rama de respaldo y el reflog para recuperarte si algo sale mal.
¿Qué hace force-with-lease?
Fuerza el push solo si la rama remota sigue donde la viste por última vez, así no puedes sobrescribir por accidente commits nuevos de un compañero.
¿Borra el rebase mis commits?
No. Crea commits nuevos con los mismos cambios, y los antiguos permanecen en el reflog hasta que Git los limpia.
Sigue aprendiendo
¿Necesitas ayuda con pruebas, WordPress o SEO?
Ayudamos a los equipos a entregar mejor software y a hacer crecer sus sitios. Cuéntanos en qué trabajas y te propondremos un siguiente paso claro.
Más guías sobre testing, IA y desarrollo moderno
¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.
Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas
Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…
Leer artículo →DevOpsExplicación de las variables de entorno: archivos .env, secretos y configuración bien hechos
Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…
Leer artículo →Desarrollo de softwareExplicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429
La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …
Leer artículo →Automatización de pruebasBurlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan
Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…
Leer artículo →Pruebas de softwareExplicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%
Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…
Leer artículo →Bases de datos y SQLDELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno
DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…
Leer artículo →Bases de datos y SQLVistas SQL explicadas: cree, use y evite los errores, con ejemplos
Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…
Leer artículo →Desarrollo de softwareInterfaz TypeScript versus tipo: diferencias reales, probadas con el compilador
Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…
Leer artículo →Desarrollo de softwarePython *args y **kwargs explicados: funciones flexibles con ejemplos claros
Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…
Leer artículo →Desarrollo de softwareFunciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas
Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…
Leer artículo →Inteligencia artificial¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar
¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…
Leer artículo →DevOpsMonitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos
Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…
Leer artículo →DevOpsDocker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta
Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…
Leer artículo →Automatización de pruebasTDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una
TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …
Leer artículo →Desarrollo de softwareGit merge vs rebase: diferencias, ejemplos y cuándo usar cada uno
Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.
Leer artículo →Desarrollo de softwareList comprehension en Python: sintaxis, ejemplos y cuándo evitarla
List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.
Leer artículo →