Rebase es una operación de Git que mueve commits de una rama a la punta de otra, creando un historial lineal sin commits de merge innecesarios. A diferencia de la fusión, rebase reescribe el historial: cada commit movido obtiene un nuevo hash porque cambia su padre. Según la documentación de Git (2026), rebase se usa para sincronizar ramas de características con el estado actual de main antes de crear un pull request. El comando git rebase es una de las herramientas principales para mantener un historial limpio en proyectos que usan Git Flow.
Puntos Clave
Rebase es un comando de Git que reubica la rama actual sobre una especificada: toma todos los commits de la rama actual, los guarda temporalmente, mueve el puntero de la rama al commit destino y aplica secuencialmente los commits guardados encima. El resultado — el historial se ve como si el desarrollador hubiera trabajado directamente desde el último commit de la rama destino.
La sintaxis básica: git rebase main — estando en una rama de características, este comando mueve todos los commits de la rama a la punta de main. Git usa una estrategia de fusión de tres vías para cada commit individualmente. Si el commit A ya está presente en la rama destino (determinado por el hash), Git lo omite automáticamente, evitando cambios duplicados.
Rebase también admite el modo onto para mover un subconjunto de commits: git rebase --onto target start end — esta forma permite extraer un rango de commits de una rama y aplicarlos sobre otra. Por ejemplo, git rebase --onto main feature~3 feature mueve los últimos tres commits de la rama feature sobre main.
# Switch to feature branch
git checkout feature
# Rebase feature onto main
git rebase main
# After successful rebase — history is linear
git log --oneline --graph
# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD
Rebase y merge resuelven la misma tarea — combinar cambios de diferentes ramas — pero lo hacen de formas fundamentalmente distintas. Merge preserva el historial completo de fusiones creando un commit de merge con dos padres. Rebase reescribe el historial, haciéndolo lineal. La elección entre ellos depende del flujo de trabajo del equipo y las reglas de gestión del repositorio.
La diferencia principal es cómo se registra el hecho de la fusión. Merge conserva: "en este punto fusionamos feature en main" — esto es informativo para el historial del proyecto pero satura el registro con fusiones frecuentes. Rebase muestra: "los commits de feature se hicieron secuencialmente desde el último estado de main" — esto es limpio pero oculta el hecho de que el desarrollo se realizó en paralelo.
La segunda diferencia es el manejo de conflictos. Con merge, los conflictos se resuelven una vez y la solución se registra en el commit de merge. Con rebase, pueden ocurrir conflictos para cada commit movido, cada uno requiere resolución separada. Esto requiere más trabajo pero permite un control más preciso sobre qué cambios llegan a la versión final.
| Criterio | Rebase | Merge |
|---|---|---|
| Historial | Lineal, sin commits de merge | No lineal, con commits de merge |
| Hashes de commits | Se reescriben (nuevos) | Se conservan originales |
| Conflictos | Para cada commit por separado | Una vez en el commit de merge |
| Ramas públicas | Prohibido | Permitido |
| Comando de deshacer | git rebase --abort | git merge --abort |
Rebase interactivo (git rebase -i) es un modo en el que Git abre un editor con una lista de commits y acciones disponibles para cada uno. El desarrollador puede reescribir el historial antes de enviarlo a un repositorio remoto. Esta es la herramienta principal para mantener commits limpios en una rama de características.
Comandos disponibles en modo interactivo: pick (dejar el commit como está), reword (cambiar el mensaje del commit), edit (detenerse para hacer cambios), squash (combinar con el commit anterior, conservando ambos mensajes), fixup (combinar, descartando el mensaje), drop (eliminar commit). Cada comando se coloca antes del hash del commit en el editor abierto.
Squash y fixup son los comandos más usados para combinar commits. Si un desarrollador hizo 5 pequeños commits de corrección durante el trabajo, squash los fusiona en un solo commit lógico con un mensaje significativo. Fixup es útil para corregir errores tipográficos: los cambios van al commit anterior sin conservar su propio mensaje.
# Open editor for last 4 commits
git rebase -i HEAD~4
# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# After saving — Git performs rebase
# and opens editor for squashed commit message
# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash
La bandera --autosquash organiza automáticamente fixup/squash para commits cuyos mensajes comienzan con fixup! o squash!. Esto acelera el trabajo si el desarrollador marca los commits de antemano para su posterior combinación. La bandera --committer-date-is-author-date conserva la fecha original del commit al reubicar — útil para mantener el orden cronológico en el historial.
Los conflictos durante rebase ocurren cuando Git no puede aplicar automáticamente un commit movido debido a contradicciones con los cambios en la rama destino. A diferencia de merge, donde el conflicto se resuelve una vez, con rebase cada commit puede causar un conflicto, y debe resolverse secuencialmente para cada commit del más antiguo al más nuevo.
Cuando ocurre un conflicto, Git pausa el rebase e informa qué commit causó el problema. El desarrollador abre el archivo en conflicto (Git marca las áreas de conflicto con marcadores <<<<<<<, =======, >>>>>>>), lo edita, lo agrega al índice (git add) y continúa el rebase con git rebase --continue. Si no se encuentra solución — git rebase --abort cancela completamente el rebase.
Consejo: con múltiples conflictos, es más eficiente usar git mergetool, que abre un editor visual para resolver conflictos. También se puede saltar el commit problemático (git rebase --skip), pero esto elimina sus cambios del historial final, lo que rara vez es la decisión correcta.
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Check status
git status
# both modified: file.txt
# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue
# If uncertain — abort
git rebase --abort
La regla de oro de rebase: nunca reubicar commits que ya se hayan enviado a un repositorio remoto y estén disponibles para otros desarrolladores. Dado que rebase reescribe los hashes de los commits, los colegas encontrarán conflictos al intentar sincronizar — su historial local divergirá del historial remoto reescrito.
Una situación en la que rebase está terminantemente prohibido: si alguien ya ha creado una rama basada en tus commits (por ejemplo, un colega creó una rama a partir de tu rama de características), reescribir el historial romperá su trabajo. En tales casos, usa merge. Tampoco se recomienda hacer rebase justo antes de una fecha límite — un error durante la resolución de conflictos puede llevar más tiempo del esperado y bloquear el lanzamiento.
Excepción: si la rama es usada por un solo desarrollador (rama de características personal, no publicada o publicada en modo borrador), rebase antes del push es una práctica estándar. Después de publicar y comenzar el trabajo colaborativo — solo merge. GitHub y GitLab ofrecen por defecto squash merge como compromiso: combina commits en uno pero no reescribe el historial de la rama destino.
Los equipos modernos utilizan con mayor frecuencia un flujo de trabajo orientado a rebase combinado con GitHub Flow. El proceso se ve así: el desarrollador crea una rama de características desde main, trabaja en ella, se sincroniza periódicamente mediante git rebase main, y antes de crear un pull request realiza un rebase interactivo para limpiar el historial.
Después de crear un PR (si es necesario incorporar nuevos cambios de main), se utiliza git pull --rebase main en lugar de un git pull normal. Esto incorpora cambios sin crear un commit de merge innecesario. Git pull con la bandera --rebase equivale a git fetch + git rebase — Git primero descarga los nuevos commits y luego reubica los cambios locales sobre ellos.
Git permite configurar rebase como comportamiento predeterminado para pull: git config --global pull.rebase true. Después de esta configuración, git pull siempre realiza rebase en lugar de merge. Si se necesita un pull normal — se usa git pull --no-rebase. Muchos equipos también habilitan autostash: git config --global rebase.autoStash true — esto guarda automáticamente los cambios no commiteados antes del rebase y los restaura después.
Preguntas Frecuentes
Hacer rebase significa ejecutar git rebase: mover commits de la rama actual a la punta de otra. Como resultado, el historial se vuelve lineal, cada commit obtiene un nuevo hash y no se crean commits de merge. El comando se usa para sincronizar ramas sin puntos de fusión innecesarios en el registro.
Merge crea un commit de merge con dos padres, conservando el historial paralelo y los hashes originales. Rebase reescribe el historial — los commits obtienen nuevos hashes y el historial se vuelve lineal. Merge es más seguro para ramas públicas, rebase proporciona un registro más limpio.
El comando git rebase -i HEAD~N abre un editor con los últimos N commits. Para cada commit se puede elegir una acción: pick (conservar), reword (renombrar), edit (modificar), squash (combinar con el anterior), fixup (combinar sin mensaje), drop (eliminar). Después de guardar, Git aplica los cambios elegidos.
Rebase reescribe los hashes de los commits, haciendo que el historial sea incompatible con las copias de los mismos commits en las máquinas de otros desarrolladores. Si un colega ya obtuvo tus commits mediante git pull, y luego tú los reubicaste, su git push será rechazado y git pull creará commits duplicados y conflictos.
Antes de completar — git rebase --abort cancela completamente. Después de completar, se puede restaurar el estado anterior mediante git reflog — encontrar el hash del commit antes del rebase y ejecutar git reset --hard hacia él. Reflog almacena el historial de movimientos de HEAD durante 30 días por defecto.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también