Arc 3 Quête 12

L'Oracle du Code

git blame, git bisect, git cherry-pick

Introduction

Dans les profondeurs de la Citadelle du Savoir, le Maître Archiviste te conduit à travers un couloir que tu n'avais jamais remarqué. Derrière une lourde porte de chêne renforcée de fer noir, une salle circulaire s'ouvre devant toi. Au centre, un miroir ancien flotte dans les airs, entouré de runes lumineuses. Des parchemins s'empilent sur des étagères qui semblent se perdre dans l'obscurité.

« Apprenti, tu as prouvé ta maîtrise des fondamentaux. Il est temps de te révéler les arts anciens de la divination. Vois-tu ce miroir ? C'est l'Oracle du Code. Grâce à lui, tu pourras remonter le temps pour trouver l'origine d'une corruption, identifier qui a écrit chaque ligne d'un parchemin, et même transplanter chirurgicalement un fragment d'une chronique à une autre. Ces trois arts sont redoutables entre les mains d'un Archiviste expérimenté. »

L'art de la divination : git blame

La première compétence de l'Oracle est la divination : savoir qui a écrit chaque ligne d'un fichier, et quand.

git blame <fichier>

Cette commande affiche chaque ligne du fichier avec :

  • Le hash du commit qui l'a modifiée en dernier
  • Le nom de l'auteur
  • La date de la modification
  • Le numéro de ligne
  • Le contenu de la ligne

Exemple de sortie :

a1b2c3d4 (Aldric le Scribe  2024-01-15 09:00:00 +0100  1) Registre des créatures
e5f6g7h8 (Elara la Sage     2024-02-05 16:30:00 +0100  2) Dernière mise à jour : an 1024

Blame sur une plage de lignes

Tu n'as pas toujours besoin de voir tout le fichier. Pour examiner uniquement les lignes 10 à 20 :

git blame -L 10,20 <fichier>

Tu peux aussi utiliser d'autres formats :

git blame -L 10,+5 <fichier>    # 5 lignes à partir de la ligne 10

Quand utiliser git blame ? Quand tu tombes sur une ligne de code étrange et que tu veux savoir qui l'a écrite, quand, et surtout dans quel commit - pour lire le message du commit et comprendre le contexte.

La recherche binaire : git bisect

Le deuxième art de l'Oracle est la recherche binaire dans l'historique. Imagine : ton programme fonctionnait il y a 10 commits, mais il est cassé maintenant. Le bug a été introduit quelque part entre ces 10 commits. Tu pourrais les tester un par un... ou laisser l'Oracle couper l'historique en deux à chaque étape.

C'est le principe de git bisect : une recherche dichotomique dans l'historique de Git.

Comment ça marche ?

  1. Démarre la recherche :
    git bisect start
  2. Indique que la version actuelle est cassée :
    git bisect bad
  3. Indique un commit où tout fonctionnait :
    git bisect good <commit>
  4. Git te place automatiquement au milieu de l'historique. Tu testes, puis tu dis à Git si cette version est bonne ou mauvaise :
    git bisect good    # si ça marche ici
    git bisect bad     # si c'est cassé ici
  5. Git coupe encore en deux. Tu testes à nouveau. Et ainsi de suite, jusqu'à trouver le commit exact qui a introduit le bug.
  6. Termine la recherche et reviens à ta branche normale :
    git bisect reset

Pourquoi c'est puissant ? Avec 10 commits, tu trouves le coupable en 3-4 tests au lieu de 10. Avec 1000 commits, tu le trouves en environ 10 tests. C'est la magie de la recherche binaire !

La chirurgie : git cherry-pick

Le troisième art de l'Oracle est la transplantation chirurgicale. Parfois, tu as besoin d'appliquer un seul commit spécifique d'une branche vers une autre, sans fusionner toute la branche.

git cherry-pick <hash-du-commit>

Cette commande prend les modifications d'un commit précis et les rejoue sur ta branche courante, créant un nouveau commit avec les mêmes changements (mais un hash différent).

Quand utiliser cherry-pick ?

  • Hotfix urgent : un correctif a été fait sur une branche de développement, mais tu dois l'appliquer immédiatement sur main sans attendre la fusion complète.
  • Porter un changement : une fonctionnalité développée sur une branche doit aussi être appliquée sur une autre branche de maintenance.
  • Récupérer un commit isolé : tu veux un commit précis d'une branche expérimentale, pas toute la branche.

Cherry-pick et conflits

Comme pour un merge, un cherry-pick peut provoquer des conflits si les modifications du commit entrent en contradiction avec l'état actuel de ta branche.

