Introduction
Git stocke les objets dans deux formats : loose (un fichier par objet sous .git/objects/xx/yyyy...) et packé (plusieurs objets dans un seul fichier .pack avec un compagnon .idx). Les packs sont bien plus efficaces sur disque et sur le réseau.
Disposition
.git/objects/
00/ ... objets loose, nommés par sha moins les deux premiers caractères
pack/
pack-<hash>.pack # les données
pack-<hash>.idx # index d'offset
pack-<hash>.rev # index inverse (Git 2.31+)
Pourquoi les packs
- Un fichier par objet est brutal sur les systèmes de fichiers avec des millions de fichiers.
- Les packs appliquent la compression delta : stocker des blobs similaires comme une base plus un diff.
- Les packs utilisent zlib en plus des deltas.
- Les fetch/push intelligents transfèrent directement les données pack.
Déclencher le packing
git gc # maintenance de routine
git gc --aggressive # recherche de delta plus lourde
git repack -a -d -f # recréer un seul pack à partir de tous les objets
git fetch # peut aussi produire des packs
L'auto-gc se déclenche quand le dépôt accumule trop d'objets loose ; ajustez avec gc.auto.
Inspecter les packs
ls .git/objects/pack
git verify-pack -v .git/objects/pack/pack-<hash>.idx | head
git count-objects -v
verify-pack -v affiche le type, la taille, la taille packée et si chaque objet est un delta contre un autre.
Index multi-pack
Pour les très gros dépôts, plusieurs packs peuvent être unifiés par un seul index :
git multi-pack-index write
git config core.multiPackIndex true
Bitmaps d'atteignabilité
Les bitmaps accélèrent les requêtes d'atteignabilité (utilisées par clone et fetch sur les serveurs d'hébergement) :
git repack -adb # construire le bitmap
git config repack.writeBitmaps true
Les bitmaps sont les plus utiles quand on sert de nombreux clones ou en exécutant de grandes requêtes git rev-list.
Détails de compression d'objets
Un delta dans un pack stocke une référence à un objet base et un flux d'instructions. La base peut être elle-même un delta. Git limite les chaînes de deltas via pack.depth (défaut 50). La base choisie est généralement un blob similaire, souvent une version précédente du même fichier.
Repacking géométrique
Maintenir un seul énorme pack est coûteux ; le réécrire à chaque gc est gaspilleur. Git moderne supporte le repacking géométrique, qui maintient une chaîne de packs de tailles géométriquement croissantes et ne repack que les petits :
git repack --geometric=2 -d --write-bitmap-index
git config maintenance.incremental-repack.enabled true
git maintenance run --task incremental-repack
Cela rend la maintenance de routine bornée : chaque gc ne touche que les plus petits packs. Combiné avec les index multi-pack et les bitmaps d'atteignabilité, le repack géométrique est la configuration recommandée pour les dépôts grands ou actifs.
Erreurs fréquentes
Supprimer manuellement un fichier .pack pour récupérer de l'espace, cassant le dépôt. Le pack contient de nombreux objets atteignables ; utilisez git gc --prune. Exécuter git gc --aggressive sur un planning ; c'est coûteux et améliore rarement par rapport à un gc normal. Garder des millions d'objets loose (après une récupération bâclée) puis faire git status sur un système de fichiers lent ; packez d'abord. Enfin, transférer des packs en copiant des fichiers au lieu d'utiliser git clone --bare ; vous pouvez manquer le .idx ou sauter des fonctionnalités plus récentes comme l'index multi-pack.