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 <[email protected]>
---
 builtin/pack-objects.c | 1 +
 builtin/prune.c        | 1 +
 builtin/rev-list.c     | 1 +
 revision.c             | 3 ++-
 revision.h             | 1 +
 t/t4202-log.sh         | 4 ++++
 t/t8002-blame.sh       | 4 ++++
 7 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index b059b86aee..c409fa25d6 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3108,6 +3108,7 @@ static void get_object_list(int ac, const char **av)
 
        repo_init_revisions(the_repository, &revs, NULL);
        save_commit_buffer = 0;
+       revs.allow_exclude_promisor_objects_opt = 1;
        setup_revisions(ac, av, &revs, NULL);
 
        /* make sure shallows are read */
diff --git a/builtin/prune.c b/builtin/prune.c
index 41230f8215..11284d0bf3 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -120,6 +120,7 @@ int cmd_prune(int argc, const char **argv, const char 
*prefix)
        save_commit_buffer = 0;
        read_replace_refs = 0;
        ref_paranoia = 1;
+       revs.allow_exclude_promisor_objects_opt = 1;
        repo_init_revisions(the_repository, &revs, prefix);
 
        argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 5064d08e1b..2880ed37e3 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -374,6 +374,7 @@ int cmd_rev_list(int argc, const char **argv, const char 
*prefix)
        git_config(git_default_config, NULL);
        repo_init_revisions(the_repository, &revs, prefix);
        revs.abbrev = DEFAULT_ABBREV;
+       revs.allow_exclude_promisor_objects_opt = 1;
        revs.commit_format = CMIT_FMT_UNSPECIFIED;
        revs.do_not_die_on_missing_tree = 1;
 
diff --git a/revision.c b/revision.c
index a1ddb9e11c..28fb2a70cd 100644
--- a/revision.c
+++ b/revision.c
@@ -2138,7 +2138,8 @@ static int handle_revision_opt(struct rev_info *revs, int 
argc, const char **arg
                revs->limited = 1;
        } else if (!strcmp(arg, "--ignore-missing")) {
                revs->ignore_missing = 1;
-       } else if (!strcmp(arg, "--exclude-promisor-objects")) {
+       } else if (revs->allow_exclude_promisor_objects_opt &&
+                  !strcmp(arg, "--exclude-promisor-objects")) {
                if (fetch_if_missing)
                        BUG("exclude_promisor_objects can only be used when 
fetch_if_missing is 0");
                revs->exclude_promisor_objects = 1;
diff --git a/revision.h b/revision.h
index 1cd0c4b200..0d2abc2d36 100644
--- a/revision.h
+++ b/revision.h
@@ -156,6 +156,7 @@ struct rev_info {
                        do_not_die_on_missing_tree:1,
 
                        /* for internal use only */
+                       allow_exclude_promisor_objects_opt:1,
                        exclude_promisor_objects:1;
 
        /* Diff flags */
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 153a506151..819c24d10e 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -1703,4 +1703,8 @@ test_expect_success 'log --source paints symmetric 
ranges' '
        test_cmp expect actual
 '
 
+test_expect_success '--exclude-promisor-objects does not BUG-crash' '
+       test_must_fail git log --exclude-promisor-objects source-a
+'
+
 test_done
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
index 380e1c1054..eea048e52c 100755
--- a/t/t8002-blame.sh
+++ b/t/t8002-blame.sh
@@ -118,4 +118,8 @@ test_expect_success '--no-abbrev works like --abbrev=40' '
        check_abbrev 40 --no-abbrev
 '
 
+test_expect_success '--exclude-promisor-objects does not BUG-crash' '
+       test_must_fail git blame --exclude-promisor-objects one
+'
+
 test_done
-- 
2.19.1.568.g152ad8e336-goog

Reply via email to