tutoriales.com

Git Rebase Interactivo: Domina la Reescritura del Historial para un Historial Limpio

Git rebase interactivo es una herramienta poderosa para reescribir el historial de tus commits, permitiéndote consolidar, editar y reordenar commits antes de integrarlos. Este tutorial te guiará a través de sus funcionalidades clave para mantener un historial de proyecto limpio y coherente.

Intermedio12 min de lectura8 views23 de marzo de 2026Reportar error

Introducción al Git Rebase Interactivo ✨

En el mundo del desarrollo de software, mantener un historial de versiones limpio, comprensible y lineal es fundamental para la colaboración, la depuración y el mantenimiento a largo plazo. Git, como sistema de control de versiones distribuido, nos ofrece herramientas extremadamente potentes para lograrlo, y entre ellas, el rebase interactivo (git rebase -i) se destaca como una de las más versátiles y, a veces, intimidantes.

Este tutorial desmitificará git rebase -i, mostrándote cómo puedes transformar un historial de commits desordenado en una narrativa clara y concisa. Aprenderás a consolidar commits pequeños, reordenar cambios, editar mensajes y eliminar commits no deseados, todo ello sin perder la integridad de tu trabajo. Si alguna vez te has sentido abrumado por un historial de Git caótico, ¡este es tu tutorial!

📌 Nota: Este tutorial asume que tienes un conocimiento básico de Git, incluyendo conceptos como commits, ramas y fusiones (merges). Si eres completamente nuevo en Git, te recomendamos familiarizarte con los fundamentos antes de sumergirte en el rebase interactivo.

¿Qué es Git Rebase y por qué "Interactivo"? 🤔

Antes de sumergirnos en la interactividad, recordemos brevemente qué es git rebase.

Git Rebase Básico

El comando git rebase se utiliza para reaplicar una serie de commits de una rama sobre otra base. A diferencia de git merge, que combina dos historiales creando un nuevo commit de fusión, git rebase reescribe el historial de commits de tu rama, haciendo que parezca que los commits se hicieron directamente sobre la nueva base. El resultado es un historial lineal, sin los commits de fusión que git merge introduce.

Comparativa Git: Merge vs Rebase Git Merge (Historial no lineal) M1 M2 M3 F1 F2 MERGE COMMIT main feature Git Rebase (Historial lineal) M1 M2 M3 F1' F2' Reaplicando commits sobre main Resultado: 1 sola rama limpia

La Magia de la Interacción (-i) ✨

Cuando añadimos la opción -i (de interactivo), git rebase no solo reaplica los commits, sino que nos da el control para modificar cómo se reaplican. Git nos presentará una lista de los commits que se van a reescribir en un editor de texto (generalmente Vim, pero puedes configurarlo a tu gusto), donde podemos especificar una acción para cada commit. Este es el corazón del rebase interactivo.

🔥 Importante: Reescribir el historial de Git puede ser peligroso si los commits ya han sido publicados y compartidos con otros. **Nunca uses `git rebase -i` en commits que ya han sido pushed a una rama pública compartida.** Si lo haces, podrías causar problemas de sincronización a tus colaboradores. Utilízalo solo en tus ramas locales o en ramas que solo tú utilizas.

Configurando tu Editor de Texto para Git ⚙️

Para que git rebase -i sea una experiencia fluida, es importante que tengas configurado tu editor de texto favorito para Git. Si no lo has hecho, Git usará Vim por defecto, que puede ser un poco intimidante si no estás familiarizado con él.

Para establecer tu editor de texto, puedes usar los siguientes comandos:

  • Para Visual Studio Code:
git config --global core.editor "code --wait"
  • Para Sublime Text:
git config --global core.editor "subl --wait"
  • Para Atom:
git config --global core.editor "atom --wait"
  • Para Notepad++ (Windows):
git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -noPlugin"
💡 Consejo: El flag `--wait` es crucial. Le dice a Git que espere hasta que cierres el editor antes de continuar con la operación de rebase.

Comandos Básicos de git rebase -i 🚀

El comando git rebase -i generalmente se usa especificando el commit al que quieres "moverte". Esto significa que todos los commits posteriores a ese commit serán los que se presenten para ser modificados.

La sintaxis más común es:

git rebase -i <commit-hash-o-referencia>

Donde <commit-hash-o-referencia> puede ser:

  • Un hash de commit específico (por ejemplo, f7e1a3b).
  • Una referencia relativa (por ejemplo, HEAD~3 para los últimos 3 commits, o main para rebasear sobre la rama main).

