@@ -1976,7 +1976,7 @@ struct submodule_update_clone {
19761976 /* configuration parameters which are passed on to the children */
19771977 struct update_data * update_data ;
19781978
1979- /* to be consumed by git-submodule.sh */
1979+ /* to be consumed by update_submodule() */
19801980 struct update_clone_data * update_clone ;
19811981 int update_clone_nr ; int update_clone_alloc ;
19821982
@@ -1992,10 +1992,8 @@ struct submodule_update_clone {
19921992struct update_data {
19931993 const char * prefix ;
19941994 const char * recursive_prefix ;
1995- const char * sm_path ;
19961995 const char * displaypath ;
19971996 const char * update_default ;
1998- struct object_id oid ;
19991997 struct object_id suboid ;
20001998 struct string_list references ;
20011999 struct submodule_update_strategy update_strategy ;
@@ -2009,12 +2007,17 @@ struct update_data {
20092007 unsigned int force ;
20102008 unsigned int quiet ;
20112009 unsigned int nofetch ;
2012- unsigned int just_cloned ;
20132010 unsigned int remote ;
20142011 unsigned int progress ;
20152012 unsigned int dissociate ;
20162013 unsigned int init ;
20172014 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 ;
20182021};
20192022#define UPDATE_DATA_INIT { \
20202023 .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
@@ -2419,7 +2422,7 @@ static int run_update_command(struct update_data *ud, int subforce)
24192422 return 0 ;
24202423}
24212424
2422- static int do_run_update_procedure (struct update_data * ud )
2425+ static int run_update_procedure (struct update_data * ud )
24232426{
24242427 int subforce = is_null_oid (& ud -> suboid ) || ud -> force ;
24252428
@@ -2449,27 +2452,10 @@ static int do_run_update_procedure(struct update_data *ud)
24492452 return run_update_command (ud , subforce );
24502453}
24512454
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 );
24702456static int update_submodules (struct update_data * update_data )
24712457{
2472- int i ;
2458+ int i , res = 0 ;
24732459 struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT ;
24742460
24752461 suc .update_data = update_data ;
@@ -2486,25 +2472,44 @@ static int update_submodules(struct update_data *update_data)
24862472 * checkout involve more straightforward sequential I/O.
24872473 * - the listener can avoid doing any work if fetching failed.
24882474 */
2489- if (suc .quickstop )
2490- return 1 ;
2475+ if (suc .quickstop ) {
2476+ res = 1 ;
2477+ goto cleanup ;
2478+ }
24912479
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 ];
24942482
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 ;
24962494}
24972495
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 )
24992497{
25002498 struct pathspec pathspec ;
25012499 struct update_data opt = UPDATE_DATA_INIT ;
25022500 struct list_objects_filter_options filter_options ;
25032501 int ret ;
25042502
2505- struct option module_update_clone_options [] = {
2503+ struct option module_update_options [] = {
2504+ OPT__FORCE (& opt .force , N_ ("force checkout updates" ), 0 ),
25062505 OPT_BOOL (0 , "init" , & opt .init ,
25072506 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" )),
25082513 OPT_STRING (0 , "prefix" , & opt .prefix ,
25092514 N_ ("path" ),
25102515 N_ ("path into the working tree" )),
@@ -2551,19 +2556,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)
25512556 git_config (git_update_clone_config , & opt .max_jobs );
25522557
25532558 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 ,
25552560 git_submodule_helper_usage , 0 );
25562561
25572562 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 );
25672565 }
25682566
25692567 opt .filter_options = & filter_options ;
@@ -2609,63 +2607,6 @@ static int update_clone(int argc, const char **argv, const char *prefix)
26092607 return ret ;
26102608}
26112609
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-
26692610static const char * remote_submodule_branch (const char * path )
26702611{
26712612 const struct submodule * sub ;
@@ -3028,8 +2969,53 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)
30282969 return 0 ;
30292970}
30302971
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 )
30333019{
30343020 char * prefixed_path ;
30353021
@@ -3075,9 +3061,44 @@ static int update_submodule2(struct update_data *update_data)
30753061 }
30763062
30773063 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 );
30793088
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 ;
30813102}
30823103
30833104struct add_data {
@@ -3468,9 +3489,7 @@ static struct cmd_struct commands[] = {
34683489 {"name" , module_name , 0 },
34693490 {"clone" , module_clone , 0 },
34703491 {"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 },
34743493 {"resolve-relative-url-test" , resolve_relative_url_test , 0 },
34753494 {"foreach" , module_foreach , SUPPORT_SUPER_PREFIX },
34763495 {"init" , module_init , SUPPORT_SUPER_PREFIX },
0 commit comments