git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/6] parse-options: recognize abbreviated negated option with arg

From
René Scharfe <l.s.r@web.de>
Date
Mar 3, 2024, 12:19 UTC
Message-ID
<20240303121944.20627-2-l.s.r@web.de>
In-Reply-To
<20240303121944.20627-1-l.s.r@web.de>

Giving an argument to an option that doesn't take one causes Git to report that error specifically:

   $ git rm --dry-run=bogus
   error: option `dry-run' takes no value
The same is true when the option is negated or abbreviated:
   $ git rm --no-dry-run=bogus
   error: option `no-dry-run' takes no value
   $ git rm --dry=bogus
   error: option `dry-run' takes no value
Not so when doing both, though:
   $ git rm --no-dry=bogus
   error: unknown option `no-dry=bogus'
   usage: git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]
(Rest of the usage message omitted.)

Improve consistency and usefulness of the error message by recognizing abbreviated negated options even if they have a (most likely bogus) argument. With this patch we get:

   $ git rm --no-dry=bogus
   error: option `no-dry-run' takes no value
Signed-off-by: René Scharfe <l.s.r@web.de>
---
 parse-options.c          |  5 +++--
 t/t0040-parse-options.sh | 16 ++++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index 63a99dea6e..e4ce33ea48 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -391,7 +391,7 @@ static enum parse_opt_result parse_long_opt(
 					ambiguous_option = abbrev_option;
 					ambiguous_flags = abbrev_flags;
 				}
-				if (!(flags & OPT_UNSET) && *arg_end)
+				if (*arg_end)
 					p->opt = arg_end + 1;
 				abbrev_option = options;
 				abbrev_flags = flags ^ opt_flags;
@@ -412,7 +412,8 @@ static enum parse_opt_result parse_long_opt(
 			if (!skip_prefix(arg + 3, long_name, &rest)) {
 				/* abbreviated and negated? */
 				if (allow_abbrev &&
-				    starts_with(long_name, arg + 3))
+				    !strncmp(long_name, arg + 3,
+					     arg_end - arg - 3))
 					goto is_abbreviated;
 				else
 					continue;
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index ec974867e4..8bb2a8b453 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -210,6 +210,22 @@ test_expect_success 'superfluous value provided: boolean' '
 	test_cmp expect actual
 '

+test_expect_success 'superfluous value provided: boolean, abbreviated' '
+	cat >expect <<-\EOF &&
+	error: option `yes'\'' takes no value
+	EOF
+	test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+	test-tool parse-options --ye=hi 2>actual &&
+	test_cmp expect actual &&
+
+	cat >expect <<-\EOF &&
+	error: option `no-yes'\'' takes no value
+	EOF
+	test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+	test-tool parse-options --no-ye=hi 2>actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'superfluous value provided: cmdmode' '
 	cat >expect <<-\EOF &&
 	error: option `mode1'\'' takes no value
--
2.44.0
Previous: René ScharfeNext: Josh Steadmon
Message 16 of 23 in “parse-options: long option parsing fixes and cleanup”
  1. 0/6 parse-options: long option parsing fixes and cleanupRené Scharfe, Feb 24, 2024
  2. 2/6 parse-options: set arg of abbreviated option lazilyRené Scharfe, Feb 24, 2024
  3. 3/6 parse-options: factor out register_abbrev() and struct parsed_optionRené Scharfe, Feb 24, 2024
  4. Junio C HamanoFeb 24, 2024
  5. 1/6 parse-options: recognize abbreviated negated option with argRené Scharfe, Feb 24, 2024
  6. 6/6 parse-options: rearrange long_name matching codeRené Scharfe, Feb 24, 2024
  7. 5/6 parse-options: normalize arg and long_name before comparisonRené Scharfe, Feb 24, 2024
  8. 4/6 parse-options: detect ambiguous self-negationRené Scharfe, Feb 24, 2024
  9. René ScharfeFeb 24, 2024
  10. 0/6 parse-options: long option parsing fixes and cleanupRené Scharfe, Mar 3, 2024
  11. 6/6 parse-options: rearrange long_name matching codeRené Scharfe, Mar 3, 2024
  12. Josh SteadmonMar 12, 2024
  13. 5/6 parse-options: normalize arg and long_name before comparisonRené Scharfe, Mar 3, 2024
  14. Josh SteadmonMar 12, 2024
  15. 2/6 parse-options: set arg of abbreviated option lazilyRené Scharfe, Mar 3, 2024
  16. 1/6 parse-options: recognize abbreviated negated option with argRené Scharfe, Mar 3, 2024
  17. Josh SteadmonMar 12, 2024
  18. 4/6 parse-options: detect ambiguous self-negationRené Scharfe, Mar 3, 2024
  19. 3/6 parse-options: factor out register_abbrev() and struct parsed_optionRené Scharfe, Mar 3, 2024
  20. Josh SteadmonMar 12, 2024
  21. Junio C HamanoMar 13, 2024
  22. René ScharfeMar 13, 2024
  23. Josh SteadmonMar 12, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.