Git development
 help / color / mirror / Atom feed
From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Patrick Steinhardt <ps@pks.im>, Elijah Newren <newren@gmail.com>,
	Jeff King <peff@peff.net>,
	"brian m . carlson" <sandals@crustytoothpaste.net>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Justin Tobler <jltobler@gmail.com>,
	Christian Couder <christian.couder@gmail.com>
Subject: [PATCH 3/6] rev-parse: fix "--" detection when it is an option value
Date: Wed,  2 Sep 2026 18:10:44 +0200	[thread overview]
Message-ID: <20260902161047.476753-4-christian.couder@gmail.com> (raw)
In-Reply-To: <20260902161047.476753-1-christian.couder@gmail.com>

`cmd_rev_parse()` walks its arguments twice. The second loop actually
parses the options, and it knows that `--default`, `--prefix` and
`--resolve-git-dir` take their value as a separate argument, so it skips
that value.

The first loop, which only looks for the "--" separating revisions from
paths, doesn't know about these options. So when such an option is given
"--" as its value, that "--" is mistaken for the separator and
`has_dashdash` is wrongly set.

This matters because `has_dashdash` makes the second loop die with a
"bad revision" error on an argument that is neither a revision nor an
existing file, instead of reporting that the argument is ambiguous and
telling how to disambiguate it. So:

  $ git rev-parse --default -- notarev
  fatal: bad revision 'notarev'

while the very same command line with any other default value gives the
usual, much more helpful, "ambiguous argument" error.

Let's fix this the same way as in a previous commit, by using
early_scan_options() and telling it about the options taking their value
as a separate argument.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
---
 builtin/rev-parse.c  | 26 ++++++++++++++++++++------
 t/t1500-rev-parse.sh |  5 +++++
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 43693454d5..7ced82e25d 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -695,6 +695,17 @@ static void print_path(const char *path, const char *prefix,
 	strbuf_release(&sb);
 }
 
+/*
+ * The options taking their value as a separate argument, which the scan
+ * looking for "--" below has to skip along with their value.
+ */
+static const struct early_scan_option rev_parse_early_options[] = {
+	EARLY_SCAN_SKIP_VALUE("default"),
+	EARLY_SCAN_SKIP_VALUE("prefix"),
+	EARLY_SCAN_SKIP_VALUE("resolve-git-dir"),
+	EARLY_SCAN_END()
+};
+
 int cmd_rev_parse(int argc,
 		  const char **argv,
 		  const char *prefix,
@@ -724,12 +735,15 @@ int cmd_rev_parse(int argc,
 	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;
-		}
-	}
+	/*
+	 * The scan below has to know about the options taking their value
+	 * as a separate argument, or such a value that happens to be "--"
+	 * would be mistaken for the "--" separating revisions from paths.
+	 */
+	i = early_scan_options(argc - 1, argv + 1, rev_parse_early_options,
+			       EARLY_SCAN_STOP_AT_DASHDASH, NULL, NULL);
+	if (i < argc - 1)
+		has_dashdash = 1;
 
 	/* No options; just report on whether we're in a git repo or not. */
 	if (argc == 1) {
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 4174ca40c3..897e9a7735 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -383,4 +383,9 @@ test_expect_success ':/ and HEAD^{/} favor more recent matching commits' '
 	)
 '
 
+test_expect_success 'rev-parse with "--" as an option value' '
+	test_must_fail git rev-parse --default -- notarev 2>err &&
+	test_grep "ambiguous argument .notarev." err
+'
+
 test_done
-- 
2.55.0.787.g3f9e2241eb.dirty


  parent reply	other threads:[~2026-09-02 16:11 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 16:10 [PATCH 0/6] Standardize early option scanning to fix argument parsing bugs Christian Couder
2026-09-02 16:10 ` [PATCH 1/6] parse-options: add early_scan_options() Christian Couder
2026-09-02 22:11   ` Junio C Hamano
2026-09-02 16:10 ` [PATCH 2/6] bisect: fix "--" detection when a term name is "--" Christian Couder
2026-09-02 22:30   ` Junio C Hamano
2026-09-02 16:10 ` Christian Couder [this message]
2026-09-02 16:10 ` [PATCH 4/6] parse-options: add parse_options_takes_argument() Christian Couder
2026-09-02 16:10 ` [PATCH 5/6] parse-options: build early scan options from a struct option array Christian Couder
2026-09-02 16:10 ` [PATCH 6/6] fast-import: use early_scan_options() for --allow-unsafe-features Christian Couder
2026-09-04  3:38   ` Junio C Hamano
2026-09-02 18:52 ` [PATCH 0/6] Standardize early option scanning to fix argument parsing bugs Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260902161047.476753-4-christian.couder@gmail.com \
    --to=christian.couder@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jltobler@gmail.com \
    --cc=newren@gmail.com \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    --cc=sandals@crustytoothpaste.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox