exclude-promisor-objects: declare when option is allowed

The --exclude-promisor-objects option causes some funny behavior in at least two commands: log and blame. It causes a BUG crash: $ git log --exclude-promisor-objects BUG: revision.c:2143: exclude_promisor_objects can only be used when fetch_if_missing is 0 Aborted [134] Fix this such that the option is treated like any other unknown option. The commands that must support it are limited, so declare in those commands that the flag is supported. In particular: pack-objects prune rev-list The commands were found by searching for logic which parses --exclude-promisor-objects outside of revision.c. Extra logic outside of revision.c is needed because fetch_if_missing must be turned on before revision.c sees the option or it will BUG-crash. The above list is supported by the fact that no other command is introspectively invoked by another command passing --exclude-promisor-object. Signed-off-by: Matthew DeVore <matvore@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matthew DeVore committed Oct 22, 2018 at 18:13 UTC 669b1d2aaec73ba762bf566078308075886ca208
7 files changed +14 -1
builtin/pack-objects.c
+1
@@ -2853,6 +2853,7 @@ static void get_object_list(int ac, const char **av)
2853
2854 init_revisions(&revs, NULL);
2855 save_commit_buffer = 0;
2856 + revs.allow_exclude_promisor_objects_opt = 1;
2857 setup_revisions(ac, av, &revs, NULL);
2858
2859 /* make sure shallows are read */
builtin/prune.c
+1
@@ -118,6 +118,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
118 save_commit_buffer = 0;
119 check_replace_refs = 0;
120 ref_paranoia = 1;
121 + revs.allow_exclude_promisor_objects_opt = 1;
122 init_revisions(&revs, prefix);
123
124 argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
builtin/rev-list.c
+1
@@ -370,6 +370,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
370 git_config(git_default_config, NULL);
371 init_revisions(&revs, prefix);
372 revs.abbrev = DEFAULT_ABBREV;
373 + revs.allow_exclude_promisor_objects_opt = 1;
374 revs.commit_format = CMIT_FMT_UNSPECIFIED;
375
376 /*
revision.c
+2 -1
@@ -2105,7 +2105,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
2105 revs->limited = 1;
2106 } else if (!strcmp(arg, "--ignore-missing")) {
2107 revs->ignore_missing = 1;
2108 - } else if (!strcmp(arg, "--exclude-promisor-objects")) {
2108 + } else if (revs->allow_exclude_promisor_objects_opt &&
2109 + !strcmp(arg, "--exclude-promisor-objects")) {
2110 if (fetch_if_missing)
2111 die("BUG: exclude_promisor_objects can only be used when fetch_if_missing is 0");
2112 revs->exclude_promisor_objects = 1;
revision.h
+1
@@ -124,6 +124,7 @@ struct rev_info {
124 tree_blobs_in_commit_order:1,
125
126 /* for internal use only */
127 + allow_exclude_promisor_objects_opt:1,
128 exclude_promisor_objects:1;
129
130 /* Diff flags */
t/t4202-log.sh
+4
@@ -1668,4 +1668,8 @@ test_expect_success 'log --source paints symmetric ranges' '
1668 test_cmp expect actual
1669 '
1670
1671 +test_expect_success '--exclude-promisor-objects does not BUG-crash' '
1672 + test_must_fail git log --exclude-promisor-objects source-a
1673 +'
1674 +
1675 test_done
t/t8002-blame.sh
+4
@@ -118,4 +118,8 @@ test_expect_success '--no-abbrev works like --abbrev=40' '
118 check_abbrev 40 --no-abbrev
119 '
120
121 +test_expect_success '--exclude-promisor-objects does not BUG-crash' '
122 + test_must_fail git blame --exclude-promisor-objects one
123 +'
124 +
125 test_done