diff options
author | Jeff King <peff@peff.net> | 2020-08-26 16:13:05 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-08-26 13:30:08 -0700 |
commit | 04a0e98515a7b6e2e43eddea239aacd2a5a71632 (patch) | |
tree | 9b198b1e7d51de576dafc99a2aa432cf37b74f79 | |
parent | Git 2.28 (diff) | |
download | tgif-04a0e98515a7b6e2e43eddea239aacd2a5a71632.tar.xz |
revision: set rev_input_given in handle_revision_arg()
Commit 7ba826290a (revision: add rev_input_given flag, 2017-08-02) added
a flag to rev_info to tell whether we got any revision arguments. As
explained there, this is necessary because some revision arguments may
not produce any pending traversal objects, but should still inhibit
default behaviors (e.g., a glob that matches nothing).
However, it only set the flag in the globbing code, but not for
revisions we get on the command-line or via stdin. This leads to two
problems:
- the command-line code keeps its own separate got_rev_arg flag; this
isn't wrong, but it's confusing and an extra maintenance burden
- even specifically-named rev arguments might end up not adding any
pending objects: if --ignore-missing is set, then specifying a
missing object is a noop rather than an error.
And that leads to some user-visible bugs:
- when deciding whether a default rev like "HEAD" should kick in, we
check both got_rev_arg and rev_input_given. That means that
"--ignore-missing $ZERO_OID" works on the command-line (where we set
got_rev_arg) but not on --stdin (where we don't)
- when rev-list decides whether it should complain that it wasn't
given a starting point, it relies on rev_input_given. So it can't
even get the command-line "--ignore-missing $ZERO_OID" right
Let's consistently set the flag if we got any revision argument. That
lets us clean up the redundant got_rev_arg, and fixes both of those bugs
(but note there are three new tests: we'll confirm the already working
git-log command-line case).
A few implementation notes:
- conceptually we want to set the flag whenever handle_revision_arg()
finds an actual revision arg ("handles" it, you might say). But it
covers a ton of cases with early returns. Rather than annotating
each one, we just wrap it and use its success exit-code to set the
flag in one spot.
- the new rev-list test is in t6018, which is titled to cover globs.
This isn't exactly a glob, but it made sense to stick it with the
other tests that handle the "even though we got a rev, we have no
pending objects" case, which are globs.
- the tests check for the oid of a missing object, which it's pretty
clear --ignore-missing should ignore. You can see the same behavior
with "--ignore-missing a-ref-that-does-not-exist", because
--ignore-missing treats them both the same. That's perhaps less
clearly correct, and we may want to change that in the future. But
the way the code and tests here are written, we'd continue to do the
right thing even if it does.
Reported-by: Bryan Turner <bturner@atlassian.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | revision.c | 16 | ||||
-rwxr-xr-x | t/t4202-log.sh | 10 | ||||
-rwxr-xr-x | t/t6018-rev-list-glob.sh | 5 |
3 files changed, 26 insertions, 5 deletions
diff --git a/revision.c b/revision.c index 6aa7f4f567..d7d4bd3ff7 100644 --- a/revision.c +++ b/revision.c @@ -1997,7 +1997,7 @@ static int handle_dotdot(const char *arg, return ret; } -int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt) +static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt) { struct object_context oc; char *mark; @@ -2072,6 +2072,14 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi return 0; } +int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt) +{ + int ret = handle_revision_arg_1(arg, revs, flags, revarg_opt); + if (!ret) + revs->rev_input_given = 1; + return ret; +} + static void read_pathspec_from_stdin(struct strbuf *sb, struct argv_array *prune) { @@ -2674,7 +2682,7 @@ static void NORETURN diagnose_missing_default(const char *def) */ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt) { - int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt; + int i, flags, left, seen_dashdash, revarg_opt; struct argv_array prune_data = ARGV_ARRAY_INIT; const char *submodule = NULL; int seen_end_of_options = 0; @@ -2763,8 +2771,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s argv_array_pushv(&prune_data, argv + i); break; } - else - got_rev_arg = 1; } if (prune_data.argc) { @@ -2793,7 +2799,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s opt->tweak(revs, opt); if (revs->show_merge) prepare_show_merge(revs); - if (revs->def && !revs->pending.nr && !revs->rev_input_given && !got_rev_arg) { + if (revs->def && !revs->pending.nr && !revs->rev_input_given) { struct object_id oid; struct object *object; struct object_context oc; diff --git a/t/t4202-log.sh b/t/t4202-log.sh index fd9af658af..2fb08d8fce 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1850,6 +1850,16 @@ test_expect_success 'log does not default to HEAD when rev input is given' ' test_must_be_empty actual ' +test_expect_success 'do not default to HEAD with ignored object on cmdline' ' + git log --ignore-missing $ZERO_OID >actual && + test_must_be_empty actual +' + +test_expect_success 'do not default to HEAD with ignored object on stdin' ' + echo $ZERO_OID | git log --ignore-missing --stdin >actual && + test_must_be_empty actual +' + test_expect_success 'set up --source tests' ' git checkout --orphan source-a && test_commit one && diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index bb5aeac07f..b31ff7eeec 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -345,6 +345,11 @@ test_expect_success 'rev-list should succeed with empty output with empty glob' test_must_be_empty actual ' +test_expect_success 'rev-list should succeed with empty output when ignoring missing' ' + git rev-list --ignore-missing $ZERO_OID >actual && + test_must_be_empty actual +' + test_expect_success 'shortlog accepts --glob/--tags/--remotes' ' compare shortlog "subspace/one subspace/two" --branches=subspace && |