This may happen when `git gc --auto` is run automatically, then the
user, to avoid wait time, switches to a new terminal, keeps working
and `git gc --auto` is started again because the first gc instance has
not clean up the repository.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 I don't know if the kill(pid, 0) trick works on Windows..

 Documentation/git-gc.txt |  6 +++++-
 builtin/gc.c             | 18 ++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index 2402ed6..e158a3b 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -9,7 +9,7 @@ git-gc - Cleanup unnecessary files and optimize the local 
repository
 SYNOPSIS
 --------
 [verse]
-'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune]
+'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] 
[--force]
 
 DESCRIPTION
 -----------
@@ -72,6 +72,10 @@ automatic consolidation of packs.
 --quiet::
        Suppress all progress reports.
 
+--force::
+       Force `git gc` to run even if there may be another `git gc`
+       instance running on this repository.
+
 Configuration
 -------------
 
diff --git a/builtin/gc.c b/builtin/gc.c
index 6be6c8d..07c566c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -169,9 +169,11 @@ static int need_to_gc(void)
 
 int cmd_gc(int argc, const char **argv, const char *prefix)
 {
+       FILE *fp;
        int aggressive = 0;
        int auto_gc = 0;
        int quiet = 0;
+       int force = 0;
 
        struct option builtin_gc_options[] = {
                OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -180,6 +182,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                        PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
                OPT_BOOLEAN(0, "aggressive", &aggressive, N_("be more thorough 
(increased runtime)")),
                OPT_BOOLEAN(0, "auto", &auto_gc, N_("enable auto-gc mode")),
+               OPT_BOOL(0, "force", &force, N_("force running gc even if there 
may be another gc running")),
                OPT_END()
        };
 
@@ -225,6 +228,21 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        } else
                add_repack_all_option();
 
+       if (!force && (fp = fopen(git_path("gc.pid"), "r")) != NULL) {
+               uintmax_t pid;
+               if (fscanf(fp, "%"PRIuMAX, &pid) == 1 && !kill(pid, 0)) {
+                       if (auto_gc)
+                               return 0; /* be quiet on --auto */
+                       die(_("gc is already running"));
+               }
+               fclose(fp);
+       }
+
+       if ((fp = fopen(git_path("gc.pid"), "w")) != NULL) {
+               fprintf(fp, "%"PRIuMAX"\n", (uintmax_t) getpid());
+               fclose(fp);
+       }
+
        if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
                return error(FAILED_RUN, pack_refs_cmd.argv[0]);
 
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to