J'ai décidé de faire un peu de tests afin de mieux comprendre le format et la recherche de certains des champs plus en détail. Les résultats ci-dessous sont à la version 1.8.5.2
. J'ai marqué des points qui, je ne sais pas / n'en ai pas trouvé avec TODO
: n'hésitez pas à compléter ces points.
Comme d'autres l'ont mentionné, l'index est stocké dans .git/index
, non pas comme un standard de l'arborescence de l'objet, et son format est binaire et documentée à:
https://github.com/git/git/blob/master/Documentation/technical/index-format.txt
Lorsque nous commençons un dépôt de test avec:
git init
echo a > b
git add b
tree --charset=ascii
L' .git
annuaire ressemble:
.git/objects/
|-- 78
| `-- 981922613b2afb6025042ff6bd878ac1994e85
|-- info
`-- pack
Et si nous récupérons le contenu de la seul objet:
git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85
Nous obtenons a
. Cela indique que:
- l'
index
des points pour le contenu du fichier, depuis git add b
créé un objet blob
- il stocke les métadonnées dans le fichier d'index, pas dans un arbre d'objet, car il n'y avait qu'un seul objet: le blob.
Maintenant, regardons l'indice lui-même:
hd .git/index
Donne:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 09 76 e6 |DIRC.... ....T.v.|
00000010 1d 81 6f c6 54 09 76 e6 1d 81 6f c6 00 00 08 05 |..o.T.v. ..o.....|
00000020 00 e4 2e 76 00 00 81 a4 00 00 03 e8 00 00 03 e8 |...v.... ........|
00000030 00 00 00 02 78 98 19 22 61 3b 2a fb 60 25 04 2f |....x.." a;*.`%./|
00000040 f6 bd 87 8a c1 99 4e 85 00 01 62 00 ee 33 c0 3a |......N. ..b..3.:|
00000050 be 41 4b 1f d7 1d 33 a9 da d4 93 9a 09 ab 49 94 |.AK...3. ......I.|
00000060
Rupture:
44 49 52 43
: DIRC
. TODO: pourquoi est-ce nécessaire?
00 00 00 02
: version du format: 2. Le format de l'indice a évolué avec le temps. Actuellement, il n'existe jusqu'à la version 4. Le format de l'index ne doit pas être un problème lors d'une collaboration entre les différents ordinateurs sur GitHub, car nus référentiels de ne pas stocker l'index: il est généré au clone de temps.
00 00 00 01
: nombre de fichiers sur l'index: juste une, b
.
Démarre ensuite une liste des entrées d'index. Ici nous n'avons qu'une. Il contient:
-
un tas de métadonnées du fichier: 8 octets ctime
, de 8 octets mtime
,
puis 4 octets: l'appareil, inode, mode, UID et GID.
Notez comment:
-
ctime
et mtime
sont les mêmes (54 09 76 e6 1d 81 6f c6
)
comme prévu puisque nous n'avons pas modifié le fichier
Les premiers octets sont de secondes depuis l'EPOCH en hexadécimal:
date --date="@$(printf "%x" "540976e6")"
Donne:
Fri Sep 5 10:40:06 CEST 2014
Ce qui est quand j'ai pris cet exemple.
Le second 4 octets sont nanosecondes.
UID et GID sont 00 00 03 e8
, 1000 en hexadécimal: une valeur commune pour un utilisateur unique configurations.
L'ensemble de ces métadonnées, la plupart de ce qui n'est pas présent dans l'arbre des objets, permet de Git pour vérifier
si un fichier a changé rapidement, sans la comparer l'intégralité du contenu.
à la ligne de départ 30
: 00 00 00 02
: 4 octets taille du fichier: 2 octets
20 octets SHA-1 du contenu: 78 98 19 22 ... c1 99 4e 85
-
2 octets drapeaux: 00 01
1 bit: supposons indicateur valide. TODO c'est pour quoi?
1 peu étendu drapeau. Détermine si l'étendue des drapeaux sont présents ou pas.
Doit être 0
sur la version 2 qui n'a pas étendu les drapeaux.
-
2 bits stade drapeau utilisé lors de la fusion. Les étapes sont documentées en man git-merge
:
- 0: fichier régulier, et non dans un conflit de fusion
- 1: de base
- 2: la nôtre
- 3: leur
Lors d'un conflit de fusion, toutes les étapes de 1 à 3 sont stockées dans l'index
pour permettre les opérations comme l' git checkout --ours
.
Si vous git add
, puis une phase 0 est ajouté à l'index pour le chemin d'accès,
et Git savent que le conflit a été marqué comme résolu. TODO: vérifier cela.
12 bits, la longueur de la trajectoire que va suivre: 0 01
: 1 octet seulement depuis le chemin d'accès a été b
2 octet étendu drapeaux
62
(ASCII b
): longueur variable de chemin d'accès. Longueur déterminée dans le précédent drapeaux.
Puis vient un 00
: zéro de remplissage, de sorte que l'indice de la fin à un multiple de 8 octets. Cela ne se produit avant de l'indice de la version 4.
Pas d'extensions ont été utilisés. Git sait ce parce qu'il n'y aurait pas assez de place dans le fichier de somme de contrôle.
Enfin, il y a 20 octets somme de contrôle ee 33 c0 3a .. 09 ab 49 94
sur le contenu de l'index.