TechLead
Lección 9 de 9
5 min de lectura
Git Avanzado

Git Bisect para depuración

Usa búsqueda binaria para encontrar el commit que introdujo un bug.

Git Bisect

Git bisect usa búsqueda binaria para encontrar el commit que introdujo un bug. Es muy eficiente, prueba log₂(n) commits en lugar de n.

Flujo básico de bisect

# Start bisect
git bisect start

# Mark current (buggy) commit as bad
git bisect bad

# Mark a known good commit
git bisect good v1.0.0
# Or: git bisect good abc1234

# Git checks out middle commit
# Test the code, then mark:
git bisect good  # If bug not present
git bisect bad   # If bug is present

# Repeat until found
# Bisecting: 3 revisions left to test
# [abc1234] First bad commit

# End bisect
git bisect reset

Bisect con rango de commits

# Start with known range
git bisect start HEAD v1.0.0

# Or specify bad and good in start
git bisect start bad-commit good-commit

# View current bisect state
git bisect log

Bisect automatizado

# Run a script to test each commit
git bisect start HEAD v1.0.0
git bisect run npm test

# Script should exit:
# 0 = good (test passes)
# 1-124, 126-127 = bad (test fails)
# 125 = skip (can't test this commit)

# Custom test script
git bisect run ./test-for-bug.sh

Ejemplo de script de test

#!/bin/bash
# test-for-bug.sh

# Build the project
npm run build || exit 125  # Skip if build fails

# Run specific test
npm test -- --grep "login feature" || exit 1

# Or check for specific behavior
if grep -r "buggy_pattern" src/; then
  exit 1  # Bad
fi

exit 0  # Good

Saltar commits

# Skip current commit (can't test)
git bisect skip

# Skip a range
git bisect skip v1.0..v1.1

# Skip commits matching pattern
git bisect skip $(git rev-list --grep="WIP" HEAD)

Bisect con términos personalizados

# Use custom terms instead of good/bad
git bisect start --term-new=fixed --term-old=broken

# Mark commits with custom terms
git bisect fixed
git bisect broken

# Useful for finding fix instead of bug:
git bisect start --term-new=fixed --term-old=unfixed

Ver progreso de bisect

# Show bisect log
git bisect log

# Save log for replay
git bisect log > bisect.log

# Replay bisect session
git bisect replay bisect.log

# Visualize bisect
git bisect visualize
# Or: gitk (GUI)

Bisect con rutas

# Only bisect commits touching specific paths
git bisect start -- src/auth/

# Limit to specific file
git bisect start -- src/components/Login.jsx

Ejemplo complejo de bisect

# Find when performance degraded
git bisect start HEAD v1.0.0

# Test script for performance
cat > perf-test.sh << 'EOF'
#!/bin/bash
npm run build 2>/dev/null || exit 125

# Run benchmark
result=$(npm run benchmark --silent | grep "ops/sec" | awk '{print $1}')

# Bad if performance below threshold
if (( $(echo "$result < 1000" | bc -l) )); then
  exit 1
fi
exit 0
EOF

chmod +x perf-test.sh
git bisect run ./perf-test.sh

Bisect para regresiones

# Find when feature stopped working
git bisect start

# Current: feature broken
git bisect bad HEAD

# Last known working
git bisect good v2.0.0

# Automated test
git bisect run sh -c '
  npm install --silent 2>/dev/null
  npm run build --silent 2>/dev/null || exit 125
  npm test -- --grep "specific feature" --silent
'

Después de encontrar el bug

# Bisect found: abc1234 is first bad commit

# View the problematic commit
git show abc1234

# See what changed
git diff abc1234^..abc1234

# View blame for specific file
git blame -L 10,20 src/file.js abc1234

# End bisect and return to branch
git bisect reset

# Create fix
git checkout -b fix-regression
# Make changes...
git commit -m "Fix regression introduced in abc1234"

Consejos para un bisect efectivo

  • Ten un test automatizado confiable
  • Usa skip para commits rotos/no testeables
  • Reduce con limitación por rutas
  • Guarda logs de bisect para documentación
  • Considera bisect run para tests complejos
  • Recuerda ejecutar bisect reset al terminar

Eficiencia

# Commits to test with bisect:
100 commits  → ~7 tests (log₂100)
1000 commits → ~10 tests
10000 commits → ~14 tests

# Much faster than linear search!

Continuar aprendiendo