Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Git memorizza gli oggetti in due formati fisici. Gli oggetti loose sono file individuali; gli oggetti packed vivono dentro un pack file con un corpo compresso a delta. Entrambe le forme descrivono gli stessi oggetti logici, indirizzati dagli stessi hash.

Layout loose

Ogni oggetto loose è in .git/objects/xx/yyy..., dove xx sono i primi due caratteri esadecimali dello SHA e yyy... sono i restanti 38. Il file è il byte deflato con zlib di <type> <size>\0<content>:

find .git/objects -type f -name '??' -prune -o -type f -print | head
git cat-file -p <sha>

Layout pack

.git/objects/pack/pack-<hash>.pack
.git/objects/pack/pack-<hash>.idx

Il file .idx mappa SHA a offset di byte all'interno del .pack; senza di esso, il pack richiederebbe una scansione lineare.

Come gli oggetti si muovono tra forme

I nuovi oggetti vengono scritti loose. Diventano packed quando:

  • git gc viene eseguito (manuale o automatico).
  • git repack viene invocato.
  • Un fetch o push li trasferisce come pack.
  • git fast-import li scrive direttamente in un pack.
git gc
git repack -a -d
git count-objects -v

count-objects -v riporta conteggio loose, uso totale del disco e statistiche dei pack.

Compromessi

  • Loose: semplice, facile da ispezionare, veloce per scrivere un singolo oggetto. Lento quando ce ne sono milioni.
  • Packed: compatto, compresso a delta, veloce per letture in massa. Richiede repacking per incorporare nuovi oggetti.

Auto-gc

Git innesca un auto-gc quando troppi oggetti loose si accumulano. Tunable:

git config gc.auto 6700           # soglia per oggetti loose
git config gc.autoPackLimit 50    # soglia per numero di pack
git config gc.auto 0              # disabilita auto-gc (sconsigliato)

Ispezionare un pack

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

Vedrai tipi di oggetto, dimensioni packed, delta e profondità della catena.

Recuperare da corruzione

git fsck --full
cp -r broken-repo backup
git unpack-objects < .git/objects/pack/pack-<hash>.pack

unpack-objects esplode un pack di nuovo in forma loose, utile quando un singolo oggetto cattivo dentro un pack sta abbattendo molte operazioni.

Cercare un oggetto

Quando Git risolve uno SHA, cerca in questo ordine: file oggetto loose, poi ogni idx di pack, poi alternates (objects/info/alternates). Il lookup è essenzialmente a tempo costante per pack grazie alla tabella fanout dell'idx. L'impatto sulla performance di avere molti pack piccoli vs un pack grande è reale, ed è per questo che gc consolida:

git count-objects -v
cat .git/objects/info/alternates 2>/dev/null
git verify-pack -s .git/objects/pack/pack-<hash>.idx

Gli alternates permettono a più repo di condividere un pool di oggetti su disco; git clone --shared crea tale setup e risparmia spazio al costo di un po' di sicurezza.

Errori comuni

Cancellare manualmente file pack- per recuperare spazio; questo distrugge la storia raggiungibile. Usa git gc. Disabilitare auto-gc su repo di lunga vita e finire con milioni di oggetti loose, rallentando ogni operazione. Eseguire git gc --aggressive regolarmente quando un gc normale basterebbe; il packing aggressivo è costoso. Infine, copiare un repo con cp -r mentre un pack è in scrittura, finendo con un index corrotto. Usa git clone --local per copie sicure.