Dans ce cas, Git s'arrête et te demande de résoudre le conflit manuellement :

  1. Ouvre le fichier en conflit
  2. Résous les marqueurs de conflit (<<<<<<<, =======, >>>>>>>)
  3. Marque comme résolu et continue :
    git add <fichier>
    git cherry-pick --continue

Pour annuler un cherry-pick en cours :

git cherry-pick --abort

git cherry-pick crée un nouveau commit avec un hash différent. Cela signifie que si tu fais plus tard un merge de la branche source, le même changement existera en double (deux commits différents, mêmes modifications). Utilise cherry-pick avec discernement - pour des cas précis, pas comme méthode de fusion par défaut.

Exercice pratique - L'Oracle du Code

Une ancienne archive du royaume a été corrompue. Un bug s'est glissé dans le Grimoire des Sortilèges - quelque part dans l'historique, une formule magique a été sabotée. L'Oracle va t'aider à retrouver l'origine de la corruption, identifier le responsable, et appliquer chirurgicalement un correctif.

Étape 1 - Récupérer l'archive

git clone archive.bundle loracle-du-code
cd loracle-du-code

Étape 2 - Examiner avec blame

Commence par examiner le Grimoire des Sortilèges :

git blame grimoire.txt

Observe qui a modifié chaque ligne et quand. Examine ensuite une section précise :

git blame -L 15,25 grimoire.txt

Le git blame te montre le hash du commit responsable de chaque ligne. Tu peux ensuite utiliser git show <hash> pour voir les détails complets du commit.

Étape 3 - Trouver le bug avec bisect

Le grimoire contient une erreur : une formule a été corrompue (la ligne contient le mot CORROMPU). Cette erreur n'était pas présente au premier commit. Utilise git bisect pour trouver le commit exact :

git bisect start
git bisect bad                    # la version actuelle contient le bug
git bisect good <premier-commit>  # le tout premier commit était bon

Remplace <premier-commit> par le hash du premier commit (visible avec git log --oneline).

À chaque étape, vérifie si le mot CORROMPU apparaît dans grimoire.txt :

grep CORROMPU grimoire.txt
  • Si le mot apparaît : git bisect bad
  • Si le mot n'apparaît pas : git bisect good

Continue jusqu'à ce que Git identifie le commit coupable. Note le hash, puis termine :

git bisect reset

Étape 4 - Appliquer le correctif avec cherry-pick

Bonne nouvelle : un Archiviste a déjà préparé un correctif sur la branche correctif. Comme le dépôt a été cloné depuis un bundle, cette branche est distante - on la référence avec le préfixe origin/. Regarde quel commit s'y trouve :

git log --oneline origin/correctif

Le dernier commit de cette branche contient le correctif. Applique-le sur main avec cherry-pick :

git cherry-pick <hash-du-correctif>

Vérifie que le grimoire ne contient plus le mot CORROMPU :

grep CORROMPU grimoire.txt

Si le cherry-pick provoque un conflit, pas de panique ! Ouvre le fichier, résous le conflit manuellement en gardant la version corrigée, puis fais git add grimoire.txt et git cherry-pick --continue.

Étape 5 - Vérifier

Lance le script de vérification pour valider ta quête :

Bash (Linux / macOS / Git Bash sur Windows) :

bash verifier.sh

PowerShell (Windows) :

.\verifier.ps1

Le script vérifie :

  1. Tu es dans un dépôt Git
  2. Tu as utilisé git bisect (trace dans le reflog)
  3. Tu as utilisé git cherry-pick (trace dans le reflog)
  4. Le grimoire ne contient plus le mot CORROMPU

Récapitulatif des commandes

Commande Description
git blame <fichier> Voir qui a modifié chaque ligne et quand
git blame -L 10,20 <fichier> Blame sur une plage de lignes spécifique
git bisect start Démarrer une recherche binaire dans l'historique
git bisect bad Marquer la version courante comme cassée
git bisect good <commit> Marquer un commit comme fonctionnel
git bisect reset Terminer la recherche et revenir à la normale
git cherry-pick <commit> Appliquer un commit spécifique sur la branche courante
git cherry-pick --abort Annuler un cherry-pick en cours

Le Maître Archiviste observe le miroir de l'Oracle, où le reflet de l'historique corrigé scintille doucement.

« Tu maîtrises maintenant les arts de la divination. Avec blame, tu sais qui a écrit quoi et quand. Avec bisect, tu peux traquer un bug à travers des centaines de commits en quelques minutes. Et avec cherry-pick, tu sais transplanter chirurgicalement un correctif là où il est nécessaire. Ces outils font de toi bien plus qu'un simple Archiviste - tu es désormais un enquêteur du code. »