# git bisect pour retrouver le commit qui a introduit une régression

> Sur un historique de plusieurs centaines de commits, une recherche dichotomique automatisée localise le commit fautif plus vite qu'une relecture manuelle.

- Auteur : WordPress Développement
- Publié le : 2022-04-24
- Mis à jour le : 2022-04-24
- Catégorie : Outils &amp; workflow
- URL : https://www.wpmoderne.fr/outils/git-bisect-retrouver-commit-regression/

## L’essentiel

- git bisect divise l'espace de recherche par deux à chaque étape
- Une bonne réduction manuelle du test accélère fortement l'opération
- Le script peut être automatisé pour éviter les erreurs de jugement humain

`git bisect start` : cette commande lance une recherche dichotomique dans l'historique d'un dépôt, pour retrouver précisément quel commit a introduit un comportement défectueux. Sur un projet dont l'historique dépasse plusieurs centaines de commits depuis la dernière version connue comme fonctionnelle, relire chaque modification une par une prendrait un temps considérable. Ce billet ne traite pas du profilage de performance lui-même, mais de la méthode pour localiser le commit responsable d'une régression déjà identifiée.

## Le principe : diviser l'espace de recherche à chaque test

Plutôt que d'examiner les commits un par un dans l'ordre chronologique, `git bisect` demande à l'utilisateur de désigner un commit connu comme fonctionnel et un commit connu comme défectueux, puis teste automatiquement le commit situé exactement au milieu de cet intervalle. Selon que ce commit intermédiaire présente ou non le défaut, l'outil réduit l'intervalle de recherche de moitié à chaque itération.

```
git bisect start
git bisect bad HEAD
git bisect good v2.3.0
# Git bascule automatiquement sur le commit médian
# Après avoir testé manuellement :
git bisect good
# ou
git bisect bad
```

## Pourquoi cette méthode est plus rapide qu'une relecture manuelle

> L'essentiel à retenir : git bisect divise l'espace de recherche par deux à chaque étape ; Une bonne réduction manuelle du test accélère fortement l'opération ; Le script peut être automatisé pour éviter les erreurs de jugement humain

Sur un intervalle de cinq cents commits entre la dernière version connue comme correcte et l'état actuel défectueux, une recherche dichotomique converge en une dizaine d'itérations seulement, grâce à la progression logarithmique de la méthode. Une relecture manuelle commit par commit, à l'inverse, demanderait potentiellement des centaines d'examens avant de tomber sur le bon, sans certitude de ne pas se tromper en cours de route.

- Chaque itération de `git bisect` divise par deux le nombre de commits restant à examiner.
- Le nombre d'itérations nécessaires suit une progression logarithmique, pas linéaire, par rapport à la taille de l'historique.
- La fiabilité du résultat dépend entièrement de la fiabilité du test appliqué à chaque commit intermédiaire.

## Automatiser le test pour éliminer l'erreur de jugement humain

Tester manuellement chaque commit intermédiaire introduit un risque : une erreur de jugement sur un seul test invalide toute la recherche dichotomique qui suit. Lorsque le défaut peut être détecté par un script, `git bisect run` automatise entièrement la recherche, en exécutant ce script à chaque étape et en interprétant son code de sortie.

```
git bisect start
git bisect bad HEAD
git bisect good v2.3.0
git bisect run vendor/bin/phpunit --filter=RegressionAffichagePrix
```

Le script fourni doit retourner un code de sortie égal à zéro si le commit testé est correct, et différent de zéro s'il reproduit le défaut. Une fois la recherche terminée, la commande `git bisect log` conserve une trace complète du raisonnement suivi, utile pour documenter la découverte dans le ticket de suivi correspondant.

## Une précaution avant de lancer la recherche

La fiabilité de `git bisect` repose entièrement sur la reproductibilité du test à chaque commit intermédiaire. Un test qui dépend de données externes changeantes, comme un appel à un service tiers dont le comportement évolue avec le temps, peut fausser la recherche en rendant un commit correct faussement identifié comme défectueux, ou l'inverse.

> Une recherche dichotomique automatisée ne vaut que ce que vaut le test qu'on lui confie à chaque étape.

### Reprendre une recherche interrompue

Une recherche dichotomique peut s'étaler sur plusieurs heures si chaque test manuel demande de recompiler ou de redéployer un environnement. Git conserve l'état de la recherche en cours même après une interruption : la commande `git bisect log` permet de consulter les étapes déjà réalisées, et `git bisect replay` permet de reconstituer une recherche à partir d'un journal sauvegardé, utile pour reprendre le travail sur un autre poste ou le partager avec un collègue qui prendrait le relais.

```
git bisect log > recherche-regression.txt
# Sur un autre poste, ou plus tard :
git bisect replay recherche-regression.txt
```

Une fois le commit fautif identifié, la commande `git bisect reset` ramène le dépôt à son état initial, avant le début de la recherche, ce qui évite de rester bloqué sur un commit intermédiaire une fois le diagnostic terminé.

## En résumé

Face à une régression apparue quelque part dans un historique de plusieurs centaines de commits, `git bisect` permet de localiser le commit fautif en une dizaine d'itérations, bien plus rapidement qu'une relecture manuelle exhaustive. Automatiser le test avec `git bisect run`, quand cela reste possible, élimine en plus le risque d'erreur de jugement à chaque étape de la recherche.
