From e58fe83faf7b55457f1e2f47a1f338bacdce475e Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sun, 28 Jun 2020 13:14:13 -0700 Subject: [PATCH] jobd/gc.sh: prune worktrees, logs and rerere together Instead of pruning the logs at the beginning of the gc and then, finally, pruning worktrees and rerere at the very end after all gc has completed, do them all together at the beginning. By pruning worktrees before checking for the `worktrees` subdir, we may save some work since Git will remove the `worktrees` subdir if it prunes the last worktree. Signed-off-by: Kyle J. McKay --- jobd/gc.sh | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/jobd/gc.sh b/jobd/gc.sh index 58702b7..70cd33b 100755 --- a/jobd/gc.sh +++ b/jobd/gc.sh @@ -1158,10 +1158,30 @@ compute_extra_reachables() { git pack-refs --all --prune [ -e packed-refs ] || >>packed-refs # should never happen... +# We didn't used to do anything about rerere or worktrees but we're +# trying to make nice with linked working trees these days :) +# Maybe even non-bare repositories too, but *shush* about those ;) + +# If we have a worktrees subdir and are running Git >= 2.5.0, prune worktrees +# By doing this first we may save some work if any worktrees are pruned +# Git will remove the worktrees subdir entirely when the last worktree is pruned +if [ -n "$var_have_git_250" ] && [ -d worktrees ]; then + # The value "3.months.ago" is hard-coded into gc.c rather than + # having the default be in worktree.c so we must provide it if + # we get nothing out of the gc.worktreePruneExpire config item + # Prior to Git v2.6.0 the config item was gc.pruneworktreesexpire + # however we just always use the newer name no matter what Git version + expiry="$(git config --get gc.worktreePruneExpire 2>/dev/null)" || : + eval git worktree prune --expire '"${expiry:-3.months.ago}"' "${quiet:+>/dev/null 2>&1}" || : +fi + # If we have a logs directory or a worktrees directory expire the ref logs now # Note that Git itself does not use either --rewrite or --updateref, so neither do we ! [ -d logs ] && ! [ -d worktrees ] || eval git reflog expire --all "${quiet:+>/dev/null 2>&1}" || : +# git rerere does it right and handles its own default/config'd expiration values +! [ -d rr-cache ] || eval git rerere gc "${quiet:+>/dev/null 2>&1}" || : + make_repack_dir ! [ -e .gc_failed ] || exit 1 rm -f .gc_in_progress # make sure @@ -1676,21 +1696,6 @@ config_set_raw girocco.reposizek "${reposizek:-0}" # Now we're finally done with this rm -rf repack -# We didn't used to do anything about rerere or worktrees but we're -# trying to make nice with linked working trees these days :) -# Maybe even non-bare repositories too, but *shush* about those ;) -if [ -n "$var_have_git_250" ] && [ -d worktrees ]; then - # The value "3.months.ago" is hard-coded into gc.c rather than - # having the default be in worktree.c so we must provide it if - # we get nothing out of the gc.worktreePruneExpire config item - # Prior to Git v2.6.0 the config item was gc.pruneworktreesexpire - # however we just always use the newer name no matter what Git version - expiry="$(git config --get gc.worktreePruneExpire 2>/dev/null)" || : - eval git worktree prune --expire '"${expiry:-3.months.ago}"' "${quiet:+>/dev/null 2>&1}" || : -fi -# git rerere does it right and handles its own default/config'd expiration values -! [ -d rr-cache ] || eval git rerere gc "${quiet:+>/dev/null 2>&1}" || : - # We use $gcstart here to avoid a race where a push occurs during the gc itself # and the next future gc could be incorrectly skipped if we used the current # timestamp here instead -- 2.11.4.GIT