On my local copy of a company-wide repository (where I make lots of short-lived branches and git rebase
very very often, and where many other people are also pushing short-lived branches to the origin
I'm pulling from), I regularly have the following conversation with git.
(env)$ git pull
remote: Counting objects: 382, done.
remote: Compressing objects: 100% (247/247), done.
remote: Total 382 (delta 182), reused 62 (delta 62), pack-reused 73
Receiving objects: 100% (382/382), 228.63 KiB | 0 bytes/s, done.
Resolving deltas: 100% (232/232), completed with 15 local objects.
From github.com:anon/anony2
aee962f..055a717 master -> origin/master
[...]
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
error: The last gc run reported the following. Please correct the root cause
and remove .git/gc.log.
Automatic cleanup will not be performed until the file is removed.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
Updating aee962f..055a717
Fast-forward
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
error: The last gc run reported the following. Please correct the root cause
and remove .git/gc.log.
Automatic cleanup will not be performed until the file is removed.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
[...]
9 files changed, 128 insertions(+), 95 deletions(-)
(env)$ git prune
Checking connectivity: 772524, done.
(env)$ rm .git/gc.log
(env)$
```
That is: I say git pull
; git spews a bunch of stuff at me, helpfully including two commands I need to run; I run those commands; then I can continue with my work.
It would be awesome if git would just run those commands for me, instead of forcing me to cut-and-paste them. I get that this wouldn't be the default behavior of git pull
, but it seems like the sort of thing that probably exists as an option I could add to my .gitconfig
. Does such a thing exist?
The problem is most likely that you generate loose objects fast enough to, in effect, overrun the default git gc
protection time of 2.weeks.ago
:
--prune=<date>
Prune loose objects older than date (default is 2 weeks ago, overridable by the config variablegc.pruneExpire
). --prune=all prunes loose objects regardless of their age (do not use --prune=all unless you know exactly what you are doing. Unless the repository is quiescent, you will lose newly created objects that haven't been anchored with the refs and end up corrupting your repository). --prune is on by default.
What's happening here is that git gc
is automatically, in the background, pruning loose objects with its default mechanism, which is to run git prune --expire=2.weeks.ago
(or whatever you have configured for gc.pruneExpire
). But this leaves behind enough loose objects that git gc
thinks it has done a poor job of pruning.
Running git prune
with no expire time (as in manual git prune
), or with --prune=all
in git gc
, removes all loose objects. This is only safe if no other Git command is running. Since git gc --auto
runs in the background, it needs a safety margin—but two weeks is too much for your usage.
If you're confident that your various Git commands will complete in just one week, or even perhaps a day, :-) you can configure gc.pruneExpire
to 1.week.ago
or 1.day.ago
to make it prune more aggressively. Unless you're generating a really huge number of loose objects, that will probably do the trick:
$ git config gc.pruneExpire 3.days.ago
Note that when set this way, you change only the setting for this repository, and override any more global setting. Or:
$ git config --global gc.pruneExpire 1.week.ago
This sets your personal (user-global) default to one week, instead of two (but this will be overridden by the repo-specific "three days" setting, if that's set).
I noticed while checking all this that extensions.preciousObjects
is not documented. (As with all config variables, this may be spelled with arbitrary upper and lower case mixtures.) It was added in Git 2.7.0 and lets you prevent all automatic pruning of objects, which you might want if you set up a shared repository. (It's tricky to use and probably not something any casual user should ever set.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With