submodule--helper: teach update_data more options

Refactor 'struct update_data' to hold the parsed args needed by "git submodule--helper update" and refactor "update-clone" and "run-update-procedure" (the functions that will be combined to form "update") to use these options. For "run-update-procedure", 'struct update_data' already holds its args, so only arg parsing code needs to be updated. For "update-clone", move its args from 'struct submodule_update_clone' into 'struct update_data', and replace them with a pointer to 'struct update_data'. Its other members hold the submodule iteration state of "update-clone", so those are unchanged. Incidentally, since we reformat the designated initializers of the affected structs, also reformat MODULE_CLONE_DATA_INIT for consistency. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Glen Choo committed Mar 15, 2022 at 14:09 UTC c9911c9358e611390e2444f718c73900d17d3d60
2 files changed +76 -76
builtin/submodule--helper.c
+75 -75
@@ -1643,7 +1643,10 @@ struct module_clone_data {
1643 unsigned int require_init: 1;
1644 int single_branch;
1645 };
1646 -#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 }
1646 +#define MODULE_CLONE_DATA_INIT { \
1647 + .reference = STRING_LIST_INIT_NODUP, \
1648 + .single_branch = -1, \
1649 +}
1650
1651 struct submodule_alternate_setup {
1652 const char *submodule_name;
@@ -1967,26 +1970,11 @@ struct update_clone_data {
1970 };
1971
1972 struct submodule_update_clone {
1970 - /* index into 'list', the list of submodules to look into for cloning */
1973 + /* index into 'update_data.list', the list of submodules to look into for cloning */
1974 int current;
1972 - struct module_list list;
1973 - unsigned warn_if_uninitialized : 1;
1974 -
1975 - /* update parameter passed via commandline */
1976 - struct submodule_update_strategy update;
1975
1976 /* configuration parameters which are passed on to the children */
1979 - int progress;
1980 - int quiet;
1981 - int recommend_shallow;
1982 - struct string_list references;
1983 - int dissociate;
1984 - unsigned require_init;
1985 - const char *depth;
1986 - const char *recursive_prefix;
1987 - const char *prefix;
1988 - int single_branch;
1989 - struct list_objects_filter_options *filter_options;
1977 + struct update_data *update_data;
1978
1979 /* to be consumed by git-submodule.sh */
1980 struct update_clone_data *update_clone;
@@ -1998,34 +1986,45 @@ struct submodule_update_clone {
1986 /* failed clones to be retried again */
1987 const struct cache_entry **failed_clones;
1988 int failed_clones_nr, failed_clones_alloc;
2001 -
2002 - int max_jobs;
2003 - unsigned int init;
1989 };
2005 -#define SUBMODULE_UPDATE_CLONE_INIT { \
2006 - .list = MODULE_LIST_INIT, \
2007 - .update = SUBMODULE_UPDATE_STRATEGY_INIT, \
2008 - .recommend_shallow = -1, \
2009 - .references = STRING_LIST_INIT_DUP, \
2010 - .single_branch = -1, \
2011 - .max_jobs = 1, \
2012 -}
1990 +#define SUBMODULE_UPDATE_CLONE_INIT { 0 }
1991
1992 struct update_data {
1993 + const char *prefix;
1994 const char *recursive_prefix;
1995 const char *sm_path;
1996 const char *displaypath;
1997 + const char *update_default;
1998 struct object_id oid;
1999 struct object_id suboid;
2000 + struct string_list references;
2001 struct submodule_update_strategy update_strategy;
2002 + struct list_objects_filter_options *filter_options;
2003 + struct module_list list;
2004 int depth;
2005 + int max_jobs;
2006 + int single_branch;
2007 + int recommend_shallow;
2008 + unsigned int require_init;
2009 unsigned int force;
2010 unsigned int quiet;
2011 unsigned int nofetch;
2012 unsigned int just_cloned;
2013 unsigned int remote;
2014 + unsigned int progress;
2015 + unsigned int dissociate;
2016 + unsigned int init;
2017 + unsigned int warn_if_uninitialized;
2018 };
2028 -#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }
2019 +#define UPDATE_DATA_INIT { \
2020 + .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
2021 + .list = MODULE_LIST_INIT, \
2022 + .recommend_shallow = -1, \
2023 + .references = STRING_LIST_INIT_DUP, \
2024 + .single_branch = -1, \
2025 + .max_jobs = 1, \
2026 + .warn_if_uninitialized = 1, \
2027 +}
2028
2029 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
2030 struct strbuf *out, const char *displaypath)
@@ -2034,7 +2033,7 @@ static void next_submodule_warn_missing(struct submodule_update_clone *suc,
2033 * Only mention uninitialized submodules when their
2034 * paths have been specified.
2035 */
2037 - if (suc->warn_if_uninitialized) {
2036 + if (suc->update_data->warn_if_uninitialized) {
2037 strbuf_addf(out,
2038 _("Submodule path '%s' not initialized"),
2039 displaypath);
@@ -2066,8 +2065,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
2065 int need_free_url = 0;
2066
2067 if (ce_stage(ce)) {
2069 - if (suc->recursive_prefix)
2070 - strbuf_addf(&sb, "%s/%s", suc->recursive_prefix, ce->name);
2068 + if (suc->update_data->recursive_prefix)
2069 + strbuf_addf(&sb, "%s/%s", suc->update_data->recursive_prefix, ce->name);
2070 else
2071 strbuf_addstr(&sb, ce->name);
2072 strbuf_addf(out, _("Skipping unmerged submodule %s"), sb.buf);
@@ -2077,8 +2076,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
2076
2077 sub = submodule_from_path(the_repository, null_oid(), ce->name);
2078
2080 - if (suc->recursive_prefix)
2081 - displaypath = relative_path(suc->recursive_prefix,
2079 + if (suc->update_data->recursive_prefix)
2080 + displaypath = relative_path(suc->update_data->recursive_prefix,
2081 ce->name, &displaypath_sb);
2082 else
2083 displaypath = ce->name;
@@ -2096,8 +2095,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
2095 }
2096 free(key);
2097
2099 - if (suc->update.type == SM_UPDATE_NONE
2100 - || (suc->update.type == SM_UPDATE_UNSPECIFIED
2098 + if (suc->update_data->update_strategy.type == SM_UPDATE_NONE
2099 + || (suc->update_data->update_strategy.type == SM_UPDATE_UNSPECIFIED
2100 && update_type == SM_UPDATE_NONE)) {
2101 strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
2102 strbuf_addch(out, '\n');
@@ -2141,33 +2140,33 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
2140 child->err = -1;
2141 strvec_push(&child->args, "submodule--helper");
2142 strvec_push(&child->args, "clone");
2144 - if (suc->progress)
2143 + if (suc->update_data->progress)
2144 strvec_push(&child->args, "--progress");
2146 - if (suc->quiet)
2145 + if (suc->update_data->quiet)
2146 strvec_push(&child->args, "--quiet");
2148 - if (suc->prefix)
2149 - strvec_pushl(&child->args, "--prefix", suc->prefix, NULL);
2150 - if (suc->recommend_shallow && sub->recommend_shallow == 1)
2147 + if (suc->update_data->prefix)
2148 + strvec_pushl(&child->args, "--prefix", suc->update_data->prefix, NULL);
2149 + if (suc->update_data->recommend_shallow && sub->recommend_shallow == 1)
2150 strvec_push(&child->args, "--depth=1");
2152 - if (suc->filter_options && suc->filter_options->choice)
2151 + else if (suc->update_data->depth)
2152 + strvec_pushf(&child->args, "--depth=%d", suc->update_data->depth);
2153 + if (suc->update_data->filter_options && suc->update_data->filter_options->choice)
2154 strvec_pushf(&child->args, "--filter=%s",
2154 - expand_list_objects_filter_spec(suc->filter_options));
2155 - if (suc->require_init)
2155 + expand_list_objects_filter_spec(suc->update_data->filter_options));
2156 + if (suc->update_data->require_init)
2157 strvec_push(&child->args, "--require-init");
2158 strvec_pushl(&child->args, "--path", sub->path, NULL);
2159 strvec_pushl(&child->args, "--name", sub->name, NULL);
2160 strvec_pushl(&child->args, "--url", url, NULL);
2160 - if (suc->references.nr) {
2161 + if (suc->update_data->references.nr) {
2162 struct string_list_item *item;
2162 - for_each_string_list_item(item, &suc->references)
2163 + for_each_string_list_item(item, &suc->update_data->references)
2164 strvec_pushl(&child->args, "--reference", item->string, NULL);
2165 }
2165 - if (suc->dissociate)
2166 + if (suc->update_data->dissociate)
2167 strvec_push(&child->args, "--dissociate");
2167 - if (suc->depth)
2168 - strvec_push(&child->args, suc->depth);
2169 - if (suc->single_branch >= 0)
2170 - strvec_push(&child->args, suc->single_branch ?
2168 + if (suc->update_data->single_branch >= 0)
2169 + strvec_push(&child->args, suc->update_data->single_branch ?
2170 "--single-branch" :
2171 "--no-single-branch");
2172
@@ -2189,8 +2188,8 @@ static int update_clone_get_next_task(struct child_process *child,
2188 const struct cache_entry *ce;
2189 int index;
2190
2192 - for (; suc->current < suc->list.nr; suc->current++) {
2193 - ce = suc->list.entries[suc->current];
2191 + for (; suc->current < suc->update_data->list.nr; suc->current++) {
2192 + ce = suc->update_data->list.entries[suc->current];
2193 if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
2194 int *p = xmalloc(sizeof(*p));
2195 *p = suc->current;
@@ -2205,7 +2204,7 @@ static int update_clone_get_next_task(struct child_process *child,
2204 * stragglers again, which we can imagine as an extension of the
2205 * entry list.
2206 */
2208 - index = suc->current - suc->list.nr;
2207 + index = suc->current - suc->update_data->list.nr;
2208 if (index < suc->failed_clones_nr) {
2209 int *p;
2210 ce = suc->failed_clones[index];
@@ -2250,8 +2249,8 @@ static int update_clone_task_finished(int result,
2249 if (!result)
2250 return 0;
2251
2253 - if (idx < suc->list.nr) {
2254 - ce = suc->list.entries[idx];
2252 + if (idx < suc->update_data->list.nr) {
2253 + ce = suc->update_data->list.entries[idx];
2254 strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
2255 ce->name);
2256 strbuf_addch(err, '\n');
@@ -2261,7 +2260,7 @@ static int update_clone_task_finished(int result,
2260 suc->failed_clones[suc->failed_clones_nr++] = ce;
2261 return 0;
2262 } else {
2264 - idx -= suc->list.nr;
2263 + idx -= suc->update_data->list.nr;
2264 ce = suc->failed_clones[idx];
2265 strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
2266 ce->name);
@@ -2468,13 +2467,15 @@ static void update_submodule(struct update_clone_data *ucd)
2467 ucd->sub->path);
2468 }
2469
2471 -static int update_submodules(struct submodule_update_clone *suc)
2470 +static int update_submodules(struct update_data *update_data)
2471 {
2472 int i;
2473 + struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
2474
2475 - run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task,
2475 + suc.update_data = update_data;
2476 + run_processes_parallel_tr2(suc.update_data->max_jobs, update_clone_get_next_task,
2477 update_clone_start_failure,
2477 - update_clone_task_finished, suc, "submodule",
2478 + update_clone_task_finished, &suc, "submodule",
2479 "parallel/update");
2480
2481 /*
@@ -2485,41 +2486,40 @@ static int update_submodules(struct submodule_update_clone *suc)
2486 * checkout involve more straightforward sequential I/O.
2487 * - the listener can avoid doing any work if fetching failed.
2488 */
2488 - if (suc->quickstop)
2489 + if (suc.quickstop)
2490 return 1;
2491
2491 - for (i = 0; i < suc->update_clone_nr; i++)
2492 - update_submodule(&suc->update_clone[i]);
2492 + for (i = 0; i < suc.update_clone_nr; i++)
2493 + update_submodule(&suc.update_clone[i]);
2494
2495 return 0;
2496 }
2497
2498 static int update_clone(int argc, const char **argv, const char *prefix)
2499 {
2499 - const char *update = NULL;
2500 struct pathspec pathspec;
2501 - struct submodule_update_clone opt = SUBMODULE_UPDATE_CLONE_INIT;
2501 + struct update_data opt = UPDATE_DATA_INIT;
2502 struct list_objects_filter_options filter_options;
2503 int ret;
2504
2505 struct option module_update_clone_options[] = {
2506 OPT_BOOL(0, "init", &opt.init,
2507 N_("initialize uninitialized submodules before update")),
2508 - OPT_STRING(0, "prefix", &prefix,
2508 + OPT_STRING(0, "prefix", &opt.prefix,
2509 N_("path"),
2510 N_("path into the working tree")),
2511 OPT_STRING(0, "recursive-prefix", &opt.recursive_prefix,
2512 N_("path"),
2513 N_("path into the working tree, across nested "
2514 "submodule boundaries")),
2515 - OPT_STRING(0, "update", &update,
2515 + OPT_STRING(0, "update", &opt.update_default,
2516 N_("string"),
2517 N_("rebase, merge, checkout or none")),
2518 OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"),
2519 N_("reference repository")),
2520 OPT_BOOL(0, "dissociate", &opt.dissociate,
2521 N_("use --reference only while cloning")),
2522 - OPT_STRING(0, "depth", &opt.depth, "<depth>",
2522 + OPT_INTEGER(0, "depth", &opt.depth,
2523 N_("create a shallow clone truncated to the "
2524 "specified number of revisions")),
2525 OPT_INTEGER('j', "jobs", &opt.max_jobs,
@@ -2546,7 +2546,6 @@ static int update_clone(int argc, const char **argv, const char *prefix)
2546 " [--recursive] [--[no-]single-branch] [--] [<path>...]"),
2547 NULL
2548 };
2549 - opt.prefix = prefix;
2549
2550 update_clone_config_from_gitmodules(&opt.max_jobs);
2551 git_config(git_update_clone_config, &opt.max_jobs);
@@ -2569,8 +2568,9 @@ static int update_clone(int argc, const char **argv, const char *prefix)
2568
2569 opt.filter_options = &filter_options;
2570
2572 - if (update)
2573 - if (parse_submodule_update_strategy(update, &opt.update) < 0)
2571 + if (opt.update_default)
2572 + if (parse_submodule_update_strategy(opt.update_default,
2573 + &opt.update_strategy) < 0)
2574 die(_("bad value for update parameter"));
2575
2576 if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) {
@@ -2611,7 +2611,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
2611
2612 static int run_update_procedure(int argc, const char **argv, const char *prefix)
2613 {
2614 - char *prefixed_path, *update = NULL;
2614 + char *prefixed_path;
2615 struct update_data update_data = UPDATE_DATA_INIT;
2616
2617 struct option options[] = {
@@ -2627,7 +2627,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
2627 OPT_STRING(0, "prefix", &prefix,
2628 N_("path"),
2629 N_("path into the working tree")),
2630 - OPT_STRING(0, "update", &update,
2630 + OPT_STRING(0, "update", &update_data.update_default,
2631 N_("string"),
2632 N_("rebase, merge, checkout or none")),
2633 OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"),
@@ -2661,7 +2661,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
2661 update_data.displaypath = get_submodule_displaypath(prefixed_path, prefix);
2662
2663 determine_submodule_update_strategy(the_repository, update_data.just_cloned,
2664 - update_data.sm_path, update,
2664 + update_data.sm_path, update_data.update_default,
2665 &update_data.update_strategy);
2666
2667 free(prefixed_path);
git-submodule.sh
+1 -1
@@ -366,7 +366,7 @@ cmd_update()
366 ${update:+--update "$update"} \
367 ${reference:+"$reference"} \
368 ${dissociate:+"--dissociate"} \
369 - ${depth:+--depth "$depth"} \
369 + ${depth:+"$depth"} \
370 ${require_init:+--require-init} \
371 $single_branch \
372 $recommend_shallow \