Vous travaillez sur la fonctionnalité de recherche de votre application d’inventaire quand un bug urgent surgit en production. Sans branches, vous seriez coincé : votre travail à moitié fini empêche toute correction propre. Les branches résolvent exactement ce dilemme. Elles vous laissent ouvrir plusieurs lignes de travail parallèles dans le même dépôt, sans qu’elles se gênent, puis les réunir au bon moment. À la fin de ce tutoriel, vous saurez créer une branche, y travailler isolément, et la fusionner dans la ligne principale — le geste qui distingue un utilisateur occasionnel de Git d’un développeur à l’aise.
🎯 Ce que vous allez apprendre
- Comprendre ce qu’est réellement une branche : un simple pointeur mobile.
- Créer, lister et basculer entre branches avec
git branchetgit switch. - Mener une fonctionnalité sur une branche dédiée sans polluer la branche principale.
- Distinguer une fusion « avance rapide » (fast-forward) d’une fusion à trois sources.
- Décider quand forcer un commit de fusion avec
--no-ff. - Supprimer et renommer des branches en sécurité.
🛠️ Ce que vous allez construire
Vous reprenez le dépôt boutique-inventaire de la leçon précédente. Vous allez y ajouter une fonctionnalité de recherche sur une branche feature/recherche-produit, la valider par plusieurs commits, puis la fusionner dans main. Vous verrez l’historique se ramifier puis se réunir, et vous saurez le lire d’un coup d’œil.
Prérequis
- Un dépôt Git existant avec au moins un commit. Si ce n’est pas le cas, suivez d’abord les bases de Git : init, add, commit, log.
- Git 2.23 ou plus récent (pour disposer de
git switch). Vérifiez avecgit --version. - Niveau débutant à intermédiaire. ⏱️ Temps estimé : environ 45 minutes.
Étape 1 — Comprendre ce qu’est une branche
Avant de taper la moindre commande, fixons le modèle mental, car c’est ici que la plupart des débutants se perdent. Dans beaucoup d’outils, « créer une branche » évoque une copie lourde de tout le projet. Dans Git, c’est l’inverse : une branche n’est qu’un pointeur léger vers un commit. Rien n’est copié. Quand vous ajoutez un commit, le pointeur de la branche courante avance automatiquement vers ce nouveau commit.
Un second pointeur, HEAD, indique sur quelle branche vous vous trouvez. « Basculer de branche » revient simplement à déplacer HEAD et à mettre à jour vos fichiers pour refléter le commit visé. Comme tout cela ne manipule que des pointeurs, la création et le changement de branche sont quasi instantanés, même sur un gros projet. Cette légèreté est précisément ce qui rend le travail par branches si naturel sous Git, là où d’autres systèmes le rendaient coûteux.
L’ensemble des commits forme un graphe orienté acyclique (en anglais DAG) : chaque commit connaît son ou ses parents, et les branches ne sont que des étiquettes posées sur certains nœuds de ce graphe.
Étape 2 — Lister et créer une branche
Commençons par observer l’existant. La commande git branch sans argument liste les branches locales et marque la branche courante d’un astérisque.
git branch
Sur un dépôt neuf, vous ne voyez que * main. Créons maintenant une branche pour notre fonctionnalité de recherche. Historiquement, on créait la branche avec git branch puis on basculait dessus avec git checkout — deux étapes. Depuis Git 2.23, la commande git switch, plus claire, fait les deux avec l’option -c (pour create).
git switch -c feature/recherche-produit
Git répond Switched to a new branch 'feature/recherche-produit'. Vous êtes désormais sur cette branche : tout commit que vous créerez s’y accumulera, laissant main intacte. Vérifiez-le avec git branch -v, qui ajoute le dernier commit de chaque branche.
git branch -v
✅ Point d’étape —
git branchdoit afficher deux branches, avec l’astérisque surfeature/recherche-produit. À ce stade,mainet votre nouvelle branche pointent encore vers le même commit : elles ne divergeront qu’après votre premier commit ici.
Étape 3 — Travailler isolément sur la branche
Ajoutons la fonctionnalité. Créons un module de recherche et enregistrons-le en deux commits, comme on le ferait dans la vraie vie : un pour la logique, un pour son intégration.
echo "function rechercher(stock, terme) { return stock.filter(p => p.nom.includes(terme)); }" > recherche.js
git add recherche.js
git commit -m "Ajoute la fonction de recherche de produits"
Ce commit n’existe que sur feature/recherche-produit. Pour le prouver de manière spectaculaire, basculez sur main et constatez que recherche.js a disparu du dossier — il réapparaîtra dès le retour sur la branche de fonctionnalité.
git switch main
ls
git switch feature/recherche-produit
Sur main, recherche.js est absent ; de retour sur la branche, il revient. C’est l’illustration concrète de l’isolation : chaque branche présente sa propre version cohérente du projet. Si git switch refuse de basculer parce que vous avez des modifications non enregistrées, c’est une protection volontaire : commitez-les, ou mettez-les de côté avec git stash (voir le tutoriel sur l’annulation et la réparation).
Anciennes habitudes : les équivalents git checkout feature/recherche-produit et git checkout -b nouvelle-branche fonctionnent toujours. git switch leur est préféré aujourd’hui car checkout est surchargé (il sert aussi à restaurer des fichiers), source de confusion et d’erreurs coûteuses.
Étape 4 — La fusion « avance rapide » (fast-forward)
Notre fonctionnalité est prête ; ramenons-la dans main. La fusion s’effectue depuis la branche de destination : on se place sur main, puis on y intègre l’autre branche.
git switch main
git merge feature/recherche-produit
Comme main n’a pas bougé pendant que vous développiez, Git n’a rien à réconcilier : il lui suffit d’avancer le pointeur main jusqu’au dernier commit de la branche de fonctionnalité. Git appelle cela une fusion fast-forward et l’annonce par Fast-forward. Aucun nouveau commit n’est créé ; l’historique reste parfaitement linéaire. C’est le cas le plus simple et le plus fréquent quand une seule personne travaille sur une fonctionnalité à la fois.
✅ Point d’étape — Après la fusion,
git log --onelinesurmaindoit inclure vos commits de recherche. La fonctionnalité fait désormais partie de la ligne principale.
Étape 5 — La fusion à trois sources et le commit de fusion
Le cas intéressant survient quand main a aussi avancé pendant votre développement — par exemple, un collègue a corrigé un bug d’affichage du stock pendant que vous codiez la recherche. Les deux branches ont alors divergé, et une simple avance rapide est impossible. Simulons-le.
git switch -c feature/tri-stock
echo "function trier(stock) { return stock.sort(); }" > tri.js
git add tri.js
git commit -m "Ajoute le tri du stock"
git switch main
echo "// correctif: affichage du stock" >> inventaire.js
git add inventaire.js
git commit -m "Corrige l'affichage du stock sur main"
Maintenant main et feature/tri-stock ont chacune un commit que l’autre n’a pas : elles ont divergé. Fusionnons.
git merge feature/tri-stock
Cette fois, Git réalise une fusion à trois sources (three-way merge) : il considère les deux sommets et leur ancêtre commun, combine les changements, et crée un commit de fusion spécial qui possède deux parents. Votre éditeur s’ouvre pour le message ; acceptez le message proposé. Si les deux branches avaient modifié les mêmes lignes, un conflit apparaîtrait — sa résolution fait l’objet d’un tutoriel dédié.
Étape 6 — Forcer un commit de fusion avec –no-ff
Parfois, on préfère garder une trace explicite qu’une fonctionnalité a été développée à part, même quand une avance rapide serait possible. L’option --no-ff (no fast-forward) force la création d’un commit de fusion dans tous les cas.
git switch -c feature/export-csv
echo "function exporter(stock) { return stock.join(','); }" > export.js
git add export.js
git commit -m "Ajoute l'export CSV"
git switch main
git merge --no-ff feature/export-csv -m "Fusionne la fonctionnalité d'export CSV"
L’historique conserve désormais un commit de fusion qui regroupe visuellement les commits de la fonctionnalité. De nombreuses équipes adoptent --no-ff pour leurs fonctionnalités, car le graphe raconte alors clairement « voici un bloc de travail cohérent », ce qui facilite la lecture et un éventuel retour en arrière groupé.
Étape 7 — Visualiser, nettoyer et renommer
Avec plusieurs fusions, le graphe devient riche. Visualisez-le pour vérifier que tout s’est passé comme prévu.
git log --oneline --graph --decorate --all
Vous distinguez les bifurcations et les points de jonction. Une fois une branche fusionnée, elle ne sert plus à rien : son contenu vit dans main. Supprimez-la pour garder un dépôt propre. L’option -d est sûre : Git refuse de supprimer une branche non fusionnée, vous protégeant d’une perte de travail.
git branch -d feature/recherche-produit
git branch -d feature/tri-stock
Si vous voulez vraiment supprimer une branche non fusionnée (travail abandonné), utilisez le -D majuscule, qui force l’opération — à manier en connaissance de cause. Pour renommer la branche courante, par exemple corriger une faute de frappe, utilisez -m.
git branch -m feature/export-csv feature/export
✅ Point d’étape —
git branchne doit plus lister que les branches utiles. Vérifiez avecgit branch --merged, qui montre les branches déjà intégrées à la branche courante : elles sont candidates à la suppression.
Le piège du HEAD détaché
Un jour, vous taperez git switch <sha> ou git checkout <sha> pour inspecter un ancien commit, et Git vous avertira : You are in detached HEAD state. Pas de panique : cela signifie simplement que HEAD pointe directement vers un commit au lieu de suivre une branche. Vous pouvez regarder, tester, compiler — mais tout commit créé dans cet état n appartient à aucune branche et risque d être perdu lors du prochain changement. Si vous voulez conserver un travail commencé ainsi, créez une branche sur-le-champ. Pour revenir à votre branche précédente, deux raccourcis précieux : git switch - rebascule sur la dernière branche quittée (comme cd - dans un terminal), et git switch main vous ramène explicitement sur la ligne principale.
git switch -c experimentation # garder le travail fait en HEAD détaché
git switch - # revenir à la branche précédente
Comprendre le HEAD détaché vous évitera l angoisse des « commits disparus » : ils ne sont jamais vraiment perdus tant que le journal des références (le reflog, abordé dans le tutoriel sur l annulation et la réparation) les garde en mémoire un certain temps.
Un mot sur les branches distantes
Jusqu’ici, toutes vos branches sont locales. Lorsque vous collaborez via un serveur, vous rencontrerez des branches distantes notées origin/main, origin/feature/... : ce sont des références en lecture vers l’état du serveur. Les pousser, les récupérer et ouvrir des demandes de fusion relèvent du travail collaboratif sur GitHub. Le modèle mental reste identique : des pointeurs vers des commits, simplement hébergés ailleurs.
🐞 Pièges fréquents
| Symptôme / erreur | Cause probable | Correctif |
|---|---|---|
| Your local changes would be overwritten by checkout | Modifications non enregistrées avant de basculer | Commiter ou git stash avant le switch |
The branch is not fully merged au -d |
Branche non fusionnée → protection | Vérifier le travail, puis -D si vraiment à jeter |
| Commits faits « sur la mauvaise branche » | Oubli de basculer avant de commiter | Voir le tutoriel annuler/réparer (reflog, reset, cherry-pick) |
| Fusion qui ouvre l’éditeur sans qu’on s’y attende | Fusion à trois sources → message de commit requis | Comportement normal : enregistrer le message proposé |
git switch introuvable |
Version de Git antérieure à 2.23 | Mettre Git à jour, ou utiliser git checkout |
Travailler avec une connexion limitée
Créer, basculer et fusionner des branches sont des opérations 100 % locales : elles ne nécessitent aucune connexion. Vous pouvez mener plusieurs fonctionnalités en parallèle, les fusionner, nettoyer vos branches, le tout hors ligne, et ne synchroniser avec un serveur qu’au moment opportun. Adopter une branche par fonctionnalité est d’ailleurs une excellente discipline lorsque l’accès au réseau est intermittent : votre travail reste organisé et prêt à être envoyé d’un seul coup dès qu’une connexion se présente.
✅ Récapitulatif
Vous savez maintenant qu’une branche est un pointeur léger, créer et basculer avec git switch -c et git switch, travailler isolément, puis fusionner — soit en avance rapide quand la destination n’a pas bougé, soit par une fusion à trois sources produisant un commit de fusion. Vous savez aussi forcer ce commit avec --no-ff, et nettoyer avec git branch -d. Cette maîtrise des branches débloque tout le travail collaboratif et ouvre une question naturelle : comment garder un historique linéaire et propre quand les branches se multiplient ? C’est là qu’intervient le rebase.
🧾 Aide-mémoire
| Commande | Rôle |
|---|---|
git branch / git branch -v |
Lister les branches (avec dernier commit) |
git switch -c <nom> |
Créer une branche et basculer dessus |
git switch <nom> |
Basculer sur une branche existante |
git merge <branche> |
Fusionner une branche dans la branche courante |
git merge --no-ff <branche> |
Forcer un commit de fusion |
git branch -d / -D |
Supprimer une branche (sûr / forcé) |
git branch -m <ancien> <nouveau> |
Renommer une branche |
git log --oneline --graph --all |
Visualiser le graphe des branches |
💪 À vous de jouer
Créez une branche feature/alerte-stock, ajoutez-y un commit, puis, depuis main, faites avancer main d’un commit indépendant. Fusionnez ensuite la branche et observez quel type de fusion Git réalise. Pourquoi n’est-ce pas une avance rapide ?
Voir une solution
git switch -c feature/alerte-stock
echo "function alerter(stock) { return stock.filter(p => p.qte < 5); }" > alerte.js
git add alerte.js
git commit -m "Ajoute l'alerte de stock faible"
git switch main
echo "// note de version" >> README.md
git add README.md
git commit -m "Met à jour la note de version"
git merge feature/alerte-stock
Comme main a reçu un commit après la création de la branche, les deux ont divergé : Git effectue une fusion à trois sources avec un commit de fusion, et non une avance rapide.
FAQ
Q : Créer une branche copie-t-il tous mes fichiers ?
R : Non. Une branche est un simple pointeur vers un commit ; rien n’est dupliqué. C’est pourquoi l’opération est instantanée.
Q : git switch ou git checkout ?
R : git switch est la commande moderne dédiée au changement de branche, plus lisible. git checkout fonctionne encore mais cumule trop de rôles, ce qui le rend piégeux.
Q : Quand utiliser --no-ff ?
R : Lorsque vous voulez qu’un commit de fusion marque explicitement l’arrivée d’une fonctionnalité, pour la lisibilité du graphe et un retour arrière groupé éventuel.
Q : J’ai commité sur la mauvaise branche, que faire ?
R : C’est récupérable sans rien perdre. Le tutoriel sur l’annulation et la réparation explique comment déplacer ces commits avec reset et cherry-pick.
Q : Différence entre -d et -D ?
R : -d refuse de supprimer une branche non fusionnée (sécurité) ; -D force la suppression, à réserver au travail volontairement abandonné.
Ressources
- Pro Git, chapitre « Les branches avec Git » : git-scm.com/book/fr/v2
- Documentation de
git switch: git-scm.com/docs/git-switch - Documentation de
git merge: git-scm.com/docs/git-merge
Dans la même série
🔝 Retour au guide complet : Maîtriser Git et GitHub.