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)
Infografía Git: Git avanzado — rebase, stash, bisect, hooks y buenas prácticas
Infografía: Git: Git avanzado — rebase, stash, bisect, hooks y buenas prácticas