git-advanced-workflows

Par wshobson · agents

Maîtrisez les workflows Git avancés, notamment le rebasing, le cherry-picking, le bisect, les worktrees et le reflog, pour maintenir un historique propre et vous sortir de n'importe quelle situation. À utiliser lors de la gestion d'historiques Git complexes, de la collaboration sur des branches de fonctionnalités ou du diagnostic de problèmes dans un repository.

npx skills add https://github.com/wshobson/agents --skill git-advanced-workflows

Workflows Git avancés

Maîtrisez les techniques Git avancées pour maintenir un historique propre, collaborer efficacement et récupérer de n'importe quelle situation en toute confiance.

Quand utiliser cette compétence

  • Nettoyer l'historique des commits avant de fusionner
  • Appliquer des commits spécifiques sur plusieurs branches
  • Trouver les commits qui ont introduit des bugs
  • Travailler sur plusieurs fonctionnalités simultanément
  • Récupérer après des erreurs Git ou des commits perdus
  • Gérer des workflows de branches complexes
  • Préparer des pull requests propres pour la revue
  • Synchroniser des branches divergées

Concepts fondamentaux

1. Interactive Rebase

Interactive rebase est le couteau suisse de l'édition d'historique Git.

Opérations courantes :

  • pick : Conserver le commit tel quel
  • reword : Modifier le message du commit
  • edit : Modifier le contenu du commit
  • squash : Fusionner avec le commit précédent
  • fixup : Comme squash mais ignorer le message
  • drop : Supprimer le commit entièrement

Utilisation basique :

# Rebase des 5 derniers commits
git rebase -i HEAD~5

# Rebase de tous les commits de la branche actuelle
git rebase -i $(git merge-base HEAD main)

# Rebase sur un commit spécifique
git rebase -i abc123

2. Cherry-Picking

Appliquer des commits spécifiques d'une branche à une autre sans fusionner les branches entières.

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

# Cherry-pick d'une plage de commits (début exclusif)
git cherry-pick abc123..def456

# Cherry-pick sans committer (stage les changements seulement)
git cherry-pick -n abc123

# Cherry-pick et éditer le message du commit
git cherry-pick -e abc123

3. Git Bisect

Recherche binaire dans l'historique des commits pour trouver le commit qui a introduit un bug.

# Démarrer bisect
git bisect start

# Marquer le commit actuel comme mauvais
git bisect bad

# Marquer un commit connu comme bon
git bisect good v1.0.0

# Git checkout le commit du milieu - le tester
# Puis marquer comme bon ou mauvais
git bisect good  # ou : git bisect bad

# Continuer jusqu'à trouver le bug
# Quand c'est fait
git bisect reset

Bisect automatisé :

# Utiliser un script pour tester automatiquement
git bisect start HEAD v1.0.0
git bisect run ./test.sh

# test.sh doit renvoyer 0 pour bon, 1-127 (sauf 125) pour mauvais

4. Worktrees

Travailler sur plusieurs branches simultanément sans stasher ou changer de branche.

# Lister les worktrees existants
git worktree list

# Ajouter un nouveau worktree pour une branche de feature
git worktree add ../project-feature feature/new-feature

# Ajouter un worktree et créer une nouvelle branche
git worktree add -b bugfix/urgent ../project-hotfix main

# Supprimer un worktree
git worktree remove ../project-feature

# Nettoyer les worktrees obsolètes
git worktree prune

5. Reflog

Votre filet de sécurité - suivi tous les mouvements de ref, même les commits supprimés.

# Afficher le reflog
git reflog

# Afficher le reflog d'une branche spécifique
git reflog show feature/branch

# Restaurer un commit supprimé
git reflog
# Trouver le hash du commit
git checkout abc123
git branch recovered-branch

# Restaurer une branche supprimée
git reflog
git branch deleted-branch abc123

Workflows pratiques

Workflow 1 : Nettoyer une branche de feature avant une PR

# Commencer avec la branche de feature
git checkout feature/user-auth

# Interactive rebase pour nettoyer l'historique
git rebase -i main

# Exemple d'opérations rebase :
# - Squasher les commits "fix typo"
# - Reword des messages de commit pour plus de clarté
# - Réordonner les commits logiquement
# - Supprimer les commits inutiles

# Force push de la branche nettoyée (sûr si personne d'autre ne l'utilise)
git push --force-with-lease origin feature/user-auth

Workflow 2 : Appliquer un hotfix sur plusieurs releases

# Créer le fix sur main
git checkout main
git commit -m "fix: critical security patch"

# Appliquer sur les branches de release
git checkout release/2.0
git cherry-pick abc123

git checkout release/1.9
git cherry-pick abc123

# Gérer les conflits s'ils surviennent
git cherry-pick --continue
# ou
git cherry-pick --abort

Workflow 3 : Trouver l'introduction d'un bug

# Démarrer bisect
git bisect start
git bisect bad HEAD
git bisect good v2.1.0

# Git checkout le commit du milieu - lancer les tests
npm test

# Si les tests échouent
git bisect bad

# Si les tests passent
git bisect good

# Git checkout automatiquement le commit suivant à tester
# Répéter jusqu'à trouver le bug

