gc: retain recently unreferenced objects for 1 day
commita7ea68a8a80e43d5094ef0b321f1e052b86e4aaf
authorKyle J. McKay <mackyle@gmail.com>
Sat, 3 Oct 2015 01:52:12 +0000 (2 18:52 -0700)
committerKyle J. McKay <mackyle@gmail.com>
Sat, 3 Oct 2015 01:52:12 +0000 (2 18:52 -0700)
treef770ef44adbd1ea51edbcfeb81ee0a1e2c7e2f29
parenta38d855b2f99f0d56360db5e7fc9b1936ac0be93
gc: retain recently unreferenced objects for 1 day

Previously we were running git repack with "-a -d" options which
results in unreachable objects in the pack being removed immediately.
Immediately thereafter we were running git prune with no options
which follows up by immediately removing any unreachable loose
objects.

In a perfect world with bug-free code and no race conditions this
would be ideal and never cause problems.

However, anytime we allow simultaneous gc to run while any other
repository activity is occurring (one or more pushes, ref updates
being sent out etc.) there's a window where gc could remove the
objects we're interested in (an old, unreachable ref for comparison
purposes or perhaps because we're resurrecting it with a push)
before we've had a chance to access them.

Attempt to avoid this situation by arranging for objects to live
on for 24 hours after they've most recently become unreachable.

We do this by running git repack with "-A -d" to unpack unreachable
objects and we arrange for them to get the current time as their
modification time rather than the pack's mod time.

We also arrange for loose objects that have become unreferenced to
acquire the modification time of their most recent unreferencing.

Then we run git prune with "--expire 1_day_ago" and that combined
with Git v2.2.0's d3038d22 (prune: keep objects reachable from
recent objects) allows objects and whatever they reference to stay
alive for at least 24 hours after they've most recently become
unreferenced.

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
hooks/pre-receive
jailsetup.sh
jobd/gc.sh
jobd/update.sh
shlib.sh