diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-11-04 02:32:33 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-11-04 02:32:33 +0300 |
commit | c1324e66d44b7d58915cd7e61c1ea85ed3db6a58 (patch) | |
tree | fced8489eb5d0a5ee81372f2df45d23c3cb5a787 /builtin | |
parent | c7bdbd6f92bbab2a030ee8bf7957af25327545e5 (diff) | |
parent | 329e6e8794c347d3da92144f88ad838945508ac6 (diff) |
Merge branch 'nd/gc-auto-background-fix' into maint
When "git gc --auto" is backgrounded, its diagnosis message is
lost. Save it to a file in $GIT_DIR and show it next time the "gc
--auto" is run.
* nd/gc-auto-background-fix:
gc: save log from daemonized gc --auto and print it next time
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/gc.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/builtin/gc.c b/builtin/gc.c index b757d9ae4f..9216f7b9e2 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -44,6 +44,7 @@ static struct argv_array prune_worktrees = ARGV_ARRAY_INIT; static struct argv_array rerere = ARGV_ARRAY_INIT; static struct tempfile pidfile; +static struct lock_file log_lock; static void git_config_date_string(const char *key, const char **output) { @@ -56,6 +57,28 @@ static void git_config_date_string(const char *key, const char **output) } } +static void process_log_file(void) +{ + struct stat st; + if (!fstat(get_lock_file_fd(&log_lock), &st) && st.st_size) + commit_lock_file(&log_lock); + else + rollback_lock_file(&log_lock); +} + +static void process_log_file_at_exit(void) +{ + fflush(stderr); + process_log_file(); +} + +static void process_log_file_on_signal(int signo) +{ + process_log_file(); + sigchain_pop(signo); + raise(signo); +} + static void gc_config(void) { const char *value; @@ -241,6 +264,24 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid) return NULL; } +static int report_last_gc_error(void) +{ + struct strbuf sb = STRBUF_INIT; + int ret; + + ret = strbuf_read_file(&sb, git_path("gc.log"), 0); + if (ret > 0) + return error(_("The last gc run reported the following. " + "Please correct the root cause\n" + "and remove %s.\n" + "Automatic cleanup will not be performed " + "until the file is removed.\n\n" + "%s"), + git_path("gc.log"), sb.buf); + strbuf_release(&sb); + return 0; +} + static int gc_before_repack(void) { if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD)) @@ -262,6 +303,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) int force = 0; const char *name; pid_t pid; + int daemonized = 0; struct option builtin_gc_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), @@ -318,13 +360,16 @@ int cmd_gc(int argc, const char **argv, const char *prefix) fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n")); } if (detach_auto) { + if (report_last_gc_error()) + return -1; + if (gc_before_repack()) return -1; /* * failure to daemonize is ok, we'll continue * in foreground */ - daemonize(); + daemonized = !daemonize(); } } else add_repack_all_option(); @@ -337,6 +382,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix) name, (uintmax_t)pid); } + if (daemonized) { + hold_lock_file_for_update(&log_lock, + git_path("gc.log"), + LOCK_DIE_ON_ERROR); + dup2(get_lock_file_fd(&log_lock), 2); + sigchain_push_common(process_log_file_on_signal); + atexit(process_log_file_at_exit); + } + if (gc_before_repack()) return -1; |