diff options
author | Junio C Hamano <gitster@pobox.com> | 2024-02-13 14:44:48 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-02-13 14:44:48 -0800 |
commit | d982de5d32582bfebf30386468d43290efa258c5 (patch) | |
tree | 074a5f8a93cac0b2087cbdcd98b0efb37ffcaddc | |
parent | 904ca69428ccf38242ad08f60f516b90561ae1ed (diff) | |
parent | 457f96252fcfd64127f71e8663e2e4b6dfd4576c (diff) | |
download | git-d982de5d32582bfebf30386468d43290efa258c5.tar.gz |
Merge branch 'rs/parse-options-with-keep-unknown-abbrev-fix' into maint-2.43
"git diff --no-rename A B" did not disable rename detection but did
not trigger an error from the command line parser.
* rs/parse-options-with-keep-unknown-abbrev-fix:
parse-options: simplify positivation handling
parse-options: fully disable option abbreviation with PARSE_OPT_KEEP_UNKNOWN
-rw-r--r-- | parse-options.c | 21 | ||||
-rwxr-xr-x | t/t4013-diff-various.sh | 6 |
2 files changed, 17 insertions, 10 deletions
diff --git a/parse-options.c b/parse-options.c index 4ce2b7ca16..63a99dea6e 100644 --- a/parse-options.c +++ b/parse-options.c @@ -357,6 +357,7 @@ static enum parse_opt_result parse_long_opt( const char *arg_end = strchrnul(arg, '='); const struct option *abbrev_option = NULL, *ambiguous_option = NULL; enum opt_parsed abbrev_flags = OPT_LONG, ambiguous_flags = OPT_LONG; + int allow_abbrev = !(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT); for (; options->type != OPTION_END; options++) { const char *rest, *long_name = options->long_name; @@ -367,12 +368,16 @@ static enum parse_opt_result parse_long_opt( if (!long_name) continue; -again: + if (!starts_with(arg, "no-") && + !(options->flags & PARSE_OPT_NONEG) && + skip_prefix(long_name, "no-", &long_name)) + opt_flags |= OPT_UNSET; + if (!skip_prefix(arg, long_name, &rest)) rest = NULL; if (!rest) { /* abbreviated? */ - if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT) && + if (allow_abbrev && !strncmp(long_name, arg, arg_end - arg)) { is_abbreviated: if (abbrev_option && @@ -396,22 +401,18 @@ is_abbreviated: if (options->flags & PARSE_OPT_NONEG) continue; /* negated and abbreviated very much? */ - if (starts_with("no-", arg)) { + if (allow_abbrev && starts_with("no-", arg)) { flags |= OPT_UNSET; goto is_abbreviated; } /* negated? */ - if (!starts_with(arg, "no-")) { - if (skip_prefix(long_name, "no-", &long_name)) { - opt_flags |= OPT_UNSET; - goto again; - } + if (!starts_with(arg, "no-")) continue; - } flags |= OPT_UNSET; if (!skip_prefix(arg + 3, long_name, &rest)) { /* abbreviated and negated? */ - if (starts_with(long_name, arg + 3)) + if (allow_abbrev && + starts_with(long_name, arg + 3)) goto is_abbreviated; else continue; diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 76b8619e2e..1a7e2b0bcb 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -663,4 +663,10 @@ test_expect_success 'diff --default-prefix overrides diff.mnemonicprefix' ' check_prefix actual a/file0 b/file0 ' +test_expect_success 'diff --no-renames cannot be abbreviated' ' + test_expect_code 129 git diff --no-rename >actual 2>error && + test_must_be_empty actual && + grep "invalid option: --no-rename" error +' + test_done |