Depuis quelques temps déjà, une nouvelle génération de gestionnaires de version a fait son apparition. Elle se différencie par son approche distribuée par opposition à l’approche centralisée sur laquelle repose Subversion. Nous allons dans ce billet comment cela se passe dans la pratique et ce que cela change pour le développeur.
Modèle centralisé
Rappelons tout d’abord le principe de fonctionnement de version (et de tous les systèmes de gestion de version non-distribués) afin de bien saisir les différences entre distribué et centralisé.
Subversion est donc composé d’un dépôt unique sur un serveur où se trouve l’ensemble des fichiers, de leurs versions ainsi que des branches qui permettent de gérer plusieurs versions du projet en parallèle.
Les développeurs (Alice et Bob par exemple) récupèrent une version du projet sur leur poste de travail (avec la commande checkout) pour pouvoir commencer à travailler dessus. Au quotidien, ils mettent à jour leur copie de travail local (update) depuis le serveur Subversion et renvoient leurs modifications (commit) vers ce même serveur. Ce mode de fonctionnement permet aux développeurs de travailler en parallèle sur le projet, de partager leurs modifications et de versionner les fichiers qu’ils modifient.

Modèle distribué
Origine de Git
- les versions contenant des patchs expérimentaux,
- celles servant d’incubateur aux nouvelles fonctionnalités (« zone de quarantaine » avant d’être décrétés suffisamment stables pour être intégrées dans la branche principale),
- les versions de maintenance
- ou encore celles dédiées à un matériel particulier.
Fonctionnement

git init # initialisation du dépôt
git add ... # ajout de fichiers
git commit -a # commit des modifications/ajouts dans le dépôt
- il est possible de travailler déconnecté du réseau puisque aucun serveur n’est requis et l’on garde tous les avantages de la gestion de version (parcours de l’historique, retour à une version précédente, …),
- il est plus facile pour le développeur de versionner ses modifications puisqu’il ne craint plus d’impacter les autres développeurs si la fonctionnalité n’est pas tout à fait stabilisée (versionner et partager deviennent alors deux actions distinctes). En effet, peut importe le nombre de versions qu’il créé, il a la possibilité de les partager seulement lorsqu’il a terminé sa fonctionnalité (il a même la possibilité de créer une seule version sur le dépôt partagé à partir de plusieurs versions locales). Cela évite les effets pervers de versions trop macroscopiques qui contiennent la correction de plusieurs bugs (voir même plusieurs fonctionnalités). Des versions plus régulières permettent de partager la correction d’un bug indépendamment d’autres modifications qui n’auraient rien en commun avec ce bug.

git branch feature1 # création de la branche feature1
git checkout feature1 # passage de la copie de travail sur la branche feature1
… (commits sur feature1)
git checkout master # retour sur la branche master
git merge feature1 # merge des modifications depuis la branche feature1 vers master (branche courante)
Maintenant que le dépôt de l’utilisatrice Alice est initialisé et fonctionnel, Bob va pouvoir cloner (avec clone) le dépôt d’Alice. Il retrouve alors tous les fichiers du dépôt d’Alice, mais aussi toutes leurs versions et les branches partagées du dépôt.

git clone $alice_repository
Le dépôt de Bob n’est alors plus dépendant de celui d’Alice. En effet, Bob a le choix lorsqu’il clone le dépôt d’Alice :
- il peut « forker » le projet d’Alice en restant indépendant et ne plus jamais se synchroniser et faire vivre son projet sans lien avec le projet d’origine,
- il peut se mettre à jour régulièrement depuis le dépôt d’Alice (pull) afin de faire évoluer son projet en parallèle sans remonter la moindre version à Alice,
- ou encore, il peut choisir de renvoyer ses modifications (push) à Alice pour rester synchronisé.

Du point de vu d’Alice :
git pull $bob_repository
git push $bob_repository
L’approche distribuée a forcé les outils comme Git à travailler sur ces aspects et il faut avouer que l’utilisation des branches devient agréable. On découvre des cas d’utilisation que l’on n’osait pas appliquer avec Subversion.
Il est, par exemple, intéressant de créer une branche par fonctionnalité pour pouvoir travailler sur plusieurs fonctionnalités en parallèle. Un développeur peut alors expérimenter plus facilement en travaillant sur ses branches, il gère les changements de priorité des fonctionnalités en mettant de côté les branches moins prioritaires pour les reprendre plus tard.
Git permet non seulement de le faire simplement mais aussi avec une rapidité déconcertante puisque tout est local, plus besoin de télécharger tout le projet lors d’un changement de branche.
Mais alors pourquoi tout le monde n’utilise pas un gestionnaire de version distribué s’il semble n’y avoir que des avantages ?
La raison est simple : ces outils restent encore jeunes. Non pas qu’ils ne soient pas stables (le noyau Linux est un bon test aux limites qui montre qu’ils fonctionnent) mais plutôt que l’écosystème des outils qui les intègre manque encore de maturité. Si Subversion est aussi populaire aujourd’hui, c’est aussi pour son intégration avec quantité d’outils liés au développement (bug tracker, IDE, …). Il existe par exemple un plugin Git pour Eclipse ou pour Jira mais ils ne sont pas encore complets et/ou utilisables par le commun des mortels.
Une autre limite du modèle distribué est que sa flexibilité apporte aussi une complexité potentielle plus importante qu’avec un modèle centralisé. En effet, comme il est possible d’échanger entre tous les dépôts sans restriction, le premier besoin est d’organiser le processus d’interaction avec le gestionnaire de version. Alors qu’avec le modèle centralisé, la version à jour est celle du dépôt unique, il est nécessaire de mettre en place un dépôt qui joue ce même rôle avec un gestionnaire de version distribué.
Enfin, la simplicité de création d’une branche peut conduire les développeurs à ne plus trop savoir qu’elle est la dernière version de leur projet.
Cet article pose les bases des gestionnaires de version distribués afin d’aborder dans un prochain article, la mise en place d’un build d’intégration continue « incassable » grâce à Git.
4 commentaires sur “Introduction à la gestion de version distribuée”
Merci David pour cet article. J'ai mieux compris l'intérêt et aussi les inconvénients d'une gestion de source distribuée.
(Merci à Alice & Bob également ;-) )
The Bob
Merci. Vraiment très intéressant.
J'ai juste un peu perdu le fil un moment sur le pull et le push. En effet on commence ? expliquer le principe du point de vue de Bob. Puis le schéma. Cela m'a déconcerté. J'ai relu, puis rerelu, en essayant de comprendre le sens des flèches.
Je me suis dit 'à revoir plus tard' et j'ai continué. Et là miracle : sous le schéma une indication qui montre qu'on prend en compte le point de vue d'Alice. Tout s'explique. :-)