Le nombre d’utilisateurs de git va croissant, usage personnel, en entreprise… Mais pour avoir observé le profil de quelques centaines de stagiaires durant les formations git, je dirais que sur l’ensemble, 80% disaient avoir déjà utilisé git depuis quelques mois. Et sur ces 80%, moins de 1% connaissent le fonctionnement interne de git.

Ok pour les chiffres mais pourquoi mettre les mains dans la plomberie ? “J’ai ma liste de commandes que j’utilise tous les jours, ça me suffit”. Sauf que quand les choses se gâtent, impossible de comprendre le pourquoi du comment…

D’où l’utilité de plonger les mains dans les entrailles de l’outil.

Git : tout est objet… enfin presque

 L’organisation des métadonnées de Git s’inspire grandement d’un système de fichiers. Tout repose sur des objets pour stocker les données et métadonnées. Avant d’aller plus loin gardons en tête que ces objets ont des caractéristiques communes :

  • chaque objet est identifié par une somme de contrôle pour garantir son unicité et son intégrité, en l’occurrence un SHA1.
  • chaque objet est immuable. Un objet créé n’est jamais modifié ni supprimé.
  • L’ensemble de ces objets sont stockés dans le dépot local, dans le répertoire .git/objects

Une fois ces pré-requis posés passons au premier objet de la liste, le blob. C’est simple, il propose le contenu intégral d’un fichier enregistré dans le projet à un moment donné de l’historique. Il est identifié par un SHA1. Le blob ne fait pas référence au nom de fichier. Pour chaque fichier, on peut trouver n blob qui représentent les n versions enregistrées.

Dans le jargon du système de fichiers on pourrait rapprocher le blob du fichier.

Le deuxième objet est le tree. Il décrit l’arborescence du projet et toujours en suivant notre parallèle avec le système de fichiers, il serait l’équivalent du répertoire. Les trees pointent l’ensemble des fichiers et répertoires, leurs noms ainsi que les SHA1 des objets correspondant. Ils contiennent également les informations d’horodatage et de permissions.

    Les blobs et trees sont assez peu utilisés dans la pratique quotidienne de git. Le troisième objet l’est : le commit. L’objet ne contient pas de code en lui-même. Il contient les éléments suivants :

    • le message de commit que vous avez peaufiné bien sûr
    • l’identité du committer et l’auteur – cette différenciation permet de tracer exactement l’origine du code, même si vous n’avez pas les droits de commit
    • un pointeur vers un tree : le commit pointe un tree spécifique représentant un état donné à un moment donné du projet
    • un parent : un pointeur vers le commit qui le précède immédiatement. C’est ce qui permet de construire l’historique des commits.

    Simple non ? Allez on remet tout bout à bout : un commit pointe un tree qui lui-même pointe des trees et des blobs.

    Git, c’est aussi des références

    OK on a des commits mais comment les organise-t-on ? Git est basé sur la notion de branche. Mais c’est quoi au final une branche ? C’est tout simple : une branche référence un commit spécifique, en l’occurrence le dernier réalisé sur la branche en question. Ce commit porte le nom de HEAD. Et tout ça se passe dans le répertoire .git/refs/heads : un fichier par branche définie, chaque fichier contient le SHA1 du commit de HEAD .

    Prenons un exemple : mon projet dispose de 2 branches

    # git branch
    dev
    * master

    Je retrouve ces branches dans le dossiers des fichiers de branche : 

    # ls .git/refs/heads
    dev master
    # cat .git/refs/heads/master
    3d7bb81994a5eaaf9eca5f12f335a8c0491eca56

    Je vérifie la nature de ce SHA1 en visualisant l’historique de la branche master :

     git log --oneline master 
    3d7bb81 images utilisées pour les supports git
    bf98d90 Utilisation du nouveau template pour la formation git avancé
    10d16d7 Utilisation du nouveau template de slides pour git en pratique
    aba2d6a Merge branch 'feature1' into 'master'

    Tout y est !

    Une dernière chose : il reste à enregistrer la branche courante pour savoir toujours où se situer dans le projet. L’information est tout simplement stockée dans le fichier .git/HEAD.

    # cat .git/HEAD
    ref: refs/heads/master

    Voilà pour la plomberie  et ce premier article sur Git. Allez plus loin avec nos formations et sinon rendez-vous dans le prochain article.