Skip to content

Commit 04a0e98

Browse files
peffgitster
authored andcommitted
revision: set rev_input_given in handle_revision_arg()
Commit 7ba8262 (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 <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 47ae905 commit 04a0e98

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

revision.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,7 @@ static int handle_dotdot(const char *arg,
19971997
return ret;
19981998
}
19991999

2000-
int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
2000+
static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
20012001
{
20022002
struct object_context oc;
20032003
char *mark;
@@ -2072,6 +2072,14 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
20722072
return 0;
20732073
}
20742074

2075+
int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt)
2076+
{
2077+
int ret = handle_revision_arg_1(arg, revs, flags, revarg_opt);
2078+
if (!ret)
2079+
revs->rev_input_given = 1;
2080+
return ret;
2081+
}
2082+
20752083
static void read_pathspec_from_stdin(struct strbuf *sb,
20762084
struct argv_array *prune)
20772085
{
@@ -2674,7 +2682,7 @@ static void NORETURN diagnose_missing_default(const char *def)
26742682
*/
26752683
int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
26762684
{
2677-
int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt;
2685+
int i, flags, left, seen_dashdash, revarg_opt;
26782686
struct argv_array prune_data = ARGV_ARRAY_INIT;
26792687
const char *submodule = NULL;
26802688
int seen_end_of_options = 0;
@@ -2763,8 +2771,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
27632771
argv_array_pushv(&prune_data, argv + i);
27642772
break;
27652773
}
2766-
else
2767-
got_rev_arg = 1;
27682774
}
27692775

27702776
if (prune_data.argc) {
@@ -2793,7 +2799,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
27932799
opt->tweak(revs, opt);
27942800
if (revs->show_merge)
27952801
prepare_show_merge(revs);
2796-
if (revs->def && !revs->pending.nr && !revs->rev_input_given && !got_rev_arg) {
2802+
if (revs->def && !revs->pending.nr && !revs->rev_input_given) {
27972803
struct object_id oid;
27982804
struct object *object;
27992805
struct object_context oc;

t/t4202-log.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,16 @@ test_expect_success 'log does not default to HEAD when rev input is given' '
18501850
test_must_be_empty actual
18511851
'
18521852

1853+
test_expect_success 'do not default to HEAD with ignored object on cmdline' '
1854+
git log --ignore-missing $ZERO_OID >actual &&
1855+
test_must_be_empty actual
1856+
'
1857+
1858+
test_expect_success 'do not default to HEAD with ignored object on stdin' '
1859+
echo $ZERO_OID | git log --ignore-missing --stdin >actual &&
1860+
test_must_be_empty actual
1861+
'
1862+
18531863
test_expect_success 'set up --source tests' '
18541864
git checkout --orphan source-a &&
18551865
test_commit one &&

t/t6018-rev-list-glob.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ test_expect_success 'rev-list should succeed with empty output with empty glob'
345345
test_must_be_empty actual
346346
'
347347

348+
test_expect_success 'rev-list should succeed with empty output when ignoring missing' '
349+
git rev-list --ignore-missing $ZERO_OID >actual &&
350+
test_must_be_empty actual
351+
'
352+
348353
test_expect_success 'shortlog accepts --glob/--tags/--remotes' '
349354
350355
compare shortlog "subspace/one subspace/two" --branches=subspace &&

0 commit comments

Comments
 (0)