git rebase -i (interactivo)
Aprende git rebase -i para combinar, renombrar, editar, eliminar y reordenar commits antes de compartirlos. Incluye referencia de comandos.
Qué es el rebase interactivo
El rebase interactivo, ejecutado con git rebase -i, permite reescribir una serie de commits antes de compartirlos. Abre una "lista de tareas" editable de commits donde decides, línea por línea, qué ocurre con cada uno: conservarlo, reescribir su mensaje, combinarlo con otro, dividirlo, reordenarlo o eliminarlo. Se basa en el git rebase normal, pero te da control sobre cada paso.
Esta página explica cómo iniciar un rebase interactivo, todos los comandos disponibles en la lista de tareas, los flujos de trabajo más comunes (combinar, renombrar, reordenar, eliminar y dividir commits), cómo recuperarse cuando algo va mal, y la única regla que lo mantiene seguro.
Un commit es una instantánea guardada de tu trabajo; HEAD es un puntero al commit en el que te encuentras actualmente. "Reescribir la historia" significa producir nuevos commits para reemplazar los existentes — Git nunca edita un commit en su lugar, por lo que cada commit reescrito obtiene un hash completamente nuevo.
Cómo iniciar un rebase interactivo
Apunta el comando al commit anterior al primero que quieres editar — el rebase reproducirá todo lo que venga después. Para revisar los últimos tres commits:
git rebase -i HEAD~3HEAD~3 significa "tres commits antes de HEAD". También puedes especificar un commit concreto (git rebase -i a1b2c3d) o, en una rama, hacer rebase de todo lo que surgió desde otra rama (git rebase -i main).
Git abre el editor configurado con una línea por commit, el más antiguo arriba (lo inverso a git log):
pick a1b2c3d add login form
pick b2c3d4e fix typo
pick c3d4e5f more css tweaksDebajo de la lista, Git incluye una hoja de referencia comentada con todos los comandos disponibles. Cambias la palabra al inicio de cada línea para elegir una acción, opcionalmente reordenas las líneas, y luego guardas y cierras. Git reproduce los commits de arriba a abajo según tus instrucciones. Si guardas el archivo sin cambios (o eliminas todas las líneas), el rebase no hace nada y se detiene.
Los comandos de la lista de tareas
Cada línea comienza con un comando. Estos son los que se usan con más frecuencia:
| Comando | Abreviatura | Efecto |
|---|---|---|
pick | p | Usa el commit tal como está. |
reword | r | Usa el commit pero edita su mensaje. |
edit | e | Pausa en el commit para que puedas modificar su contenido (enmendar, dividir o agregar archivos). |
squash | s | Combina con el commit anterior, fusionando ambos mensajes. |
fixup | f | Como squash, pero descarta el mensaje de este commit. |
drop | d | Elimina el commit por completo (eliminar la línea tiene el mismo efecto). |
exec | x | Ejecuta un comando de shell (p. ej., pruebas) en ese punto del rebase. |
No existe un comando reorder — reordenas los commits simplemente moviendo las líneas hacia arriba o hacia abajo en la lista de tareas. Las líneas se aplican de arriba a abajo, por lo que el orden en que las dejes es el orden que Git creará.
Combinar commits
Una limpieza habitual es fusionar varios commits pequeños en uno solo. Marca el primero como pick y el resto como squash (o fixup para descartar sus mensajes):
pick a1b2c3d add login form
squash b2c3d4e fix typo
fixup c3d4e5f more css tweakssquash/fixup siempre fusiona hacia arriba, con la línea anterior. Al guardar, Git combina los tres en un único commit. Como b2c3d4e fue combinado con squash, Git abre un segundo editor mostrando ambos mensajes de commit para que puedas escribir uno limpio; el fixup de c3d4e5f aporta sus cambios pero descarta su mensaje silenciosamente.
Si solo quieres incorporar pequeños commits de "oops" en uno anterior, considera git commit --fixup (consulta git commit --amend y git rebase -i --autosquash), que marca las líneas automáticamente por ti.
Renombrar un mensaje de commit
Para corregir una errata o aclarar un mensaje sin tocar el código, marca la línea con reword:
pick a1b2c3d add login form
reword b2c3d4e fix tpyo
pick c3d4e5f more css tweaksGit reproduce a1b2c3d tal como está, luego se detiene y abre un editor con el mensaje antiguo de b2c3d4e para que puedas reescribirlo, y después continúa. Los cambios del commit no se tocan — solo cambia el mensaje (y su hash).
Reordenar y eliminar commits
Para cambiar el orden, mueve las líneas. Para eliminar un commit, márcalo con drop o borra la línea. Esta lista de tareas reordena el ajuste de CSS antes de la corrección de erratas y elimina el commit de la errata por completo:
pick a1b2c3d add login form
pick c3d4e5f more css tweaks
drop b2c3d4e fix typoEliminar o reordenar puede causar conflictos si un commit posterior dependía del que eliminaste o moviste — Git se detendrá y te permitirá resolverlos.
Dividir un commit
Para dividir un commit grande en varios, márcalo con edit. Git se detiene en ese commit con los cambios ya aplicados; luego deshaces el commit conservando los cambios y haces nuevos commits más pequeños:
# rebase pauses on the commit marked 'edit'
git reset HEAD~ # move the commit's changes back to the working tree
git add login.js
git commit -m "add login form markup"
git add styles.css
git commit -m "style the login form"
git rebase --continue # resume the rest of the rebasegit reset HEAD~ deshace el último commit pero deja sus cambios en tus archivos (consulta git reset), de modo que puedes prepararlos y confirmarlos como commits separados y más pequeños.
Terminar o cancelar
Si un paso produce un conflicto, Git se detiene para que puedas resolverlo. Edita los archivos conflictivos, prepara las correcciones con git add y luego continúa:
git rebase --continueSi decides que un commit en particular no debe aplicarse mientras estás detenido en un conflicto, usa git rebase --skip. Para abandonar todo el rebase y volver exactamente a donde empezaste:
git rebase --abortIncluso después de que el rebase finaliza, los commits originales no se pierden de inmediato — permanecen accesibles a través de git reflog durante un tiempo, que es la red de seguridad si haces un rebase y te arrepientes.
Una advertencia importante
El rebase interactivo reescribe la historia — los commits resultantes tienen hashes nuevos. Eso es perfecto para ordenar tu propia rama antes de abrir una pull request, pero nunca hagas rebase de commits que otros ya hayan descargado. Reescribir la historia compartida obliga a todos los demás a reconciliar copias divergentes, y publicar el resultado requiere un push forzado (git push --force-with-lease). La regla de oro: rebase en local, merge en público.
Si solo necesitas cambiar el último commit, normalmente no necesitas un rebase completo — git commit --amend es más sencillo. Para copiar un commit individual de otro lugar a tu rama, consulta git cherry-pick.
Un ejemplo completo de squash
Aquí tienes una secuencia completa que puedes ejecutar en una carpeta vacía para ver el squash en acción. Crea cuatro commits y luego fusiona los últimos tres en uno:
git init -b main demo && cd demo
git config user.email [email protected]
git config user.name You
echo "init" > base && git add base && git commit -m "initial commit"
echo "a" > f && git add f && git commit -m "add login form"
echo -e "a\nb" > f && git add f && git commit -m "fix typo"
echo -e "a\nb\nc" > f && git add f && git commit -m "more css tweaks"
git log --oneline # four commits
git rebase -i HEAD~3 # mark line 2 'squash', line 3 'fixup', save
git log --oneline # now: "initial commit" + one combined commitDespués del rebase, git log --oneline muestra solo dos commits — el commit inicial y un único commit combinado — y el archivo f todavía contiene las tres líneas (a, b, c). El trabajo es idéntico; solo el historial de commits es más ordenado.