Guide pratique des stratégies de branches Git
La plupart des équipes ne choisissent pas une stratégie de branches : elles héritent de ce que les ingénieurs fondateurs ont fait, et cela se fige avant que quiconque se demande si cela convient à la taille réelle de l'équipe et à son rythme de livraison. C'est ainsi qu'une startup de cinq personnes applique un processus conçu pour une organisation de cent personnes avec des releases trimestrielles, ou qu'une équipe qui livre en production chaque jour maintient encore une branche develop permanente dont personne ne se rappelle l'utilité. La bonne stratégie dépend entièrement de la fréquence de vos déploiements et du nombre de chantiers en cours simultanément, et non de celle qui a le schéma le plus sophistiqué.
Le développement sur tronc (trunk-based)
Tout le monde commit sur main (ou sur des branches très courtes fusionnées dans la journée), derrière des feature flags si le travail n'est pas prêt à être vu par les utilisateurs.
git checkout main
git pull
git checkout -b add-export-button
# ... small, focused change ...
git push -u origin add-export-button
# open PR, merge same day, delete branch
Cela fonctionne bien quand vous déployez fréquemment (plusieurs fois par jour, ou au moins chaque jour) et que vous avez une CI solide et des feature flags. Tout l'intérêt est que les branches ne vivent jamais assez longtemps pour s'éloigner de main, de sorte que les conflits de fusion restent petits et que les problèmes d'intégration apparaissent immédiatement au lieu de s'accumuler. Sans feature flags, le système s'effondre : si le « petit changement ciblé » devient discrètement une « fonctionnalité à moitié terminée visible par les utilisateurs », vous venez de réinventer une branche de longue durée avec des étapes en plus.
Git Flow
Le modèle classique et lourd : une branche develop permanente pour l'intégration, des branches feature/ issues de develop, des branches release/ pour stabiliser une version, et main réservée à ce qui est réellement en production, avec des branches hotfix/* pour la corriger directement.
git checkout develop
git checkout -b feature/user-avatars
# ... work, potentially over days or weeks ...
git checkout develop
git merge --no-ff feature/user-avatars
# when develop is ready to ship
git checkout -b release/2.4.0 develop
# stabilization fixes go here, then:
git checkout main
git merge --no-ff release/2.4.0
git tag v2.4.0
git checkout develop
git merge --no-ff release/2.4.0
Cela a du sens quand vous livrez réellement selon un calendrier : une application de bureau avec des releases trimestrielles, une mise à jour de firmware embarqué, tout cas où « ce qui est actuellement dans main » et « ce que nous construisons activement » doivent être deux choses différentes pendant des semaines. Pour une application web déployée en continu, la séparation develop/release ajoute du cérémonial sans bénéfice correspondant : il n'y a pas de moment de « release » distinct vers lequel stabiliser.
GitHub Flow
Le compromis : pas de develop, pas de branches release. main est toujours déployable, les branches de fonctionnalité partent directement de lui, et la fusion dans main déclenche un déploiement.
git checkout main
git pull
git checkout -b fix-pagination-off-by-one
# ... work ...
git push -u origin fix-pagination-off-by-one
# open PR, get review, merge — CI deploys main automatically
C'est le choix par défaut vers lequel beaucoup d'équipes devraient se tourner : la clarté de Git Flow (une vraie branche par unité de travail, relue via PR) sans la comptabilité multi-branches, et il s'adapte naturellement au déploiement continu puisqu'une seule branche compte. Le compromis par rapport au développement sur tronc concerne la durée de vie des branches : une branche de fonctionnalité ici peut vivre quelques jours de relecture et d'itération, ce qui réintroduit un peu de dérive de fusion que le tronc pur évite, mais en échange vous obtenez un vrai point de relecture avant que le code n'atteigne main.
Choisir
- Trunk-based : déploiement plusieurs fois par jour, infrastructure de feature flags en place, équipe disciplinée sur les petits commits.
- GitHub Flow : déploiement au moins quelques fois par semaine, relecture par PR comme barrière, pas besoin de lignes de release parallèles.
- Git Flow : livraison de versions numérotées distinctes avec un vrai délai entre elles, besoin de corriger une ancienne version tout en développant la suivante.
La taille de l'équipe compte moins qu'on ne le croit. Un développeur seul profite de la discipline « une PR par changement » de GitHub Flow comme documentation de l'intention, même sans personne pour relire. Une équipe de vingt personnes peut pratiquer avec succès le développement sur tronc si l'investissement en CI et en flags est là : la contrainte est la maturité des processus, pas l'effectif.
Des conventions de nommage vraiment utiles
Quelle que soit la stratégie choisie, un préfixe de branche cohérent rend git branch -a et les tableaux de bord de CI lisibles d'un coup d'œil :
feature/short-description
fix/short-description
chore/short-description
hotfix/short-description
Évitez d'intégrer un numéro de ticket comme seul identifiant (JIRA-4521) : six mois plus tard, plus personne ne se souvient de ce que c'était sans aller voir, alors que fix/export-csv-encoding vous le dit immédiatement. Si votre outil de suivi compte pour l'automatisation, placez l'identifiant du ticket après la description, pas à sa place : fix/export-csv-encoding-JIRA-4521.
L'habitude qui compte plus que la stratégie
Quel que soit le modèle utilisé : fusionnez ou rebasez depuis la branche de base avant d'ouvrir une PR, et non après que les commentaires de relecture commencent à s'accumuler sur un diff devenu périmé.
git checkout feature/add-export-button
git fetch origin
git rebase origin/main
# resolve conflicts here, while the change is fresh in your head
git push --force-with-lease
--force-with-lease plutôt que --force est important ici : il refuse d'écraser la branche distante si quelqu'un d'autre y a poussé depuis votre dernier fetch, ce que --force seul écraserait silencieusement.
À retenir
Il n'existe pas de stratégie de branches universellement correcte, seulement celle qui correspond à votre vraie fréquence de déploiement. Trunk-based et GitHub Flow supposent tous deux que main est presque toujours livrable et diffèrent surtout par la friction de relecture avant une fusion ; Git Flow suppose que ce n'est pas le cas, et le paie avec davantage de branches à suivre. Choisissez selon la fréquence de vos livraisons, pas selon le schéma qui a l'air le plus sophistiqué dans le wiki.