Comprendre Git
Les types d'objets de Git
Les objets Git sont les données de Git, il y a 4 types d'objets principaux Blob, Tree, Commit, Tag.
Les objets sont stockés dans le répertoire Git qui se trouve généralement à la
racine du projet .git/objects/
.
Prenons un exemple simple de bibliothèque python:
.
├── README.rst
├── setup.py
└── src
└── simple.py
Blob
Les Blobs sont les contenu des fichiers.
. │
├── README.rst │ blob: c473879
├── setup.py │ blob: b44050e
└── src │
└── simple.py │ blob: 3d81cdc
explorons les blobs:
$ git cat-file -t c473879
blob
$ git cat-file -p c473879
=======================
Simple librairie python
=======================
Ceci est une fausse bibliothèque pour montrer le
fonctionnement interne de git.
Important: notez bien que seulement le contenu des fichiers est stocké et non le fichier, les noms et modes du fichier sont stockés dans les objets de type Tree
Tree
Les répertoires correspondent aux trees.
. │ tree: 0332ef0
├── README.rst │ blob: c473879
├── setup.py │ blob: b44050e
└── src │ tree: ed93e4e
└── simple.py │ blob: 3d81cdc
Le contenu d'un objet de type tree est une liste d'objets trees ou blobs avec chaque entrée le mode, le type, le sha et le nom:
$ git cat-file -t 0332ef0
tree
$ git cat-file -p 0332ef0
100644 blob c47387 README.rst
100644 blob b44050 setup.py
040000 tree ed93e4 src
Commit
Le commit permet de gérer l'historique.
│ commit: 825d425
. │ tree: 0332ef0
├── README.rst │ blob: c473879
├── setup.py │ blob: b44050e
└── src │ tree: ed93e4e
└── simple.py │ blob: 3d81cdc
Un objet commit contient un pointeur vers un objet tree, un auteur, un committer, un message et les commits parents.
$ git ls-tree 825d425
100644 blob c47387 README.rst
100644 blob b44050 setup.py
040000 tree ed93e4 src
$ git cat-file -t 825d425
commit
$ git cat-file -p 825d425
tree 0332ef0
author Pierre Verkest <[email protected]> 1461854704 +0200
committer Pierre Verkest <[email protected]> 1461854704 +0200
Initial commit
Comme c'était le commit initial, il n'y a pas de commit parent, voici ce que ça donne avec un second commit
$ git l
* faad5e8 (HEAD, master) Implement Hello the world
* 825d425 Initial commit
$ git cat-file -p faad5e8
tree 69012a
parent 825d42
author Pierre Verkest <[email protected]> 1461856311 +0200
committer Pierre Verkest <[email protected]> 1461856311 +0200
Implement Hello the world
Note: un commit qui merge 2 branches aura 2 parents!
Tag
L'objet de type tag permet de faire des raccourcis vers un commit en particulier
│ tag: bf207a373
│ commit: 825d425
. │ tree: 0332ef0
├── README.rst │ blob: c473879
├── setup.py │ blob: b44050e
└── src │ tree: ed93e4e
└── simple.py │ blob: 3d81cdc
Un tag contient les informations d'objet sha vers lequel il pointe, le type (normalement un commit), le tag lui même, la personne ayant créé le tag, un message et il peut également contenir une signature gpg pour permettre de valider l'intégrité d'une version ou d'une release.
$ git cat-file -t bf207a373
tag
$ git cat-file -p bf207a373
object 825d425
type commit
tag v1
tagger Pierre Verkest <[email protected]> 1461858515 +0200
Realease v1
Important: Les branches (qui pointent également vers des commits) ne sont pas sauvegardées comme des objets.
Les références
Nous venons de voir les objets qui ne peuvent pas être modifiés, à l'inverse
les réfénces, également enregistrées (répertoire .git/refs
) par git peuvent
changer constamment. Ce sont de simples pointeurs vers des commits, un peu comme
des tags mais plus facilement modifiables.
Le modèle
Schématisons l'exemple ci dessus
Pour rappel au premier commit nous avions ajouté l'ensemble des fichiers suivants :
│ tag: bf207a373
│ commit: 825d425
. │ tree: 0332ef0
├── README.rst │ blob: c473879
├── setup.py │ blob: b44050e
└── src │ tree: ed93e4e
└── simple.py │ blob: 3d81cdc
Puis au second commit nous avons modifié le fichier simple.py
nous arrivons
donc à l'état suivant:
$ git l
* faad5e8 (HEAD, master) Implement Hello the world
* 825d425 (tag: v1) Initial commit
Ce chapitre est très grandement inspiré de l'excellent document Git Internals de Scott Chacon