Git mysteriously runs Garbage collection "from time to time" and deletes and orphaned commits you have.
https://www.kernel.org/pub/software/scm/git/docs/git-gc.html
Scientifically, this will occur approximately 6-8 hours before you realize you really needed that commit which was just deleted.
I'd rather not have my files deleted by Git. How can I disable automatic garbage collection altogether?
From the very same page you just linked to:
Some git commands may automatically run git gc; see the --auto flag below for details. If you know what you’re doing and all you want is to disable this behavior permanently without further considerations, just do:
$ git config --global gc.auto 0
Another approach, recently documented in:
Documentation/config: mention "now
" and "never
" for 'expire' settings
In addition to approxidate-style values ("
2.months.ago
", "yesterday
"), consumers of 'gc.*expire*
' configuration variables also accept and respect 'now
' ("do it immediately") and 'never
' ("suppress entirely").
See commit 8cc8816 (28 Jul 2015) by Eric Sunshine (sunshineco
).
Suggested-by: Michael Haggerty (mhagger
).
(Merged by Junio C Hamano -- gitster
-- in commit 8cc8816, 28 Jul 2015)
That means this would also prevent any gc:
git config --global gc.pruneExpire never
git config --global gc.reflogExpire never
However, you may encounter (if you use configuration value never
):
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
In that case, you probably want to set gc.auto
to some high value (e.g. 100000
) if you really do not want to expire anything. That will silence the warning but may cause garbage collection to be less effective overall so this should be considered as a workaround, not a real fix. See Is it possible to get `git gc` to pack reflog objects? for additional details.
To avoid git gc
only in background, set, as in nornagon's answer:
git config --global gc.autodetach false
That comes from Git v2.14.0-rc1 commit c45af94 (11 Jul 2017) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit 764046f, 18 Jul 2017)
We run an early part of "
git gc
" that deals with refs before daemonising (and not under lock) even when running a background auto-gc, which caused multiple gc processes attempting to run the early part at the same time.
This is now prevented by running the early part also under the GC lock.
gc
: run pre-detach operations under lock
We normally try to avoid having two
auto-gc
operations run at the same time, because it wastes resources.
This was done long ago in 64a99eb (gc
: reject if anothergc
is running, unless--force
is given, 2013-08-08, v1.8.5-rc0).When we do a detached
auto-gc
, we run the ref-related commands before detaching, to avoid confusing lock contention.
This was done by 62aad18 (gc --auto
: do not lock refs in the background, 2014-05-25, Git v2.0.1).These two features do not interact well.
The pre-detach operations are run before we check thegc.pid
lock, meaning that on a busy repository we may run many of them concurrently.
Ideally we'd take the lock before spawning any operations, and hold it for the duration of the program.This is tricky, though, with the way the pid-file interacts with the
daemonize()
process.
Other processes will check that the pid recorded in the pid-file still exists. But detaching causes us to fork and continue running under a new pid.
So if we take the lock before detaching, the pid-file will have a bogus pid in it. We'd have to go back and update it with the new pid after detaching.
We'd also have to play some tricks with the tempfile subsystem to tweak the "owner" field, so that the parent process does not clean it up on exit, but the child process does.Instead, we can do something a bit simpler: take the lock only for the duration of the pre-detach work, then detach, then take it again for the post-detach work.
Technically, this means that the post-detach lock could lose to another process doing pre-detach work.
But in the long run this works out.That second process would then follow-up by doing post-detach work. Unless it was in turn blocked by a third process doing pre-detach work, and so on.
This could in theory go on indefinitely, as the pre-detach work does not repack, and so
need_to_gc()
will continue to trigger.
But in each round we are racing between the pre- and post-detach locks.
Eventually, one of the post-detach locks will win the race and complete the fullgc
.So in the worst case, we may racily repeat the pre-detach work, but we would never do so simultaneously (it would happen via a sequence of serialized race-wins).
I found this answer because I was trying to prevent git from running git gc
in the background, because it was messing with other operations I was trying to perform on the repo. It turns out you can specifically disable the backgrounding behaviour with
$ git config gc.autodetach false
If you want this behavior on all repos:
$ git config --global gc.autodetach false
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