Merge branch 'nd/parse-options-aliases'
authorJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:28 +0000 (16:45 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:28 +0000 (16:45 +0900)
Attempt to use an abbreviated option in "git clone --recurs" is
responded by a request to disambiguate between --recursive and
--recurse-submodules, which is bad because these two are synonyms.
The parse-options API has been extended to define such synonyms
more easily and not produce an unnecessary failure.

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

1  2 
builtin/clone.c
parse-options.h
diff --combined builtin/clone.c
index ffdd94e8f66193626e343e4cd0b14bd12d262d0e,703b7247ade1e58e493e8e7e910303977b22aa36..85b0d3155de0d9ee9257ac44acc699c004022836
@@@ -66,7 -66,6 +66,7 @@@ static int option_dissociate
  static int max_jobs = -1;
  static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
  static struct list_objects_filter_options filter_options;
 +static struct string_list server_options = STRING_LIST_INIT_NODUP;
  
  static int recurse_submodules_cb(const struct option *opt,
                                 const char *arg, int unset)
@@@ -99,10 -98,7 +99,7 @@@ static struct option builtin_clone_opti
                    N_("don't use local hardlinks, always copy")),
        OPT_BOOL('s', "shared", &option_shared,
                    N_("setup as shared repository")),
-       { OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules,
-         N_("pathspec"), N_("initialize submodules in the clone"),
-         PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb,
-         (intptr_t)"." },
+       OPT_ALIAS(0, "recursive", "recurse-submodules"),
        { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
          N_("pathspec"), N_("initialize submodules in the clone"),
          PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
                   N_("separate git dir from working tree")),
        OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
                        N_("set config inside the new repository")),
 +      OPT_STRING_LIST(0, "server-option", &server_options,
 +                      N_("server-specific"), N_("option to transmit")),
        OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
                        TRANSPORT_FAMILY_IPV4),
        OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
@@@ -660,8 -654,7 +657,8 @@@ static void update_remote_refs(const st
                               const char *branch_top,
                               const char *msg,
                               struct transport *transport,
 -                             int check_connectivity)
 +                             int check_connectivity,
 +                             int check_refs_only)
  {
        const struct ref *rm = mapped_refs;
  
  
                opt.transport = transport;
                opt.progress = transport->progress;
 +              opt.check_refs_only = !!check_refs_only;
  
                if (check_connected(iterate_ref_map, &rm, &opt))
                        die(_("remote did not send all necessary objects"));
@@@ -1141,9 -1133,6 +1138,9 @@@ int cmd_clone(int argc, const char **ar
                transport_set_option(transport, TRANS_OPT_UPLOADPACK,
                                     option_upload_pack);
  
 +      if (server_options.nr)
 +              transport->server_options = &server_options;
 +
        if (filter_options.choice) {
                struct strbuf expanded_filter_spec = STRBUF_INIT;
                expand_list_objects_filter_spec(&filter_options,
  
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
                           branch_top.buf, reflog_msg.buf, transport,
 -                         !is_local);
 +                         !is_local, filter_options.choice);
  
        update_head(our_head_points_at, remote_head, reflog_msg.buf);
  
diff --combined parse-options.h
index bd00cf004900c478a0dfae2f0d311d356a67b3c6,bb49efc2da430ed933d8a2a1f6cdd732f7078ed4..98ea42ffd9ecd977b655143651359bf1859eba2a
@@@ -7,6 -7,7 +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 +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 +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,
@@@ -277,12 -283,8 +283,12 @@@ int parse_opt_abbrev_cb(const struct op
  int parse_opt_expiry_date_cb(const struct option *, const char *, int);
  int parse_opt_color_flag_cb(const struct option *, const char *, int);
  int parse_opt_verbosity_cb(const struct option *, const char *, int);
 +/* value is struct oid_array* */
  int parse_opt_object_name(const struct option *, const char *, int);
 +/* value is struct object_id* */
 +int parse_opt_object_id(const struct option *, const char *, int);
  int parse_opt_commits(const struct option *, const char *, int);
 +int parse_opt_commit(const struct option *, const char *, int);
  int parse_opt_tertiary(const struct option *, const char *, int);
  int parse_opt_string_list(const struct option *, const char *, int);
  int parse_opt_noop_cb(const struct option *, const char *, int);
@@@ -320,6 -322,5 +326,6 @@@ int parse_opt_passthru_argv(const struc
  #define OPT_NO_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH("no-contains", v, h, PARSE_OPT_NONEG)
  #define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH("with", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG)
  #define OPT_WITHOUT(v, h) _OPT_CONTAINS_OR_WITH("without", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG)
 +#define OPT_CLEANUP(v) OPT_STRING(0, "cleanup", v, N_("mode"), N_("how to strip spaces and #comments from message"))
  
  #endif