On Tue, Aug 25, 2020 at 12:40:42PM -0700, Junio C Hamano wrote: > Bryan Turner <bturner@xxxxxxxxxxxxx> writes: > > > It appears the way --stdin processes input discards nonexistent > > commits before the machinery that decides whether you provided any > > revs or not runs, and so if every --stdin rev is discarded then you > > get the default HEAD. If you provide them via the command line, > > though, then it seems like they're discarded later and you don't get a > > default. > > > > I'm not sure whether this is intentional or not (certainly I don't see > > it anywhere in the git log documentation for --ignore-missing or > > --stdin), but it results in a behavior mismatch that's impossible to > > reconcile without requiring extra git processes. I can't always > > provide HEAD since, if multiple revs are supplied, if any revs exist > > then HEAD would not be included regardless of whether the revs were > > supplied via the command line or --stdin. > > As the intent for adding the "--stdin" option to any subcommand has > always been "we may need to feed many many things, that may bust the > command line length limit, hence we let you feed these things from > the standard input, but otherwise there should be no change in > behaviour or semantics", when the behaviour of command line and > "--stdin" differ, it is a bug in the latter. Agreed. It also helps in this case that the command-line behavior is sensible and the --stdin one is not. :) I think the solution is probably something like: diff --git a/revision.c b/revision.c index 96630e3186..f5bbefa091 100644 --- a/revision.c +++ b/revision.c @@ -2099,12 +2099,13 @@ static void read_pathspec_from_stdin(struct strbuf *sb, strvec_push(prune, sb->buf); } -static void read_revisions_from_stdin(struct rev_info *revs, - struct strvec *prune) +static int read_revisions_from_stdin(struct rev_info *revs, + struct strvec *prune) { struct strbuf sb; int seen_dashdash = 0; int save_warning; + int got_rev_arg = 0; save_warning = warn_on_object_refname_ambiguity; warn_on_object_refname_ambiguity = 0; @@ -2124,12 +2125,14 @@ static void read_revisions_from_stdin(struct rev_info *revs, if (handle_revision_arg(sb.buf, revs, 0, REVARG_CANNOT_BE_FILENAME)) die("bad revision '%s'", sb.buf); + got_rev_arg = 1; } if (seen_dashdash) read_pathspec_from_stdin(&sb, prune); strbuf_release(&sb); warn_on_object_refname_ambiguity = save_warning; + return got_rev_arg; } static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what) @@ -2754,7 +2757,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s } if (revs->read_from_stdin++) die("--stdin given twice?"); - read_revisions_from_stdin(revs, &prune_data); + if (read_revisions_from_stdin(revs, &prune_data)) + got_rev_arg = 1; continue; } Possibly it would make sense to push that flag into rev_info, though, and let handle_revision_arg() set it. That would fix this bug and prevent similar ones in other code paths (though we're not likely to get revisions from anywhere else, I suppose). -Peff