summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-07-18 19:48:10 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-07-18 19:48:10 (GMT)
commit764046f6b0ea8480ef7f79dd2b9c48cab0c32d22 (patch)
tree93ed2ebca9705953bfee7f6238c93463893a880a
parent11157492230874c0c2f36481e75f08406c4ed6e7 (diff)
parentc45af94dbc960cbb46ac482ec9cb7f73f55ea270 (diff)
downloadgit-764046f6b0ea8480ef7f79dd2b9c48cab0c32d22.zip
git-764046f6b0ea8480ef7f79dd2b9c48cab0c32d22.tar.gz
git-764046f6b0ea8480ef7f79dd2b9c48cab0c32d22.tar.bz2
Merge branch 'jk/gc-pre-detach-under-hook'
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. * jk/gc-pre-detach-under-hook: gc: run pre-detach operations under lock
-rw-r--r--builtin/gc.c4
-rwxr-xr-xt/t6500-gc.sh21
2 files changed, 25 insertions, 0 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index 2ba50a2..e6b8447 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -414,8 +414,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (report_last_gc_error())
return -1;
+ if (lock_repo_for_gc(force, &pid))
+ return 0;
if (gc_before_repack())
return -1;
+ delete_tempfile(&pidfile);
+
/*
* failure to daemonize is ok, we'll continue
* in foreground
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index cc7acd1..41b0be5 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -95,6 +95,27 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
test_line_count = 1 packs
'
+test_expect_success 'background auto gc respects lock for all operations' '
+ # make sure we run a background auto-gc
+ test_commit make-pack &&
+ git repack &&
+ test_config gc.autopacklimit 1 &&
+ test_config gc.autodetach true &&
+
+ # create a ref whose loose presence we can use to detect a pack-refs run
+ git update-ref refs/heads/should-be-loose HEAD &&
+ test_path_is_file .git/refs/heads/should-be-loose &&
+
+ # now fake a concurrent gc that holds the lock; we can use our
+ # shell pid so that it looks valid.
+ hostname=$(hostname || echo unknown) &&
+ printf "$$ %s" "$hostname" >.git/gc.pid &&
+
+ # our gc should exit zero without doing anything
+ run_and_wait_for_auto_gc &&
+ test_path_is_file .git/refs/heads/should-be-loose
+'
+
# DO NOT leave a detached auto gc process running near the end of the
# test script: it can run long enough in the background to racily
# interfere with the cleanup in 'test_done'.