git cherry-pick : appliquer un commit précis sur une autre branche
git cherry-pick reprend les modifications d'un commit donné et crée sur la branche courante un nouveau commit avec le même diff et le même message, mais un hash différent. Placez-vous sur la branche cible et lancez git cherry-pick <hash> ; en cas de conflit, corrigez les fichiers, faites git add puis git cherry-pick --continue.
git cherry-pick applique les modifications d'un commit précis sur la branche courante, sans fusionner toute la branche. Git calcule le diff du commit choisi par rapport à son parent, l'applique sur votre HEAD et crée un nouveau commit — avec le même message et le même auteur, mais un hash différent, puisque son parent n'est pas le même.
Scénario typique : vous avez corrigé un bug dans une branche de fonctionnalité, et ce correctif doit partir d'urgence dans la branche de release, où la fonctionnalité n'est pas encore prête. Impossible de fusionner toute la branche, mais un seul commit, si.
Appliquer un commit sur une autre branche
Trouvez d'abord le hash du commit voulu, placez-vous sur la branche de destination et lancez le cherry-pick.
# 1. On repère le commit dans la branche feature
git log --oneline feature
a1b2c3d Corriger la division par zéro dans le calcul de remise
9f8e7d6 Ajouter le nouvel écran de paiement
# 2. On passe sur la branche cible
git switch release-1.4
# 3. On applique le commit
git cherry-pick a1b2c3d
[release-1.4 4e5f6a7] Corriger la division par zéro dans le calcul de remise
Date: Mon Oct 5 14:12:03 2026 +0300
1 file changed, 3 insertions(+), 1 deletion(-)
Remarquez que le nouveau commit a pour hash 4e5f6a7 et non a1b2c3d. Ce sont deux objets distincts avec les mêmes modifications. La branche d'origine feature reste inchangée.
À la place du hash, vous pouvez passer n'importe quelle référence de commit : git cherry-pick feature prendra le dernier commit de la branche feature, git cherry-pick feature~2 l'avant-avant-dernier.
Appliquer plusieurs commits
En les listant
Vous pouvez passer une liste de hashes — Git les appliquera dans l'ordre indiqué et créera autant de nouveaux commits.
git cherry-pick a1b2c3d 7c8d9e0 3f4a5b6
L'ordre compte : si le deuxième commit dépend du premier et que vous les listez à l'envers, vous obtiendrez un conflit ou du code cassé. Le plus sûr est de les indiquer du plus ancien au plus récent.
Avec une plage
Pour des commits consécutifs, on utilise la syntaxe de plage. Il y a ici un piège dans lequel presque tout le monde tombe : A..B signifie « les commits accessibles depuis B mais pas depuis A », donc A lui-même n'est pas inclus dans la plage.
# Applique les commits APRÈS A jusqu'à B inclus
git cherry-pick A..B
# Applique A et tout jusqu'à B inclus
git cherry-pick A^..B
Pour appliquer tout ce qui se trouve dans la branche feature et pas dans main, l'écriture git cherry-pick main..feature est pratique. Mais s'il y a beaucoup de commits, posez-vous la question : vous avez peut-être besoin d'un rebase ou d'un merge, pas d'un cherry-pick.
Options utiles de git cherry-pick
| Option | Effet | Quand l'utiliser |
|---|---|---|
-x | Ajoute au message la ligne « (cherry picked from commit …) » | Pour reporter des correctifs entre branches publiques — l'origine reste visible |
-n, --no-commit | Applique les modifications dans l'index et le répertoire de travail sans commiter | Pour regrouper plusieurs commits en un seul ou retoucher avant de commiter |
-e, --edit | Ouvre l'éditeur pour modifier le message | Pour adapter le message à la branche cible |
-s, --signoff | Ajoute une ligne Signed-off-by | Projets qui exigent un DCO |
-m 1 | Indique le parent « principal » d'un commit de merge | Pour reporter un commit de merge |
--ff | Avance la branche si HEAD est le parent du commit choisi | Rarement ; évite de créer un doublon |
--allow-empty | Autorise le report de commits vides à l'origine | Commits vides techniques |
À quoi sert -x
Dans six mois, quelqu'un verra un correctif dans la branche de release et voudra savoir d'où il vient. La ligne ajoutée par -x répond directement :
git cherry-pick -x a1b2c3d
git log -1
Corriger la division par zéro dans le calcul de remise
(cherry picked from commit a1b2c3d4e5f60718293a4b5c6d7e8f9012345678)
Utilisez -x quand le commit d'origine est déjà publié. Pour un report depuis votre branche locale que vous supprimerez ensuite, la référence ne mènerait nulle part — l'option est inutile dans ce cas.
Regrouper plusieurs commits en un : -n
git cherry-pick -n a1b2c3d 7c8d9e0
git status # les modifications des deux commits sont dans l'index
git commit -m "Correctifs du calcul de remise"
Résoudre les conflits de cherry-pick
Un conflit survient quand les modifications du commit ne s'appliquent pas sur le code actuel : dans la branche cible, les mêmes lignes ont déjà une autre forme. Git s'arrête et vous le signale.
git cherry-pick a1b2c3d
Auto-merging src/discount.js
CONFLICT (content): Merge conflict in src/discount.js
error: could not apply a1b2c3d... Corriger la division par zéro dans le calcul de remise
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
Vous avez alors trois options :
- Résoudre et continuer. Ouvrez le fichier, supprimez les marqueurs
<<<<<<<,=======,>>>>>>>en gardant la bonne version, puisgit add src/discount.jsetgit cherry-pick --continue. - Sauter le commit. Lors du report d'une liste,
git cherry-pick --skipignore le commit problématique et passe au suivant. - Tout annuler.
git cherry-pick --abortramène la branche à son état d'avant l'opération.
Il existe aussi git cherry-pick --quit : il interrompt l'opération mais conserve les commits déjà appliqués et l'état actuel des fichiers. Pratique quand la moitié de la liste est passée sans encombre et que vous voulez continuer à la main.
Si les mêmes conflits reviennent sans cesse (par exemple, si vous reportez régulièrement des correctifs dans plusieurs branches de release), activez git config rerere.enabled true — Git mémorisera votre résolution et l'appliquera automatiquement la fois suivante.
Cherry-pick d'un commit de merge
Un commit de merge a deux parents, et Git ne sait pas par rapport auquel calculer le diff. Sans indication, vous obtiendrez une erreur :
git cherry-pick 5d6e7f8
error: commit 5d6e7f8 is a merge but no -m option was given.
L'option -m 1 signifie : calcule les modifications par rapport au premier parent — généralement la branche dans laquelle on a fusionné. Vous reportez ainsi en un seul commit tout ce qu'a apporté la branche fusionnée.
git cherry-pick -m 1 5d6e7f8
Attention : Git ne considérera pas pour autant la branche comme fusionnée, et lors d'un merge ultérieur il pourra tenter d'appliquer à nouveau les mêmes modifications.
git cherry-pick ou git apply : quelle différence ?
On cite souvent git apply à côté de cherry-pick, car les deux commandes « appliquent des modifications ». Mais elles ne travaillent pas sur les mêmes données d'entrée.
| git cherry-pick | git apply | |
|---|---|---|
| Source | Un commit présent dans le dépôt | Un fichier patch (diff) |
| Crée un commit | Oui (sans -n) | Non, modifie seulement les fichiers (avec --index, aussi l'index) |
| Conserve l'auteur et le message | Oui | Non, ils ne figurent pas dans le patch |
| Conflits | Fusion à trois voies avec marqueurs | Par défaut, simple refus ; avec --3way, marqueurs |
| Nécessite un dépôt commun | Oui, le commit doit être disponible en local | Non, le patch peut être transmis par n'importe quel moyen |
Exemple d'utilisation de git apply quand le commit n'est pas dans votre dépôt — un collègue vous a envoyé un diff sous forme de fichier :
# Côté collègue
git diff main..fix-discount > fix.patch
# De votre côté, vous vérifiez et appliquez
git apply --check fix.patch # vérifier que le patch s'applique
git apply fix.patch # l'appliquer au répertoire de travail
git apply --3way fix.patch # en cas de divergences, avec marqueurs de conflit
Pour transmettre un commit complet, avec son auteur et son message, utilisez le duo git format-patch et git am : le premier enregistre les commits dans des fichiers, le second recrée des commits à partir d'eux. C'est en somme un cherry-pick « par e-mail ».
D'ailleurs, un cherry-pick depuis un autre dépôt est aussi possible : ajoutez-le comme remote, lancez git fetch, et ses commits deviennent accessibles par leur hash.
Quand cherry-pick est une mauvaise idée
Cherry-pick crée des doublons : une même modification vit dans l'historique sous deux hashes. À petite dose, c'est normal, mais dans certains cas il fait plus de mal que de bien.
- Reporter des dizaines de commits. Si vous reportez presque toute la branche, c'est un rebase ou un merge qu'il vous faut. Ici, cherry-pick produira un long historique de doublons et davantage de conflits.
- Reports dans les deux sens. Un commit a été reporté de feature vers main, puis feature est fusionnée dans main. Git s'en sort généralement (les modifications sont identiques), mais si les lignes ont été retouchées après le report, vous aurez un conflit tombé du ciel.
- Commits dépendants. Le commit utilise une fonction ajoutée deux commits plus tôt. Cherry-pick ne reporte que le commit lui-même, et le code ne compilera pas dans la branche cible. Vérifiez toujours le build et les tests après un report.
Une bonne pratique pour les hotfixes : faire le correctif directement dans la plus ancienne branche maintenue, puis le fusionner « vers le haut » dans les plus récentes. Cherry-pick ne sert alors qu'en cas exceptionnel.
Annuler un cherry-pick
Si l'opération est encore en cours (conflit) — git cherry-pick --abort. Si le commit est déjà créé mais pas encore poussé sur le serveur, supprimez-le :
git reset --hard HEAD~1
Si le commit a déjà été poussé sur une branche partagée, on ne réécrit pas l'historique — créez un commit inverse :
git revert 4e5f6a7
Et si vous avez fait un reset puis changé d'avis, le commit perdu se retrouve via git reflog.
Vérifier si un commit a déjà été reporté
Comme les hashes diffèrent, le classique git branch --contains ne sert à rien. Git sait comparer les commits selon le contenu de leurs modifications (patch-id) :
git cherry -v release-1.4 feature
- a1b2c3d Corriger la division par zéro dans le calcul de remise
+ 9f8e7d6 Ajouter le nouvel écran de paiement
Le moins signifie qu'une modification équivalente existe déjà dans release-1.4, le plus qu'elle n'y est pas encore. Autre option : git log --cherry-pick --oneline release-1.4...feature, qui masque les commits jumeaux. Si vous avez utilisé -x, il suffit de chercher dans les messages : git log --grep="cherry picked from commit a1b2c3d".
En résumé
git cherry-pick est un outil chirurgical : reporter un hotfix dans une release, récupérer un commit utile dans une branche abandonnée, rattraper un commit fait sur la mauvaise branche. Retenez trois choses : le nouveau commit reçoit un nouveau hash, la plage A..B n'inclut pas A, et pour les branches publiques mieux vaut ajouter -x. Si vous devez appliquer non pas un commit mais un diff depuis un fichier, utilisez git apply. Rebase, stash, cherry-pick et les tags sont mis en pratique en détail dans le cours Git.
Questions fréquentes
Le cherry-pick modifie-t-il la branche d'origine ?
Non. Le commit d'origine reste en place, et une copie avec un nouveau hash apparaît dans la branche courante.
Peut-on faire un cherry-pick d'un commit d'une branche distante ?
Oui. Lancez git fetch : le commit devient alors accessible par son hash ou via origin/nom-de-branche, et vous pouvez le passer à git cherry-pick.
Pourquoi le commit a-t-il un hash différent après un cherry-pick ?
Le hash dépend du parent, de la date du commit et du contenu de l'arbre. La copie a un autre parent et une autre date de committer, donc un autre hash.
L'auteur du commit est-il conservé lors d'un cherry-pick ?
Oui, l'auteur et la date de création proviennent du commit d'origine, tandis que vous devenez le committer, avec la date actuelle.
Que faire si cherry-pick indique que le commit est vide ?
Cela signifie que ces modifications sont déjà présentes dans la branche. Sautez-le avec git cherry-pick --skip ou enregistrez-le vide avec git commit --allow-empty.
Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».
Voir le cours