summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/gc.c24
-rwxr-xr-xt/t6500-gc.sh5
2 files changed, 29 insertions, 0 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index 6e0d81ab32..dd910fbc37 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -14,6 +14,7 @@
#include "cache.h"
#include "parse-options.h"
#include "run-command.h"
+#include "sigchain.h"
#include "argv-array.h"
#define FAILED_RUN "failed to run %s"
@@ -35,6 +36,21 @@ static struct argv_array repack = ARGV_ARRAY_INIT;
static struct argv_array prune = ARGV_ARRAY_INIT;
static struct argv_array rerere = ARGV_ARRAY_INIT;
+static char *pidfile;
+
+static void remove_pidfile(void)
+{
+ if (pidfile)
+ unlink(pidfile);
+}
+
+static void remove_pidfile_on_signal(int signo)
+{
+ remove_pidfile();
+ sigchain_pop(signo);
+ raise(signo);
+}
+
static int gc_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "gc.packrefs")) {
@@ -179,6 +195,10 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
FILE *fp;
int fd, should_exit;
+ if (pidfile)
+ /* already locked */
+ return NULL;
+
if (gethostname(my_host, sizeof(my_host)))
strcpy(my_host, "unknown");
@@ -219,6 +239,10 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
strbuf_release(&sb);
commit_lock_file(&lock);
+ pidfile = git_pathdup("gc.pid");
+ sigchain_push_common(remove_pidfile_on_signal);
+ atexit(remove_pidfile);
+
return NULL;
}
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index b1a63655f9..63194d819e 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -9,6 +9,11 @@ test_expect_success 'gc empty repository' '
git gc
'
+test_expect_success 'gc does not leave behind pid file' '
+ git gc &&
+ test_path_is_missing .git/gc.pid
+'
+
test_expect_success 'gc --gobbledegook' '
test_expect_code 129 git gc --nonsense 2>err &&
test_i18ngrep "[Uu]sage: git gc" err