Et si vous regardiez Git comme une base de donnée ? – Les entrailles

Aujourd’hui, tout le monde ou presque utilise Git comme outil de gestion des sources. Mais n’avez-vous jamais pensé à utiliser Git pour autre chose que gérer vos codes sources ?

 

Pour ma part c’est, entre autre, la lecture de progit et du chapitre dédié aux entrailles de Git qui a commencé à m’y faire penser. En effet, si vous regardez (vraiment) bien, git peut être vu comme une “simple” base de donnée clé/valeur. Bon ok, simple mais avec tout de même une gestion de l’historique, faut pas oublier ce qui fait l’essence de Git quand même. Et c’est là tout l’intérêt de la chose.

 

Lors du dernier Sogiday, nous avons eu l’occasion de travailler sur ce point : utiliser Git comme moteur de stockage pour une application.

 

Voici donc la première partie relatant cette exploration : les entrailles deGit !

Et si on commençait en parlant un peu de Git quand même ?

Pourquoi vouloir utiliser Git pour stocker des données (autre que du code) ? C’est pas faute d’avoir un grand nombre de bases de données disponibles.

Oui, mais. Il y a plein de choses sympa avec Git. La première étant évidemment l’accès à l’historique. Pouvoir remonter dans le temps peut être vraiment intéressant suivant les données que l’on manipule. Et avec Git c’est en standard (c’est un peu le but…).

 

Mais Git permet aussi de facilement gérer la réplication. Il suffit de faire un clone.

 

Git est aussi plutôt pratique pour scripter des actions. Si on souhaite envoyer une notification à chaque fois qu’une donnée est modifiée, il suffit d’utiliser les hooks.

 

Une autre raison est de pouvoir imaginer sauvegarder des données simplement dans une branche d’un dépôt de code. Par exemple que les bugs, le backlog, les choses à faire, votre kanban, etc., peuvent être persistés directement dans une branche de votre dépôt, juste à côté de votre code. Ces données deviennent donc synchrônes de votre code, vous clonez votre logiciel vous avez automatiquement les choses à faire. Sympa, non ?

 

Et puis ça semble fun aussi !

Enregistrer une donnée dans Git

La première étape est de pouvoir enregistrer une donnée dans Git.

 

La version naïve serait la suivante :

  • créer un fichier dans un dépôt Git
  • écrire les données qu’on souhaite dans le fichier
  • committer le fichier

 

Ok, ça fonctionne. Par contre, ce n’est quand même pas génial. Il faut gérer les fichiers à la main. Faire des commits et autre. En gros, juste écrire un wrapper au dessus des commandes haut niveau de Git.

 

Le problème, c’est qu’on n’est pas tellement au niveau du stockage des données, on est au niveau du stockage des fichiers. Et c’est pas exactement pareil. Et surtout, Git nous offre des outils bien plus précis.

 

Git permet de créer des blobs de données, sans manipuler des fichiers. Et ça c’est cool.

Git, clés et valeurs

Allez, un petit exemple :

Et là, j’ai un blob. Alors oui, en vrai un fichier a été créé :

Et on peut évidemment demander à git de nous afficher la valeur correspondant à ce hash :

Nous avons alors une base de donnée clé/valeur ! Pour une valeur on nous donne une clé, et si on demande à Git la valeur de la clé, il nous la donne. C’était pas si dur quand même 🙂

 

Enfin presque.

 

Le problème est que si nous changeons la valeur… la clé va changer. Et là nous sommes face à un sérieux problème. Comment accéder correctement à une valeur si la clé change tout le temps ?

Promenons-nous dans les bois, pendant que…

En effet, la solution se trouve derrière un arbre.

Nous venons de créer un tree qui pointe vers notre blob. Mais surtout, nous venons d’ajouter une clé, 1.json, qui elle ne devrait pas bouger à chaque modification de valeur.

 

Et histoire que tout soit bien enregistré, nous pouvons commiter le tree ce qui va permettre de l’horodater, d’ajouter un message lors de la création.

Histoire de vous assurer que tout s’est bien passé comme prévu, vous pouvez demander à Git de vous afficher les informations liées à ce hash :

Il manque enfin une dernière chose : il nous faut une référence pour pouvoir y accéder facilement.

Si on regarde le fichier .git/refs/heads/master nous avons bien le commit créé :

Nous avons donc la structure suivante :

Ok c’est bien joli tout ça, mais on va pas maintenant devoir faire un checkout et lire le fichier à la main quand même ? Evidemment non, sinon ça ne servirait à rien et le côté base de données serait assez peu pratique.

Tree et blobs en chaine

Alors, plutôt simple, non ? Maintenant, pour bien comprendre comment cela fonctionne, faisons la même chose avec une clé plus complexe.

 

Au lieu d’enregistrer mon blob sous 1.json je vais le faire sous items/json/1.json :

A ce moment on ne voit pas beaucoup de différences. Et pourtant ! Si vous regardez dans le répertoire .git/objects vous n’avez pas 2 objets (le blob et le tree) mais 4 :

Pour commencer à explorer, regardons ce qui est derrière 7eccf3dc9a845af20fca5f41c9d0f5077e167c12 :

Nous avons bien un tree, comme précédemment. Mais celui-ci contient uniquement items/ comme enfant, et non items/json/1.json par exemple.

 

Visualisons alors l’arbre :

Voici donc ce qui se cache derrière. Notre arbre contient un enfant items. Qui est un arbre contenant un enfant json. Qui est un arbre contenant un blob 1.json. Vous pouvez aussi faire un show sur chaque hash pour voir le détail.

 

Vous pouvez alors créer un commit et mettre à jour master :

La structure est donc désormais ainsi :

Bien évidemment vous pouvez toujours récupérer le contenu par votre clé :

Conclusion

Cette première partie à la découverte (succinte) de Git est terminée. Vous avez pu voir que git nous offre réellement la possibilité d’utiliser ses couches internes et nous expose son modèle de stockage. Ceci permet d’imaginer de nouvelles utilisations de git et surtout autrement qu’en wrappant les commandes Git de haut niveau ce qui serait ni agréable, ni fiable, ni amusant.

 

Le prochain article vous permettra de réaliser la même chose qu’ici mais intégré dans un code Ruby.

 

Un dernier point sur git avant de se quitter. Sogilis dispense aussi des formations Git !