Git currently does not detect the ambiguity of an option that starts
with "no" like --notes and its negated form if given just --n or --no.
All Git commands with such options have other negatable options, and
we detect the ambiguity with them, so that's currently only a potential
problem for scripts that use git rev-parse --parseopt.
Let's fix it nevertheless, as there's no need for that confusion. To
detect the ambiguity we have to loosen the check in register_abbrev(),
as an option is considered an alias of itself. Add non-matching
negation flags as a criterion to recognize an option being ambiguous
with its negated form.
And we need to keep going after finding a non-negated option as an
abbreviated candidate and perform the negation checks in the same
loop.
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
if (p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
return;
if (abbrev->option &&
- !is_alias(p, abbrev->option, option)) {
+ !(abbrev->flags == flags && is_alias(p, abbrev->option, option))) {
/*
* If this is abbreviated, it is
* ambiguous. So when there is no
if (!strncmp(long_name, arg, arg_end - arg)) {
register_abbrev(p, options, flags ^ opt_flags,
&abbrev, &ambiguous);
- continue;
}
/* negation allowed? */
if (options->flags & PARSE_OPT_NONEG)
check_invalid_long_option optionspec-neg --negative
check_invalid_long_option optionspec-neg --no-no-negative
+test_expect_success 'ambiguous: --no matches both --noble and --no-noble' '
+ cat >spec <<-\EOF &&
+ some-command [options]
+ --
+ noble The feudal switch.
+ EOF
+ test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+ git rev-parse --parseopt -- <spec 2>err --no &&
+ grep "error: ambiguous option: no (could be --noble or --no-noble)" err
+'
+
test_done