parse-options: don't emit "ambiguous option" for aliases

Change the option parsing machinery so that e.g. "clone --recurs ..."
doesn't error out because "clone" understands both "--recursive" and
"--recurse-submodules" to mean the same thing.

Initially "clone" just understood --recursive until the
--recurses-submodules alias was added in ccdd3da652 ("clone: Add the
--recurse-submodules option as alias for --recursive",
2010-11-04). Since bb62e0a99f ("clone: teach --recurse-submodules to
optionally take a pathspec", 2017-03-17) the longer form has been
promoted to the default.

But due to the way the options parsing machinery works this resulted
in the rather absurd situation of:

    $ git clone --recurs [...]
    error: ambiguous option: recurs (could be --recursive or --recurse-submodules)

Add OPT_ALIAS() to express this link between two or more options and use
it in git-clone. Multiple aliases of an option could be written as

    OPT_ALIAS(0, "alias1", "original-name"),
    OPT_ALIAS(0, "alias2", "original-name"),
    ...

The current implementation is not exactly optimal in this case. But we
can optimize it when it becomes a problem. So far we don't even have two
aliases of any option.

A big chunk of code is actually from Junio C Hamano.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy
2019-04-29 17:05:25 +07:00
committed by Junio C Hamano
parent 83232e3864
commit 5c387428f1
5 changed files with 164 additions and 10 deletions

View File

@ -7,6 +7,7 @@ enum parse_opt_type {
OPTION_ARGUMENT,
OPTION_GROUP,
OPTION_NUMBER,
OPTION_ALIAS,
/* options with no arguments */
OPTION_BIT,
OPTION_NEGBIT,
@ -183,6 +184,9 @@ struct option {
N_("no-op (backward compatibility)"), \
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
#define OPT_ALIAS(s, l, source_long_name) \
{ OPTION_ALIAS, (s), (l), (source_long_name) }
/*
* parse_options() will filter out the processed options and leave the
* non-option arguments in argv[]. argv0 is assumed program name and
@ -258,6 +262,8 @@ struct parse_opt_ctx_t {
const char *opt;
int flags;
const char *prefix;
const char **alias_groups; /* must be in groups of 3 elements! */
struct option *updated_options;
};
void parse_options_start(struct parse_opt_ctx_t *ctx,