1976
/* configuration parameters which are passed on to the children */
1977
struct update_data *update_data;
1978
1979
- /* to be consumed by git-submodule.sh */
1979
+ /* to be consumed by update_submodule() */
1980
struct update_clone_data *update_clone;
1981
int update_clone_nr; int update_clone_alloc;
1982
1992
struct update_data {
1993
const char *prefix;
1994
const char *recursive_prefix;
1995
- const char *sm_path;
1995
const char *displaypath;
1996
const char *update_default;
1998
- struct object_id oid;
1997
struct object_id suboid;
1998
struct string_list references;
1999
struct submodule_update_strategy update_strategy;
2007
unsigned int force;
2008
unsigned int quiet;
2009
unsigned int nofetch;
2012
- unsigned int just_cloned;
2010
unsigned int remote;
2011
unsigned int progress;
2012
unsigned int dissociate;
2013
unsigned int init;
2014
unsigned int warn_if_uninitialized;
2015
+ unsigned int recursive;
2016
+
2017
+ /* copied over from update_clone_data */
2018
+ struct object_id oid;
2019
+ unsigned int just_cloned;
2020
+ const char *sm_path;
2021
};
2022
#define UPDATE_DATA_INIT { \
2023
.update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
2422
return 0;
2423
}
2424
2422
-static int do_run_update_procedure(struct update_data *ud)
2425
+static int run_update_procedure(struct update_data *ud)
2426
{
2427
int subforce = is_null_oid(&ud->suboid) || ud->force;
2428
2452
return run_update_command(ud, subforce);
2453
}
2454
2452
-/*
2453
- * NEEDSWORK: As we convert "git submodule update" to C,
2454
- * update_submodule2() will invoke more and more functions, making it
2455
- * difficult to preserve the function ordering without forward
2456
- * declarations.
2457
- *
2458
- * When the conversion is complete, this forward declaration will be
2459
- * unnecessary and should be removed.
2460
- */
2461
-static int update_submodule2(struct update_data *update_data);
2462
-static void update_submodule(struct update_clone_data *ucd)
2463
-{
2464
- fprintf(stdout, "dummy %s %d\t%s\n",
2465
- oid_to_hex(&ucd->oid),
2466
- ucd->just_cloned,
2467
- ucd->sub->path);
2468
-}
2469
-
2455
+static int update_submodule(struct update_data *update_data);
2456
static int update_submodules(struct update_data *update_data)
2457
{
2472
- int i;
2458
+ int i, res = 0;
2459
struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
2460
2461
suc.update_data = update_data;
2472
* checkout involve more straightforward sequential I/O.
2473
* - the listener can avoid doing any work if fetching failed.
2474
*/
2489
- if (suc.quickstop)
2490
- return 1;
2475
+ if (suc.quickstop) {
2476
+ res = 1;
2477
+ goto cleanup;
2478
+ }
2479
2492
- for (i = 0; i < suc.update_clone_nr; i++)
2493
- update_submodule(&suc.update_clone[i]);
2480
+ for (i = 0; i < suc.update_clone_nr; i++) {
2481
+ struct update_clone_data ucd = suc.update_clone[i];
2482
2495
- return 0;
2483
+ oidcpy(&update_data->oid, &ucd.oid);
2484
+ update_data->just_cloned = ucd.just_cloned;
2485
+ update_data->sm_path = ucd.sub->path;
2486
+
2487
+ if (update_submodule(update_data))
2488
+ res = 1;
2489
+ }
2490
+
2491
+cleanup:
2492
+ string_list_clear(&update_data->references, 0);
2493
+ return res;
2494
}
2495
2498
-static int update_clone(int argc, const char **argv, const char *prefix)
2496
+static int module_update(int argc, const char **argv, const char *prefix)
2497
{
2498
struct pathspec pathspec;
2499
struct update_data opt = UPDATE_DATA_INIT;
2500
struct list_objects_filter_options filter_options;
2501
int ret;
2502
2505
- struct option module_update_clone_options[] = {
2503
+ struct option module_update_options[] = {
2504
+ OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
2505
OPT_BOOL(0, "init", &opt.init,
2506
N_("initialize uninitialized submodules before update")),
2507
+ OPT_BOOL(0, "remote", &opt.remote,
2508
+ N_("use SHA-1 of submodule's remote tracking branch")),
2509
+ OPT_BOOL(0, "recursive", &opt.recursive,
2510
+ N_("traverse submodules recursively")),
2511
+ OPT_BOOL('N', "no-fetch", &opt.nofetch,
2512
+ N_("don't fetch new objects from the remote site")),
2513
OPT_STRING(0, "prefix", &opt.prefix,
2514
N_("path"),
2515
N_("path into the working tree")),
2556
git_config(git_update_clone_config, &opt.max_jobs);
2557
2558
memset(&filter_options, 0, sizeof(filter_options));
2554
- argc = parse_options(argc, argv, prefix, module_update_clone_options,
2559
+ argc = parse_options(argc, argv, prefix, module_update_options,
2560
git_submodule_helper_usage, 0);
2561
2562
if (filter_options.choice && !opt.init) {
2558
- /*
2559
- * NEEDSWORK: Don't use usage_with_options() because the
2560
- * usage string is for "git submodule update", but the
2561
- * options are for "git submodule--helper update-clone".
2562
- *
2563
- * This will no longer be an issue when "update-clone"
2564
- * is replaced by "git submodule--helper update".
2565
- */
2566
- usage(git_submodule_helper_usage[0]);
2563
+ usage_with_options(git_submodule_helper_usage,
2564
+ module_update_options);
2565
}
2566
2567
opt.filter_options = &filter_options;
2607
return ret;
2608
}
2609
2612
-static int run_update_procedure(int argc, const char **argv, const char *prefix)
2613
-{
2614
- struct update_data update_data = UPDATE_DATA_INIT;
2615
-
2616
- struct option options[] = {
2617
- OPT__QUIET(&update_data.quiet,
2618
- N_("suppress output for update by rebase or merge")),
2619
- OPT__FORCE(&update_data.force, N_("force checkout updates"),
2620
- 0),
2621
- OPT_BOOL('N', "no-fetch", &update_data.nofetch,
2622
- N_("don't fetch new objects from the remote site")),
2623
- OPT_BOOL(0, "just-cloned", &update_data.just_cloned,
2624
- N_("overrides update mode in case the repository is a fresh clone")),
2625
- OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")),
2626
- OPT_STRING(0, "prefix", &prefix,
2627
- N_("path"),
2628
- N_("path into the working tree")),
2629
- OPT_STRING(0, "update", &update_data.update_default,
2630
- N_("string"),
2631
- N_("rebase, merge, checkout or none")),
2632
- OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix, N_("path"),
2633
- N_("path into the working tree, across nested "
2634
- "submodule boundaries")),
2635
- OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"),
2636
- N_("SHA1 expected by superproject"), PARSE_OPT_NONEG,
2637
- parse_opt_object_id),
2638
- OPT_BOOL(0, "remote", &update_data.remote,
2639
- N_("use SHA-1 of submodule's remote tracking branch")),
2640
- OPT_END()
2641
- };
2642
-
2643
- const char *const usage[] = {
2644
- N_("git submodule--helper run-update-procedure [<options>] <path>"),
2645
- NULL
2646
- };
2647
-
2648
- argc = parse_options(argc, argv, prefix, options, usage, 0);
2649
-
2650
- if (argc != 1)
2651
- usage_with_options(usage, options);
2652
-
2653
- update_data.sm_path = argv[0];
2654
-
2655
- return update_submodule2(&update_data);
2656
-}
2657
-
2658
-static int resolve_relative_path(int argc, const char **argv, const char *prefix)
2659
-{
2660
- struct strbuf sb = STRBUF_INIT;
2661
- if (argc != 3)
2662
- die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc);
2663
-
2664
- printf("%s", relative_path(argv[1], argv[2], &sb));
2665
- strbuf_release(&sb);
2666
- return 0;
2667
-}
2668
-
2610
static const char *remote_submodule_branch(const char *path)
2611
{
2612
const struct submodule *sub;
2969
return 0;
2970
}
2971
3031
-/* NEEDSWORK: this is a temporary name until we delete update_submodule() */
3032
-static int update_submodule2(struct update_data *update_data)
2972
+static void update_data_to_args(struct update_data *update_data, struct strvec *args)
2973
+{
2974
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
2975
+ strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
2976
+ if (update_data->recursive_prefix)
2977
+ strvec_pushl(args, "--recursive-prefix",
2978
+ update_data->recursive_prefix, NULL);
2979
+ if (update_data->quiet)
2980
+ strvec_push(args, "--quiet");
2981
+ if (update_data->force)
2982
+ strvec_push(args, "--force");
2983
+ if (update_data->init)
2984
+ strvec_push(args, "--init");
2985
+ if (update_data->remote)
2986
+ strvec_push(args, "--remote");
2987
+ if (update_data->nofetch)
2988
+ strvec_push(args, "--no-fetch");
2989
+ if (update_data->dissociate)
2990
+ strvec_push(args, "--dissociate");
2991
+ if (update_data->progress)
2992
+ strvec_push(args, "--progress");
2993
+ if (update_data->require_init)
2994
+ strvec_push(args, "--require-init");
2995
+ if (update_data->depth)
2996
+ strvec_pushf(args, "--depth=%d", update_data->depth);
2997
+ if (update_data->update_default)
2998
+ strvec_pushl(args, "--update", update_data->update_default, NULL);
2999
+ if (update_data->references.nr) {
3000
+ struct string_list_item *item;
3001
+ for_each_string_list_item(item, &update_data->references)
3002
+ strvec_pushl(args, "--reference", item->string, NULL);
3003
+ }
3004
+ if (update_data->filter_options && update_data->filter_options->choice)
3005
+ strvec_pushf(args, "--filter=%s",
3006
+ expand_list_objects_filter_spec(
3007
+ update_data->filter_options));
3008
+ if (update_data->recommend_shallow == 0)
3009
+ strvec_push(args, "--no-recommend-shallow");
3010
+ else if (update_data->recommend_shallow == 1)
3011
+ strvec_push(args, "--recommend-shallow");
3012
+ if (update_data->single_branch >= 0)
3013
+ strvec_push(args, update_data->single_branch ?
3014
+ "--single-branch" :
3015
+ "--no-single-branch");
3016
+}
3017
+
3018
+static int update_submodule(struct update_data *update_data)
3019
{
3020
char *prefixed_path;
3021
3061
}
3062
3063
if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)
3078
- return do_run_update_procedure(update_data);
3064
+ if (run_update_procedure(update_data))
3065
+ return 1;
3066
+
3067
+ if (update_data->recursive) {
3068
+ struct child_process cp = CHILD_PROCESS_INIT;
3069
+ struct update_data next = *update_data;
3070
+ int res;
3071
+
3072
+ if (update_data->recursive_prefix)
3073
+ prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix,
3074
+ update_data->sm_path);
3075
+ else
3076
+ prefixed_path = xstrfmt("%s/", update_data->sm_path);
3077
+
3078
+ next.recursive_prefix = get_submodule_displaypath(prefixed_path,
3079
+ update_data->prefix);
3080
+ next.prefix = NULL;
3081
+ oidcpy(&next.oid, null_oid());
3082
+ oidcpy(&next.suboid, null_oid());
3083
+
3084
+ cp.dir = update_data->sm_path;
3085
+ cp.git_cmd = 1;
3086
+ prepare_submodule_repo_env(&cp.env_array);
3087
+ update_data_to_args(&next, &cp.args);
3088
3080
- return 3;
3089
+ /* die() if child process die()'d */
3090
+ res = run_command(&cp);
3091
+ if (!res)
3092
+ return 0;
3093
+ die_message(_("Failed to recurse into submodule path '%s'"),
3094
+ update_data->displaypath);
3095
+ if (res == 128)
3096
+ exit(res);
3097
+ else if (res)
3098
+ return 1;
3099
+ }
3100
+
3101
+ return 0;
3102
}
3103
3104
struct add_data {
3489
{"name", module_name, 0},
3490
{"clone", module_clone, 0},
3491
{"add", module_add, SUPPORT_SUPER_PREFIX},
3471
- {"update-clone", update_clone, 0},
3472
- {"run-update-procedure", run_update_procedure, 0},
3473
- {"relative-path", resolve_relative_path, 0},
3492
+ {"update", module_update, 0},
3493
{"resolve-relative-url-test", resolve_relative_url_test, 0},
3494
{"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
3495
{"init", module_init, SUPPORT_SUPER_PREFIX},