Merge branch 'jn/gc-auto'

"gc --auto" ended up calling exit(-1) upon error, which has been
corrected to use exit(1).  Also the error reporting behaviour when
daemonized has been updated to exit with zero status when stopping
due to a previously discovered error (which implies there is no
point running gc to improve the situation); we used to exit with
failure in such a case.

* jn/gc-auto:
  gc: do not return error for prior errors in daemonized mode
This commit is contained in:
Junio C Hamano
2018-10-16 16:16:02 +09:00
3 changed files with 32 additions and 10 deletions

View File

@ -1643,7 +1643,8 @@ gc.writeCommitGraph::
for details. for details.
gc.logExpiry:: gc.logExpiry::
If the file gc.log exists, then `git gc --auto` won't run If the file gc.log exists, then `git gc --auto` will print
its content and exit with status zero instead of running
unless that file is more than 'gc.logExpiry' old. Default is unless that file is more than 'gc.logExpiry' old. Default is
"1.day". See `gc.pruneExpire` for more ways to specify its "1.day". See `gc.pruneExpire` for more ways to specify its
value. value.

View File

@ -441,9 +441,15 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
return NULL; return NULL;
} }
static void report_last_gc_error(void) /*
* Returns 0 if there was no previous error and gc can proceed, 1 if
* gc should not proceed due to an error in the last run. Prints a
* message and returns -1 if an error occured while reading gc.log
*/
static int report_last_gc_error(void)
{ {
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
int ret = 0;
ssize_t len; ssize_t len;
struct stat st; struct stat st;
char *gc_log_path = git_pathdup("gc.log"); char *gc_log_path = git_pathdup("gc.log");
@ -452,7 +458,8 @@ static void report_last_gc_error(void)
if (errno == ENOENT) if (errno == ENOENT)
goto done; goto done;
die_errno(_("cannot stat '%s'"), gc_log_path); ret = error_errno(_("cannot stat '%s'"), gc_log_path);
goto done;
} }
if (st.st_mtime < gc_log_expire_time) if (st.st_mtime < gc_log_expire_time)
@ -460,18 +467,26 @@ static void report_last_gc_error(void)
len = strbuf_read_file(&sb, gc_log_path, 0); len = strbuf_read_file(&sb, gc_log_path, 0);
if (len < 0) if (len < 0)
die_errno(_("cannot read '%s'"), gc_log_path); ret = error_errno(_("cannot read '%s'"), gc_log_path);
else if (len > 0) else if (len > 0) {
die(_("The last gc run reported the following. " /*
* A previous gc failed. Report the error, and don't
* bother with an automatic gc run since it is likely
* to fail in the same way.
*/
warning(_("The last gc run reported the following. "
"Please correct the root cause\n" "Please correct the root cause\n"
"and remove %s.\n" "and remove %s.\n"
"Automatic cleanup will not be performed " "Automatic cleanup will not be performed "
"until the file is removed.\n\n" "until the file is removed.\n\n"
"%s"), "%s"),
gc_log_path, sb.buf); gc_log_path, sb.buf);
ret = 1;
}
strbuf_release(&sb); strbuf_release(&sb);
done: done:
free(gc_log_path); free(gc_log_path);
return ret;
} }
static void gc_before_repack(void) static void gc_before_repack(void)
@ -564,7 +579,13 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n")); fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
} }
if (detach_auto) { if (detach_auto) {
report_last_gc_error(); /* dies on error */ int ret = report_last_gc_error();
if (ret < 0)
/* an I/O error occured, already reported */
exit(128);
if (ret == 1)
/* Last gc --auto failed. Skip this one. */
return 0;
if (lock_repo_for_gc(force, &pid)) if (lock_repo_for_gc(force, &pid))
return 0; return 0;

View File

@ -137,11 +137,11 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
test_config gc.autopacklimit 1 && test_config gc.autopacklimit 1 &&
test_config gc.autodetach true && test_config gc.autodetach true &&
echo fleem >.git/gc.log && echo fleem >.git/gc.log &&
test_must_fail git gc --auto 2>err && git gc --auto 2>err &&
test_i18ngrep "^fatal:" err && test_i18ngrep "^warning:" err &&
test_config gc.logexpiry 5.days && test_config gc.logexpiry 5.days &&
test-tool chmtime =-345600 .git/gc.log && test-tool chmtime =-345600 .git/gc.log &&
test_must_fail git gc --auto && git gc --auto &&
test_config gc.logexpiry 2.days && test_config gc.logexpiry 2.days &&
run_and_wait_for_auto_gc && run_and_wait_for_auto_gc &&
ls .git/objects/pack/pack-*.pack >packs && ls .git/objects/pack/pack-*.pack >packs &&