Git Virtual File System, du code, beaucoup de code

Les équipes de développement logiciel, en société d'édition, de service ou en entreprise qui fait du développement en interne partagent du code, des fichiers et des ressources, L'organisation des équipes devient un élément clé pour la réussite des projets, ou à minima assurer la bonne entente entre les membres !

Git est universellement reconnu pour son efficacité quand il s’agit de gérer des dépôts de code de tailles différentes face à des équipes -elles aussi- de tailles différentes.

Cependant, Git a montré ses limites avec l'augmentation parfois démesurée de certains projet par rapport aux années 90. En effet, Git a été conçu dans le cadre du développement du Kernel Linux qui devait tenir sur une disquette, tourner sur des machines de 4Mo de Ram tout en laissant un peu de souffle à des applications tierces !
Linus Torvalds lui-même a commenté les dépôts du Kernel Linux qu'il a décrit comme gros et immenses, avec 200Mo de code étalés sur quelques 60000 fichiers.

Le fait est que Microsoft a intégré Git comme gestionnaire de dépôts dans Visual Studio Team Services (VSTS)  et y a hébergé entre-autres le code source de Windows, rien que ça !

Le code de Windows, c'est près de 3.5 millions de fichiers, un dépôt de 300GB utilisé par 4000 personnes qui génèrent plusieurs centaines de builds dans plusieurs centaines de branches et des milliers de pull requests... quotidiennement.

Sachant que dans ce cas précis, un checkout prend 3 heures, un clone 12 heures, un commit 30 minutes et un simple status 8 minutes, dire que l'outil devient un frein à la productivité est tout sauf un euphémisme.

Il existe déjà Git LFS, censé mieux gérer les fichiers binaires volumineux, mais ce dernier est parfaitement inadapté au cas de milliers de petits fichiers.

Certes, tout le monde ne développe pas un logiciels avec des proportions comparables à Windows, mais il m'a été donné de voir des projets d'une taille honorable, avec un grand nombre de branches actives ou pas... etc et qui connaissent, à moindre échelle, le même type de contraintes que les équipes de Microsoft ont rencontré.

Mais alors, que faire ?

Microsoft, justement, nous apporte une solution que je vous propose d'explorer ici: Git Virtual File System (GVFS), un projet Open Source sur Github censé répondre à cette problématique et dont  l'ambition serait d'être adopté dans le projet original afin de faire profiter toute la communauté.

GVFS virtualise le système de fichier de votre dépôt Git local pour qu'un client Git puisse virtuellement y avoir accès, là où en réalité, les fichiers ne sont pas physiquement présents sur le disque. GVFS s'occupe de télécharger les fichiers en cas de besoins.
Il s'occupe parallèlement de gérer l'état des fichiers en interne de manière à ne tenir compte que des fichiers auxquels vous avez accédé, au lieu d'examiner la totalité des fichiers du dépôt. Cela permets à des opérations telles que checkout ou status de s'exécuter aussi vite que possible.

Pour ce faire, GVFS télécharge lors du clone l'arborescence et l'historique du dépôt. C'est seulement à l'ouverture d'un fichier que ce dernier sera physiquement téléchargé. Concrètement, selon les tâches que l’on réalise, on se retrouve avec une petite partie du dépôt au lieu de la totalité.

Parallèlement, GVFS tient à jour la liste des fichiers ouverts. Lors d'un status par exemple, le client Git aura l'illusion d'examiner tout le dépôt alors qu'en réalité, les accès vers le disque ne se font que sur les fichiers de cette liste, le reste des informations provenant des métadonnées que GVFS garde du reste du dépôt distant.

A ce stade, il est légitime de se poser la question de la compatibilité avec avec le standard Git. Effectivement, le fonctionnement de GVFS impose quelques modifications au niveaux client ET serveur.

