Logo SmartBooster Playbook

Gestion des branches

Choisir sa branche de base, nommer sa branche et savoir à quel moment le code part sur le dépôt.

La gestion des branches n’est pas un détail d’outillage laissé à la préférence de chacun. Elle décide de ce que nous pouvons livrer, à quel moment, et de ce que nous restons capables de retirer d’une livraison sans tout défaire. Le choix d’une branche de base est donc une décision de livraison.

Cette page couvre le travail sur le dépôt pendant la réalisation du ticket. La préparation de la revue est traitée dans la merge request.

Prérequis valable pour toute la page : toujours faire un fetch avant de choisir sa branche de base. Partir d’un dépôt local qui n’est plus à jour produit des conflits qui n’avaient aucune raison d’exister.

Choisir sa branche de base

La branche de base est le point d’origine à partir duquel la branche du ticket est créée. Quatre situations se présentent, dans cet ordre de fréquence.

Une fonctionnalité indépendante ou une correction

La branche est tirée de la branche principale main. En partant de main, nous avons la garantie que le travail repose sur la dernière version stable du projet.

# Synchroniser les branches distantes sur son poste
git fetch origin
# Créer la branche du ticket depuis main et basculer dessus
git switch -c <nouvelle_branche> origin/main

Depuis 2020, la majorité des plateformes d’hébergement de dépôts ont fait évoluer leur politique de nommage vers des termes plus inclusifs, d’où le terme main. Sur nos projets les plus anciens, la branche principale peut encore s’appeler master : partout dans le playbook, nous écrivons main.

Une fonctionnalité avec plusieurs intervenants

C’est le cas classique d’une fonctionnalité qui se découpe en plusieurs parties réparties entre plusieurs développeurs (par exemple : une partie backend, un front et des commandes de cron), ou d’un développement qu’une autre personne finalise pour des raisons de disponibilité.

Dans ce cas, le développeur en charge du code dont les autres ont besoin crée la première branche, et les autres tirent la leur depuis cette première branche.

Graphe git montrant une branche tirée depuis la branche d'un autre développeur plutôt que depuis main

Sur ce graphe, la branche setup_glide est basée sur pages : son auteur n’a pas eu à attendre que la merge request de pages soit finalisée pour bénéficier du code de la macro. Lors de la merge request, il suffit de choisir comme cible la branche pages.

Un lot d’évolution

Un lot d’évolution est une branche cible qui recevra plusieurs merge requests successives avant d’être déployée.

Dans la majorité des cas, un seul lot est en cours à la fois : nous le nommons next_mep, tiré depuis main.

Une fois le lot déployé, next_mep ne disparaît pas immédiatement. Elle reste en place le temps de vérifier que la mise en production est stable, puis elle est fusionnée dans main. La branche next_mep suivante est créée le jour où le travail sur un nouveau lot commence, jamais par automatisme et jamais à l’avance.

Sur les gros projets, plusieurs lots peuvent avancer en parallèle et l’ordre d’intégration peut être décidé en fonction de l’avancement des développements et de la validation. Dans ce contexte, chaque lot a une branche cible clairement définie.

Un correctif urgent en production

C’est le seul cas où la branche de base ne se discute pas : elle est tirée de la branche actuellement en production, dans la majorité des cas main.

Partir de next_mep embarquerait dans la livraison d’urgence l’intégralité d’un lot qui n’a pas fini d’être validé. Le correctif ne serait plus livrable seul, et c’est exactement ce qu’un correctif urgent doit rester.

Le contenu de la branche est préfixé par hotfix_, ce qui rend sa nature lisible dans la liste des branches du dépôt et dans les pipelines par exemple : Correction du pattern téléphonique en production → CU-1234_hotfix_pattern_tel_france

Nommer la branche de son ticket

Format : préfixe id du ticket + _ + suffixe décrivant le contenu

Le préfixe reprend l’identifiant du ticket, disponible sur l’outil de gestion de projet. Il est nécessaire pour que l’intégration entre le dépôt et l’outil de gestion des tickets fonctionne, et il doit être repris de la même façon en préfixe des messages de commit.

Le suffixe est un texte court qui décrit le contenu :

  • Admin : visualisation et édition des prospects → admin_prospect_visu_edit
  • Correction du pattern téléphonique sur les fichiers de type France → fix_pattern_tel_france

Deux règles complètent le format : n’utiliser que des caractères alphanumériques et le _ à la place des espaces, pour prévenir tout problème d’encodage ou d’interprétation par git, et suffixer en anglais si le dépôt est hébergé sur GitHub.

Les articles et les mots de liaison inutiles sont omis pour raccourcir le nom. Et rien n’oblige à une seule branche par ticket : un ticket peut être découpé en plusieurs branches pour être intégré progressivement.

Quand pousser le code de sa branche

Il n’est pas nécessaire de pousser à chaque commit. Le code part sur le dépôt distant quand il est en état d’être lu par quelqu’un d’autre, ou quand il devient risqué de le laisser sur un seul poste :

  • lancer la qualimétrie et les tests avant de pousser, dès lors que du code technique est modifié
  • ne pas pousser à chaque commit sur une demande simple qui tient en moins d’une demi-journée : un push global à la fin suffit
  • ne jamais pousser de code incomplet qui casserait le projet, par exemple un calcul de prix à moitié écrit. Si c’est volontaire, pour obtenir un premier avis, le marquer d’un préfixe WIP dans le message de commit
  • vérifier que la branche cible est à jour, et au besoin la récupérer et rebaser dessus avant de pousser
git push origin <nom_branche>

Deux repères de timing : dès que l’avancement constitue un livrable intermédiaire ou complet qui mérite une revue, et de toute façon si aucun push n’a été fait sur la branche depuis plus d’une journée, auquel cas les commits intermédiaires partent quand même pour sauvegarde.

Sur les projets avec une intégration continue, chaque push consomme du temps de traitement, et du budget de CI. Un push inutile entame ce budget et mobilise des ressources serveur pour rien. Si vous constatez qu’un push était inutile, annulez le lancement depuis le menu des pipelines du projet. Même principe lorsque vous intégrez plusieurs merge requests à la suite : les builds intermédiaires ne servent à personne.

Changer de branche en cours de travail

Le cas est classique : une personne est en plein développement et une priorité impose de basculer sur un autre ticket. Le travail en cours ne peut pas être commité en l’état, et il n’est pas question de l’embarquer dans la branche du ticket prioritaire.

Nous nous efforçons de ne pas changer de branche pendant un travail en cours. Les motifs qui le justifient sont peu nombreux :

  • un bug important est apparu en production
  • un retour sur une merge request En cours bloque une livraison ou le travail d’un collègue
  • un ticket revenu en Retour recette bloque une livraison ou le travail d’un collègue

Pour conserver ses changements locaux sans les commiter :

# -u embarque aussi les fichiers non suivis
git stash -u
git switch <nom_branche_prioritaire>

Au retour sur la branche précédente, le travail se récupère avec :

git stash pop

Ce scénario est un argument de plus pour commiter son travail par étapes : plus le découpage est fin, moins il reste de travail en suspens le jour où il faut basculer dans l’urgence.