Merge branch 'jc/parseopt-expiry-errors'
authorJunio C Hamano <gitster@pobox.com>
Tue, 8 May 2018 06:59:33 +0000 (15:59 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 8 May 2018 06:59:33 +0000 (15:59 +0900)
"git gc --prune=nonsense" spent long time repacking and then
silently failed when underlying "git prune --expire=nonsense"
failed to parse its command line. This has been corrected.

* jc/parseopt-expiry-errors:
parseopt: handle malformed --expire arguments more nicely
gc: do not upcase error message shown with die()

1  2 
builtin/gc.c
t/t5304-prune.sh
diff --combined builtin/gc.c
index 3e67124eaaed256f440eea2a08101e87678eee0e,90a10679714d000c0a4b386963def520d3f5d61c..d604940bb64c8b21b02931e48e875580c454383e
@@@ -11,7 -11,6 +11,7 @@@
   */
  
  #include "builtin.h"
 +#include "repository.h"
  #include "config.h"
  #include "tempfile.h"
  #include "lockfile.h"
@@@ -21,7 -20,6 +21,7 @@@
  #include "argv-array.h"
  #include "commit.h"
  #include "packfile.h"
 +#include "object-store.h"
  
  #define FAILED_RUN "failed to run %s"
  
@@@ -174,7 -172,8 +174,7 @@@ static int too_many_packs(void
        if (gc_auto_pack_limit <= 0)
                return 0;
  
 -      prepare_packed_git();
 -      for (cnt = 0, p = packed_git; p; p = p->next) {
 +      for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                if (p->pack_keep)
@@@ -354,6 -353,7 +354,7 @@@ int cmd_gc(int argc, const char **argv
        const char *name;
        pid_t pid;
        int daemonized = 0;
+       timestamp_t dummy;
  
        struct option builtin_gc_options[] = {
                OPT__QUIET(&quiet, N_("suppress progress reporting")),
                        N_("prune unreferenced objects"),
                        PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
                OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
 -              OPT_BOOL(0, "auto", &auto_gc, N_("enable auto-gc mode")),
 -              OPT_BOOL(0, "force", &force, N_("force running gc even if there may be another gc running")),
 +              OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
 +                         PARSE_OPT_NOCOMPLETE),
 +              OPT_BOOL_F(0, "force", &force,
 +                         N_("force running gc even if there may be another gc running"),
 +                         PARSE_OPT_NOCOMPLETE),
                OPT_END()
        };
  
        /* default expiry time, overwritten in gc_config */
        gc_config();
        if (parse_expiry_date(gc_log_expire, &gc_log_expire_time))
-               die(_("Failed to parse gc.logexpiry value %s"), gc_log_expire);
+               die(_("failed to parse gc.logexpiry value %s"), gc_log_expire);
  
        if (pack_refs < 0)
                pack_refs = !is_bare_repository();
        if (argc > 0)
                usage_with_options(builtin_gc_usage, builtin_gc_options);
  
+       if (prune_expire && parse_expiry_date(prune_expire, &dummy))
+               die(_("failed to parse prune expiry value %s"), prune_expire);
        if (aggressive) {
                argv_array_push(&repack, "-f");
                if (aggressive_depth > 0)
                        argv_array_push(&prune, prune_expire);
                        if (quiet)
                                argv_array_push(&prune, "--no-progress");
 +                      if (repository_format_partial_clone)
 +                              argv_array_push(&prune,
 +                                              "--exclude-promisor-objects");
                        if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
                                return error(FAILED_RUN, prune.argv[0]);
                }
                return error(FAILED_RUN, rerere.argv[0]);
  
        report_garbage = report_pack_garbage;
 -      reprepare_packed_git();
 +      reprepare_packed_git(the_repository);
        if (pack_garbage.nr > 0)
                clean_pack_garbage();
  
diff --combined t/t5304-prune.sh
index f0f6e2a5f3d015cb8d753c3d965c1c42e27b5784,af69cdc112c7f5667fc4c9069137716aee44becc..f20f03c1039256f0bc674e3969176a2c592919dd
@@@ -15,7 -15,7 +15,7 @@@ add_blob() 
        BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
 -      test-chmtime =+0 $BLOB_FILE
 +      test-tool chmtime =+0 $BLOB_FILE
  }
  
  test_expect_success setup '
@@@ -33,7 -33,7 +33,7 @@@ test_expect_success 'prune stale packs
        orig_pack=$(echo .git/objects/pack/*.pack) &&
        : > .git/objects/tmp_1.pack &&
        : > .git/objects/tmp_2.pack &&
 -      test-chmtime =-86501 .git/objects/tmp_1.pack &&
 +      test-tool chmtime =-86501 .git/objects/tmp_1.pack &&
        git prune --expire 1.day &&
        test_path_is_file $orig_pack &&
        test_path_is_file .git/objects/tmp_2.pack &&
@@@ -47,7 -47,7 +47,7 @@@ test_expect_success 'prune --expire' 
        git prune --expire=1.hour.ago &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
 -      test-chmtime =-86500 $BLOB_FILE &&
 +      test-tool chmtime =-86500 $BLOB_FILE &&
        git prune --expire 1.day &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
  test_expect_success 'gc: implicit prune --expire' '
  
        add_blob &&
 -      test-chmtime =-$((2*$week-30)) $BLOB_FILE &&
 +      test-tool chmtime =-$((2*$week-30)) $BLOB_FILE &&
        git gc &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
 -      test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
 +      test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git gc &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
@@@ -141,7 -141,7 +141,7 @@@ test_expect_success 'prune: do not prun
  test_expect_success 'gc --no-prune' '
  
        add_blob &&
 -      test-chmtime =-$((5001*$day)) $BLOB_FILE &&
 +      test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git config gc.pruneExpire 2.days.ago &&
        git gc --no-prune &&
        verbose test 1 = $(git count-objects | sed "s/ .*//") &&
@@@ -163,7 -163,7 +163,7 @@@ test_expect_success 'gc respects gc.pru
  test_expect_success 'gc --prune=<date>' '
  
        add_blob &&
 -      test-chmtime =-$((5001*$day)) $BLOB_FILE &&
 +      test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git gc --prune=5002.days.ago &&
        test_path_is_file $BLOB_FILE &&
        git gc --prune=5000.days.ago &&
@@@ -205,7 -205,7 +205,7 @@@ test_expect_success 'prune --expire=nev
  
  test_expect_success 'gc: prune old objects after local clone' '
        add_blob &&
 -      test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
 +      test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git clone --no-hardlinks . aclone &&
        (
                cd aclone &&
@@@ -320,4 -320,14 +320,14 @@@ test_expect_success 'prune: handle HEA
        test_cmp expected actual
  '
  
+ test_expect_success 'prune: handle expire option correctly' '
+       test_must_fail git prune --expire 2>error &&
+       test_i18ngrep "requires a value" error &&
+       test_must_fail git prune --expire=nyah 2>error &&
+       test_i18ngrep "malformed expiration" error &&
+       git prune --no-expire
+ '
  test_done