git repack
Git stores objects in two ways: as individual loose files under .git/objects/, or inside compressed pack files (.pack) in .git/objects/pack/. git repack consolidates loose objects and existing pack files into new, optimized pack files using delta compression. The result is a much smaller repository that performs better for clones and fetches. Most of the time, git gc calls git repack for you — but understanding repack directly helps you tune repository performance.
How Delta Compression Works
When Git packs objects, it does not simply compress each one independently. Instead, it finds objects that are similar to each other (for example, different versions of the same file) and stores most of them as deltas — just the differences from a base object. A file that changes by 10 lines across 100 commits might be stored as one full copy plus 99 tiny delta objects, rather than 100 full copies. This is what makes pack files dramatically smaller than storing objects individually.
Before repack — loose objects
.git/objects/ 4b/825dc642cb6eb9a060e54bf8d69288fbee4904 ← each object is a separate file 9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4 e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 ... (thousands more files)
After repack — pack files
.git/objects/pack/ pack-a1b2c3d4e5f6789012345678901234567890.idx ← index for fast object lookup pack-a1b2c3d4e5f6789012345678901234567890.pack ← all objects delta-compressed
git repack -a: Pack All Objects
The -a flag packs all reachable objects (including those already in existing pack files) into a single new pack file. This creates one authoritative pack but does NOT delete the old pack files — use -d for that.
Pack all objects into one new pack
git repack -a
git repack -A -d: Pack All and Delete Redundant Packs
The combination -A -d is the most commonly used form. -A unpacks objects from existing packs before repacking (unlike lowercase -a which just packs everything together), and -d deletes redundant pack files afterward — packs whose contents are now fully contained in the new pack.
Full repack with cleanup
git repack -A -d
Example output
Enumerating objects: 8241, done. Counting objects: 100% (8241/8241), done. Delta compression using up to 8 threads Compressing objects: 100% (4118/4118), done. Writing objects: 100% (8241/8241), done. Total 8241 (delta 5503), reused 0 (delta 0), pack-reused 0
Bitmap Indexes for Faster Clone and Fetch
A pack bitmap is a data structure stored alongside a pack file that allows Git to quickly compute which objects need to be sent to a client during a clone or fetch. Without bitmaps, Git must traverse the entire object graph for every pack operation. With bitmaps, it can answer reachability queries in near-constant time.
Create a pack with bitmap index
git repack -b --write-bitmap-index # Or combined with the full repack: git repack -A -d -b --write-bitmap-index
Pack files with bitmap
.git/objects/pack/ pack-a1b2c3d4e5f6789012345678901234567890.bitmap ← bitmap index pack-a1b2c3d4e5f6789012345678901234567890.idx pack-a1b2c3d4e5f6789012345678901234567890.pack
Measuring Before and After with count-objects
Check repo size before repack
git count-objects -vH
Before repack
count: 6841 ← 6841 loose objects size: 98.23 MiB ← space used by loose objects in-pack: 2105 packs: 4 ← fragmented into 4 pack files size-pack: 31.45 MiB prune-packable: 0 garbage: 0 size-garbage: 0 bytes
Repack and check again
git repack -A -d -b --write-bitmap-index git count-objects -vH
After repack
count: 0 ← no more loose objects size: 0 bytes in-pack: 8946 ← all objects in one pack packs: 1 ← single optimized pack size-pack: 18.72 MiB ← ~40% smaller due to better delta chains prune-packable: 0 garbage: 0 size-garbage: 0 bytes
When to Manually Repack vs Letting gc Handle It
Scenario | Use |
|---|---|
Routine maintenance on a developer workstation | Let git gc handle it automatically |
Large import from SVN, Mercurial, or another VCS | git repack -A -d immediately after import |
Hosting a repository that many users clone | git repack -A -d -b --write-bitmap-index |
Repo has grown significantly from deleted large files | git filter-repo first, then git repack -A -d |
Running a CI/CD system that clones frequently | Enable bitmaps on the server-side repo |
After git filter-repo to remove secrets/large files | git repack -A -d to consolidate |