Ejemplo: Rebaseando los Últimos N Commits

Para rebasear los últimos 3 commits en tu rama actual, usarías:

git rebase -i HEAD~3

Esto abrirá tu editor con una lista similar a esta (el orden es del más antiguo al más reciente):

pick 1234567 Fix: Pequeño error de typo
pick 890abc1 Feat: Añadir funcionalidad de login
pick def0123 Refactor: Mejorar rendimiento del carrito

# Rebase def0123..1234567 onto 1234567 (3 commands)
#
# Comandos:
# p, pick <commit> = usar commit
# r, reword <commit> = usar commit, pero editar mensaje
# e, edit <commit> = usar commit, pero parar para modificar cambios del commit
# s, squash <commit> = usar commit, pero fusionarlo con el commit anterior
# f, fixup <commit> = como squash, pero descartar mensaje del commit
# x, exec <comando> = ejecutar comando (por ejemplo, git commit --amend)
# b, break = parar aquí (para editar los cambios introducidos por este commit)
# d, drop <commit> = eliminar commit
# l, label <label> = añadir un label a este punto
# t, toggle <label> = mover el HEAD al label
# m, merge <label> [-C <commit> | -c <commit>] = crear un commit de fusión
#
# Estos comandos pueden ser combinados y reordenados. Para ver qué pasaría, ejecuta:
# git rebase --continue (para continuar)
# git rebase --abort (para abortar)
# git rebase --skip (para saltar el commit actual)
#

En este archivo, cada línea de pick representa un commit. La magia está en cambiar la palabra pick por cualquiera de los otros comandos disponibles.


Casos de Uso Comunes de Git Rebase Interactivo 🛠️

Ahora, exploremos los escenarios más comunes donde git rebase -i brilla con luz propia.

1. Consolidar Commits (Squash y Fixup) 🧱

Es común hacer varios commits pequeños mientras trabajamos en una característica: "WIP: arreglando algo", "Otro pequeño cambio", "Corrección final". Antes de fusionar a main, queremos que estos commits se conviertan en uno solo, limpio y significativo.

  • squash (s): Combina el commit actual con el anterior y te permite editar el mensaje combinado de ambos.
  • fixup (f): Similar a squash, pero descarta el mensaje del commit actual, utilizando solo el mensaje del commit anterior. Ideal para commits de "arreglos rápidos" o "typos".

Escenario: Tienes 3 commits:

  1. feat: Implementar botón de añadir al carrito
  2. fix: Corregir icono del botón
  3. refactor: Optimizar lógica del botón

Quieres que todos se conviertan en un único commit feat: Implementar botón de añadir al carrito con un mensaje que incluya los cambios de los otros.

git rebase -i HEAD~3

En el editor, harías esto:

pick 1234567 feat: Implementar botón de añadir al carrito
s 890abc1 fix: Corregir icono del botón
s def0123 refactor: Optimizar lógica del botón

Al guardar y salir del editor, Git te abrirá otro editor para que combines los mensajes de los commits fix y refactor en el mensaje del commit feat.

Consolidado con Éxito

2. Editar Mensajes de Commit (Reword) 📝

¿Cometiste un error tipográfico en un mensaje de commit o quieres mejorarlo para que sea más claro?

  • reword (r): Utiliza el commit, pero te permite editar su mensaje.

Escenario: Tienes un commit con el mensaje feat: Añadir nuva funcion. Quieres corregirlo a feat: Añadir nueva función.

git rebase -i HEAD~1 # O el número de commits para llegar a ese commit

En el editor:

r 1234567 feat: Añadir nuva funcion

Al guardar y salir, Git abrirá un editor con el mensaje del commit, permitiéndote corregirlo.

3. Eliminar Commits (Drop) 🗑️

¿Hiciste un commit que ya no es relevante o fue un error?

  • drop (d): Elimina el commit del historial.

Escenario: Tienes un commit debug: Quitar logs de consola que ya no es necesario.

git rebase -i HEAD~3

En el editor:

pick 1234567 feat: Implementar login
d 890abc1 debug: Quitar logs de consola
pick def0123 refactor: Mejorar css

Al guardar, ese commit desaparecerá del historial.

4. Reordenar Commits 🔄

A veces, el orden en que hicimos los commits no es el más lógico para el historial del proyecto. git rebase -i te permite cambiar el orden de los commits simplemente moviendo las líneas en el editor.

Escenario: Tienes:

  1. fix: Corregir error de validación
  2. feat: Añadir nueva característica

Quieres que el fix aparezca después del feat por alguna razón.

