path: root/parse-options.h
diff options
authorNguyễn Thái Ngọc Duy <>2019-04-29 10:05:25 (GMT)
committerJunio C Hamano <>2019-05-07 03:23:22 (GMT)
commit5c387428f10c27c24d3adb890cd466e2300518fa (patch)
treedfe83739e3ed8989f54a6dc58222a51959534c99 /parse-options.h
parent83232e38648b51abbcbdb56c94632b6906cc85a6 (diff)
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 <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'parse-options.h')
1 files changed, 6 insertions, 0 deletions
diff --git a/parse-options.h b/parse-options.h
index cc9230a..bb49efc 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -7,6 +7,7 @@ enum parse_opt_type {
/* options with no arguments */
@@ -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,