Skip to content

Commit c1324e6

Browse files
committed
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
2 parents c7bdbd6 + 329e6e8 commit c1324e6

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

builtin/gc.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static struct argv_array prune_worktrees = ARGV_ARRAY_INIT;
4444
static struct argv_array rerere = ARGV_ARRAY_INIT;
4545

4646
static struct tempfile pidfile;
47+
static struct lock_file log_lock;
4748

4849
static void git_config_date_string(const char *key, const char **output)
4950
{
@@ -56,6 +57,28 @@ static void git_config_date_string(const char *key, const char **output)
5657
}
5758
}
5859

60+
static void process_log_file(void)
61+
{
62+
struct stat st;
63+
if (!fstat(get_lock_file_fd(&log_lock), &st) && st.st_size)
64+
commit_lock_file(&log_lock);
65+
else
66+
rollback_lock_file(&log_lock);
67+
}
68+
69+
static void process_log_file_at_exit(void)
70+
{
71+
fflush(stderr);
72+
process_log_file();
73+
}
74+
75+
static void process_log_file_on_signal(int signo)
76+
{
77+
process_log_file();
78+
sigchain_pop(signo);
79+
raise(signo);
80+
}
81+
5982
static void gc_config(void)
6083
{
6184
const char *value;
@@ -241,6 +264,24 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
241264
return NULL;
242265
}
243266

267+
static int report_last_gc_error(void)
268+
{
269+
struct strbuf sb = STRBUF_INIT;
270+
int ret;
271+
272+
ret = strbuf_read_file(&sb, git_path("gc.log"), 0);
273+
if (ret > 0)
274+
return error(_("The last gc run reported the following. "
275+
"Please correct the root cause\n"
276+
"and remove %s.\n"
277+
"Automatic cleanup will not be performed "
278+
"until the file is removed.\n\n"
279+
"%s"),
280+
git_path("gc.log"), sb.buf);
281+
strbuf_release(&sb);
282+
return 0;
283+
}
284+
244285
static int gc_before_repack(void)
245286
{
246287
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)
262303
int force = 0;
263304
const char *name;
264305
pid_t pid;
306+
int daemonized = 0;
265307

266308
struct option builtin_gc_options[] = {
267309
OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -318,13 +360,16 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
318360
fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
319361
}
320362
if (detach_auto) {
363+
if (report_last_gc_error())
364+
return -1;
365+
321366
if (gc_before_repack())
322367
return -1;
323368
/*
324369
* failure to daemonize is ok, we'll continue
325370
* in foreground
326371
*/
327-
daemonize();
372+
daemonized = !daemonize();
328373
}
329374
} else
330375
add_repack_all_option();
@@ -337,6 +382,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
337382
name, (uintmax_t)pid);
338383
}
339384

385+
if (daemonized) {
386+
hold_lock_file_for_update(&log_lock,
387+
git_path("gc.log"),
388+
LOCK_DIE_ON_ERROR);
389+
dup2(get_lock_file_fd(&log_lock), 2);
390+
sigchain_push_common(process_log_file_on_signal);
391+
atexit(process_log_file_at_exit);
392+
}
393+
340394
if (gc_before_repack())
341395
return -1;
342396

0 commit comments

Comments
 (0)