Una vez dominados los fundamentos de Git, existen herramientas avanzadas que permiten mantener un historial impecable, depurar regresiones y automatizar tareas. Este artículo cubre rebase interactivo, stash, bisect, hooks y buenas prácticas.
Rebase interactivo: limpia tu historia
El rebase interactivo permite editar, fusionar, reordenar o eliminar commits antes de integrarlos en otra rama. Es ideal para mantener commits pequeños y atómicos.
# Rebase interactivo de los últimos 3 commits
git rebase -i HEAD~3
# Editor mostrará:
pick a1b2c3 Primer commit
pick d4e5f6 Segundo commit
pick g7h8i9 Tercer commit
# Opciones disponibles:
# pick → usar commit tal cual
# reword → cambiar mensaje del commit
# squash → fusionar commit con el anterior
# fixup → como squash pero descarta mensaje
# drop → eliminar commit
# edit → pausar para modificar
# Ejemplo: fusionar los últimos 3 en 1
# Cambiar las líneas 2 y 3 de pick a squash
git stash avanzado
El stash permite guardar cambios sin commitear. Pero también admite operaciones más finas:
# Stash con nombre descriptivo
git stash push -m "WIP: refactor módulo de pagos"
# Stash solo archivos específicos
git stash push -m "Fix temporal" src/pagos.js
# Mostrar diff de un stash sin aplicarlo
git stash show -p stash@{0}
# Crear una rama desde un stash (con conflicto evitado)
git stash branch feature/nueva stash@{0}
# Aplicar un stash manteniéndolo en la lista
git stash apply stash@{1}
git bisect: búsqueda binaria de bugs
Cuando un bug aparece pero no sabes qué commit lo introdujo, git bisect realiza una búsqueda binaria sobre el historial:
# Iniciar bisección
git bisect start
# Marcar commit actual como malo
git bisect bad
# Marcar un commit antiguo conocido como bueno
git bisect good v1.0.0
# Git checkout automáticamente el commit intermedio.
# Prueba, luego marca:
git bisect good # si funciona
git bisect bad # si no funciona
# Repetir hasta encontrar el commit culpable
# Al final:
git bisect reset
# Automatizar con un script:
git bisect run npm test
Git hooks: automatización en eventos
Los hooks son scripts que se ejecutan automáticamente en eventos de Git. Se almacenan en .git/hooks/ y pueden prevenir malas prácticas.
# PRE-COMMIT: validar antes de cada commit
cat .git/hooks/pre-commit
#!/bin/bash
# Evitar commits con código comentado
if grep -r 'console\.log' --include='*.js' .; then
echo "❌ Elimina los console.log antes de commitear"
exit 1
fi
# COMMIT-MSG: validar formato del mensaje
cat .git/hooks/commit-msg
#!/bin/bash
# Requerir formato: tipo(scope): descripción
if ! grep -Eq '^(feat|fix|chore|docs|refactor|test)\(.+\): .{10,}' "$1"; then
echo "❌ Formato: tipo(scope): descripción (mín 10 chars)"
exit 1
fi
# Hacer el hook ejecutable
chmod +x .git/hooks/pre-commit .git/hooks/commit-msg
Tags: versionar tu proyecto
Las etiquetas (tags) marcan puntos específicos en la historia, típicamente para releases:
# Crear tag anotado (recomendado)
git tag -a v1.0.0 -m "Versión 1.0.0 - Primer release estable"
# Crear tag ligero
git tag v0.9.0-rc1
# Listar tags
git tag -l "v1.*"
# Subir tags al remoto
git push origin v1.0.0
git push --tags # Todos los tags
Buenas prácticas para mensajes de commit
Un buen mensaje de commit es la diferencia entre un historial útil y uno ilegible:
# Formato recomendado (Conventional Commits)
feat(auth): implementar login con JWT
Agregar autenticación usando JSON Web Tokens.
Incluye refresh token con expiración a 7 días.
Closes #42
# Tipos comunes:
feat → Nueva funcionalidad
fix → Corrección de bug
chore → Mantenimiento
docs → Documentación
refactor → Refactorización sin cambios funcionales
test → Agregar o modificar tests
# Reglas de oro:
1. Primera línea ≤ 50 caracteres
2. Cuerpo envuelto a 72 caracteres
3. Explicar QUÉ y POR QUÉ, no CÓMO
4. Referenciar issues (#42, #123)
