Simuler une régression sur une page
Objectif : Retrouver avec bisect le commit qui a cassé un contrôle choisi sur une page du site.
Un lien de navigation peut rester visible tout en menant vers une section qui n’existe plus. Dans un historique de plusieurs changements, examiner les commits un par un est lent et favorise les suppositions. Vous allez tester une règle précise sur index.html et laisser Git réduire l’intervalle jusqu’au commit qui la fait échouer.
Dans le projet fil rouge, le contrôle portera sur le lien « Branches » de la navigation : la page doit contenir un lien vers #branches et une section dont l’identifiant est branches. Ce scénario suppose que l’historique du dépôt contient bien une révision où ce contrôle passe et une autre où il échoue. Les étapes de test reproductible et les commandes de bisect sont déjà présentées dans les leçons précédentes ; ici, vous les appliquez à cette page.
Choisir le contrôle et les bornes
Avant de lancer la recherche, confirmez que la branche de travail ne contient pas de modifications à préserver et relevez les deux révisions qui encadrent le défaut. La révision saine doit réussir le contrôle ci-dessous ; la révision défectueuse doit l’échouer. Remplacez les valeurs d’exemple par les identifiants réellement observés dans l’historique : ne choisissez pas une borne en fonction de la date seulement.
git status --short
git log --oneline --decorate -12Le contrôle analyse le HTML de la page avec le module html.parser de Python. Il ne dépend pas d’une expression régulière fragile : il compare les liens internes de la navigation aux identifiants effectivement présents dans le document, puis vérifie explicitement la destination « Branches ». Le script est créé dans le répertoire temporaire de votre système, pas parmi les fichiers du projet.
cat > /tmp/controle-page-git.sh <<'SH'
#!/bin/sh
python3 - <<'PY'
from html.parser import HTMLParser
from pathlib import Path
class Controle(HTMLParser):
def __init__(self):
super().__init__()
self.ids = set()
self.liens_navigation = set()
self.dans_navigation = False
def handle_starttag(self, tag, attrs):
a = dict(attrs)
if tag == "nav" and a.get("class") == "depot-navigation":
self.dans_navigation = True
if "id" in a:
self.ids.add(a["id"])
if self.dans_navigation and tag == "a":
href = a.get("href", "")
if href.startswith("#"):
self.liens_navigation.add(href[1:])
def handle_endtag(self, tag):
if tag == "nav":
self.dans_navigation = False
page = Path("index.html")
if not page.is_file():
raise SystemExit("index.html absent")
controle = Controle()
controle.feed(page.read_text(encoding="utf-8"))
manquants = controle.liens_navigation - controle.ids
if "branches" not in controle.liens_navigation:
manquants.add("lien #branches absent de la navigation")
if "branches" not in controle.ids:
manquants.add("section #branches absente")
if manquants:
print("ÉCHEC : " + ", ".join(sorted(manquants)))
raise SystemExit(1)
print("OK : les destinations de navigation existent, dont #branches")
PY
SH
chmod +x /tmp/controle-page-git.shDepuis la racine du dépôt, exécutez d’abord le test sur l’état courant. Un code de sortie nul indique que toutes les destinations internes de la navigation existent et que le lien ciblé est présent ; un code différent de zéro signale un défaut pour ce contrôle. Cette première exécution vérifie aussi que le script et le chemin de fichier conviennent avant de les confier à la recherche.
/tmp/controle-page-git.shOK : les destinations de navigation existent, dont #branchesLaisser bisect tester les révisions
Démarrez avec le hash de la révision défectueuse, puis indiquez celui de la révision saine. Git sélectionne les commits intermédiaires et appelle le script sur chacun d’eux. À chaque étape, l’historique de la page est extrait dans l’arbre de travail temporaire de bisect ; le script lit alors le index.html de cette révision, et non celui que vous aviez initialement sous les yeux.
git bisect start <commit-defectueux> <commit-sain>
git bisect run /tmp/controle-page-git.shGit affiche les révisions testées, le résultat de chaque exécution et termine en indiquant le premier commit qui a fait échouer le contrôle.Conservez la sortie complète de la commande : elle constitue le journal des résultats, avec les révisions testées et le commit identifié. Si un commit ne peut pas être testé parce que index.html ou Python manque à cet état de l’historique, le script doit distinguer cette impossibilité d’un défaut réel ; le test fourni ici suppose que le fichier et Python sont disponibles à toutes les bornes. Si cette hypothèse est fausse, interrompez la recherche et adaptez le contrôle au dépôt avant de tirer une conclusion.
Confirmer la preuve et terminer proprement
Le commit annoncé est une piste vérifiable, pas encore une explication complète. Inspectez son diff et relancez le même contrôle sur le commit identifié puis sur son parent : le premier doit échouer et le second réussir. Si les résultats ne correspondent pas, vérifiez les bornes, les changements de structure HTML ou la reproductibilité du script avant de communiquer l’identification à l’équipe.
git show --stat --oneline <commit-identifie>
git show --format=fuller -- index.html <commit-identifie>
git switch --detach <commit-identifie>
/tmp/controle-page-git.sh
git switch --detach <commit-identifie>^
/tmp/controle-page-git.sh
git bisect resetLe contrôle échoue sur le commit identifié et réussit sur son parent. `git bisect reset` termine la session et ramène au point de départ de la recherche.Dans la commande git show, la forme la plus explicite pour afficher le changement est git show <commit-identifié> -- index.html ; utilisez-la pour isoler le fichier concerné. Après la validation sur le commit et son parent, rédigez un compte rendu bref : contrôle testé, hashes des bornes, hash fautif, résultats des deux exécutions et changement du diff qui explique la rupture. La leçon suivante simulera une perte de commit ; ne réécrivez pas l’historique pour réparer cette régression dans cet exercice.
À retenir
- Choisissez un contrôle précis sur une page et des bornes réellement saine et défectueuse.
- Exécutez le test sur l’état courant avant de lancer git bisect run.
- Conservez le journal de bisect et vérifiez le commit identifié ainsi que son parent.
- Terminez la session avec git bisect reset et consignez les preuves de la régression.