Same data, two storage formats:
Loose — one file per object under .git/objects/<2-char>/<38-char>. Each zlib-compressed. Used immediately on git add / git commit because writes are atomic and fast.
Packed — many objects bundled in a single .pack file + a .idx for lookup. Used for storage efficiency; gc repacks older objects.
Lookup order:
- Check loose:
.git/objects/ab/c123…
- Check each pack's index.
- Found → return; not found → object missing (probably need to fetch).
Inspect counts:
git count-objects -v # loose object count + size
git count-objects -vH # human-readable
Output of git count-objects -v after gc:
count: 0 # loose objects
size: 0
in-pack: 8423 # packed objects
packs: 1
size-pack: 14.2M
Clean repos are mostly packed; busy ones accumulate loose objects until the next gc.