]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rev-parse: correctly diagnose revision errors before "--"
authorJeff King <peff@peff.net>
Fri, 6 Dec 2013 22:05:48 +0000 (17:05 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Dec 2013 19:01:23 +0000 (11:01 -0800)
Rev-parse understands that a "--" may separate revisions and
filenames, and that anything after the "--" is taken as-is.
However, it does not understand that anything before the
token must be a revision (which is the usual rule
implemented by the setup_revisions parser).

Since rev-parse prefers revisions to files when parsing
before the "--", we end up with the correct result (if such
an argument is a revision, we parse it as one, and if it is
not, it is an error either way).  However, we misdiagnose
the errors:

  $ git rev-parse foobar -- >/dev/null
  fatal: ambiguous argument 'foobar': unknown revision or path not in the working tree.
  Use '--' to separate paths from revisions, like this:
  'git <command> [<revision>...] -- [<file>...]'

  $ >foobar
  $ git rev-parse foobar -- >/dev/null
  fatal: bad flag '--' used after filename

In both cases, we should know that the real error is that
"foobar" is meant to be a revision, but could not be
resolved.

Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rev-parse.c
t/t1506-rev-parse-diagnosis.sh

index c76b89dc5bcccb42f7c2613072b1093a58c7d21c..8be641e07793fa247aaa6d7427484285ccfaa965 100644 (file)
@@ -476,6 +476,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
 int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 {
        int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+       int has_dashdash = 0;
        int output_prefix = 0;
        unsigned char sha1[20];
        const char *name = NULL;
@@ -489,6 +490,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
        if (argc > 1 && !strcmp("-h", argv[1]))
                usage(builtin_rev_parse_usage);
 
+       for (i = 1; i < argc; i++) {
+               if (!strcmp(argv[i], "--")) {
+                       has_dashdash = 1;
+                       break;
+               }
+       }
+
        prefix = setup_git_directory();
        git_config(git_default_config, NULL);
        for (i = 1; i < argc; i++) {
@@ -765,6 +773,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                }
                if (verify)
                        die_no_single_rev(quiet);
+               if (has_dashdash)
+                       die("bad revision '%s'", arg);
                as_is = 1;
                if (!show_file(arg, output_prefix))
                        continue;
index f950c101287c2f05bbd70c1faffbcf2cda1edbee..613d9bfe1bbb153d1c2e647aee26a60e07a6af86 100755 (executable)
@@ -196,4 +196,28 @@ test_expect_success 'dotdot is not an empty set' '
        test_cmp expect actual
 '
 
+test_expect_success 'arg before dashdash must be a revision (missing)' '
+       test_must_fail git rev-parse foobar -- 2>stderr &&
+       test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (file)' '
+       >foobar &&
+       test_must_fail git rev-parse foobar -- 2>stderr &&
+       test_i18ngrep "bad revision" stderr
+'
+
+test_expect_success 'arg before dashdash must be a revision (ambiguous)' '
+       >foobar &&
+       git update-ref refs/heads/foobar HEAD &&
+       {
+               # we do not want to use rev-parse here, because
+               # we are testing it
+               cat .git/refs/heads/foobar &&
+               printf "%s\n" --
+       } >expect &&
+       git rev-parse foobar -- >actual &&
+       test_cmp expect actual
+'
+
 test_done