Pour une Collaboration Efficace
23 octobre 2023
Un workflow Git définit une série de règles et de bonnes pratiques pour organiser et gérer le travail collaboratif sur des projets de développement logiciel en utilisant Git
Exemples de règles définies par un workflow Git :
Git est très flexible et n'impose pas de workflow particulier, c'est-à-dire qu'il n'impose pas de règles pour l'organisation et le cycle de vie des branches.
Il n'existe pas de modèle de workflow Git universel !
Il existe plusieurs "standards" plus ou moins adaptés en fonction des équipes et des projets.
Ces standards peuvent être adaptés et combinés pour répondre aux besoins d'une équipe.
Quelques critères à prendre en compte
Source : https://xkcd.com/1597/
Un repo centralisé (e.g. sur GitLab ou GitHub) contient l'historique partégé du projet
La branche de développement par défaut se nomme "main" (ou "master"). Tous les changements sont intégrés dans cette branche.
Ce workflow n'utilise pas d'autre branche.
Il peut convenir pour les petits projets avec très peu de collaborateurs.
git clone ssh://bob@host/path/to/repo.git
git clone ssh://alice@host/path/to/repo.git
git add some-file
git commit -m "Add some-file"
git push
git pull
git add some-file
git commit -m "Add some-file"
git push
git pull
Comme plusieurs développeurs travaillent sur la branche principale, il est difficile de trouver un moment stable pour déployer le projet (en prod).
Les développeurs doivent alors conserver les modifications instables en local jusqu'à ce qu'elles soient prêtes à être publiées.
La branche principale (master ou main) contient la version "distribuable" du projet.
Chaque nouvelle fonctionnalité est développée dans une branche dédiée plutôt que dans la branche principale.
Ainsi, les développeurs peuvent travailler sur leurs fonctionnalités sans modifier la branche principale.
La branche principale n'est plus polluée par des fonctionnalités inachevées (moins de risques de bugs).
C'est une nécessité pour les environnements d'intégration continue (CI/CD).
bob (???) $ git checkout main
bob (main) $ git checkout -b user-authentication
Les branches de fonctionnalité doivent avoir des noms descriptifs, comme "sso-authentication" ou "issue-#3029".
Chaque branche doit répondre à un objectif clair et précis.
bob (user-authentication) $ git add app.py
bob (user-authentication) $ git commit -m "Add a user authentication function."
bob (user-authentication) $ git push -u origin user-authentication
alice (main) $ git fetch
alice (user-authentication) $ git checkout -t origin/user-authentication
alice (user-authentication) $ git add app.py
alice (user-authentication) $ git commit -m "Add type hints."
alice (user-authentication) $ git push
Création d'une merge request
Bob indique que le merge la feature branch est prête à être fusionnée dans la branche principale
Le reviewer rejete la requête et demande un développement supplémentaire
Il peut préciser les modifications à apporter dans le code
bob (user-authentication) $ git pull
bob (user-authentication) $ git add app.py
bob (user-authentication) $ git commit -m "Add documentation"
bob (user-authentication) $ git push
Revue de la merge request
Approbation du merge par le reviewer
bob (user-authentication) $ git pull
bob (user-authentication) $ git checkout main
bob (user-authentication) $ git pull
bob (user-authentication) $ git branch -d user-authentication
bob (user-authentication) $ git push origin --delete user-authentication
bob (user-authentication) $ git fetch -p
On supprime la branche de fonctionnalité quand la fonctionnalité est achevée et mergée dans la branche principale.
alice (user-authentication) $ git checkout main
alice (user-authentication) $ git pull
alice (user-authentication) $ git branch -d user-authentication
alice (user-authentication) $ git fetch -p
Idéalement, une branche de fonctionnalité devrait avoir une durée de vie courte : quelques jours voir quelques heures.
Plus la durée de vie de la branche est longue, plus le risque de trouver des conflits d'intégration lors de la fusion avec la branche principale est élevé.
Chaque développeur a une branche personnelle sur le dépôt centralisé.
La branche principale reflète l'état du projet en production.
Les développeurs poussent leurs modifications de leur branche personnelle vers la branche principale quand les features ajoutées sont prètes.
Les développeurs peuvent travailler sur des fonctionnalités sans "polluer" la branche principale avec des fonctionnalités inachevées.
On a les mêmes avantages que le feature branching mais avec moins de branches (pour les petites équipes) donc plus facile à gérer.
Ça peut être une option si tous les développeurs travaillent sur des fonctionnalités différentes.
Ça peut être utile pour les développements longs qui ne tiennent pas sur un sprint.
Adapté dans le cadre d'un workflow de logiciel basé sur la livraison.
Gitflow fournit un canal dédié pour les hotfix vers la production.
Il a perdu en popularité.
Difficile à utiliser avec l'intégration et le développement continus.
Utilise des branches de fonctionnalité et plusieurs branches primaires.
Dans ce modèle, les développeurs créent une branche de fonctionnalité et attendent que la fonctionnalité soit terminée pour la merger à la branche « trunk » principale.
Outre les branches de fonctionnalité (feature), le workflow utilise des branches individuelles pour la préparation, la maintenance et l'enregistrement des livraisons.
Modèle de Référentiel Partagé
Modèle de "Fork & Pull"
Modèle de "Fork & Pull"
Modèle de "Fork & Pull"
git clone ssh://bob@host/path/to/repo.git
Modèle de "Fork & Pull"
Modèle de "Fork & Pull"
git clone ssh://alice@host/path/to/repo.git
Modèle de "Fork & Pull"
git add bob_file
git commit -m "Bob's update."
Modèle de "Fork & Pull"
git push -u origin main
Modèle de "Fork & Pull"
Exemple : le GitHub flow
https://docs.github.com/fr/get-started/quickstart/github-flow
Similaire au feature branch workflow
Les branches sont créées directement sur GitLab (i.e. sur le dépôt distant) via l'intégration au gestionnaire d'"Issues".
GitLab offre un workflow intégré, depuis le codage jusqu'à la production.
GitLab encourage l'utilisation des branches feature, des merge requests pour la révision du code, et des pipelines CI/CD pour l'automatisation des tests et du déploiement.
Restreindre les droits d'écriture dans la branche principale
Utilise des GitHooks et les GitLab Webhooks pour imposer la conformité des commits à des règles préétablies via des linters et outils d'analyse de code statique
Adopter une approche systématique dans l'utilisation de tests unitaires et outils de converture de code pour éviter les régressions
Un commit doit contenir des changements cohérents qui vont ensemble.
Les corrections de deux bugs différents doivent se retrouver dans deux commits différents.
Les petits commits sont plus faciles à relire pour les autres développeurs.
En cas de problème, il est plus facile de revenir en arrière avec des commits atomiques.
Source: Git à 100%, R. Hertzog, P. Habouzit. Ed Eyrolles
Faites des commits fréquents et prévenez les conflits.
Partagez votre code avec les autres développeurs le plus tôt possible.
Pour prévenir les conflits qui arrivent plus régulièrement en cas d'intégration tardive dans une branche.
Faire des commits peu fréquents et de grande taille augmente le risque de conflits et génère des conflits plus difficiles à résoudre.
Source: Git à 100%, R. Hertzog, P. Habouzit. Ed Eyrolles
Un commit doit contenir un travail complet.
Pour autant que possible, un commit doit être atomique i.e. pas trop volumineux.
Il ne s'agit pas de faire en un seul commit une fonctionnalité compliquée, mais de découper la fonctionnalité en plusieurs petites tâches, et de faire un commit pour chacune de ces tâches.
Ne faites pas un commit le soir avant de quitter le bureau juste pour avoir un répertoire de travail synchronisé. Pour ça, utilisez git stash nom / git stash apply.
Source: Git à 100%, R. Hertzog, P. Habouzit. Ed Eyrolles
Les messages s'adressent tant aux autres qu'à vous-même, ils seront lus par toutes les personnes qui vont ausculter l'historique et ses demander invariablement "pourquoi ce changement ? Qu'est-ce qui a changé ?" plutôt que "Comment fonctionne le code ?"
Un bon message de commit commence par un résumé d'une cinquantaine de caractères qui décrit le changement. Suit une ligne vide qui le sépare du message détaillé, qui sera aussi long que nécessaire.
Un bon message précise donc :
Source: Git à 100%, R. Hertzog, P. Habouzit. Ed Eyrolles
Source : https://xkcd.com/1296/
Testez votre code avant de publier un commit.
Don’t wait to test until everything has been merged into master. Test commits along the way to catch problems earlier in the process. And run all tests on all the commits, even if you have to run tests in parallel. Code reviews > merging into master. Why wait? "Don’t test everything at the end of the week," Sid writes. "Do it on the spot, because you'll be more likely to catch things that could cause problems, and others will also be working to come up with solutions."
https://about.gitlab.com/blog/2020/03/05/what-is-gitlab-flow/#follow-the-rulesQui fait les revues de code ?