Git Gc
git gc repacks a repository's objects, and runs automatically -- so the times you need it by hand are rare.
git gc does housekeeping: it packs loose objects into packfiles, prunes objects
nothing can reach, and expires reflog entries and unreachable objects older than
a threshold.
It runs automatically — git gc --auto is what Git invokes in the background
after commands like commit and merge — so in normal use you should never need to
run it. This page exists mostly so you know what it is when you see it in output
or in a troubleshooting guide.
Running it
git gc # the defaults
git gc --aggressive # repack everything, much slower
git gc --auto # only if something looks like it is needed
Seeing whether it is needed
git count-objects -v
count and size in loose objects, in-pack and size-pack for packfiles. A
repository with tens of thousands of loose objects is one that has not been
through git gc, and packing it will be faster afterwards.
Why it is safe
Objects are immutable, and packing does not change any commit, hash or
reference. A packfile is the same objects stored more efficiently. The one
visible difference is that git log over an old, unpacked repository gets
noticeably faster afterwards, because it stops stat-ing thousands of small
files.
What it prunes, and what it cannot
git gc removes objects that are unreachable and older than gc.pruneExpire,
90 days by default. Two things protect you:
- The reflog keeps a record of where
HEADand your branches have been, so a commit you reset away is still reachable. See Git Reflog. - Recent objects are never pruned regardless of reachability, which is what makes "I lost a commit yesterday" recoverable.
This is why "run git gc --prune=now" is bad advice given casually: it deletes
the window in which a lost commit could be found in the reflog. The safe version
is to leave the default expiry alone and check the reflog before pruning.
When you would actually reach for it
After a history rewrite, when a repository is noticeably slower than it
should be — a filter-repo run on a long history can leave a lot behind. See
Rewriting History.
After a lot of failed rebases or amends, where unreachable objects have
accumulated and git count-objects -v shows a large loose count.
To check integrity, which is a different command entirely:
git fsck
git fsck verifies that objects and their connections are sound. It is the
diagnostic; git gc is the repair.