rev-list: make empty --stdin not an error
authorJeff King <peff@peff.net>
Wed, 22 Aug 2018 21:37:23 +0000 (17:37 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 22 Aug 2018 21:44:50 +0000 (14:44 -0700)
When we originally did the series that contains 7ba826290a
(revision: add rev_input_given flag, 2017-08-02) the intent
was that "git rev-list --stdin </dev/null" would similarly
become a successful noop. However, an attempt at the time to
do that did not work[1]. The problem is that rev_input_given
serves two roles:

- it tells rev-list.c that it should not error out

- it tells revision.c that it should not have the "default"
ref kick (e.g., "HEAD" in "git log")

We want to trigger the former, but not the latter. This is
technically possible with a single flag, if we set the flag
only after revision.c's revs->def check. But this introduces
a rather subtle ordering dependency.

Instead, let's keep two flags: one to denote when we got
actual input (which triggers both roles) and one for when we
read stdin (which triggers only the first).

This does mean a caller interested in the first role has to
check both flags, but there's only one such caller. And any
future callers might want to make the distinction anyway
(e.g., if they care less about erroring out, and more about
whether revision.c soaked up our stdin).

In fact, we already keep such a flag internally in
revision.c for this purpose, so this is really just exposing
that to the caller (and the old function-local flag can go
away in favor of our new one).

[1] https://public-inbox.org/git/20170802223416.gwiezhbuxbdmbjzx@sigill.intra.peff.net/

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rev-list.c
revision.c
revision.h
t/t6018-rev-list-glob.sh
index 6fcb0ff6d56154b9849108028f529c09d0c3450e..475cfcf6df19dfac535a7cb04749122f3889d824 100644 (file)
@@ -493,7 +493,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        if ((!revs.commits && reflog_walk_empty(revs.reflog_info) &&
             (!(revs.tag_objects || revs.tree_objects || revs.blob_objects) &&
              !revs.pending.nr) &&
-            !revs.rev_input_given) ||
+            !revs.rev_input_given && !revs.read_from_stdin) ||
            revs.diff)
                usage(rev_list_usage);
 
index a2570397b6685fbd6e3a7d77ad7e2c554cc03772..7fbdb18f260df15dd757c6cb1c1644158b8fc396 100644 (file)
@@ -2315,7 +2315,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, read_from_stdin, got_rev_arg = 0, revarg_opt;
+       int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt;
        struct argv_array prune_data = ARGV_ARRAY_INIT;
        const char *submodule = NULL;
 
@@ -2345,7 +2345,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
        revarg_opt = opt ? opt->revarg_opt : 0;
        if (seen_dashdash)
                revarg_opt |= REVARG_CANNOT_BE_FILENAME;
-       read_from_stdin = 0;
        for (left = i = 1; i < argc; i++) {
                const char *arg = argv[i];
                if (*arg == '-') {
@@ -2364,7 +2363,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
                                        argv[left++] = arg;
                                        continue;
                                }
-                               if (read_from_stdin++)
+                               if (revs->read_from_stdin++)
                                        die("--stdin given twice?");
                                read_revisions_from_stdin(revs, &prune_data);
                                continue;
index c599c34da91e57572b1c5b315c353d33399e8a09..5f020b461622415c636763c1874ab0a711d61f87 100644 (file)
@@ -81,6 +81,11 @@ struct rev_info {
         */
        int rev_input_given;
 
+       /*
+        * Whether we read from stdin due to the --stdin option.
+        */
+       int read_from_stdin;
+
        /* topo-sort */
        enum rev_sort_order sort_order;
 
index 0bf10d0686982418682ff03e3a42ef3a16e2cfb4..db8a7834d88e6d01b3cc5106af749ede7b75866a 100755 (executable)
@@ -255,7 +255,7 @@ test_expect_success 'rev-list accumulates multiple --exclude' '
        compare rev-list "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches
 '
 
-test_expect_failure 'rev-list should succeed with empty output on empty stdin' '
+test_expect_success 'rev-list should succeed with empty output on empty stdin' '
        git rev-list --stdin </dev/null >actual &&
        test_must_be_empty actual
 '