Concepts Avancés
Versionnement et synchronisation
Comment Git fait pour faire ce qu'il fait de mieux, à savoir le versionnement ?
Tout d'abord, il faut comprendre qu'entre deux commits différents, si des fichiers ont des contenus identiques ils ne seront stockés en dur sur votre machine qu'une seule fois.
De façon analogue, si dans un repertoire, vous possédez 1 000 fichiers ayant un contenu identique mais tous des noms différents, vous n'aurez qu'un seul fichier d'enregistré sur votre disque. Bien entendu, on retrouvera la trace des 1 000 fichiers avec leurs noms dans le récapitulatif, mais le contenu ne sera sauvegardé qu'une et unique fois.
Mais comment est-ce possible ? (cf SHA1)
Dans le cas d'un serveur distant comprenant votre projet, Git vous propose plusieurs protocoles pour récupérer vos données :
- HTTP
- HTTPS
- SSH
- Git
Un autre avantage de Git est qu'il n'éxiste aucune différence de configuration entre un server et un client, puisqu'il suffit de contenir le repertoire du projet pour bénéficier de tout l'historique. Et que par le mécanisme simple du SHA1 étudié plus bas, il est très facile de connaître les commits distants que l'on ne possède pas en local et que l'on voudrait récupérer.
SHA1
SHA1 est un algorithme de Hashage prenant un entrée jusqu'à 264 bits, et retourne une suite unique de 40 caractères Héxadécimaux.

C'est ce procédé qu'utilise Git pour connaitre les objets qu'il a à sauvegarder. En effet, Git se moque des noms des fichiers, il ne considère que le contenu. En hashant le contenu d'un fichier, il obtient une série de digits unique symbolisant le fichier. Ainsi, si un autre fichier produit la même suite de digits, alors le contenu des deux fichiers est identique et n'ont pas besoin d'etre sauvegardés deux fois.
Les Objets Git
Les objets Git sont définis par trois champs : Leur Type, leur Taille et leur Contenu.
Le contenu d'un objet Git est fait de la façon suivante : Header + contenu.
Le header contient le type d'objet dont il s'agit, la taille en octet, et enfin son contenu
Comme Objets Git on trouve :
- Le Blob, pour Binary Large Object. Il représente plus communément un fichier.
- Le Tree. Il représente plus communément un repertoire ou dossier de votre application. Son contenu est la liste des SHA1 des Blobs ou autres Trees qu'il peut contenir. Ce qui donne une arborescence de fichiers.
- Le Commit. Il s'agit de l'état complet de votre projet à un instant donné (cf snapshot première partie). Son contenu est le SHA1 du Tree source, et différentes informations comme le nom du commit, le nom de l'auteur, la date etc..
- Le Tag. Il s'agit d'un objet servant à qualifier un commit particulier en lui attribuant un commentaire.
- config : fichier relatif à la configuration de l'environnement Git, comme par exemple des informations sur le développeur (son nom, son email ...)
- description : contient les informations sur votre projet
- objects/ : c'est dans ce répertoire que sont stockés tous les objets Git (commits, tags, trees, blobs)
- ref/* : contient les informations sur les branches locales du repository
- logs/* : contient les messages de logs
- index : fichier contenant des informations sur l'état du prochain commit
- HEAD : Pointeur sur la branche actuelle
- hooks/ : Dossier contenant des
hooks
outriggers
, c'est à dire des actions/scripts pouvant être éxectués en pre ou post condition

Le schéma ci-dessus représente la structure des objets Git dans un projet donné. On voit bien que chaque élément possède un SHA1 unique et possède la liste des SHA1 qu'il contient dans le cas d'un commit ou d'un Tree. Ceci a pour effet de donner un structure pyramidale, si le contenu d'un blob change alors son SHA1 sera automatiquement différent. Si ce dernier change de SHA1, alors le SHA1 du tree le contenant change également par répercussion puisque ce dernier contient le fichier. Et de fil en aiguille on remonte finalement au commit qui voit son SHA1 changé.
Deux commits avec deux SHA1 différents représentent donc deux versions différentes de votre projet puisqu'on est sûrs que le contenu d'au moins un fichier a changé.
Le Stockage
Comment sont stockés les fichiers sur le disque dur ? Voilà une bonne question. Une autre force de Git est sa simplicité. En effet, ce dernier ne comporte qu'un seul dossier appelé .git
à la racine de votre projet et c'est tout... Ce dernier contient tout l'historique du projet.
Voyons à quoi cela ressemble :
On pourrait également se dire que puisqu'un seul fichier contient l'historique de tout le projet, et donc tous les fichiers, le poids en octet de ce dernier peut grossir très vite et devenir pénalisant
et terme de performance.
La réponse est non grâce au système de compression Zlib
qu'utilise Git pour compresser les données et conserver un poids correct.
Enfin, SHA1 intervient encore dans le stockage des fichiers. En effet comment retrouver un objet en particulier ? Ces dernier sont stockés dans : /.Git/objects/ .
Admettons que vous cherchiez le blob 4A558...
. Git va créer un repertoire du nom des 2 premiers caractères du SHA1, et stocker le contenu compressé du fichier avec Zlib sous le nom des 38 caractères restants.
Ainsi on obtient l'arborescence suivante : /.Git/objects/4A/558...