Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Git memorizza gli oggetti in due formati: loose (un file per oggetto sotto .git/objects/xx/yyyy...) e packed (molti oggetti in un singolo file .pack con un compagno .idx). I pack sono molto più efficienti su disco e in rete.

Layout

.git/objects/
  00/  ... oggetti loose, nominati per sha meno i primi due caratteri
  pack/
    pack-<hash>.pack    # i dati
    pack-<hash>.idx     # indice di offset
    pack-<hash>.rev     # indice inverso (Git 2.31+)

Perché i pack

  • Un file per oggetto è brutale sui filesystem con milioni di file.
  • I pack applicano compressione delta: memorizzano blob simili come una base più un diff.
  • I pack usano zlib oltre ai delta.
  • Smart fetch/push trasferiscono i dati pack direttamente.

Innescare il packing

git gc                    # manutenzione di routine
git gc --aggressive       # ricerca delta più pesante
git repack -a -d -f       # ricrea un pack da tutti gli oggetti
git fetch                 # può anche produrre pack

L'auto-gc scatta quando il repo accumula troppi oggetti loose; regola con gc.auto.

Ispezionare i pack

ls .git/objects/pack
git verify-pack -v .git/objects/pack/pack-<hash>.idx | head
git count-objects -v

verify-pack -v mostra il tipo, dimensione, dimensione packed di ogni oggetto e se è un delta contro un altro oggetto.

Indici multi-pack

Per repo molto grandi, più pack possono essere unificati da un singolo indice:

git multi-pack-index write
git config core.multiPackIndex true

Bitmap di raggiungibilità

I bitmap accelerano le query di raggiungibilità (usate da clone e fetch sui server di hosting):

git repack -adb        # costruisce il bitmap
git config repack.writeBitmaps true

I bitmap sono più utili quando si servono molti clone o quando si eseguono grandi query git rev-list.

Dettagli di compressione degli oggetti

Un delta in un pack memorizza un riferimento a un oggetto base e uno stream di istruzioni. La base può essa stessa essere un delta. Git limita le catene di delta tramite pack.depth (default 50). La base scelta è di solito un blob simile, spesso una versione precedente dello stesso file.

Repack geometrico

Mantenere un singolo pack enorme è costoso; riscriverlo a ogni gc è dispendioso. Git moderno supporta il repack geometrico, che mantiene una catena di pack di dimensione geometricamente crescente e fa repack solo dei piccoli:

git repack --geometric=2 -d --write-bitmap-index
git config maintenance.incremental-repack.enabled true
git maintenance run --task incremental-repack

Questo rende la manutenzione di routine limitata: ogni gc tocca solo i pack più piccoli. Combinato con indici multi-pack e bitmap di raggiungibilità, il repack geometrico è la configurazione consigliata per repository grandi o trafficati.

Errori comuni

Cancellare manualmente un file .pack per recuperare spazio, rompendo il repo. Il pack contiene molti oggetti raggiungibili; usa invece git gc --prune. Eseguire git gc --aggressive programmato; è costoso e raramente migliora rispetto a un normale gc. Tenere milioni di oggetti loose (dopo un recupero pasticciato) e poi fare git status su un filesystem lento; impacchetta prima. Infine, trasferire pack copiando i file invece di usare git clone --bare; potresti perdere il .idx o saltare funzionalità più nuove come l'indice multi-pack.