parse-options: add a separate case for help output on error

When we parse a command line option such as -h or --help, we currently exit 129, since that is the exit code when help output is printed. In a future commit, we'll change this to exit 0 instead, since we're doing what the user wanted successfully. However, there are some cases where we print help output because the user has provided ambiguous or invalid input, such as an ambiguous option, and we'll want to exit unsuccessfully there. Make this easier by defining a new return code, PARSE_OPT_HELP_ERROR, that can be used in this case, while reserving PARSE_OPT_HELP for those cases where the user has requested help directly. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Jul 8, 2026 at 00:15 UTC 154aee0bd2d7feba0de20ab6ffbeac081fe6051a
5 files changed +13 -4
builtin/blame.c
+1
@@ -1013,6 +1013,7 @@ int cmd_blame(int argc,
1013 case PARSE_OPT_UNKNOWN:
1014 break;
1015 case PARSE_OPT_HELP:
1016 + case PARSE_OPT_HELP_ERROR:
1017 case PARSE_OPT_ERROR:
1018 case PARSE_OPT_SUBCOMMAND:
1019 exit(129);
builtin/shortlog.c
+1
@@ -433,6 +433,7 @@ int cmd_shortlog(int argc,
433 case PARSE_OPT_UNKNOWN:
434 break;
435 case PARSE_OPT_HELP:
436 + case PARSE_OPT_HELP_ERROR:
437 case PARSE_OPT_ERROR:
438 case PARSE_OPT_SUBCOMMAND:
439 exit(129);
builtin/update-index.c
+1
@@ -1133,6 +1133,7 @@ int cmd_update_index(int argc,
1133 break;
1134 switch (parseopt_state) {
1135 case PARSE_OPT_HELP:
1136 + case PARSE_OPT_HELP_ERROR:
1137 case PARSE_OPT_ERROR:
1138 exit(129);
1139 case PARSE_OPT_COMPLETE:
parse-options.c
+8 -3
@@ -583,7 +583,7 @@ static enum parse_opt_result parse_long_opt(
583 ambiguous.option->long_name,
584 (abbrev.flags & OPT_UNSET) ? "no-" : "",
585 abbrev.option->long_name);
586 - return PARSE_OPT_HELP;
586 + return PARSE_OPT_HELP_ERROR;
587 }
588 if (abbrev.option) {
589 if (*arg_end)
@@ -1037,6 +1037,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
1037 usage_with_options(usagestr, options);
1038 case PARSE_OPT_COMPLETE:
1039 case PARSE_OPT_HELP:
1040 + case PARSE_OPT_HELP_ERROR:
1041 case PARSE_OPT_ERROR:
1042 case PARSE_OPT_DONE:
1043 case PARSE_OPT_NON_OPTION:
@@ -1072,6 +1073,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
1073 case PARSE_OPT_NON_OPTION:
1074 case PARSE_OPT_SUBCOMMAND:
1075 case PARSE_OPT_HELP:
1076 + case PARSE_OPT_HELP_ERROR:
1077 case PARSE_OPT_COMPLETE:
1078 BUG("parse_short_opt() cannot return these");
1079 case PARSE_OPT_DONE:
@@ -1099,6 +1101,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
1101 case PARSE_OPT_SUBCOMMAND:
1102 case PARSE_OPT_COMPLETE:
1103 case PARSE_OPT_HELP:
1104 + case PARSE_OPT_HELP_ERROR:
1105 BUG("parse_short_opt() cannot return these");
1106 case PARSE_OPT_DONE:
1107 break;
@@ -1132,6 +1135,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
1135 case PARSE_OPT_UNKNOWN:
1136 goto unknown;
1137 case PARSE_OPT_HELP:
1138 + case PARSE_OPT_HELP_ERROR:
1139 goto show_usage;
1140 case PARSE_OPT_NON_OPTION:
1141 case PARSE_OPT_SUBCOMMAND:
@@ -1197,6 +1201,7 @@ int parse_options(int argc, const char **argv,
1201 parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
1202 switch (parse_options_step(&ctx, options, usagestr)) {
1203 case PARSE_OPT_HELP:
1204 + case PARSE_OPT_HELP_ERROR:
1205 case PARSE_OPT_ERROR:
1206 exit(129);
1207 case PARSE_OPT_COMPLETE:
@@ -1363,7 +1368,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
1368 parse_options_check_harder(opts);
1369
1370 if (!usagestr)
1366 - return PARSE_OPT_HELP;
1371 + return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;
1372
1373 if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1374 fprintf(outfile, "cat <<\\EOF\n");
@@ -1476,7 +1481,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
1481 if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1482 fputs("EOF\n", outfile);
1483
1479 - return PARSE_OPT_HELP;
1484 + return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;
1485 }
1486
1487 void NORETURN usage_with_options(const char * const *usagestr,
parse-options.h
+2 -1
@@ -57,7 +57,8 @@ enum parse_opt_option_flags {
57 };
58
59 enum parse_opt_result {
60 - PARSE_OPT_COMPLETE = -3,
60 + PARSE_OPT_COMPLETE = -4,
61 + PARSE_OPT_HELP_ERROR = -3,
62 PARSE_OPT_HELP = -2,
63 PARSE_OPT_ERROR = -1, /* must be the same as error() */
64 PARSE_OPT_DONE = 0, /* fixed so that "return 0" works */