parseopt: enable subcommand autocorrection for git-remote and git-notes

Add PARSE_OPT_SUBCOMMAND_AUTOCORR to enable autocorrection for
subcommands parsed with PARSE_OPT_SUBCOMMAND_OPTIONAL.

Use it for git-remote and git-notes, so mistyped subcommands can be
automatically corrected, and builtin entry points no longer need to
handle the unknown subcommand error path themselves.

This is safe for these two builtins, because they either resolve to a
single subcommand or take no subcommand at all. This means that if the
subcommand parser encounters an unknown argument, it must be a mistyped
subcommand.

Signed-off-by: Jiamu Sun <39@barroit.sh>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jiamu Sun
2026-03-10 20:41:06 +09:00
committed by Junio C Hamano
parent bdd1ed4ad2
commit 94d7bdf646
4 changed files with 17 additions and 22 deletions

View File

@@ -1149,14 +1149,10 @@ int cmd_notes(int argc,
repo_config(the_repository, git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, git_notes_usage,
PARSE_OPT_SUBCOMMAND_OPTIONAL);
if (!fn) {
if (argc) {
error(_("unknown subcommand: `%s'"), argv[0]);
usage_with_options(git_notes_usage, options);
}
PARSE_OPT_SUBCOMMAND_OPTIONAL |
PARSE_OPT_SUBCOMMAND_AUTOCORR);
if (!fn)
fn = list;
}
if (override_notes_ref) {
struct strbuf sb = STRBUF_INIT;

View File

@@ -1953,15 +1953,11 @@ int cmd_remote(int argc,
};
argc = parse_options(argc, argv, prefix, options, builtin_remote_usage,
PARSE_OPT_SUBCOMMAND_OPTIONAL);
PARSE_OPT_SUBCOMMAND_OPTIONAL |
PARSE_OPT_SUBCOMMAND_AUTOCORR);
if (fn) {
if (fn)
return !!fn(argc, argv, prefix, repo);
} else {
if (argc) {
error(_("unknown subcommand: `%s'"), argv[0]);
usage_with_options(builtin_remote_usage, options);
}
else
return !!show_all();
}
}

View File

@@ -693,14 +693,16 @@ static enum parse_opt_result handle_subcommand(struct parse_opt_ctx_t *ctx,
if (!err)
return PARSE_OPT_SUBCOMMAND;
/*
* arg is neither a short or long option nor a subcommand. Since this
* command has a default operation mode, we have to treat this arg and
* all remaining args as args meant to that default operation mode.
* So we are done parsing.
*/
if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL &&
!(ctx->flags & PARSE_OPT_SUBCOMMAND_AUTOCORR)) {
/*
* arg is neither a short or long option nor a subcommand.
* Since this command has a default operation mode, we have to
* treat this arg and all remaining args as args meant to that
* default operation mode. So we are done parsing.
*/
return PARSE_OPT_DONE;
}
find_subcommands(&cmds, options);
assumed = autocorrect_subcommand(arg, &cmds);

View File

@@ -40,6 +40,7 @@ enum parse_opt_flags {
PARSE_OPT_ONE_SHOT = 1 << 5,
PARSE_OPT_SHELL_EVAL = 1 << 6,
PARSE_OPT_SUBCOMMAND_OPTIONAL = 1 << 7,
PARSE_OPT_SUBCOMMAND_AUTOCORR = 1 << 8,
};
enum parse_opt_option_flags {