Introduction
Little Pine Goods prépare des devis pour de petits cadeaux à retirer en boutique. Un client signale que l'offre FRIEND10 n'accorde plus la réduction promise. L'historique récent contient aussi des mises à jour utiles de produits, de textes et de retrait ; ramener toute la boutique à une ancienne version ferait donc perdre du travail valide.
Exécutez une commande normale et la commande cadeau défectueuse, puis utilisez un test métier déterministe préparé pour classer les anciennes versions. Exercez-vous brièvement à la recherche dichotomique manuelle avec Git avant de laisser le même test automatiser la recherche. Comparez le premier instantané défectueux à son parent direct, quittez la recherche et réparez la boutique actuelle tout en conservant les mises à jour ultérieures. Livrez un fichier de devis client complet en plus du commit correctif.
Les prérequis sont les bases de la navigation dans le terminal, des commits, des branches et de la lecture simple de log/diff. Git bisect, les extractions temporaires avec HEAD détachée, les codes de sortie des tests et la petite modification du fichier d'offres sont expliqués ici. Python et le programme de devis sont préparés ; vous les exécutez sans écrire de Python. Il s'agit d'un véritable historique Git local et d'un outil de devis fondé sur des fichiers, sur une seule machine de formation, avec des commandes fictives et des prix en EUR. Aucun site web, compte hébergé ni déploiement réseau n'est nécessaire. Utilisez le Terminal par défaut. La durée de 50 minutes est une estimation de l'auteur.
Trouver le premier devis défectueux
Dans cette étape, établissez le bon résultat métier, testez de véritables instantanés historiques et identifiez la frontière où la réduction est devenue incorrecte.
Commencez dans Terminal et entrez dans le dépôt de la boutique :
cd /home/labex/project/quote-desk/shop
cd change le répertoire de ce terminal. Si vous saisissez mal un chemin, utilisez pwd pour afficher votre emplacement et ls pour lister ce répertoire, puis répétez la commande cd complète ci-dessus. Les erreurs de navigation courantes ne nécessitent pas de réinitialiser la VM.
Lisez la demande du client. cat affiche un fichier texte ; .. désigne le répertoire parent :
cat ../request.txt
FRIEND10 promet une réduction de 10% sur le sous-total des articles. Il n'y a ni frais de livraison ni taxe. La commande cadeau comprend trois mugs de camping à EUR 16.00 chacun : sous-total EUR 48.00, réduction EUR 4.80, total EUR 43.20. Le catalogue, la commande et les règles d'offre existants constituent les faits métier ; ne les modifiez pas pour les faire correspondre à un résultat défectueux.
Exécutez d'abord une commande normale. python3 exécute le programme fourni quote.py ; son argument suivant est le fichier de commande préparé. Vous n'avez pas besoin de modifier ni de comprendre le code source Python :
python3 quote.py ../orders/plain.order
La commande d'un mug utilise le code NONE. Vous devez obtenir un sous-total et un total de EUR 16.00, une réduction de EUR 0.00, la phrase d'accueil actuelle et le retrait le samedi jusqu'à 16:00. Cela établit un devis normal utile.
Exécutez la commande signalée :
python3 quote.py ../orders/gift.order
Pour lire le code de sortie natif de la dernière commande, utilisez la valeur du shell $?. echo affiche cette valeur. Exécutez-le immédiatement après la commande de devis :
echo $?
Vous devez obtenir 0 : le programme s'est exécuté avec succès même si le résultat monétaire est incorrect.
Le programme s'exécute, mais le devis est faux : réduction de EUR 0.48 et total de EUR 47.52. Une sortie réussie du programme est différente d'une réponse métier correcte.
Le test préparé se trouve en dehors du dépôt afin que l'extraction d'anciennes versions ne puisse pas le remplacer. Il exécute le véritable programme de devis pour plusieurs quantités et un cas témoin sans code de réduction, en comparant les résultats complets aux règles d'offre inchangées. Exécutez-le :
python3 /opt/labex/quote-desk/check.py
Lisez immédiatement le code de sortie de ce test avec la même valeur du shell :
echo $?
Vous devez obtenir 1 : ce test détecte l'écart métier.
Des lignes FAIL pour FRIEND10 et un code de sortie natif de 1 sont attendus. Les cas témoins NONE réussissent. Le test renvoie 0 pour des devis corrects, 1 pour cet échec métier et 128 s'il ne peut pas tester une version ; une impossibilité de tester doit arrêter la recherche, et non être interprétée au hasard comme une régression de réduction. Cet historique préparé ne comporte ni échecs de compilation ni versions ignorées.
Inspectez la branche courante et l'état propre. branch --show-current affiche la branche ; --short produit une liste compacte des fichiers :
git branch --show-current
git status --short
Vous devez obtenir main et aucune sortie de fichier modifié. Gardez la boutique propre pendant la recherche. Lisez son historique : --no-pager affiche directement la sortie au lieu d'ouvrir un visualiseur défilant, --oneline abrège les entrées et --decorate ajoute les étiquettes des branches et des tags :
git --no-pager log --oneline --decorate
Le tag fixe incident-tip marque la pointe courante héritée, et known-good marque l'ancienne version fonctionnelle. Les sujets des commits décrivent le travail, mais leur formulation ne prouve pas à quel moment le devis est devenu défectueux. Préservez les deux tags et tous les commits hérités.
L'option --revision du test exécute l'instantané enregistré sélectionné dans un répertoire temporaire isolé, sans modifier votre extraction ni la réparer. Établissez les deux bornes à partir du comportement réel :
python3 /opt/labex/quote-desk/check.py --revision known-good
python3 /opt/labex/quote-desk/check.py --revision incident-tip
La première commande doit réussir avec le code 0. La seconde doit échouer avec le code 1. Une bonne version et une mauvaise version ultérieure bornent la recherche. Cet exercice contient une seule introduction de la panne et aucune correction ultérieure dans cet intervalle.
Classer deux versions à la main
Git bisect réduit cet intervalle en testant des versions entre les bornes. Commencez avec la révision connue comme mauvaise en premier et la révision connue comme bonne en second :
git bisect start incident-tip known-good
Git extrait un instantané intermédiaire et affiche l'intervalle restant. Pendant la recherche, une HEAD détachée signifie que vous consultez directement un commit au lieu de déplacer main. Ne modifiez pas ces versions temporaires et n'y créez pas de commit.
Exécutez le même test sur cet instantané extrait :
python3 /opt/labex/quote-desk/check.py
Cette première sélection préparée échoue avec le code 1. Classez la version observée comme mauvaise ; bad décrit le résultat du test métier, et non le message du commit :
git bisect bad
Git sélectionne un autre instantané. Testez-le plutôt que de deviner :
python3 /opt/labex/quote-desk/check.py
Cette sélection réussit avec le code 0. Enregistrez cette observation :
git bisect good
Git réduit de nouveau l'intervalle. Vous avez vu comment chaque résultat élimine une partie de l'espace de recherche. Pour vous exercer au parcours automatique à partir des mêmes bornes d'origine, quittez d'abord cette recherche incomplète. bisect reset efface l'état de recherche et revient à la branche et à la révision de départ ; il n'annule pas de commits :
git bisect reset
git branch --show-current
Vous devez obtenir main. Si vous classez une version incorrectement pendant l'exercice, ce même reset et un nouveau départ permettent de recommencer à partir des résultats réels du test, sans supprimer de fichiers.
Laisser le test piloter la recherche
Recommencez, puis donnez à bisect run la même commande de test complète. Git utilise chaque code de sortie natif pour choisir automatiquement bon ou mauvais :
git bisect start incident-tip known-good
git bisect run python3 /opt/labex/quote-desk/check.py
Vous devez voir plusieurs exécutions de test et une ligne se terminant par is the first bad commit. La commande de recherche elle-même se termine avec le code 0 lorsqu'elle trouve correctement la frontière, même si certains tests de devis individuels ont échoué. Les identifiants de commits peuvent différer.
La référence Git bisect/bad pointe vers le premier mauvais commit identifié. La HEAD courante peut encore être la dernière bonne version testée ; ne supposez pas qu'elle correspond au résultat annoncé. Lisez le patch du véritable candidat. show sélectionne ce commit et son patch ; -- sépare le chemin du fichier :
git --no-pager show bisect/bad -- discounts.txt
Le pourcentage FRIEND10 est passé de 10 à 1. Vérifiez les deux côtés avec le test externe. Un ^ final sélectionne l'unique premier parent direct d'un commit : bisect/bad^ est donc la version immédiatement avant le candidat, et non une plage entière :
python3 /opt/labex/quote-desk/check.py --revision bisect/bad
python3 /opt/labex/quote-desk/check.py --revision bisect/bad^
Le candidat doit échouer avec le code 1 et son parent doit réussir avec le code 0. Les valeurs et le comportement réel concordent. Laissez la recherche terminée ouverte pour ce point de contrôle ; vous reviendrez ensuite à la boutique actuelle avant de modifier quoi que ce soit.
Réparer la boutique actuelle et livrer le devis
Dans cette étape, quittez la recherche historique, enregistrez une correction ciblée sur la branche courante et livrez un devis complet sans perdre les produits ultérieurs ni les informations de retrait.
Restez dans Terminal, dans /home/labex/project/quote-desk/shop. Revenez à la branche d'origine avec la remise à zéro de la recherche enseignée :
git bisect reset
git branch --show-current
git --no-pager log -1 --oneline --decorate
git status --short
Vous devez obtenir main, la pointe héritée marquée incident-tip et aucune sortie de fichier modifié. L'option de journal -1 limite la sortie au commit le plus récent. Ne réparez pas une version historique détachée et ne remplacez pas toute la boutique par known-good : le travail valide ultérieur doit faire partie du résultat.
Lisez le petit fichier d'offres et les détails actuels à préserver :
cat discounts.txt
cat welcome.txt pickup.txt care.txt
cat catalog.json
L'arbre courant comprend le Trail pin, la nouvelle phrase d'accueil et le retrait le samedi jusqu'à 16:00. Seul le pourcentage de FRIEND10 est faux. Le fichier d'offres contient un paramètre CODE=integer-percent par ligne ; TRAIL15 reste à 15 et STUDENT5 à 5.
Remplacez uniquement ce petit fichier. printf affiche des valeurs selon un format : %s signifie du texte et \n ajoute un saut de ligne après chaque valeur fournie. Les apostrophes préservent le texte littéral. > écrit la sortie dans le fichier nommé, en remplaçant uniquement ce fichier :
printf '%s\n' 'FRIEND10=10' 'TRAIL15=15' 'STUDENT5=5' > discounts.txt
Examinez la véritable correction. Une comparaison simple compare les fichiers de travail à l'index, la zone de préparation de Git :
git --no-pager diff -- discounts.txt
Seul FRIEND10 doit repasser de 1 à 10. Définissez une identité de commit propre au dépôt avant d'enregistrer la réparation. --local évite la configuration globale ; les guillemets maintiennent ensemble un nom avec des espaces. Vous pouvez remplacer ces exemples fictifs :
git config --local user.name "Little Pine Maintainer"
git config --local user.email "maintainer@little-pine.example"
Préparez ce fichier avec add. Inspectez le patch préparé avec --cached, qui compare l'index au commit courant :
git add discounts.txt
git --no-pager diff --cached -- discounts.txt
Créez le commit de correction ciblée. -m fournit directement un message pertinent :
git commit -m "Restore the promised FRIEND10 discount"
Comparez le résultat à la pointe héritée fixe. Il s'agit d'un nouveau commit correctif qui conserve chaque commit d'origine au lieu de réécrire l'historique :
git --no-pager diff incident-tip HEAD
git --no-pager log -2 --oneline --decorate
git status --short
Vous devez retrouver uniquement la correction du pourcentage, votre réparation immédiatement après incident-tip et un état propre des fichiers suivis. Le message exact et les valeurs d'auteur ne sont pas le critère de réussite.
Exécutez le test préparé sur le véritable programme courant :
python3 /opt/labex/quote-desk/check.py
Tous les cas réussissent maintenant avec le code 0. Générez le devis du client :
python3 quote.py ../orders/gift.order
Vous devez obtenir la description actuelle du mug et la phrase d'accueil, la quantité 3, FRIEND10, le sous-total EUR 48.00, la réduction EUR 4.80, le total EUR 43.20 et les informations actuelles de retrait jusqu'au samedi à 16:00.
Livrez cette véritable sortie dans le répertoire préparé quotes. Comme enseigné, > enregistre la sortie standard dans ce fichier nommé ; il ne modifie ni la commande client ni le programme :
python3 quote.py ../orders/gift.order > ../quotes/mug-gift.txt
cat ../quotes/mug-gift.txt
Lisez le devis enregistré complet, et pas seulement son nom de fichier. Le fichier est le résultat utilisable par le client, tandis que le commit rend la correction réutilisable.
Vérifiez la commande normale et le produit ultérieur, qui doivent rester utilisables :
python3 quote.py ../orders/plain.order
python3 quote.py ../orders/new-item.order
Le mug sans réduction reste à EUR 16.00. Deux Trail pins avec STUDENT5 ont un sous-total de EUR 10.00, une réduction de EUR 0.50 et un total de EUR 9.50. Les deux devis conservent l'accueil et les détails de retrait actuels. Le point de contrôle observe le véritable commit courant, l'arbre complet préservé, le comportement de la frontière historique et le devis livré ; il ne note ni une transcription des commandes ni un mot-clé de message.
Résumé
Vous avez utilisé une commande client normale et une commande client défectueuse pour définir un test métier, classé des versions historiques manuellement et automatisé la même recherche avec Git bisect. Vous avez distingué sa référence du premier mauvais commit de HEAD, vérifié le candidat et son parent, retrouvé main et enregistré une réparation ciblée sans perdre les mises à jour ultérieures de la boutique. Le client a reçu un devis complet et correct.
Le challenge indépendant change le code de réduction, la commande client et la position de la panne, tout en utilisant le même programme fourni, les mêmes règles et le même format de test. Choisissez à partir des véritables éléments observés plutôt qu'en recopiant un décalage de commit.



