summaryrefslogtreecommitdiff
path: root/builtin/gc.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2014-05-25 07:38:29 +0700
committerJunio C Hamano <gitster@pobox.com>2014-05-27 12:33:53 -0700
commit62aad1849f3009d1e6c7126a321e5515c1543dc3 (patch)
tree82fa560c984a543c4c9ccf103969e2c942ac8c9e /builtin/gc.c
parent9f673f9477c63433aa0774c11b9e42979721f4d6 (diff)
downloadgit-62aad1849f3009d1e6c7126a321e5515c1543dc3.tar.gz
gc --auto: do not lock refs in the backgroundnd/daemonize-gc
9f673f9 (gc: config option for running --auto in background - 2014-02-08) puts "gc --auto" in background to reduce user's wait time. Part of the garbage collecting is pack-refs and pruning reflogs. These require locking some refs and may abort other processes trying to lock the same ref. If gc --auto is fired in the middle of a script, gc's holding locks in the background could fail the script, which could never happen before 9f673f9. Keep running pack-refs and "reflog --prune" in foreground to stop parallel ref updates. The remaining background operations (repack, prune and rerere) should not impact running git processes. Reported-by: Adam Borowski <kilobyte@angband.pl> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/gc.c')
-rw-r--r--builtin/gc.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index ed5cc3c031..4588af70df 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -26,6 +26,7 @@ static const char * const builtin_gc_usage[] = {
};
static int pack_refs = 1;
+static int prune_reflogs = 1;
static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
static int gc_auto_pack_limit = 50;
@@ -252,6 +253,19 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
return NULL;
}
+static int gc_before_repack(void)
+{
+ if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, pack_refs_cmd.argv[0]);
+
+ if (prune_reflogs && run_command_v_opt(reflog.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, reflog.argv[0]);
+
+ pack_refs = 0;
+ prune_reflogs = 0;
+ return 0;
+}
+
int cmd_gc(int argc, const char **argv, const char *prefix)
{
int aggressive = 0;
@@ -313,12 +327,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
}
- if (detach_auto)
+ if (detach_auto) {
+ if (gc_before_repack())
+ return -1;
/*
* failure to daemonize is ok, we'll continue
* in foreground
*/
daemonize();
+ }
} else
add_repack_all_option();
@@ -330,11 +347,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
name, (uintmax_t)pid);
}
- if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
- return error(FAILED_RUN, pack_refs_cmd.argv[0]);
-
- if (run_command_v_opt(reflog.argv, RUN_GIT_CMD))
- return error(FAILED_RUN, reflog.argv[0]);
+ if (gc_before_repack())
+ return -1;
if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
return error(FAILED_RUN, repack.argv[0]);