← retour aux snippets

git: bisect pour trouver le commit bug

Isoler rapidement le commit fautif avec git bisect (manuel ou automatisé via un script de test).


objectif

Identifier le commit qui a introduit un bug en testant une plage de commits par dichotomie, à la main ou automatiquement.

code minimal

# démarrer en indiquant un commit mauvais (HEAD) et un bon (ex: tag v1.2.3)
git bisect start HEAD v1.2.3

# marquer l'état courant si nécessaire
git bisect bad
git bisect good v1.2.3

# une fois le coupable trouvé
git bisect reset

utilisation

# workflow manuel
git bisect start
git bisect bad            # commit actuel contient le bug
git bisect good v1.2.3    # ce tag ne l'a pas
# git choisit un commit au milieu -> testez, puis:
git bisect bad            # si le bug est présent
# ou
git bisect good           # si le bug est absent
# répétez jusqu'à identification, puis:
git bisect reset

# automatiser avec un script de test (0=good, 1..127=bad, 125=skip)
git bisect start HEAD v1.2.3
git bisect run bash -lc '
  set -Eeuo pipefail
  # nettoyage pour éviter les artefacts
  git clean -xdf >/dev/null
  # build/tests
  make -s build >/dev/null 2>&1 || exit 1
  pytest -q tests/test_feature.py >/dev/null 2>&1 && exit 0 || exit 1
'

# si un commit ne compile pas ou test impossible -> skip
git bisect skip

variante(s) utile(s)

# tester un service web: retourne 0 si l'endpoint repond 200, sinon 1
git bisect start HEAD v1.2.3
git bisect run bash -lc '
  set -Eeuo pipefail
  git clean -xdf >/dev/null
  (timeout 60s ./start.sh >/dev/null 2>&1 &)          # demarrage
  sleep 3
  curl -fsS http://127.0.0.1:8080/health >/dev/null && rc=0 || rc=1
  pkill -TERM -f start.sh >/dev/null 2>&1 || true
  exit "$rc"
'

# cibler une plage specifique (ex: les 200 derniers commits)
git bisect start HEAD~200 HEAD

# ignorer des merges (si votre test est non deterministe dessus)
git bisect run bash -lc '
  git show -s --format=%p HEAD | grep -q " " && exit 125
  ./run_test.sh
'

# limiter l'impact sur le working tree (stash auto)
git bisect start HEAD v1.2.3
git -c rebase.autostash=true bisect run ./run_test.sh

notes

  • toujours terminer par git bisect reset pour revenir a l’etat initial.
  • git bisect run attend 0 pour “good”, 125 pour “skip”, tout autre code = “bad”.
  • nettoyez entre essais (git clean -xdf) et reconstruisez pour eviter des faux positifs lies a des artefacts.
  • choisissez un commit “good” fiable (tag de release, SHA connu) et un “bad” certain (souvent HEAD).
  • consignez la commande de reproduction la plus courte possible pour stabiliser le diagnostic.