From 62aad1849f3009d1e6c7126a321e5515c1543dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 25 May 2014 07:38:29 +0700 Subject: gc --auto: do not lock refs in the background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/builtin/gc.c b/builtin/gc.c index ed5cc3c..4588af7 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]); -- cgit v0.10.2-6-g49f6