Appliquer un correctif avec cherry-pick
- Leçon 14
- 45 min
- Module 5 : Mises en production et correctifs urgents
Leçon 14 sur 15 · L'essentiel de Git et du développement en équipeAppliquer un correctif avec cherry-pick
1. Comprendre un dépôt
2. Travailler avec les branches et les dépôts distants
3. Collaborer par la revue de code
4. Résoudre et récupérer
5. Mises en production et correctifs urgents
Ce que vous saurez faire
Corrigez un bogue dans une version publiée sans publier du travail inachevé. Vous copiez un commit (enregistrement de changements) de main vers la branche de version. Vous pouvez prouver que rien d’autre ne l’accompagne.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Ce que sont
main,release/1.0etv1.0.0, expliqué dans Branches de version et étiquettes : l’équipe publie une version. - Comment ouvrir une demande de tirage simulée et la fusionner avec
git merge --no-ff, expliqué dans Les étapes d’une demande de tirage : 8. Fusionner. - Comment résoudre un conflit et annuler un commit, expliqué dans Les conflits, étape par étape : résoudre, tester et créer un commit et Annuler en toute sécurité : l’annuler avec revert.
Ce qu’il vous faut sur votre ordinateur
- Le dossier
~/projects/nextia-learning-labs. Vous l’avez cloné dans Les étapes d’une demande de tirage : préparer le laboratoire d’exercice. S’il manque, faites l’étape 2 de cette section. - Cette leçon utilise l’état d’exercice
hotfix. Vous le créez dans Préparer l’état d’exercice. La commande de préparation supprime votre dossierc14-labet le recrée. Cet état contient déjàrelease/1.0etv1.0.0. Vous n’avez donc pas besoin de votre travail de la leçon précédente.
Un bogue dans la version 1.0
Section intitulée « Un bogue dans la version 1.0 »Le centre d’assistance utilise la version 1.0. Il appelle l’équipe réseau au poste 4410, mais personne ne répond. Le bon poste est le 4401.
Sam a déjà corrigé ce problème sur main. Mais main contient deux autres nouveaux commits depuis la publication :
| Commit | Message | Peut-il faire partie d’un correctif pour la version 1.0? |
|---|---|---|
3cf73f7 |
Commencer l’exportation des billets (inachevée) | Non. Le travail n’est pas terminé. |
aeeb4b6 |
Corriger le poste de l’équipe réseau | Oui. C’est le correctif. |
3f4d833 |
Ajouter le billet 105 | Non. C’est du nouveau contenu, pas un correctif. |
Si l’équipe fusionne main dans release/1.0, les trois commits entrent dans la version. Le centre d’assistance reçoit alors une exportation inachevée. L’équipe a seulement besoin de aeeb4b6.
Un correctif urgent (hotfix) corrige une version que des gens utilisent déjà. L’équipe le publie comme une version PATCH (corrective), ici v1.0.1.
Cherry-pick (copie sélective) copie le changement d’un commit sur votre branche actuelle, sous forme d’un nouveau commit. Git lit le diff (les différences) du commit choisi et l’applique à votre branche. Le nouveau commit conserve le même message et le même auteur. Son identifiant de hachage est différent, car son parent est différent.
Le correctif et sa copie ont la même couleur, car ils contiennent le même changement. Ce sont des commits distincts, avec des identifiants de hachage différents.
La séquence du correctif urgent
Section intitulée « La séquence du correctif urgent »Chaque étape se déroule sur une branche connue. Vérifiez la branche avant chaque commande.
| Étape | Branche actuelle | Source → cible de la demande de tirage |
|---|---|---|
| 1. Trouver et examiner le correctif | release/1.0 |
aucune |
| 2. Créer la branche du correctif urgent | release/1.0 → hotfix/1.0.1 |
aucune |
| 3. Copier avec cherry-pick, vérifier, pousser | hotfix/1.0.1 |
aucune |
| 4. Ouvrir et réviser la demande de tirage | hotfix/1.0.1 |
hotfix/1.0.1 → release/1.0 |
| 5. Fusionner, étiqueter, pousser | release/1.0 |
hotfix/1.0.1 → release/1.0 (fusionnée) |
Le correctif entre dans la version par une demande de tirage, comme les autres changements. La cible est release/1.0, pas main.
Préparer l’état d’exercice
Section intitulée « Préparer l’état d’exercice »-
Exécutez le script de préparation avec le scénario
hotfix:Terminal cd ~/projectssh nextia-learning-labs/C14/setup.sh hotfix --resetcd c14-lab/ticket-notesLa sortie commence par
Ready:(prêt). -
Consultez toutes les références :
Terminal git log --oneline --graph --all --decorate -5Sortie * 3f4d833 (HEAD -> main, origin/main, origin/HEAD) Add ticket 105* aeeb4b6 Fix the network team extension* 3cf73f7 Start the ticket export (not finished)* 465d7ea (tag: v1.0.0, origin/release/1.0) Add escalation rules* f330fdc Add ticket 104Vous avez la branche distante
origin/release/1.0, mais pas encore de branche localerelease/1.0.
Exemple détaillé : publier la version 1.0.1
Section intitulée « Exemple détaillé : publier la version 1.0.1 »1. Trouver le correctif
Section intitulée « 1. Trouver le correctif »Branche actuelle : main. Amira passe à release/1.0. Git crée une branche locale qui suit origin/release/1.0 :
git switch release/1.0Switched to a new branch 'release/1.0'branch 'release/1.0' set up to track 'origin/release/1.0'.Branche actuelle : release/1.0. Elle liste les commits présents sur main, mais absents de release/1.0. A..B signifie « les commits dans B qui ne sont pas dans A » :
git log --oneline release/1.0..main3f4d833 Add ticket 105aeeb4b6 Fix the network team extension3cf73f7 Start the ticket export (not finished)2. Examiner le correctif
Section intitulée « 2. Examiner le correctif »Le message d’un commit décrit le changement, mais le diff est le changement lui-même. Amira lit le diff avant de le copier :
git show aeeb4b6commit aeeb4b6389efc1d6d75e474e911499fc5fe73e12Author: Sam Okafor <sam@example.com>Date: Tue Oct 6 09:12:00 2026 -0400
Fix the network team extension
diff --git a/contacts.txt b/contacts.txtindex 0ce0116..48d016f 100644--- a/contacts.txt+++ b/contacts.txt@@ -1,3 +1,3 @@ Help desk: ext. 4100Network team: ext. 4410Network team: ext. 4401 Accounts team: ext. 4300Le commit modifie une ligne dans un seul fichier. Il fait ce que le message annonce.
3. Vérifier les dépendances
Section intitulée « 3. Vérifier les dépendances »Un correctif dépend d’un commit précédent quand il modifie des lignes ajoutées par ce commit. Si ce commit précédent est absent de la version, le correctif ne peut pas s’y appliquer. Amira se pose deux questions.
La version contient-elle les lignes que le correctif modifie? Elle affiche contacts.txt tel qu’il est sur release/1.0 :
git show release/1.0:contacts.txtHelp desk: ext. 4100Network team: ext. 4410Accounts team: ext. 4300La version contient la ligne Network team: ext. 4410 (équipe réseau : poste 4410), identique à celle que le correctif supprime. Le correctif peut donc s’appliquer.
Le correctif a-t-il besoin d’un autre commit de main? Le seul commit entre la version et le correctif est celui de l’exportation. --stat affiche les fichiers qu’il a modifiés :
git show --stat 3cf73f7 Start the ticket export (not finished)
export.txt | 2 ++ 1 file changed, 2 insertions(+)L’exportation a seulement modifié export.txt. Le correctif a seulement modifié contacts.txt. Le correctif n’a pas besoin de l’exportation.
4. Créer la branche du correctif urgent à partir de la version
Section intitulée « 4. Créer la branche du correctif urgent à partir de la version »Branche actuelle : release/1.0. Amira crée la branche du correctif urgent ici, pas sur main. Une branche part du commit où vous vous trouvez, et le correctif doit aller dans la version :
git switch -c hotfix/1.0.1Switched to a new branch 'hotfix/1.0.1'5. Copier le correctif avec cherry-pick
Section intitulée « 5. Copier le correctif avec cherry-pick »Branche actuelle : hotfix/1.0.1. L’option -x ajoute une ligne au message du nouveau commit. Cette ligne indique le commit d’origine pour que chacun puisse retrouver la source de la copie.
git cherry-pick -x aeeb4b6[hotfix/1.0.1 19b64c1] Fix the network team extension Author: Sam Okafor <sam@example.com> Date: Tue Oct 6 09:12:00 2026 -0400 1 file changed, 1 insertion(+), 1 deletion(-)Le nouveau commit est 19b64c1. Votre identifiant de hachage est différent, car vous avez fait la copie à un autre moment. Git a gardé Sam comme auteur, car il a écrit le changement. Le message complet montre la ligne ajoutée par -x :
git log -1commit 19b64c13a2bb62fa029d4884fc18af8816ff3f1dAuthor: Sam Okafor <sam@example.com>Date: Tue Oct 6 09:12:00 2026 -0400
Fix the network team extension
(cherry picked from commit aeeb4b6389efc1d6d75e474e911499fc5fe73e12)Le graphe montre maintenant la copie sur sa propre ligne, à partir de v1.0.0 :
git log --oneline --graph --all --decorate -6* 19b64c1 (HEAD -> hotfix/1.0.1) Fix the network team extension| * 3f4d833 (origin/main, origin/HEAD, main) Add ticket 105| * aeeb4b6 Fix the network team extension| * 3cf73f7 Start the ticket export (not finished)|/* 465d7ea (tag: v1.0.0, origin/release/1.0, release/1.0) Add escalation rules* f330fdc Add ticket 1046. Vérifier, pousser et ouvrir la demande de tirage
Section intitulée « 6. Vérifier, pousser et ouvrir la demande de tirage »Branche actuelle : hotfix/1.0.1. Amira lance la vérification, puis pousse la branche :
sh check.shgit push -u origin hotfix/1.0.1PASS: 4 ticket lines checkedTo /Users/amira/projects/c14-lab/team-remote.git * [new branch] hotfix/1.0.1 -> hotfix/1.0.1branch 'hotfix/1.0.1' set up to track 'origin/hotfix/1.0.1'.Demande de tirage : source hotfix/1.0.1 → cible release/1.0. C’est une demande de tirage simulée, comme dans le module 3. Sam, qui fait la révision, vérifie le diff que la demande de tirage ajoute à la version :
git diff release/1.0...hotfix/1.0.1diff --git a/contacts.txt b/contacts.txtindex 0ce0116..48d016f 100644--- a/contacts.txt+++ b/contacts.txt@@ -1,3 +1,3 @@ Help desk: ext. 4100-Network team: ext. 4410+Network team: ext. 4401 Accounts team: ext. 4300Le diff contient une ligne modifiée. Aucune exportation, aucun billet 105. Sam approuve.
7. Fusionner, étiqueter et pousser
Section intitulée « 7. Fusionner, étiqueter et pousser »Branche actuelle : release/1.0. Amira passe à la cible de la demande de tirage et la fusionne :
git switch release/1.0git merge --no-ff --no-edit hotfix/1.0.1Merge made by the 'ort' strategy. contacts.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)Branche actuelle : release/1.0. Elle étiquette la version, puis pousse la branche et l’étiquette :
git tag -a v1.0.1 -m "Help desk notes 1.0.1"git pushgit push origin v1.0.1To /Users/amira/projects/c14-lab/team-remote.git 465d7ea..257b55a release/1.0 -> release/1.0To /Users/amira/projects/c14-lab/team-remote.git * [new tag] v1.0.1 -> v1.0.18. Prouver le résultat
Section intitulée « 8. Prouver le résultat »Amira prouve que la version 1.0.1 contient le correctif, et rien d’autre. D’abord, les fichiers modifiés entre les deux versions :
git diff v1.0.0 v1.0.1 --stat contacts.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)Ensuite, les commits présents dans 1.0.1, mais absents de 1.0.0 :
git log --oneline v1.0.0..v1.0.1257b55a Merge branch 'hotfix/1.0.1' into release/1.019b64c1 Fix the network team extensionEnfin, l’exportation inachevée est absente de la version :
git show v1.0.1:export.txtfatal: path 'export.txt' does not exist in 'v1.0.1'Cette erreur est le résultat qu’elle souhaite. Le graphe complet correspond maintenant au schéma du début de la leçon :
* 257b55a (HEAD -> release/1.0, tag: v1.0.1, origin/release/1.0) Merge branch 'hotfix/1.0.1' into release/1.0|\| * 19b64c1 (origin/hotfix/1.0.1, hotfix/1.0.1) Fix the network team extension|/| * 3f4d833 (origin/main, origin/HEAD, main) Add ticket 105| * aeeb4b6 Fix the network team extension| * 3cf73f7 Start the ticket export (not finished)|/* 465d7ea (tag: v1.0.0) Add escalation rules* f330fdc Add ticket 104* e058b3f Add ticket 103Exercice guidé : publier la version 1.0.1
Section intitulée « Exercice guidé : publier la version 1.0.1 »-
Exécutez la préparation de Préparer l’état d’exercice. Vous êtes sur
maindansticket-notes. -
Passez à la branche de version :
Terminal git switch release/1.0Branche actuelle :
release/1.0. La sortie contientset up to track 'origin/release/1.0'(configurée pour suivre « origin/release/1.0 »). -
Exécutez
git log --oneline release/1.0..main. La sortie liste trois commits. Notez l’identifiant de hachage deFix the network team extension(corriger le poste de l’équipe réseau). -
Exécutez
git show aeeb4b6. Vérifiez qu’il modifie seulement la ligne de l’équipe réseau danscontacts.txt. -
Exécutez
git show release/1.0:contacts.txt. Vérifiez que la version contientNetwork team: ext. 4410. -
Créez la branche du correctif urgent à partir de la version :
Terminal git switch -c hotfix/1.0.1Branche actuelle :
hotfix/1.0.1. -
Copiez le correctif :
Terminal git cherry-pick -x aeeb4b6La sortie commence par
[hotfix/1.0.1et un nouvel identifiant de hachage. -
Exécutez
git log -1. Le message se termine par(cherry picked from commit aeeb4b6...)(copié depuis le commit aeeb4b6…). -
Exécutez
sh check.sh. La sortie commence parPASS(réussite). -
Poussez la branche du correctif urgent :
Terminal git push -u origin hotfix/1.0.1 -
Révisez la demande de tirage simulée, source
hotfix/1.0.1→ ciblerelease/1.0:Terminal git diff release/1.0...hotfix/1.0.1Le diff montre une ligne modifiée dans
contacts.txt, et rien d’autre. -
Passez à la branche cible et fusionnez :
Terminal git switch release/1.0git merge --no-ff --no-edit hotfix/1.0.1Branche actuelle :
release/1.0. La sortie contientMerge made by the 'ort' strategy.(fusion effectuée avec la stratégie « ort »). -
Étiquetez la version :
Terminal git tag -a v1.0.1 -m "Help desk notes 1.0.1" -
Poussez la branche, puis l’étiquette :
Terminal git pushgit push origin v1.0.1 -
Exécutez
git diff v1.0.0 v1.0.1 --stat. La sortie liste seulementcontacts.txt. -
Exécutez
git show v1.0.1:export.txt. La sortie estfatal: path 'export.txt' does not exist in 'v1.0.1'(erreur fatale : le chemin « export.txt » n’existe pas dans « v1.0.1 »).
À vous de jouer : version 1.0.2
Section intitulée « À vous de jouer : version 1.0.2 »Sam trouve un deuxième bogue : le poste de l’équipe de comptabilité est 4310, et non 4300. Vous jouez les deux rôles. Partez de la fin de l’exercice guidé.
- Dans le rôle de Sam, dans
sam-notes, corrigez la ligne decontacts.txtsurmain. Créez un commit (enregistrement des modifications) avec le messageFix the accounts team extension(corriger le poste de l’équipe de comptabilité), puis poussez-le. - Dans le rôle d’Amira, dans
ticket-notes, publiez la correction dans la version 1.0.2. - Pour chaque étape, indiquez la branche courante et, s’il y a une demande de tirage, ses branches source et cible.
Deux règles s’appliquent. Add ticket 105 (ajouter le billet 105) ajoute du contenu; ce n’est pas une correction. Il ne doit donc pas faire partie de la version. La version ne doit pas contenir export.txt.
Afficher une réponse modèle
| Étape | Où | Branche courante | Source → cible de la demande de tirage |
|---|---|---|---|
| Sam tire, corrige, crée un commit et pousse | sam-notes |
main |
aucune (dans une vraie équipe : fix-accounts → main) |
| Amira tire la correction | ticket-notes |
main |
aucune |
| Trouver et examiner la correction | ticket-notes |
main |
aucune |
| Créer la branche de correction urgente | ticket-notes |
release/1.0 → hotfix/1.0.2 |
aucune |
| Copier le commit par cherry-pick, vérifier et pousser | ticket-notes |
hotfix/1.0.2 |
aucune |
| Réviser | ticket-notes |
hotfix/1.0.2 |
hotfix/1.0.2 → release/1.0 |
Fusionner, créer l’étiquette v1.0.2 et pousser |
ticket-notes |
release/1.0 |
hotfix/1.0.2 → release/1.0 (fusionnée) |
Dans le rôle de Sam, récupérez la dernière version de main. Dans votre éditeur, remplacez ensuite Accounts team: ext. 4300 (équipe de comptabilité : poste 4300) par Accounts team: ext. 4310 (équipe de comptabilité : poste 4310). Créez un commit et poussez-le :
cd ../sam-notesgit pullgit commit -am "Fix the accounts team extension"git pushDans le rôle d’Amira, trouvez la correction. git log affiche quatre commits, car la copie de la première correction a une empreinte différente de l’original de Sam. La prochaine leçon explique pourquoi.
cd ../ticket-notesgit switch maingit pullgit log --oneline release/1.0..main772b7bf Fix the accounts team extension3f4d833 Add ticket 105aeeb4b6 Fix the network team extension3cf73f7 Start the ticket export (not finished)Copiez seulement 772b7bf (votre empreinte sera différente). Vérifiez-le d’abord avec git show 772b7bf.
git switch release/1.0git switch -c hotfix/1.0.2git cherry-pick -x 772b7bfsh check.shgit push -u origin hotfix/1.0.2git diff release/1.0...hotfix/1.0.2git switch release/1.0git merge --no-ff --no-edit hotfix/1.0.2git tag -a v1.0.2 -m "Help desk notes 1.0.2"git pushgit push origin v1.0.2Prouvez le résultat :
git diff v1.0.1 v1.0.2 --statgit log --oneline v1.0.1..v1.0.2 contacts.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)3a01c9f Merge branch 'hotfix/1.0.2' into release/1.09e8c739 Fix the accounts team extensiongit show v1.0.2:tickets.txt se termine par le billet 104. Le billet 105 ne fait donc pas partie de la version.
Erreur courante
Le cherry-pick s'arrête à cause d'un conflit
Symptôme : Sam a modifié le texte du billet 105 sur main, dans un commit nommé Fix the wording of ticket 105 (corriger le texte du billet 105). Sur hotfix/1.0.1, vous essayez de le copier :
git cherry-pick -x bd75493Auto-merging tickets.txtCONFLICT (content): Merge conflict in tickets.txterror: could not apply bd75493... Fix the wording of ticket 105git status affiche You are currently cherry-picking commit bd75493 (vous copiez actuellement le commit bd75493 par cherry-pick) et both modified: tickets.txt (modifié des deux côtés : tickets.txt).
Cause : le commit dépend d’un commit absent de la version. Il modifie la ligne du billet 105, qui provient de Add ticket 105. La version n’a pas cette ligne :
git show release/1.0:tickets.txtTicket 101: printer offline. Restarted the spooler.Ticket 102: password reset email not received.Ticket 103: shared drive is slow. Moved the user to the new server.Ticket 104: laptop will not charge. Replaced the power adapter.Correction :
-
Arrêtez le cherry-pick. Git remet la branche dans son état précédent :
Terminal git cherry-pick --abortgit statusSortie On branch hotfix/1.0.1nothing to commit, working tree clean -
Décidez avec votre équipe. Ici, la version n’a pas de billet 105, donc elle n’a pas besoin de cette correction. Ne copiez pas ce commit.
Si une vraie correction dépend d’un commit précédent, vous devez aussi copier ce commit ou réécrire la correction pour la version. Ne résolvez pas le conflit en ajoutant des lignes que la version n’a jamais eues. Exécutez toujours git show avant de copier un commit pour repérer d’abord la dépendance.
Erreur courante
J'ai copié le mauvais commit
Symptôme : vous avez copié 3cf73f7 au lieu de la correction, puis poussé la branche de correction urgente. La révision de la demande de tirage montre le mauvais fichier :
git diff release/1.0...hotfix/1.0.1 --stat export.txt | 2 ++ 1 file changed, 2 insertions(+)Cause : les empreintes 3cf73f7 et aeeb4b6 se trouvent sur des lignes voisines dans git log. Il est facile de copier la mauvaise.
Correction : sur hotfix/1.0.1, avant de fusionner la demande de tirage :
-
Annulez la mauvaise copie :
Terminal git revert --no-edit HEADOutput (first line) [hotfix/1.0.1 38d6b6e] Revert "Start the ticket export (not finished)" -
Copiez le bon commit :
git cherry-pick -x aeeb4b6. -
Révisez de nouveau les différences de la demande de tirage :
Terminal git diff release/1.0...hotfix/1.0.1 --statSortie contacts.txt | 2 +-1 file changed, 1 insertion(+), 1 deletion(-) -
Poussez et demandez une nouvelle révision.
Les différences sont maintenant correctes. L’historique de la branche de correction urgente montre encore l’erreur et son annulation. C’est honnête et sûr.
Vérifiez votre compréhension
Prédisez : vous copiez aeeb4b6 sur hotfix/1.0.1 par cherry-pick. Le nouveau commit a-t-il l'empreinte aeeb4b6? Après la fusion de la correction urgente, git log release/1.0..main affiche-t-il encore aeeb4b6?
Afficher la réponse
Non à la première question. La copie est un nouveau commit avec une nouvelle empreinte, car son parent est différent. Oui à la deuxième : release/1.0 contient la copie, et non aeeb4b6 lui-même. Donc, git log release/1.0..main affiche encore aeeb4b6. La ligne -x permet de retrouver l’original à partir de la copie.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Vérification pratique : prouvez que v1.0.1 contient la correction, mais ne contient ni l'exportation inachevée ni le billet 105.
Afficher la réponse
git show v1.0.1:contacts.txtafficheNetwork team: ext. 4401(équipe réseau : poste 4401).git diff v1.0.0 v1.0.1 --stataffiche seulementcontacts.txt.git log --oneline v1.0.0..v1.0.1affiche seulement la copie de la correction et le commit de fusion.git show v1.0.1:export.txtéchoue avecdoes not exist(n’existe pas), etgit show v1.0.1:tickets.txtse termine par le billet 104.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Le cherry-pick copie les modifications d’un commit sur votre branche courante, dans un nouveau commit avec une nouvelle empreinte.
- Utilisez
git log --oneline release/1.0..mainpour trouver la correction, puisgit showpour la lire avant de la copier. - Vérifiez les dépendances : la version doit avoir les lignes que la correction modifie. La correction ne doit pas nécessiter d’autres commits de
main. - Créez
hotfix/1.0.1à partir derelease/1.0, copiez le commit avec-x, puis ouvrez une demande de tirage ciblantrelease/1.0. - Créez l’étiquette
v1.0.1sur le résultat fusionné, poussez l’étiquette et vérifiez la version avecgit diff v1.0.0 v1.0.1 --stat.
Leçon suivante : Garder des historiques cohérents