git rebase -i HEAD~2

En el editor (cambia el orden de las líneas):

pick 890abc1 feat: Añadir nueva característica
pick 1234567 fix: Corregir error de validación
⚠️ Advertencia: Reordenar commits que introducen cambios en los mismos archivos puede causar conflictos complejos. Procede con precaución y resuelve los conflictos cuidadosamente.

5. Dividir Commits (Edit y Reset) ✂️

Quizás un commit es demasiado grande y contiene cambios para dos funcionalidades distintas. Puedes usar edit para dividirlo en múltiples commits.

  • edit (e): Git detendrá el rebase después de aplicar este commit, permitiéndote modificarlo. Puedes hacer git reset HEAD~1 para deshacer el commit pero mantener los cambios, luego git add y git commit varias veces para crear nuevos commits a partir de esos cambios.

Escenario: Tienes un commit feat: Implementar carrito y pago que es demasiado grande.

git rebase -i HEAD~1

En el editor:

e 1234567 feat: Implementar carrito y pago

Git detendrá el rebase. Ahora, en tu terminal, puedes:

git reset HEAD~1 # Deshace el commit pero mantiene los cambios en el staging area
git status # Verás los archivos modificados
git add <archivos-del-carrito>
git commit -m "feat: Implementar funcionalidad de carrito"
git add <archivos-del-pago>
git commit -m "feat: Implementar proceso de pago"
git rebase --continue # Continúa el rebase

Resolviendo Conflictos Durante un Rebase 💥

Es muy común encontrarse con conflictos de fusión (merge conflicts) durante un rebase interactivo. Esto sucede cuando Git no puede aplicar automáticamente un commit porque los cambios en ese commit entran en conflicto con los cambios en la nueva base o con un commit anterior que ya ha sido reaplicado.

Cuando ocurre un conflicto, Git pausará el proceso de rebase y te informará. Tu terminal mostrará algo como:

Applying: Feat: Añadir nueva funcionalidad
Using index info to reconstruct a base tree...
M .gitignore
M src/app.js
Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
error: could not apply 1234567... Feat: Añadir nueva funcionalidad

Pasos para Resolver Conflictos:

  1. Identificar los archivos en conflicto: git status te mostrará los archivos que tienen conflictos sin resolver.
  2. Editar los archivos: Abre cada archivo en conflicto en tu editor y busca las marcas de conflicto (<<<<<<<, =======, >>>>>>>). Resuelve manualmente las diferencias, eligiendo qué cambios quieres conservar.
  3. Marcar como resuelto: Una vez que hayas resuelto los conflictos en un archivo, márcalo como resuelto usando git add <archivo-en-conflicto>.
  4. Continuar el rebase: Después de resolver todos los conflictos y hacer git add en los archivos, ejecuta git rebase --continue.
⚠️ Advertencia: Si te sientes abrumado por los conflictos o no estás seguro de cómo resolverlos, puedes abortar el rebase en cualquier momento usando `git rebase --abort`. Esto revertirá tu rama a su estado anterior al inicio del rebase, sin pérdida de trabajo.
¿Por qué el comando `git rebase --skip`?A veces, un commit es la fuente de un conflicto irresoluble o simplemente ya no lo quieres. En lugar de abortar todo el rebase, puedes usar `git rebase --skip` para omitir el commit actual y continuar con el siguiente. Ten en cuenta que esto eliminará completamente el commit que estás saltando del historial.

Ejercicio Práctico: Limpiando un Historial Real 🎯

Vamos a poner en práctica lo aprendido con un escenario común.

Setup del Repositorio

Crea un nuevo repositorio y algunos commits:

mkdir rebase-practice
cd rebase-practice
git init

echo "Inicialización del proyecto" > README.md
git add README.md
git commit -m "feat: Primera versión del README"

echo "console.log('Hola Mundo');" > app.js
git add app.js
git commit -m "feat: Añadir hola mundo"

echo "console.log('Hello World');" >> app.js
git add app.js
git commit -m "fix: Correccion del mensaje"

echo "function sum(a, b) { return a + b; }" >> app.js
git add app.js
git commit -m "feat: Añadir funcion de suma"

echo "// TODO: mejorar la funcion sum" >> app.js
git add app.js
git commit -m "WIP: Suma incompleta"

git log --oneline

Tu git log --oneline debería verse algo así (los hashes serán diferentes):

a1b2c3d WIP: Suma incompleta
e4f5g6h feat: Añadir funcion de suma
i7j8k9l fix: Correccion del mensaje
m0n1o2p feat: Añadir hola mundo
q3r4s5t feat: Primera versión del README

