Aller au contenu principal

git cherry-pick & git bisect — Chirurgie de précision

Module 05 45 min

Objectifs de la section​

  • Utiliser git cherry-pick pour appliquer des commits spécifiques à une autre branche
  • Utiliser git bisect pour trouver le commit qui a introduit un bug
  • Connaître les limitations et cas d'usage de ces commandes

git cherry-pick — Appliquer des commits spécifiques​

git cherry-pick prend un commit d'une branche et l'applique à une autre, créant un nouveau commit avec les mêmes changements (hash différent).

Utilisation de base​

# Cherry-pick d'un seul commit
git cherry-pick abc1234

# Cherry-pick de plusieurs commits
git cherry-pick abc1234 def5678 ghi9012

# Cherry-pick d'une plage de commits (exclusif du premier)
git cherry-pick abc1234..def5678

# Cherry-pick sans créer de commit (staging uniquement)
git cherry-pick --no-commit abc1234

# Cherry-pick en éditant le message de commit
git cherry-pick -e abc1234

Gérer les conflits de cherry-pick​

# Si un conflit se produit :
# 1. Corriger le conflit
git status # Affiche les fichiers en conflit
# éditer les fichiers...
git add fichier-corrige.py

# 2. Continuer
git cherry-pick --continue

# OU : Abandonner
git cherry-pick --abort

# OU : Ignorer ce commit
git cherry-pick --skip

Quand utiliser cherry-pick​

ScénarioUtiliser cherry-pick ?Alternative
Correction critique nécessaire sur la branche release✅ Oui-
Commit accidentellement sur la mauvaise branche✅ Oui-
Réutiliser une fonction utilitaire d'une autre branche✅ Oui-
Intégrer toute une fonctionnalité❌ NonMerge ou rebase
Synchronisation régulière des branches❌ NonMerge ou rebase
Cherry-pick vs Merge

Cherry-pick crée une copie du commit (nouveau hash). Si vous fusionnez ensuite la branche originale, Git verra ces changements en double. Utilisez cherry-pick avec parcimonie et pour des cas spécifiques.

Exemples pratiques​

# Scénario 1 : Correction critique nécessaire sur la branche release
git switch release/v1.0
git cherry-pick hash-du-commit-hotfix
git push origin release/v1.0

# Scénario 2 : Commit sur la mauvaise branche
git log --oneline # Trouver le hash du commit à déplacer
git switch bonne-branche
git cherry-pick abc1234 # Appliquer sur la bonne branche
git switch mauvaise-branche
git reset HEAD~1 # Supprimer de la mauvaise branche

git bisect — Recherche binaire de bugs​

git bisect effectue une recherche binaire dans votre historique de commits pour trouver le commit exact qui a introduit un bug.

Bisect manuel​

# 1. Démarrer bisect
git bisect start

# 2. Marquer le commit actuel comme mauvais (bug présent)
git bisect bad

# 3. Marquer un commit connu comme bon (pas de bug)
git bisect good v1.0.0
# ou par hash :
git bisect good abc1234

# Git va checkout le commit du milieu
# Tester votre application...

# 4. Marquer chaque commit testé
git bisect good # Pas de bug sur ce commit
git bisect bad # Bug présent sur ce commit

# 5. Git trouve et affiche le commit coupable :
# abc1234 est le premier mauvais commit

# 6. Quitter bisect
git bisect reset # Retourne au HEAD original

Bisect automatisé​

Si vous avez un test qui peut détecter le bug, vous pouvez automatiser complètement bisect.

Créez un script de test test_bug.sh :

#!/bin/bash
# Retourne 0 (succès) si pas de bug, 1 si bug présent
python -c "
from app import obtenir_statistiques
from app import TACHES
TACHES.clear()
try:
stats = obtenir_statistiques()
if stats['total'] == 0:
exit(0)
else:
exit(1)
except ZeroDivisionError:
exit(1)
"
chmod +x test_bug.sh

# Laisser Git faire le bisect automatiquement !
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run ./test_bug.sh

# Git exécute le script sur chaque commit et trouve le coupable automatiquement
# À la fin :
git bisect reset

Log et replay de bisect​

# Sauvegarder une session bisect pour plus tard
git bisect log > session-bisect.log

# Rejouer une session sauvegardée
git bisect replay session-bisect.log

git reflog — Le filet de sécurité​

git reflog enregistre chaque mouvement de HEAD dans votre dépôt — c'est votre filet de sécurité ultime :

# Voir le reflog
git reflog

# Sortie :
# d5a1b4c HEAD@{0}: commit: feat: ajout statistiques
# c2e8f3a HEAD@{1}: checkout: moving from feature to main
# b7c9d1e HEAD@{2}: reset: moving to HEAD~1
# a3f4b2c HEAD@{3}: commit: feat: ajout recherche

Récupérer des commits « perdus »​

# Vous avez accidentellement lancé git reset --hard et perdu des commits
git reset --hard HEAD~5 # Oups !

# Trouver les commits perdus dans le reflog
git reflog
# HEAD@{2} était avant le reset

# Récupérer
git reset --hard HEAD@{2}

# Ou créer une nouvelle branche depuis l'état perdu
git switch -c branche-recuperee HEAD@{2}
Reflog reste local

Le reflog n'est pas poussé vers GitHub. C'est un filet de sécurité local uniquement. Les entrées de reflog sont conservées 90 jours par défaut.


Résumé​

CommandeDescription
git cherry-pick <hash>Appliquer un commit spécifique
git cherry-pick --continueContinuer après un conflit
git cherry-pick --abortAnnuler le cherry-pick
git bisect startDémarrer la recherche binaire
git bisect good/badMarquer un commit comme bon/mauvais
git bisect run <script>Bisect automatisé
git bisect resetTerminer la session bisect
git reflogVoir tous les mouvements de HEAD

Prochaines étapes​