Skip to content

Commit d982de5

Browse files
committed
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
2 parents 904ca69 + 457f962 commit d982de5

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

parse-options.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ static enum parse_opt_result parse_long_opt(
357357
const char *arg_end = strchrnul(arg, '=');
358358
const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
359359
enum opt_parsed abbrev_flags = OPT_LONG, ambiguous_flags = OPT_LONG;
360+
int allow_abbrev = !(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT);
360361

361362
for (; options->type != OPTION_END; options++) {
362363
const char *rest, *long_name = options->long_name;
@@ -367,12 +368,16 @@ static enum parse_opt_result parse_long_opt(
367368
if (!long_name)
368369
continue;
369370

370-
again:
371+
if (!starts_with(arg, "no-") &&
372+
!(options->flags & PARSE_OPT_NONEG) &&
373+
skip_prefix(long_name, "no-", &long_name))
374+
opt_flags |= OPT_UNSET;
375+
371376
if (!skip_prefix(arg, long_name, &rest))
372377
rest = NULL;
373378
if (!rest) {
374379
/* abbreviated? */
375-
if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
380+
if (allow_abbrev &&
376381
!strncmp(long_name, arg, arg_end - arg)) {
377382
is_abbreviated:
378383
if (abbrev_option &&
@@ -396,22 +401,18 @@ static enum parse_opt_result parse_long_opt(
396401
if (options->flags & PARSE_OPT_NONEG)
397402
continue;
398403
/* negated and abbreviated very much? */
399-
if (starts_with("no-", arg)) {
404+
if (allow_abbrev && starts_with("no-", arg)) {
400405
flags |= OPT_UNSET;
401406
goto is_abbreviated;
402407
}
403408
/* negated? */
404-
if (!starts_with(arg, "no-")) {
405-
if (skip_prefix(long_name, "no-", &long_name)) {
406-
opt_flags |= OPT_UNSET;
407-
goto again;
408-
}
409+
if (!starts_with(arg, "no-"))
409410
continue;
410-
}
411411
flags |= OPT_UNSET;
412412
if (!skip_prefix(arg + 3, long_name, &rest)) {
413413
/* abbreviated and negated? */
414-
if (starts_with(long_name, arg + 3))
414+
if (allow_abbrev &&
415+
starts_with(long_name, arg + 3))
415416
goto is_abbreviated;
416417
else
417418
continue;

t/t4013-diff-various.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,4 +663,10 @@ test_expect_success 'diff --default-prefix overrides diff.mnemonicprefix' '
663663
check_prefix actual a/file0 b/file0
664664
'
665665

666+
test_expect_success 'diff --no-renames cannot be abbreviated' '
667+
test_expect_code 129 git diff --no-rename >actual 2>error &&
668+
test_must_be_empty actual &&
669+
grep "invalid option: --no-rename" error
670+
'
671+
666672
test_done

0 commit comments

Comments
 (0)