gitgit-gc

How to avoid that "git gc" generates garbage loose objects?


Before I ran git gc, I had a few thousand loose objects:

$ git count-objects -v
count: 3706
size: 17164
in-pack: 147149
packs: 9
size-pack: 46619
prune-packable: 0
garbage: 0
size-garbage: 0

(note the loose object count and size). After git gc I had more of it:

$ git count-objects -v
count: 6735
size: 19687
in-pack: 142215
packs: 1
size-pack: 43373
prune-packable: 0
garbage: 0
size-garbage: 0

I know that this happens because git gc evicts objects from packs when they become unreachable; it gives them a new "lease of life" as loose objects.

How can I avoid that this single behavior of git gc happens? I want all its other behaviors to remain, i.e., all timeouts, all sorts of garbage removals, everything except this one.

I run git gc monthly at most. For some reason that I do not know, git gc --auto barely ever runs (and I do not want to change that).


Solution

  • If you're sure no other Git command is running in that repository at the time you run git gc on that repository, you can add --prune=all. The default is --prune=2.weeks.ago, which gives those other running commands 14 days to complete their work; you can use --prune=1.day.ago to give them less time, for instance.

    You can also configure gc.pruneExpire: if not set, it defaults to 2.weeks.ago which is what produces the above default. As j6t notes, the gc.pruneExpire setting variant of this is now rather than all. It's unwise to set now here though: an automatic git gc will use this value and will run in the background, while other Git operations run.

    Note that if you have a version of Git >= 2.5 but below 2.15.0, a reduced gc.pruneExpire can break your added work-trees in less time than the default two weeks. The bug is that git gc fails to use the HEAD and index of the added work-tree as a starting point for the reachability traversal of the object DAG. As a result, git gc can remove added blobs that have not yet been committed, and, if you have a worktree with a detached HEAD, even some commits. The best fix for this is to upgrade to 2.15.0 or later, since even the 2-week default isn't necessarily enough.