Introduction
Git stocke les objets en deux formats physiques. Les objets loose sont des fichiers individuels ; les objets packés vivent dans un pack file avec un corps delta-compressé. Les deux formes décrivent les mêmes objets logiques, adressés par les mêmes hachages.
Disposition loose
Chaque objet loose est à .git/objects/xx/yyy..., où xx est les deux premiers caractères hex du SHA et yyy... les 38 restants. Le fichier est les octets dégonflés zlib de <type> <size>\0<content> :
find .git/objects -type f -name '??' -prune -o -type f -print | head
git cat-file -p <sha>
Disposition pack
.git/objects/pack/pack-<hash>.pack
.git/objects/pack/pack-<hash>.idx
Le fichier .idx mappe SHA vers offset d'octet dans le .pack ; sans lui, le pack nécessiterait un parcours linéaire.
Comment les objets se déplacent entre formes
Les nouveaux objets sont écrits loose. Ils deviennent packés quand :
git gcs'exécute (manuel ou automatique).git repackest invoqué.- Un fetch ou push les transfère comme un pack.
git fast-importles écrit directement dans un pack.
git gc
git repack -a -d
git count-objects -v
count-objects -v rapporte le nombre de loose, l'utilisation totale de disque et les stats de pack.
Compromis
- Loose : simple, facile à inspecter, rapide à écrire un seul objet. Lent quand il y en a des millions.
- Packé : compact, delta-compressé, rapide à lire en masse. Nécessite un repacking pour incorporer de nouveaux objets.
Auto-gc
Git déclenche un auto-gc quand trop d'objets loose s'accumulent. Réglages :
git config gc.auto 6700 # seuil pour les objets loose
git config gc.autoPackLimit 50 # seuil pour le nombre de packs
git config gc.auto 0 # désactiver auto-gc (non recommandé)
Inspecter un pack
git verify-pack -v .git/objects/pack/pack-<hash>.idx | head
git verify-pack -s .git/objects/pack/pack-<hash>.idx
Vous verrez les types d'objets, tailles packées, deltas et profondeurs de chaîne.
Récupérer après corruption
git fsck --full
cp -r broken-repo backup
git unpack-objects < .git/objects/pack/pack-<hash>.pack
unpack-objects explose un pack en forme loose, utile quand un seul mauvais objet à l'intérieur d'un pack fait planter de nombreuses opérations.
Rechercher un objet
Quand Git résout un SHA, il cherche dans cet ordre : fichier d'objet loose, puis chaque idx de pack, puis les alternates (objects/info/alternates). La recherche est essentiellement à temps constant par pack grâce à la table fanout de l'idx. L'impact de performance d'avoir de nombreux petits packs vs un gros pack est réel, c'est pourquoi gc consolide :
git count-objects -v
cat .git/objects/info/alternates 2>/dev/null
git verify-pack -s .git/objects/pack/pack-<hash>.idx
Les alternates permettent à plusieurs dépôts de partager un pool d'objets sur disque ; git clone --shared crée une telle configuration et économise de l'espace au prix d'une certaine sécurité.
Erreurs fréquentes
Supprimer manuellement les fichiers pack- pour récupérer de l'espace ; cela détruit l'historique atteignable. Utilisez git gc. Désactiver auto-gc sur des dépôts de longue durée et finir avec des millions d'objets loose, ralentissant chaque opération. Exécuter git gc --aggressive régulièrement quand un gc normal suffirait ; le packing agressif est coûteux. Enfin, copier un dépôt avec cp -r pendant qu'un pack est en cours d'écriture, finissant avec un index corrompu. Utilisez git clone --local pour des copies sûres.