Objetivo del Ejercicio

Queremos lograr el siguiente historial limpio:

  1. Un commit inicial feat: Primera versión del README.
  2. Un commit feat: Implementar función de saludo que incluya el "Hola Mundo" y su corrección.
  3. Un commit feat: Añadir función de suma con la función de suma.

Pasos para el Rebase Interactivo

Vamos a rebasear desde el commit m0n1o2p (o el hash de tu "feat: Añadir hola mundo"), o simplemente los últimos 4 commits (HEAD~4).

git rebase -i HEAD~4

Tu editor se abrirá con algo parecido a esto:

pick m0n1o2p feat: Añadir hola mundo
pick i7j8k9l fix: Correccion del mensaje
pick e4f5g6h feat: Añadir funcion de suma
pick a1b2c3d WIP: Suma incompleta

# Rebase ... onto ... (4 commands)
# ...

Modifica el archivo para lograr el objetivo:

pick m0n1o2p feat: Añadir hola mundo
s i7j8k9l fix: Correccion del mensaje
pick e4f5g6h feat: Añadir funcion de suma
f a1b2c3d WIP: Suma incompleta

Explicación de los cambios:

  • m0n1o2p (feat: Añadir hola mundo) se mantiene como pick.
  • i7j8k9l (fix: Correccion del mensaje) se convierte en squash para fusionarse con el anterior y combinar sus mensajes.
  • e4f5g6h (feat: Añadir funcion de suma) se mantiene como pick.
  • a1b2c3d (WIP: Suma incompleta) se convierte en fixup para fusionarse con el anterior y descartar su mensaje "WIP".

Guarda y cierra el editor.

Git te pedirá que edites el mensaje para el commit que combinó "hola mundo" y su corrección. Edita el mensaje para que sea más descriptivo, por ejemplo:

feat: Implementar función de saludo

Se añadió la funcionalidad de mostrar un saludo por consola.

Guarda y cierra este editor. Git terminará el rebase.

Finalmente, verifica el historial:

git log --oneline

Deberías ver un historial limpio y conciso:

new_hash_for_sum feat: Añadir funcion de suma
new_hash_for_hello feat: Implementar función de saludo
m0n1o2p feat: Primera versión del README

¡Felicidades! Has utilizado git rebase -i para transformar un historial desordenado en uno impecable.


Buenas Prácticas y Consejos Adicionales ✅

  • Trabaja en Ramas Privadas: Siempre realiza git rebase -i en ramas de desarrollo que no hayan sido pushed a un repositorio remoto compartido. Esto evita conflictos y problemas para otros desarrolladores.
  • Haz Commits Pequeños y Frecuentes: Aunque el rebase interactivo permite consolidar, es buena práctica hacer commits pequeños y atómicos desde el principio. Esto facilita el rebase y la depuración.
  • Rebase Frecuentemente: Si estás trabajando en una rama de característica y la rama main (o develop) avanza, haz rebase de tu rama sobre la main con frecuencia. Esto mantiene tu rama actualizada y reduce el número de conflictos al final.
  • Guarda un Respaldo (Opcional): Antes de un rebase complejo, si te sientes inseguro, puedes crear una nueva rama apuntando al HEAD actual (git branch backup-rebase-antes) o usar git reflog para recuperar commits si algo sale mal.
  • Entiende git reflog: Si alguna vez te equivocas con un rebase o quieres volver a un estado anterior, git reflog es tu mejor amigo. Muestra un historial de todas las acciones que tu repositorio de Git ha realizado, permitiéndote volver a cualquier punto.
git reflog
# Puedes ver algo como:
# e4f5g6h HEAD@{0}: rebase -i (finish): returning to refs/heads/master
# ...
# Para volver a un estado anterior:
# git reset --hard HEAD@{n}

Conclusión 🎉

El git rebase -i es una de las herramientas más poderosas que Git ofrece para mantener un historial de proyecto limpio y significativo. Aunque puede parecer complejo al principio, dominarlo te permitirá presentar tu trabajo de una manera mucho más profesional, facilitando la revisión de código, la depuración y la colaboración.

Recuerda siempre la regla de oro: nunca hagas rebase de commits públicos y compartidos. Úsalo con sabiduría en tus ramas locales y privadas, y verás cómo la calidad de tu historial de Git mejora drásticamente.

¡Ahora tienes las herramientas para convertirte en un maestro de la reescritura del historial de Git! ¡A practicar!

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!