Automatización Linux, scripting Bash y herramientas para sysadmins

git bisect, reflog y cherry-pick: las 3 herramientas que me salvaron el día

#git#debugging#devops

El trío de emergencia

Hay tres comandos de git que no usas todos los días. Pero el día que los necesitas, no hay sustituto. Si trabajas solo, el 90% del tiempo te basta con add, commit, push, pull. Pero cuando algo sale mal —un bug apareció de la nada, borraste una rama por error, necesitas un commit de otra rama sin hacer merge— este trío te salva.

git bisect: encontrar el commit que rompió todo

Alguien reporta un bug. Funcionaba en la versión de hace 2 semanas. Hoy no. Hay 50 commits entre medio. ¿Cuál lo rompió?

git bisect hace una búsqueda binaria. Le dices un commit “bueno” y uno “malo”, y él te va moviendo al punto medio para que pruebes. En 6 pasos encuentras al culpable entre 50 commits.

git bisect start
git bisect bad HEAD           # La versión actual está rota
git bisect good abc123        # Hace 2 semanas funcionaba

# Git te mueve a un commit intermedio
# Pruebas si el bug existe...
# Si el bug está presente:
git bisect bad

# Si el bug NO está:
git bisect good

# Repites hasta que git te dice:
# "abc123 is the first bad commit"

Puedes automatizarlo con un script:

git bisect start HEAD abc123
git bisect run npm test     # Ejecuta los tests en cada paso

Si npm test falla, git marca bad automáticamente. En segundos tienes al culpable sin intervención humana.

Cuando terminas:

git bisect reset

git reflog: recuperar lo que creías perdido

Borraste una rama por error. Hiciste git reset --hard y perdiste commits. reflog guarda un historial de TODO lo que hizo git en tu repositorio local. Cada movimiento de HEAD queda registrado por 90 días.

git reflog

Salida típica:

abc1234 HEAD@{0}: commit: Agregado rate limiting
def5678 HEAD@{1}: merge feature/login: Fast-forward
ghi9012 HEAD@{2}: checkout: moving from main to feature/login
jkl3456 HEAD@{3}: commit: Fix typo en docs

Cada entrada tiene un índice (HEAD@{0}, HEAD@{1}…). Para recuperar:

# Volver al estado de hace 3 movimientos
git reset --hard HEAD@{3}

# Recuperar una rama borrada (estaba en feature/login)
git checkout -b feature/login HEAD@{2}

# Recuperar un commit específico del reflog
git cherry-pick jkl3456

El reflog es local. No se pushea. Si clonas el repo de nuevo, lo pierdes. Pero en tu máquina, es tu red de seguridad.

git cherry-pick: aplica un commit sin hacer merge

Tienes un fix urgente en develop que necesitas en main, pero no quieres mergear toda la rama. cherry-pick toma commits individuales y los aplica:

git checkout main
git cherry-pick abc123

Si el commit aplica limpiamente, listo. Si hay conflicto, lo resuelves como cualquier merge:

# Resolver conflictos...
git add .
git cherry-pick --continue

Para varios commits:

git cherry-pick abc123 def456

Y si solo quieres los cambios pero en staging (sin commit automático):

git cherry-pick -n abc123
git diff --cached   # Revisas qué trajo
git commit -m "Fix aplicado desde develop"

No necesitas estos comandos todas las semanas. Pero la primera vez que bisect encuentra un bug en 30 segundos, o reflog recupera 4 horas de trabajo perdido, entiendes por qué existen.