]> git.ipfire.org Git - thirdparty/git.git/commitdiff
parse-options: recognize abbreviated negated option with arg
authorRené Scharfe <l.s.r@web.de>
Sun, 3 Mar 2024 12:19:38 +0000 (13:19 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 3 Mar 2024 17:49:21 +0000 (09:49 -0800)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
parse-options.c
t/t0040-parse-options.sh

index 63a99dea6ef06b19bbb679a3ddd76087abc2a028..e4ce33ea48b02e577caac2d436f58a86926e2544 100644 (file)
@@ -391,7 +391,7 @@ is_abbreviated:
                                        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 @@ is_abbreviated:
                        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;
index ec974867e4337ca503cb817fd79926193c518710..8bb2a8b453ce0bd6ce1960542e21d3bcd74567e0 100755 (executable)
@@ -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