Le développeur devra naturellement installer le driver virtuel GVFS sur une machine sous Windows 10 version 1703 ou plus, et ajouter un fork du client Git pour Windows patché pour l'occasion par Microsoft. Celui-ci fonctionne comme le client standard sauf si l'option gvfs dans le fichier .git/config est sur true.
Le serveur Git pour sa part doit pouvoir accepter des requêtes REST supplémentaires. VSTS est aujourd’hui le seul serveur à intégrer cette API nativement et le serveur BitBucket fournit une extension en bêta à ajouter au moment de l’installation.
Il est enfin à noter que Microsoft a annoncé lors du dernier événement Connect(); 2017 la collaboration avec GitHub pour porter cette technologie sur les serveurs de ce dernier ainsi que sur Mac et Linux.

Maintenant que ce rapide tour théorique est fait, passons à un peu de pratique.

Installer GVFS

Nous allons tout d'abord récupérer le code source de GVFS depuis Github.

Pour compiler GVFS depuis le code source, il faudra :

  1. Disposer de Visual Studio 2017 Community Edition ou plus
  2. Inclure (ou ajouter par après) les composants suivants (Les versions sont importantes) :
    • Outils de développement .Net Framework 3.5
    • Prise en charge C++/CLI
    • Outils VC++ 2015.3 v140
    • Windows 10 SDK (10.0.10240.0)
  3. Installer InnoSetup 5.5.9 ou plus récent (http://www.jrsoftware.org/isdl.php) dans le dossier par défaut. Si ce dernier est installé dans un dossier personnalisé, il faudra adapter le fichier GVFS.csproj en conséquence.
  4. Créer un dossier pour cloner le dépôt de GVFS
  5. Ouvrir GVFS.sln dans Visual Studio. Ne rien modifier ni mettre à jour.
  6. Générer GVFS.sln

Tester GVFS

GVFS nécessite pour fonctionner Windows 10 Creators Update (Windows 10 version 1703) ou plus récent.
Installer Git pour Windows (2.13.0.gvfs.1 ou plus récent), le client patché pour GVFS depuis https://github.com/Microsoft/git/releases 

Version de git modifiée pour GVFS

Installer GVFS qui a été généré par Visual Studio précédemment. L'installeur devrait se trouver dans

C:\{dossier du code source GVFS}\BuildOutput\GVFS\bin\x64\[Debug|Release]\Setup\SetupGVFS.exe

Ouvrez un invite de commande et explorez l’aide en ligne :

 

La commande gvfs help

Une commande très utile à ce stade :

gvfs help <commande>

où <commande> représente une des commandes de gvfs.

GVFS fonctionnera avec n'importe quel service qui supporte le protocole GVFS. Pour le test nous serons amenés à créer un dépôt dans VSTS (si ce n'est déjà fait) et d'y pousser du contenu (un projet hello world suffira mais quelque chose de plus volumineux nous permettra de mieux comprendre l’intérêt de cette feature).

Important, Il y a 2 contraintes à respecter au niveau de votre dépôt :

  1. Il ne devra PAS contenir de filtres type clean/smudge. En effet ces filtres servent à lancer des scripts à la volée lors des stage/checkout en passant par les entrées/sorties standards, ce que GVFS ne peut gérer. Ceci implique donc qu'il est impossible de combiner GVFS et Git LFS.
  2. Votre dépôt devra contenir un fichier supplémentaire à sa racine : .gitattributes avec comme contenu :
* -text

Clonez votre projet dans un dossier dédié:

gvfs clone [-b branche] <URL du dépot> [nom_de_dossier]

GVFS construira une arborescence dans le dossier que vous avez choisi en ajoutant le sous-dossier \src qui contiendra le dépôt local (à la différence de git clone qui copiera le code à la racine du dossier).

Le dossier de niveau supérieur sera appelé le «GVFS enlistment», il contient à minima les dossiers \.gvfs et \src

Vous pouvez travailler avec git comme d'habitude.

