@@ -44,6 +44,7 @@ static struct argv_array prune_worktrees = ARGV_ARRAY_INIT;
44
44
static struct argv_array rerere = ARGV_ARRAY_INIT ;
45
45
46
46
static struct tempfile pidfile ;
47
+ static struct lock_file log_lock ;
47
48
48
49
static void git_config_date_string (const char * key , const char * * output )
49
50
{
@@ -56,6 +57,28 @@ static void git_config_date_string(const char *key, const char **output)
56
57
}
57
58
}
58
59
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
+
59
82
static void gc_config (void )
60
83
{
61
84
const char * value ;
@@ -241,6 +264,24 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
241
264
return NULL ;
242
265
}
243
266
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
+
244
285
static int gc_before_repack (void )
245
286
{
246
287
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)
262
303
int force = 0 ;
263
304
const char * name ;
264
305
pid_t pid ;
306
+ int daemonized = 0 ;
265
307
266
308
struct option builtin_gc_options [] = {
267
309
OPT__QUIET (& quiet , N_ ("suppress progress reporting" )),
@@ -318,13 +360,16 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
318
360
fprintf (stderr , _ ("See \"git help gc\" for manual housekeeping.\n" ));
319
361
}
320
362
if (detach_auto ) {
363
+ if (report_last_gc_error ())
364
+ return -1 ;
365
+
321
366
if (gc_before_repack ())
322
367
return -1 ;
323
368
/*
324
369
* failure to daemonize is ok, we'll continue
325
370
* in foreground
326
371
*/
327
- daemonize ();
372
+ daemonized = ! daemonize ();
328
373
}
329
374
} else
330
375
add_repack_all_option ();
@@ -337,6 +382,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
337
382
name , (uintmax_t )pid );
338
383
}
339
384
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
+
340
394
if (gc_before_repack ())
341
395
return -1 ;
342
396
0 commit comments