🌿 Rebase y Buenas Prácticas en Git
Hasta ahora has visto cómo crear ramas con git branch, unirlas con git merge y solucionar conflictos directos. En proyectos profesionales y equipos de alto rendimiento, la forma en que integras tus cambios y documentas tu trabajo determina la mantenibilidad del código a largo plazo.
En esta lección aprenderás:
- Qué es
git rebasey cómo funciona internamente su modelo mental. - Cuándo conviene usar
mergey cuándorebase(criterio técnico y tradeoffs). - Cómo resolver conflictos durante un rebase paso a paso.
- La Regla de Oro del Rebase (y por qué romperla perjudica a tu equipo).
- Buenas prácticas profesionales: commits atómicos, Conventional Commits y gestión rigurosa de
.gitignore.
🔄 ¿Qué es Git Rebase?
El comando git merge une dos historias creando un commit de unión (merge commit). Esto conserva la cronología exacta, pero genera ramas cruzadas en el árbol del historial.
git rebase ofrece un enfoque alternativo: replantear la base de tu rama. En lugar de crear un commit de fusión, Git toma los commits que hiciste en tu rama, los “despega” momentáneamente, avanza tu rama hasta la punta de la rama principal (main), y vuelve a aplicar (replay) tus commits uno a uno sobre esa nueva base.
Modelo mental (antes y después)
Imagina esta situación: creaste una rama feature a partir del commit B. Mientras trabajabas, tus compañeros agregaron el commit C a main.
git rebase: los commits de la rama de trabajo se despegan y se vuelven a aplicar secuencialmente sobre el último commit de main, logrando un historial limpio y sin bifurcaciones.Observa que los commits ahora se llaman D' y E': sus identificadores (hashes SHA-1) cambiaron, porque ahora tienen un commit padre diferente (C en lugar de B).
El resultado es un historial completamente lineal, como si hubieses empezado a programar tu función justo después del commit C.
⚖️ Merge vs Rebase: Criterio Técnico
Ningún comando es intrínsecamente mejor que el otro; resuelven problemas diferentes con prioridades distintas:
| Criterio | git merge | git rebase |
|---|---|---|
| Forma del historial | Árbol con bifurcaciones y uniones explícitas | Línea recta continua y sin bifurcaciones |
| Contexto histórico | Conserva con exactitud cuándo se bifurcó y unió la rama | Reescribe la historia para simular trabajo secuencial |
| Resolución de conflictos | Se resuelve una sola vez en el merge commit | Se resuelve commit por commit durante la reaplicación |
| Trazabilidad de Pull Requests | Excelente para documentar la integración de un feature completo | Excelente para actualizar ramas locales antes de integrar |
Regla práctica de la industria:
- Usa
git rebasepara mantener tu rama local actualizada con los últimos cambios demainantes de enviar un Pull Request. - Usa
git merge(o el botón de merge de GitHub) para integrar formalmente una funcionalidad terminada a la rama principal compartida.
🛠️ Cómo ejecutar un Rebase paso a paso
Supongamos que estás trabajando en la rama feature/carrito y quieres sincronizarla con las novedades que llegaron a main.
1. Actualiza tu rama principal local
# 1. Cambiar a la rama main
git switch main
# 2. Descargar las novedades del remoto asegurando fast-forward
git pull --ff-only
2. Vuelve a tu rama de trabajo
# Cambiar a tu rama de funcionalidad activa
git switch feature/carrito
3. Aplica el rebase sobre la punta de main
# Reaplicar los commits de feature/carrito encima de la punta actual de main
git rebase main
Si tus cambios no tocan las mismas líneas que main, Git aplicará cada commit automáticamente y verás:
Successfully rebased and updated refs/heads/feature/carrito.
💥 Manejo de conflictos durante un Rebase
A diferencia de un merge (donde todos los conflictos se resuelven en un solo paso al final), durante un rebase Git reaplica los commits uno a uno. Si el commit D entra en conflicto con los cambios de main, el proceso se detiene en ese commit específico.
Pasos para resolver el conflicto:
1. Inspecciona qué archivos entraron en conflicto
# Ver qué archivos tienen conflictos en este commit específico
git status
Verás los archivos marcados como both modified.
2. Abre el archivo y resuelve los marcadores
Al igual que en un merge tradicional, verás los marcadores de conflicto:
<<<<<<< HEAD (novedades provenientes de main)
const TAX_RATE = 0.21;
=======
const TAX_RATE = 0.18;
>>>>>>> D (tu commit que se está reaplicando)
Edita el archivo, elige la versión correcta y borra los marcadores (<<<<<<<, =======, >>>>>>>).
3. Marca el archivo como resuelto
# Marcar el conflicto de este paso como resuelto
git add src/config.js
4. Continúa el rebase (¡NO hagas commit!)
⚠️ Punto crítico: En un rebase no ejecutas git commit. El commit original ya existe; Git simplemente necesita que le indiques que el conflicto de ese paso fue resuelto para continuar con el siguiente commit:
# Indicar a Git que continúe aplicando los siguientes commits
git rebase --continue
Git continuará aplicando los siguientes commits. Si otro commit presenta conflicto, repite estos pasos hasta que finalice.
¿Algo salió mal o quieres cancelar?
Si te equivocaste o prefieres volver exactamente al estado en que estabas antes de iniciar el rebase, puedes abortar la operación limpiamente:
# Abortar el rebase por completo y restaurar la rama al estado previo
git rebase --abort
🚫 La Regla de Oro del Rebase
NUNCA hagas rebase sobre ramas públicas o compartidas.
Aplica rebase únicamente a tus ramas privadas locales que nadie más ha descargado.
¿Por qué?
Como vimos, el rebase altera los hashes de los commits. Si haces rebase en una rama que tus compañeros de equipo ya clonaron (como main o develop), sus historiales locales quedarán desconectados del remoto. Si intentas forzar la subida con git push --force, reescribirás la historia de todos tus colaboradores, generando errores de sincronización y potenciales pérdidas de código.
🏆 Buenas Prácticas Profesionales con Git
Aprender los comandos no basta para trabajar en equipo. Los estándares de la industria exigen disciplina en el flujo de trabajo:
1. Commits atómicos y enfocados
Un commit atómico realiza un único cambio lógico indivisible.
- ❌ Mal: Un commit que agrega una pantalla de login, arregla un bug del carrito y refactoriza estilos de 15 archivos (
"varios arreglos y login"). - ✔️ Bien: Tres commits separados con propósito único.
¿Por qué son fundamentales?
- Hacen que el código sea fácil de revisar en un Pull Request.
- Permiten revertir una falla puntual con
git revertsin deshacer trabajo sano. - Facilitan encontrar el origen exacto de un bug usando
git bisect.
2. Conventional Commits (El estándar de mensajes)
Los equipos profesionales usan el estándar Conventional Commits para mantener un historial legible por humanos y automatizable por herramientas de CI/CD:
<tipo>(<alcance opcional>): <descripción corta en imperativo>
Tipos comunes:
feat:Una nueva característica o funcionalidad.- Ejemplo:
feat(auth): add google oauth login
- Ejemplo:
fix:Corrección de un error o bug.- Ejemplo:
fix(cart): prevent negative item quantities
- Ejemplo:
docs:Cambios exclusivamente en documentación o README.- Ejemplo:
docs(api): update endpoints table
- Ejemplo:
refactor:Cambio en el código que no agrega funcionalidad ni arregla un bug (reestructuración, limpieza).- Ejemplo:
refactor(db): extract query builder helper
- Ejemplo:
test:Añadir o corregir pruebas unitarias o de integración.- Ejemplo:
test(auth): add unit test for token validation
- Ejemplo:
chore:Tareas auxiliares, actualización de dependencias o configuración del proyecto.- Ejemplo:
chore(deps): bump astro to version 6.0
- Ejemplo:
3. Uso riguroso de .gitignore
El archivo .gitignore le indica a Git qué archivos o carpetas deben ser ignorados y nunca formar parte del repositorio:
# Dependencias (se descargan con el gestor de paquetes)
node_modules/
vendor/
# Archivos de compilación y empaquetado
dist/
build/
*.class
# Secretos y variables de entorno (¡CRÍTICO!)
.env
.env.local
*.pem
*.key
# Archivos temporales del sistema operativo y editores
.DS_Store
Thumbs.db
.vscode/
.idea/
🔒 Regla fundamental de seguridad:
Nunca subas contraseñas, tokens, llaves de API ni archivos .env a Git. Si un secreto llega a un commit, borrarlo en el siguiente commit no lo elimina del historial: cualquier persona con acceso al repositorio puede ver los commits anteriores. Si esto ocurre, debes revocar o rotar el secreto inmediatamente.
4. Inspección constante antes de confirmar
Antes de hacer git add y git commit, adquiere el hábito de revisar qué vas a incluir:
# Revisar de forma resumida el estado de archivos modificados y no rastreados
git status --short
# Comparar las líneas modificadas en el working tree contra el último commit
git diff
No confirmes archivos a ciegas con git add . sin antes comprobar que no estás agregando archivos temporales, logs o cambios no deseados.
📌 Resumen de Comandos de esta Lección
| Acción | Comando |
|---|---|
Replantear la base de la rama actual sobre main | git rebase main |
| Continuar el rebase tras resolver un conflicto | git rebase --continue |
| Cancelar el rebase y volver al estado previo | git rebase --abort |
| Ver el estado conciso de los archivos | git status --short |
| Ver diferencias en archivos modificados | git diff |