Git : passer au niveau supérieur
Rebase, cherry-pick, reflog, hooks, signatures, worktrees, bisect. Tout ce que tu utiliseras quand tu sortiras du cycle add/commit/push de base.
À la fin du cours, tu sais
- Choisir un workflow adapté à ton équipe (Git Flow, GitHub Flow, trunk-based)
- Maîtriser rebase, interactive rebase et cherry-pick
- Récupérer un commit perdu avec reflog
- Versionner proprement avec tags et bisect une régression
- Mettre en place des hooks pour la qualité locale
- Signer tes commits et utiliser les worktrees
Prérequis
- Avoir suivi le cours « Premiers pas avec Git et GitHub » ou équivalent
- Être à l'aise avec branch, merge, push, pull, pull requests
Chapitre 1
Stratégies de branches et workflows
Choisir le bon modèle de collaboration, c'est la décision qui structure tout le reste. Trois grandes familles dominent.
Les 3 workflows principaux
- Git Flow :
main,develop,release/*,hotfix/*,feature/*. Adapté aux releases versionnées (mobile, desktop, banking) - GitHub Flow : une seule branche longue
main, feature branches courtes, déploiement continu - Trunk-Based Development : tout le monde commit fréquemment sur
main, feature flags pour le code en cours, release every commit
Critères de choix
- Taille de l'équipe
- Fréquence des déploiements (par jour ? par mois ?)
- Contraintes réglementaires (banking, santé : Git Flow souvent imposé)
- Maturité de la CI/CD (le trunk-based exige une CI solide)
Conventions de nommage
git switch -c feat/auth-oauth # nouvelle fonctionnalité
git switch -c fix/null-on-signup # correction de bug
git switch -c chore/upgrade-deps # tâche annexe (upgrade, doc)
git switch -c hotfix/payment-broken # correction critique de prod
git switch -c refactor/extract-auth # refactor sans changement de comportementEn 2025, le plus courant : GitHub Flow
main. Si tu hésites, commence par lui.Chapitre 2
Rebase vs Merge
Comprendre quand réécrire l'historique et quand le préserver. C'est le sujet qui sépare les utilisateurs basiques de Git des autres.
Merge : préserver l'historique
git merge garde l'historique réel : les deux branches restent visibles, un commit de merge matérialise leur réunion. Honnête, lisible si l'équipe est petite.
Rebase : linéariser l'historique
git rebase rejoue tes commits au sommet de la branche cible. Le résultat est un historique linéaire, comme si tu avais codé après l'autre. Plus propre à lire, mais réécrit l'histoire.
# Récupérer les derniers changements de main et rebaser ma feature dessus
git fetch origin
git rebase origin/main
# En cas de conflit
# 1) Résoudre les conflits dans les fichiers
git add fichier-resolu.ts
git rebase --continue
# Pour abandonner et revenir à l'état initial
git rebase --abortLa règle d'or du rebase
main alors que tes collègues sont basés dessus, leurs commits divergent et c'est l'enfer. Rebase tes branches feature avant le merge, jamais après push partagé.Squash and merge sur GitHub
Le bouton Squash and merge sur GitHub combine les deux : il squashe tous tes commits de feature en un seul, puis le merge sur main. Historique main propre (un commit par PR), pas besoin de rebase manuel.
Chapitre 3
Interactive rebase : nettoyer son historique
Avant de proposer une PR, on peut nettoyer ses commits pour que la review soit lisible. C'est ce que fait l'interactive rebase.
Lancer un rebase interactif
# Sur les 5 derniers commits
git rebase -i HEAD~5
# Ou jusqu'à la branche main
git rebase -i mainGit ouvre un éditeur avec la liste des commits, et tu peux changer la commande devant chacun :
pick: garder le commit tel quelreword: modifier le message (le contenu reste)squash(ous) : fusionner avec le commit précédent, garder les messagesfixup(ouf) : fusionner avec le précédent, jeter le message (le plus courant)drop(oud) : supprimer le commitedit: s'arrêter sur le commit pour le modifier
Le combo magique : --fixup + --autosquash
# Tu fais ton commit normal
git commit -m "feat: ajout du formulaire de login"
# Tu vois un typo plus tard, tu corriges et tu fais un fixup
git add .
git commit --fixup=<sha-du-commit-cible>
# Ton historique : ...[feat: login]...[fixup! feat: login]...
# Lance interactive rebase avec --autosquash
git rebase -i --autosquash main
# Git positionne automatiquement le fixup au bon endroit. Tu valides.Push après rebase
git push classique sera refusé. Utilise git push --force-with-lease (pas --force). --force-with-lease refuse de pousser si quelqu'un a poussé entre-temps, protégeant le travail des autres.Chapitre 4
Cherry-pick, stash, reflog
Trois outils pour manipuler des commits, mettre du travail de côté, ou récupérer un commit qu'on croyait perdu.
Cherry-pick : appliquer un commit ailleurs
# Récupérer un commit précis d'une autre branche
git cherry-pick abc1234
# Avec une référence au commit original dans le message (recommandé)
git cherry-pick -x abc1234
# Cherry-pick d'une plage de commits
git cherry-pick abc1234..def5678Cas typique : tu as fait un hotfix sur main, tu veux l'appliquer aussi sur une branche release en cours.
Stash : mettre du travail de côté
# Tu as des modifs non commitées et tu dois changer de branche d'urgence
git stash push -m "wip: refacto navigation"
# Plus tard, retour à ton travail
git stash list # voir tous les stashes
git stash pop # appliquer le plus récent et le supprimer du stash
git stash apply stash@{1} # appliquer un stash précis sans le supprimer
git stash drop stash@{1} # supprimer un stash
# Inclure les fichiers non suivis (untracked)
git stash push -u -m "wip avec nouveaux fichiers"Reflog : ton filet de sécurité
git reflog est le journal de toutes les positions de HEAD. Même un git reset --hard ne supprime pas vraiment tes commits : ils restent retrouvables via reflog pendant ~30 jours.
# Voir tous les déplacements de HEAD
git reflog
# Output exemple :
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: feat: ajout du dashboard
# ...
# Récupérer un commit "perdu"
git reset --hard HEAD@{1} # revient à la position d'avant le reset
# Ou créer une branche à partir de ce commit
git switch -c recup HEAD@{1}Tant que tu n'as pas fait git gc
git reflog.Chapitre 6
Hooks, aliases et config avancée
Industrialiser ta qualité locale et raccourcir tes commandes.
Hooks client
pre-commit: lance avant la création du commit (lint, tests rapides)commit-msg: valide le format du message (Conventional Commits)pre-push: avant un push (tests complets, vérifications)
En pratique, on ne touche pas .git/hooks/ à la main. On utilise des outils : Husky (Node), lefthook (multi-langage), pre-commit (Python). Ces outils versionnent les hooks dans le repo et les installent à npm install.
// package.json
{
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"]
}
}
// .husky/pre-commit
npx lint-stagedAliases Git utiles
git config --global alias.co "checkout"
git config --global alias.sw "switch"
git config --global alias.br "branch"
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.unstage "reset HEAD --"
git config --global alias.last "log -1 HEAD"
git config --global alias.amend "commit --amend --no-edit"Configs à mettre en place
# Pull rebase par défaut (historique linéaire)
git config --global pull.rebase true
# Mémoriser la résolution de conflits
git config --global rerere.enabled true
# Push uniquement la branche courante
git config --global push.default current
# Couleur partout
git config --global color.ui autoChapitre 7
Signatures et sécurité
Prouver que c'est bien toi qui a écrit ce commit. Important pour l'open source et pour les équipes qui imposent des branches protégées.
Signature SSH (Git 2.34+, le plus simple)
Tu réutilises la clé SSH que tu as déjà pour GitHub. Pas de GPG à installer.
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# Signer un commit
git commit -S -m "feat: secure login"
# Vérifier
git log --show-signaturePour que GitHub affiche le badge Verified, ajoute ta clé SSH comme Signing key dans Settings → SSH and GPG keys → New SSH key (en mode Signing key, pas Authentication key).
Signature GPG (historique)
Méthode plus ancienne, mais toujours valide. Demande d'installer GPG, de générer une clé GPG, et de l'uploader sur GitHub. Plus de friction, mais standard de l'open source historique.
Branche protégée + signature obligatoire
main soient signés. Combiné avec Require pull request review, tu obtiens un haut niveau de garantie sur ce qui est mergé.Chapitre 8
Worktrees : plusieurs branches en parallèle
Tu codes une grosse feature, et tu dois faire un hotfix urgent. Avant : tu stashes, tu changes de branche, tu codes, tu reviens, tu unstash. Avec les worktrees : tu ouvres un 2e dossier en parallèle.
Le concept
Un worktree est un dossier supplémentaire qui partage le même .git. Tu peux avoir 2 versions du repo en parallèle, sur 2 branches différentes, sans cloner deux fois ni stasher.
# Tu es dans ~/projets/mon-app sur la branche feat/dashboard
# Hotfix urgent demandé sur main
# Crée un nouveau worktree pour le hotfix
git worktree add ../mon-app-hotfix hotfix/payment-broken
# Bascule dans le dossier
cd ../mon-app-hotfix
# Tu codes, tu commits, tu pushes
git add . && git commit -m "fix: payment provider URL"
git push -u origin hotfix/payment-broken
# Une fois le hotfix mergé : supprimer le worktree
cd ../mon-app
git worktree remove ../mon-app-hotfix
# Lister les worktrees
git worktree list
# Nettoyer les worktrees obsolètes
git worktree pruneUne branche, un seul worktree
Les worktrees servent aussi à tester un bug rapporté sur une vieille version sans toucher à ton travail courant. Tu sors un worktree sur le tag v1.2.0, tu reproduis, tu fermes.
🛠️ Exercice optionnel
Nettoyer une feature branch avant le merge
Tu as une branche feat/profile avec 6 commits, dont 2 typos, 1 « wip » et 1 « fix lint ». Avant d'ouvrir la PR, tu vas nettoyer l'historique pour que la review soit lisible.
Ta mission
- Crée la branche et fabrique l'historique pourri :
git switch -c feat/profile main # 6 commits avec des messages comme : # - feat: ajout du composant Profile # - wip # - fix tipo # - feat: ajout des actions # - fix lint # - typo final - Lance
git rebase -i main. - Marque comme
fixuples commits "wip", "fix lint" et les typos. rewordles 2 commits restants au format Conventional Commits.- Vérifie avec
git log --oneline: tu dois avoir exactement 2 commits propres. - Push avec
git push -u origin feat/profile --force-with-lease. - Ouvre la PR sur GitHub.
Tu bloques ? Des indices, à dévoiler quand tu en as besoin.
Indice 1
Indice masqué.
Indice 2
Indice masqué.
Indice 3
Indice masqué.
✅ QCM de fin de cours
Teste tes acquis
10 questions, plusieurs réponses parfois possibles. Coche tout ce qui te semble juste, puis valide pour voir ton score et les explications.
- 1
Quelle commande te permet de récupérer un commit supprimé par un
git reset --hard? - 2
Que fait
git rebase -i --autosquash? - 3
Quelle stratégie de branches convient le mieux au déploiement continu ?
- 4
À quoi sert
git push --force-with-leaseplutôt que--force? - 5
Quelle est la différence entre un tag annoté et un tag léger ?
- 6
Que fait
git cherry-pick -x abc1234? - 7
Quel hook Git valide le format du message de commit ?
- 8
Combien de worktrees peuvent avoir la même branche en checkout simultanément ?
- 9
Quelle config évite les merges parasites lors d'un
git pull? - 10
Que fait
git bisect run ./test.sh?
Tu peux laisser des questions sans réponse, elles compteront comme fausses.
Tu veux ce cours pour ton équipe ?
Je peux adapter et animer ce cours pour tes formateur·ices ou tes apprenant·es, en présentiel ou en distanciel. Parlons-en pendant l'audit gratuit.
Réserver un audit gratuit →