Attention, rappelez-vous que la version de git est le fork de Microsoft, il fonctionne normalement avec tous les dépôts Git sauf ceux exploitant GVFS. Si vous utilisez un outil tiers (type SourceTree, GitKraken...) assurez-vous de sa compatibilité. A cette heure, le client de Visual Studio 2017 et SourceTree sont parfaitement compatibles, GitKraken annonce le support de GVFS pour une prochaine version.

Après avoir ajouté le fichier .gitattributes à la racine de mon projet :

Fichier .gitattributes et son contenu


je clone ce dernier dans 2 dossiers différents, l’un avec git et l’autre avec gvfs :

Clonage du même dépôt dans des dossiers différents pour git et gvfs


et voici le résultat :

L'état des dossiers après le clonage

Je vous laisse regarder le fichier sparse-checkout :

sparse-checkout contient l'index des fichiers "hydratés" par GVFS


maintenant, ouvrons les deux projets dans Visual Studio. DEV02 mettra plus de temps à s’ouvrir puisqu’à chaque fois que le contenu d’un fichier est demandé par l’éditeur, GVFS ira le chercher (hydrater) en temps réel.

L'état des dossiers après l'ouverture dans Visual Studio 2017

Vous remarquerez aussi que le fichier sparse-checkout a évolué.

Selon le volume de votre projet et le travail que vous avez effectué, la fluidité des opérations git habituelles ainsi que l’occupation de l’espace de votre disque seront de plus en plus contrastées selon que vous exploitiez GVFS ou pas.

A la fin du travail, vous pouvez «démonter» le volume:

gvfs unmout

puis le remonter si besoin

gvfs mount

Conclusion

GVFS a été la réponse à un besoin précis dans un contexte précis, mais à bien des égards, il mériterait sa place au sein du projet Git standard :

  1. Il répond à une problématique que de plus en plus d’entreprises devront gérer ou gèrent déjà : les projets informatiques modernes, de par leur compléxité mais également la facilité de gestion apportée par les IDEs actuels, les méthodes de gestion de projets et la multiplication de frameworks ouverts, prennent de l’ampleur, du volume.
  2. Il ne constitue pas une régression dans les spécifications de Git, bien au contraire, et il s’y intègre assez correctement.
  3. Si l’on passe sur l’opération de clonage qui se fait avec la commande gvfs, ce dernier ne modifie en rien la manière de gérer le code source au quotidien, puisque la configuration ne se fera qu’une fois au départ.
  4. Il est Open Source et l’ambition affichée par Microsoft est de le faire adopter au sein de la spécification standard du protocole Git. D’ailleurs, code source et spécifications techniques sont ouverts pour être adoptés par les fournisseurs de serveur Git.
  5. La gestion du code source de Windows est rendue possible grâce à GVFS !

Bien que ce soit un projet récent et encore en phase de développement, avec ce que ça implique du point de vue de la stabilité,  il est fort à parier qu’il sera rapidement un incontournable des gros dépôts de code source.

Références

  • Visual Studio 2017 : https://www.visualstudio.com/downloads/
  • Site officiel de GVFS : http://gvfs.io/
  • Dépôt Github de GVFS : https://github.com/Microsoft/GVFS
  • Microsoft annonce la collaboration avec GitHub : https://blogs.msdn.microsoft.com/bharry/2017/11/15/connect-announcements/
  • Client Git modifié : https://github.com/Microsoft/git/releases
  • Protocole REST pour serveurs Git : https://github.com/Microsoft/GVFS/blob/master/Protocol.md
  • InnoSetup : http://www.jrsoftware.org/isdl.php
  • Saeed Noursalehi (PPM du projet) : https://www.visualstudio.com/fr/learn/git-at-scale/
  • Billet de blog annonçant GVFS : https://blogs.msdn.microsoft.com/bharry/2017/05/24/the-largest-git-repo-on-the-planet/
Tarik Ouali