Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Debug avec git bisect et git blame

9 min de lecture

Votre code régresse et vous ne savez pas quel commit en est la cause ? git bisect trouve le commit fautif par recherche dichotomique (O(log n)) — sur 1000 commits, ~10 tests suffisent — et git blame identifie qui a écrit chaque ligne. Ce guide vous apprend à utiliser les deux outils, y compris bisect en mode automatisé et blame avec .git-blame-ignore-revs pour masquer les reformatages.

Prérequis : Consulter l’historique et Sélection de révisions.

  • Utiliser git bisect manuellement pour isoler le commit d’une régression
  • Automatiser bisect avec un script de test pour des audits rapides
  • Lire git blame pour identifier l’auteur et le contexte d’une ligne
  • Combiner bisect et blame dans un workflow de débogage complet

bisect fonctionne comme une recherche dichotomique :

  1. Vous indiquez un commit bon (sans le bug) et un commit mauvais (avec le bug)
  2. Git sélectionne le commit au milieu
  3. Vous testez et dites si c’est bon ou mauvais
  4. Git réduit de moitié à chaque étape
  1. Démarrez la session bisect :

    Fenêtre de terminal
    git bisect start
  2. Marquez le commit actuel comme mauvais :

    Fenêtre de terminal
    git bisect bad
  3. Marquez un commit connu comme bon (par exemple un tag ou un SHA ancien) :

    Fenêtre de terminal
    git bisect good v1.0.0
    # Ou avec un SHA :
    git bisect good a1b2c3d
  4. Git checkout automatiquement le commit du milieu :

    Bisecting: 15 revisions left to test after this (roughly 4 steps)
    [e4f5a6b...] Refactor module pricing
  5. Testez (lancez vos tests, vérifiez manuellement…) puis marquez :

    Fenêtre de terminal
    git bisect good # Ce commit est OK
    # ou
    git bisect bad # Ce commit a le bug
  6. Répétez l’étape 5 jusqu’à ce que Git identifie le commit fautif :

    d7c8b9a is the first bad commit
    Author: Bob <bob@example.com>
    Date: Thu Mar 20 10:00:00 2026
    feat: modifier le calcul de remise
  7. Terminez la session :

    Fenêtre de terminal
    git bisect reset
    # Retour à la branche d'origine

Si un commit ne compile pas ou n’est pas testable :

Fenêtre de terminal
git bisect skip

Git essaie un commit voisin.

Fenêtre de terminal
git bisect log # Historique de la session
git bisect visualize # Ouvre gitk avec les commits restants

Le vrai pouvoir de bisect : un script teste automatiquement chaque commit.

Fenêtre de terminal
git bisect start HEAD v1.0.0
git bisect run ./test-regression.sh

Le script doit retourner :

  • 0 → le commit est bon
  • 1 à 124, 126 à 127 → le commit est mauvais
  • 125 → le commit est non testable (skip)
test-regression.sh
#!/bin/bash
# Compiler le projet
make build 2>/dev/null || exit 125 # 125 = skip si ça ne compile pas
# Lancer le test spécifique
python -m pytest tests/test_pricing.py::test_remise
# pytest retourne 0 si OK, 1 si échec → parfait pour bisect
Fenêtre de terminal
chmod +x test-regression.sh
git bisect start HEAD v1.0.0
git bisect run ./test-regression.sh

Git exécute le script sur chaque commit testé et trouve le fautif sans intervention manuelle.

Fenêtre de terminal
# Projet C/C++
git bisect run sh -c 'make clean && make && ./run_tests'
# Projet Node.js
git bisect run sh -c 'npm ci && npm test'

git blame annote chaque ligne d’un fichier avec le commit, l’auteur et la date :

Fenêtre de terminal
git blame src/pricing.py
a1b2c3d4 (Alice 2026-03-15 14:30:00 +0100 1) def calculate_price(qty, price):
a1b2c3d4 (Alice 2026-03-15 14:30:00 +0100 2) total = qty * price
d7c8b9a0 (Bob 2026-03-20 10:00:00 +0100 3) if qty > 100:
d7c8b9a0 (Bob 2026-03-20 10:00:00 +0100 4) total *= 0.9
a1b2c3d4 (Alice 2026-03-15 14:30:00 +0100 5) return total

Les lignes 3-4 ont été ajoutées par Bob le 20 mars.

OptionEffetExemple
-L 10,25Limiter aux lignes 10-25git blame -L 10,25 file.py
-L :funcLimiter à une fonctiongit blame -L :calculate_price file.py
-CDétecter les lignes copiées depuis un autre fichiergit blame -C file.py
-C -CDétecter aussi dans les commits de créationgit blame -C -C file.py
-wIgnorer les changements de whitespacegit blame -w file.py
-MDétecter les lignes déplacées dans le même fichiergit blame -M file.py
--sinceDepuis une dategit blame --since=2.weeks file.py

Les reformatages massifs (prettier, black) polluent le blame. Créez un fichier d’exclusion :

.git-blame-ignore-revs
# Reformatage avec black
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
# Migration vers prettier
e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3
Fenêtre de terminal
# Configurer Git pour ignorer ces commits
git config blame.ignoreRevsFile .git-blame-ignore-revs

Ajoutez .git-blame-ignore-revs au repo pour que toute l’équipe en bénéficie. GitHub reconnaît aussi ce fichier automatiquement.

git annotate est un alias de blame avec un format de sortie légèrement différent. En pratique, utilisez blame — c’est le standard.

Fenêtre de terminal
# 1. Un bug est signalé. Trouver le commit fautif :
git bisect start HEAD v1.0.0
git bisect run npm test
# 2. bisect trouve le commit d7c8b9a. Voir les détails :
git show d7c8b9a
# 3. Identifier les lignes modifiées :
git blame -L 3,4 src/pricing.py
# 4. Comprendre le contexte avec le log de la fonction :
git log -L :calculate_price:src/pricing.py
# 5. Corriger et committer :
git revert d7c8b9a # ou fix manuel
SymptômeCause probableSolution
bisect retourne un mauvais commitScript de test non fiableTestez le script sur un commit bon et un mauvais manuellement
bisect tourne en boucleCommits non testables (ne compilent pas)Retournez 125 dans le script pour skipper
blame montre un commit de reformatageReformatage massifCréez .git-blame-ignore-revs
-L :func ne fonctionne pasLangage non reconnuConfigurez *.ext diff=lang dans .gitattributes
bisect corrompuSession interrompuegit bisect reset pour tout nettoyer
  • git bisect : recherche dichotomique — O(log n) commits à tester
  • git bisect run script : automatisation complète — le script retourne 0 (bon) ou 1 (mauvais)
  • git blame : identifie l’auteur et le commit de chaque ligne
  • -C détecte les copier-coller, -w ignore le whitespace
  • .git-blame-ignore-revs pour exclure les reformatages du blame
  • Workflow : bisectshowblamelog -L → fix

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn