Unreachable Objects

How Long Git Keeps Unreachable Objects

The safety net has a time limit, set by three settings (12). git gc, which Git 1,932 also runs on its own now and then (git gc --auto, triggered by about 6,700 loose objects), first expires old reflog entries: after gc.reflogExpire, 90 days by default, for entries still reachable from the branch tip, and after gc.reflogExpireUnreachable, 30 days, for entries a reset or rebase left behind. Objects that nothing references any more are then deleted once they are older than gc.pruneExpire, two weeks. A copy of BookNest's .git shows what forcing all three to "now" does:

Expiring the reflog and pruning, in a throwaway copyShell
cp -a .git ../gc-lab.git && cd ../gc-lab.git
git fsck --no-progress --unreachable --no-reflogs | wc -l
git reflog expire --expire-unreachable=now --all
git gc -q --prune=now
git fsck --no-progress --unreachable --no-reflogs | wc -l
cd ../booknest && rm -rf ../gc-lab.git
Output
72
0

--unreachable --no-reflogs counts everything that only a reflog, or nothing, still holds, such as the commits rewritten in Rebase and Conflicts and Working with Remotes, the rebase copies of Undoing a Bad Rebase and the dangling tags. After the expiry and a prune with no grace period, all 72 objects are gone for good, and no command can bring them back. Never run that pair in a repository you might need to recover from. The defaults give you a month for reset or rebased-away commits, three months for the rest; git config gc.reflogExpireUnreachable 90.days buys more time on a project where that matters.

How long the reflog and the object database keep work you have moved away from
How long the reflog and the object database keep work you have moved away from