Retour au cours

infra / git-github

git log avancé et git bisect

Leçon 101 exercice

Explication

Ce que vous allez apprendre

  • Filtrer git log par auteur, période, mot-clé ou contenu de code modifié
  • Retrouver l'auteur et le commit d'origine d'une ligne précise avec git blame
  • Comprendre le principe de recherche dichotomique appliqué par git bisect
  • Isoler un commit fautif en un nombre logarithmique d'étapes plutôt que linéaire
  • Automatiser entièrement une recherche de bug avec git bisect run

Dans quel contexte ?

Un test automatisé qui passait il y a deux mois sur boutique-api échoue aujourd'hui, sans qu'aucun développeur ne se souvienne d'un changement lié à ce module. Entre les deux dates, plus de 200 commits ont été faits. Tester chacun manuellement prendrait des heures ; git bisect isole le commit fautif en une dizaine de tests grâce à une recherche par dichotomie.

Une vue brute vite inutilisable

D'abord, git log sans options donne une liste chronologique de commits, mais dans un vrai projet avec des centaines ou des milliers de commits, cette vue brute est vite inutilisable.

Transformer log en outil d'enquête

Les filtres avancés transforment git log en un véritable outil d'enquête : chercher un commit par mot-clé dans son message, par auteur, par période, ou même par un morceau de code précis ajouté ou supprimé.

Une compétence qui distingue les niveaux

Savoir interroger précisément son historique est une compétence qui distingue un usage superficiel de Git d'une vraie maîtrise.

Retrouver l'origine d'une ligne de code

Une fois l'historique bien filtré, il reste un besoin fréquent en debug : savoir qui a écrit une ligne précise, et dans quel commit. C'est le rôle de git blame.

Ce que blame sert vraiment à faire

Ce n'est pas un outil pour "accuser" quelqu'un, malgré son nom, mais pour retrouver le contexte et l'intention derrière un choix de code, souvent en consultant ensuite le message du commit identifié.

Un problème plus difficile : retrouver un bug dans l'historique

Imagine un bug présent aujourd'hui, mais absent il y a deux mois, sans savoir dans lequel des centaines de commits entre les deux il a été introduit.

Ce que ça coûterait de tester un par un

Tester chaque commit un par un serait extrêmement long.

La solution : une recherche par dichotomie

git bisect applique une recherche dichotomique : il te fait tester un commit "au milieu" de la plage, te demande s'il est bon ou mauvais, puis réduit la zone de recherche de moitié à chaque itération.

Le gain de cette approche

Il trouve le coupable en un nombre d'étapes logarithmique plutôt que linéaire, souvent en moins de dix tests même sur des centaines de commits.

Commande git logCe qu'elle recherche
--grep="mot"Un mot-clé dans le MESSAGE du commit
-S "code"Les commits qui ajoutent/retirent cette chaîne exacte
-G "regex"Une recherche par expression régulière dans les diffs
--author="nom"Les commits d'un auteur précis

Prérequis

Il est utile de déjà savoir lire un git log --oneline basique (vu dans la leçon sur les commits) avant d'aborder ces filtres plus avancés.

Automatiser entièrement la recherche

Enfin, quand le critère "bon/mauvais" peut être vérifié par un script, comme une suite de tests automatisés, bisect run élimine même le besoin de tester manuellement à chaque étape.

Bonne pratique

Avant de lancer un git bisect run, vérifie que ton script de test retourne bien un code de sortie 0 pour "bon" et un code non nul pour "mauvais" (125 pour "impossible à tester"). Un script mal calibré peut faire converger le bisect vers un mauvais commit sans que tu t'en aperçoives.

La prochaine leçon te montre comment récupérer un commit apparemment perdu après une manipulation destructive, grâce au reflog.

Commandes & code

git log avancé & bisect

bash
# Filtres puissants de git log
git log --oneline --graph --decorate --all
git log --grep="fix" -i                     # recherche insensible à la casse dans les messages
git log -S "calculateTotal" --oneline        # commits qui AJOUTENT/RETIRENT cette chaîne exacte
git log -G "regex.*pattern" --oneline        # recherche par regex dans les diffs
git log --follow -- ancien-nom-fichier.js    # suit un fichier à travers ses renommages
git log --stat                                # + statistiques de lignes ajoutées/supprimées
git log --format="%h %an %ar - %s"           # format custom (hash, auteur, date relative, sujet)
bash
# Trouver QUI a introduit une ligne précise
git blame src/utils/pricing.js
git blame -L 40,60 src/utils/pricing.js       # limite à une plage de lignes
bash
# git bisect : recherche dichotomique automatique du commit fautif
git bisect start
git bisect bad                       # HEAD actuel est cassé
git bisect good v1.4.0                # cette ancienne version fonctionnait

# Git checkout automatiquement un commit "au milieu" à chaque étape
# -> tester, puis répondre :
git bisect good     # si ce commit fonctionne
git bisect bad       # si ce commit est cassé
# ... répéter jusqu'à ce que Git isole LE commit fautif ...
git bisect reset      # revient à l'état d'avant le bisect
bash
# Automatiser le bisect avec un script de test (0 = good, 1-127 = bad, 125 = skip)
git bisect start HEAD v1.4.0
git bisect run npm test -- --testPathPattern=pricing
# Git enchaîne automatiquement TOUTES les étapes sans intervention manuelle

Résumé

  • -S/-G recherchent dans le CONTENU des diffs, pas seulement les messages de commit.
  • git blame identifie l'auteur et le commit d'origine d'une ligne précise.
  • git bisect isole un commit fautif par dichotomie en O(log n) étapes.
  • bisect run <script> automatise entièrement la recherche, sans tester manuellement.

Exercices pratiques

1 disponible
1

Mission : traquer un bug apparu il y a deux mois

Objectif : Utiliser les filtres avancés de git log et git bisect pour isoler efficacement un commit fautif parmi des centaines.

Contexte

Un test automatisé qui passait il y a deux mois sur boutique-api échoue aujourd'hui. Plus de 200 commits séparent les deux dates, et aucun développeur ne se souvient d'un changement lié à ce module.

Résoudre l’exercice →