Merge branch 'jn/gc-auto-prep'
authorJunio C Hamano <gitster@pobox.com>
Tue, 16 Oct 2018 07:16:02 +0000 (16:16 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 Oct 2018 07:16:02 +0000 (16:16 +0900)
Code clean-up.

* jn/gc-auto-prep:
gc: exit with status 128 on failure
gc: improve handling of errors reading gc.log

1  2 
builtin/gc.c
t/t6500-gc.sh
diff --combined builtin/gc.c
index 6591ddbe83c46b22aa514cd962a1087294cd1caa,95c8afd07bca53463eea6d9ce12ea36430405592..705c3d3851c7ba708a2c3a13426d48ad90fd23ab
@@@ -20,7 -20,6 +20,7 @@@
  #include "sigchain.h"
  #include "argv-array.h"
  #include "commit.h"
 +#include "commit-graph.h"
  #include "packfile.h"
  #include "object-store.h"
  #include "pack.h"
@@@ -41,7 -40,6 +41,7 @@@ static int aggressive_depth = 50
  static int aggressive_window = 250;
  static int gc_auto_threshold = 6700;
  static int gc_auto_pack_limit = 50;
 +static int gc_write_commit_graph;
  static int detach_auto = 1;
  static timestamp_t gc_log_expire_time;
  static const char *gc_log_expire = "1.day.ago";
@@@ -131,7 -129,6 +131,7 @@@ static void gc_config(void
        git_config_get_int("gc.aggressivedepth", &aggressive_depth);
        git_config_get_int("gc.auto", &gc_auto_threshold);
        git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
 +      git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph);
        git_config_get_bool("gc.autodetach", &detach_auto);
        git_config_get_expiry("gc.pruneexpire", &prune_expire);
        git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
@@@ -183,7 -180,7 +183,7 @@@ static struct packed_git *find_base_pac
  {
        struct packed_git *p, *base = NULL;
  
 -      for (p = get_packed_git(the_repository); p; p = p->next) {
 +      for (p = get_all_packs(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                if (limit) {
@@@ -208,7 -205,7 +208,7 @@@ static int too_many_packs(void
        if (gc_auto_pack_limit <= 0)
                return 0;
  
 -      for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
 +      for (cnt = 0, p = get_all_packs(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                if (p->pack_keep)
@@@ -441,10 -438,10 +441,10 @@@ static const char *lock_repo_for_gc(in
        return NULL;
  }
  
- static int report_last_gc_error(void)
+ static void report_last_gc_error(void)
  {
        struct strbuf sb = STRBUF_INIT;
-       int ret = 0;
+       ssize_t len;
        struct stat st;
        char *gc_log_path = git_pathdup("gc.log");
  
                if (errno == ENOENT)
                        goto done;
  
-               ret = error_errno(_("Can't stat %s"), gc_log_path);
-               goto done;
+               die_errno(_("cannot stat '%s'"), gc_log_path);
        }
  
        if (st.st_mtime < gc_log_expire_time)
                goto done;
  
-       ret = strbuf_read_file(&sb, gc_log_path, 0);
-       if (ret > 0)
-               ret = error(_("The last gc run reported the following. "
+       len = strbuf_read_file(&sb, gc_log_path, 0);
+       if (len < 0)
+               die_errno(_("cannot read '%s'"), gc_log_path);
+       else if (len > 0)
+               die(_("The last gc run reported the following. "
                               "Please correct the root cause\n"
                               "and remove %s.\n"
                               "Automatic cleanup will not be performed "
        strbuf_release(&sb);
  done:
        free(gc_log_path);
-       return ret;
  }
  
- static int gc_before_repack(void)
+ static void gc_before_repack(void)
  {
        if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
-               return error(FAILED_RUN, pack_refs_cmd.argv[0]);
+               die(FAILED_RUN, pack_refs_cmd.argv[0]);
  
        if (prune_reflogs && run_command_v_opt(reflog.argv, RUN_GIT_CMD))
-               return error(FAILED_RUN, reflog.argv[0]);
+               die(FAILED_RUN, reflog.argv[0]);
  
        pack_refs = 0;
        prune_reflogs = 0;
-       return 0;
  }
  
  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;
+                       report_last_gc_error(); /* dies on error */
  
                        if (lock_repo_for_gc(force, &pid))
                                return 0;
-                       if (gc_before_repack())
-                               return -1;
+                       gc_before_repack(); /* dies on failure */
                        delete_tempfile(&pidfile);
  
                        /*
                atexit(process_log_file_at_exit);
        }
  
-       if (gc_before_repack())
-               return -1;
+       gc_before_repack();
  
        if (!repository_format_precious_objects) {
 +              close_all_packs(the_repository->objects);
                if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
-                       return error(FAILED_RUN, repack.argv[0]);
+                       die(FAILED_RUN, repack.argv[0]);
  
                if (prune_expire) {
                        argv_array_push(&prune, prune_expire);
                                argv_array_push(&prune,
                                                "--exclude-promisor-objects");
                        if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
-                               return error(FAILED_RUN, prune.argv[0]);
+                               die(FAILED_RUN, prune.argv[0]);
                }
        }
  
        if (prune_worktrees_expire) {
                argv_array_push(&prune_worktrees, prune_worktrees_expire);
                if (run_command_v_opt(prune_worktrees.argv, RUN_GIT_CMD))
-                       return error(FAILED_RUN, prune_worktrees.argv[0]);
+                       die(FAILED_RUN, prune_worktrees.argv[0]);
        }
  
        if (run_command_v_opt(rerere.argv, RUN_GIT_CMD))
-               return error(FAILED_RUN, rerere.argv[0]);
+               die(FAILED_RUN, rerere.argv[0]);
  
        report_garbage = report_pack_garbage;
        reprepare_packed_git(the_repository);
        if (pack_garbage.nr > 0)
                clean_pack_garbage();
  
 +      if (gc_write_commit_graph)
 +              write_commit_graph_reachable(get_object_directory(), 0,
 +                                           !quiet && !daemonized);
 +
        if (auto_gc && too_many_loose_objects())
                warning(_("There are too many unreachable loose objects; "
                        "run 'git prune' to remove them."));
diff --combined t/t6500-gc.sh
index b3fbd87ee7d0da56ff47ff2fc77a2312592da4bb,c474a94a9fd320d769e7611c76dec2fe09be11da..76a2d25dd202ee493d0709fed649b7e24ce536fe
@@@ -4,7 -4,6 +4,7 @@@ test_description='basic git gc test
  '
  
  . ./test-lib.sh
 +. "$TEST_DIRECTORY"/lib-terminal.sh
  
  test_expect_success 'setup' '
        # do not let the amount of physical memory affects gc
@@@ -100,26 -99,6 +100,26 @@@ test_expect_success 'auto gc with too m
        test_line_count = 2 new # There is one new pack and its .idx
  '
  
 +test_expect_success 'gc --no-quiet' '
 +      git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
 +      test_must_be_empty stdout &&
 +      test_line_count = 1 stderr &&
 +      test_i18ngrep "Computing commit graph generation numbers" stderr
 +'
 +
 +test_expect_success TTY 'with TTY: gc --no-quiet' '
 +      test_terminal git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr &&
 +      test_must_be_empty stdout &&
 +      test_i18ngrep "Enumerating objects" stderr &&
 +      test_i18ngrep "Computing commit graph generation numbers" stderr
 +'
 +
 +test_expect_success 'gc --quiet' '
 +      git -c gc.writeCommitGraph=true gc --quiet >stdout 2>stderr &&
 +      test_must_be_empty stdout &&
 +      test_must_be_empty stderr
 +'
 +
  run_and_wait_for_auto_gc () {
        # We read stdout from gc for the side effect of waiting until the
        # background gc process exits, closing its fd 9.  Furthermore, the
@@@ -138,7 -117,7 +138,7 @@@ test_expect_success 'background auto g
        test_config gc.autodetach true &&
        echo fleem >.git/gc.log &&
        test_must_fail git gc --auto 2>err &&
-       test_i18ngrep "^error:" err &&
+       test_i18ngrep "^fatal:" err &&
        test_config gc.logexpiry 5.days &&
        test-tool chmtime =-345600 .git/gc.log &&
        test_must_fail git gc --auto &&