Command Palette

Search for a command to run...

Hectal
PHASE 8Advanced ~7 min· topic 2 of 4

Topic 8.2

Packfiles, Garbage Collection & Repository Health

In one line

Git stores objects loose at first, then packs them with delta compression. Garbage collection removes unreachable objects after a grace period, fsck checks integrity, and git maintenance keeps big repos fast.

0/4 · 0%

Think of it like this

A warehouse where new deliveries are left as individual parcels near the door (loose objects) and, every night, similar items are packed together in labelled crates that store only the differences between near-identical items (packfiles with deltas).

Key ideas

  1. 01

    LOOSE OBJECTS live in .git/objects/ab/cdef…, zlib-compressed. PACKFILES (.git/objects/pack/*.pack + .idx) store many objects, with similar objects stored as DELTAS against each other. Clones and fetches transfer packfiles, which is why they're efficient.

  2. 02

    GARBAGE COLLECTION (git gc, run automatically): repacks objects and prunes UNREACHABLE ones, but only after they're older than the reflog/prune expiry (reflog entries default to 90 days, unreachable ones 30). That grace period is what lets you recover 'lost' commits with the reflog (Phase 5).

  3. 03

    git fsck verifies object integrity and reports dangling/unreachable objects (useful for recovering orphaned work). git count-objects -vH shows repository size. git maintenance start schedules background tasks (prefetch, commit-graph, loose-objects, incremental repack) that keep large repos fast.

  4. 04

    Big-file mistakes: a large binary committed once stays in history forever, making every clone slower. Find it (git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -k3 -n | tail), remove it from history with git filter-repo, and prevent it with Git LFS and pre-commit size checks (Phase 7).

Code & diagrams

health checkbash
git count-objects -vH                # size-pack: 1.20 GiB   count: 312 (loose)
git fsck --no-reflogs | head          # dangling commit 4f2a…  (recoverable work)
git maintenance start                 # schedule background optimisation
# biggest blobs in history
git rev-list --objects --all \
 | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
 | awk '$1=="blob"' | sort -k3 -n | tail -5

Explain it without notes

01

Why can you usually recover a commit you 'lost' with reset --hard, even though it's no longer on any branch?

Practice

01

A repo takes 10 minutes to clone. Diagnose why.

Done when you can

  • I know how packfiles, gc, and reflog expiry interact

  • I can find what makes a repository large