# Version automatisée
git bisect start HEAD v2.1.0
git bisect run npm test

Workflow 4 : Développement sur plusieurs branches

# Répertoire principal du projet
cd ~/projects/myapp

# Créer un worktree pour un bugfix urgent
git worktree add ../myapp-hotfix hotfix/critical-bug

# Travailler sur le hotfix dans un répertoire séparé
cd ../myapp-hotfix
# Faire des changements, committer
git commit -m "fix: resolve critical bug"
git push origin hotfix/critical-bug

# Revenir au travail principal sans interruption
cd ~/projects/myapp
git fetch origin
git cherry-pick hotfix/critical-bug

# Nettoyer quand c'est fait
git worktree remove ../myapp-hotfix

Workflow 5 : Récupérer après des erreurs

# Reset accidentel sur le mauvais commit
git reset --hard HEAD~5  # Oh non !

# Utiliser le reflog pour trouver les commits perdus
git reflog
# Le résultat montre :
# abc123 HEAD@{0}: reset: moving to HEAD~5
# def456 HEAD@{1}: commit: my important changes

# Récupérer les commits perdus
git reset --hard def456

# Ou créer une branche à partir du commit perdu
git branch recovery def456

Techniques avancées

Stratégie Rebase vs Merge

Quand faire un rebase :

  • Nettoyer les commits locaux avant de pousser
  • Tenir à jour une branche de feature avec main
  • Créer un historique linéaire pour une revue plus facile

Quand fusionner :

  • Intégrer les features complètes dans main
  • Préserver l'historique exact de la collaboration
  • Branches publiques utilisées par d'autres
# Mettre à jour la branche de feature avec les changements de main (rebase)
git checkout feature/my-feature
git fetch origin
git rebase origin/main

# Gérer les conflits
git status
# Corriger les conflits dans les fichiers
git add .
git rebase --continue

# Ou fusionner à la place
git merge origin/main

Workflow Autosquash

Squasher automatiquement les commits fixup pendant le rebase.

# Faire le commit initial
git commit -m "feat: add user authentication"

# Plus tard, corriger quelque chose dans ce commit
# Stage les changements
git commit --fixup HEAD  # ou spécifier le hash du commit

# Faire plus de changements
git commit --fixup abc123

# Rebase avec autosquash
git rebase -i --autosquash main

# Git marque automatiquement les commits fixup

Split Commit

Diviser un commit en plusieurs commits logiques.

# Démarrer interactive rebase
git rebase -i HEAD~3

# Marquer le commit à diviser avec 'edit'
# Git s'arrêtera à ce commit

# Reset le commit mais garder les changements
git reset HEAD^

# Stage et committer par chunks logiques
git add file1.py
git commit -m "feat: add validation"

git add file2.py
git commit -m "feat: add error handling"

# Continuer le rebase
git rebase --continue

Partial Cherry-Pick

Cherry-pick seulement des fichiers spécifiques d'un commit.

# Afficher les fichiers dans le commit
git show --name-only abc123

# Checkout des fichiers spécifiques du commit
git checkout abc123 -- path/to/file1.py path/to/file2.py

# Stage et committer
git commit -m "cherry-pick: apply specific changes from abc123"

Bonnes pratiques

  1. Toujours utiliser --force-with-lease : Plus sûr que --force, empêche d'écraser le travail d'autres
  2. Rebase seulement les commits locaux : Ne pas faire rebase des commits qui ont été pushés et partagés
  3. Messages de commit descriptifs : Vous futur vous remerciera
  4. Commits atomiques : Chaque commit doit être un seul changement logique
  5. Tester avant force push : S'assurer que la réécriture d'historique n'a rien cassé
  6. Rester conscient du reflog : Rappelez-vous que le reflog est votre filet de sécurité pendant 90 jours
  7. Créer une branche avant les opérations risquées : Créer une branche de secours avant des rebases complexes
# Force push sûr
git push --force-with-lease origin feature/branch

# Créer une sauvegarde avant une opération risquée
git branch backup-branch
git rebase -i main
# Si quelque chose se passe mal
git reset --hard backup-branch

Pièges courants

  • Faire rebase des branches publiques : Cause des conflits d'historique pour les collaborateurs
  • Force push sans lease : Peut écraser le travail d'un coéquipier
  • Perdre du travail pendant un rebase : Résoudre les conflits soigneusement, tester après le rebase
  • Oublier de nettoyer les worktrees : Les worktrees orphelins consomment de l'espace disque
  • Ne pas faire de sauvegarde avant une expérience : Toujours créer une branche de sécurité
  • Bisect sur un répertoire de travail sale : Committer ou stasher avant de faire bisect

Commandes de récupération

# Abandonner les opérations en cours
git rebase --abort
git merge --abort
git cherry-pick --abort
git bisect reset

# Restaurer un fichier à partir d'une version spécifique d'un commit
git restore --source=abc123 path/to/file

# Annuler le dernier commit mais garder les changements
git reset --soft HEAD^

# Annuler le dernier commit et ignorer les changements
git reset --hard HEAD^

# Récupérer une branche supprimée (dans les 90 jours)
git reflog
git branch recovered-branch abc123

Skills similaires