1212#include "sha1-array.h"
1313#include "argv-array.h"
1414#include "blob.h"
15+ #include "thread-utils.h"
1516
1617static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND ;
1718static struct string_list changed_submodule_paths ;
@@ -610,37 +611,28 @@ static void calculate_changed_submodule_paths(void)
610611 initialized_fetch_ref_tips = 0 ;
611612}
612613
613- int fetch_populated_submodules (const struct argv_array * options ,
614- const char * prefix , int command_line_option ,
615- int quiet )
614+ struct submodule_parallel_fetch {
615+ int count ;
616+ struct argv_array args ;
617+ const char * work_tree ;
618+ const char * prefix ;
619+ int command_line_option ;
620+ int quiet ;
621+ int result ;
622+ };
623+ #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0}
624+
625+ static int get_next_submodule (struct child_process * cp ,
626+ struct strbuf * err , void * data , void * * task_cb )
616627{
617- int i , result = 0 ;
618- struct child_process cp = CHILD_PROCESS_INIT ;
619- struct argv_array argv = ARGV_ARRAY_INIT ;
620- const char * work_tree = get_git_work_tree ();
621- if (!work_tree )
622- goto out ;
623-
624- if (read_cache () < 0 )
625- die ("index file corrupt" );
626-
627- argv_array_push (& argv , "fetch" );
628- for (i = 0 ; i < options -> argc ; i ++ )
629- argv_array_push (& argv , options -> argv [i ]);
630- argv_array_push (& argv , "--recurse-submodules-default" );
631- /* default value, "--submodule-prefix" and its value are added later */
632-
633- cp .env = local_repo_env ;
634- cp .git_cmd = 1 ;
635- cp .no_stdin = 1 ;
636-
637- calculate_changed_submodule_paths ();
628+ int ret = 0 ;
629+ struct submodule_parallel_fetch * spf = data ;
638630
639- for (i = 0 ; i < active_nr ; i ++ ) {
631+ for (; spf -> count < active_nr ; spf -> count ++ ) {
640632 struct strbuf submodule_path = STRBUF_INIT ;
641633 struct strbuf submodule_git_dir = STRBUF_INIT ;
642634 struct strbuf submodule_prefix = STRBUF_INIT ;
643- const struct cache_entry * ce = active_cache [i ];
635+ const struct cache_entry * ce = active_cache [spf -> count ];
644636 const char * git_dir , * default_argv ;
645637 const struct submodule * submodule ;
646638
@@ -652,7 +644,7 @@ int fetch_populated_submodules(const struct argv_array *options,
652644 submodule = submodule_from_name (null_sha1 , ce -> name );
653645
654646 default_argv = "yes" ;
655- if (command_line_option == RECURSE_SUBMODULES_DEFAULT ) {
647+ if (spf -> command_line_option == RECURSE_SUBMODULES_DEFAULT ) {
656648 if (submodule &&
657649 submodule -> fetch_recurse !=
658650 RECURSE_SUBMODULES_NONE ) {
@@ -675,40 +667,102 @@ int fetch_populated_submodules(const struct argv_array *options,
675667 default_argv = "on-demand" ;
676668 }
677669 }
678- } else if (command_line_option == RECURSE_SUBMODULES_ON_DEMAND ) {
670+ } else if (spf -> command_line_option == RECURSE_SUBMODULES_ON_DEMAND ) {
679671 if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
680672 continue ;
681673 default_argv = "on-demand" ;
682674 }
683675
684- strbuf_addf (& submodule_path , "%s/%s" , work_tree , ce -> name );
676+ strbuf_addf (& submodule_path , "%s/%s" , spf -> work_tree , ce -> name );
685677 strbuf_addf (& submodule_git_dir , "%s/.git" , submodule_path .buf );
686- strbuf_addf (& submodule_prefix , "%s%s/" , prefix , ce -> name );
678+ strbuf_addf (& submodule_prefix , "%s%s/" , spf -> prefix , ce -> name );
687679 git_dir = read_gitfile (submodule_git_dir .buf );
688680 if (!git_dir )
689681 git_dir = submodule_git_dir .buf ;
690682 if (is_directory (git_dir )) {
691- if (!quiet )
692- fprintf (stderr , "Fetching submodule %s%s\n" , prefix , ce -> name );
693- cp .dir = submodule_path .buf ;
694- argv_array_push (& argv , default_argv );
695- argv_array_push (& argv , "--submodule-prefix" );
696- argv_array_push (& argv , submodule_prefix .buf );
697- cp .argv = argv .argv ;
698- if (run_command (& cp ))
699- result = 1 ;
700- argv_array_pop (& argv );
701- argv_array_pop (& argv );
702- argv_array_pop (& argv );
683+ child_process_init (cp );
684+ cp -> dir = strbuf_detach (& submodule_path , NULL );
685+ cp -> env = local_repo_env ;
686+ cp -> git_cmd = 1 ;
687+ if (!spf -> quiet )
688+ strbuf_addf (err , "Fetching submodule %s%s\n" ,
689+ spf -> prefix , ce -> name );
690+ argv_array_init (& cp -> args );
691+ argv_array_pushv (& cp -> args , spf -> args .argv );
692+ argv_array_push (& cp -> args , default_argv );
693+ argv_array_push (& cp -> args , "--submodule-prefix" );
694+ argv_array_push (& cp -> args , submodule_prefix .buf );
695+ ret = 1 ;
703696 }
704697 strbuf_release (& submodule_path );
705698 strbuf_release (& submodule_git_dir );
706699 strbuf_release (& submodule_prefix );
700+ if (ret ) {
701+ spf -> count ++ ;
702+ return 1 ;
703+ }
707704 }
708- argv_array_clear (& argv );
705+ return 0 ;
706+ }
707+
708+ static int fetch_start_failure (struct child_process * cp ,
709+ struct strbuf * err ,
710+ void * cb , void * task_cb )
711+ {
712+ struct submodule_parallel_fetch * spf = cb ;
713+
714+ spf -> result = 1 ;
715+
716+ return 0 ;
717+ }
718+
719+ static int fetch_finish (int retvalue , struct child_process * cp ,
720+ struct strbuf * err , void * cb , void * task_cb )
721+ {
722+ struct submodule_parallel_fetch * spf = cb ;
723+
724+ if (retvalue )
725+ spf -> result = 1 ;
726+
727+ return 0 ;
728+ }
729+
730+ int fetch_populated_submodules (const struct argv_array * options ,
731+ const char * prefix , int command_line_option ,
732+ int quiet )
733+ {
734+ int i ;
735+ int max_parallel_jobs = 1 ;
736+ struct submodule_parallel_fetch spf = SPF_INIT ;
737+
738+ spf .work_tree = get_git_work_tree ();
739+ spf .command_line_option = command_line_option ;
740+ spf .quiet = quiet ;
741+ spf .prefix = prefix ;
742+
743+ if (!spf .work_tree )
744+ goto out ;
745+
746+ if (read_cache () < 0 )
747+ die ("index file corrupt" );
748+
749+ argv_array_push (& spf .args , "fetch" );
750+ for (i = 0 ; i < options -> argc ; i ++ )
751+ argv_array_push (& spf .args , options -> argv [i ]);
752+ argv_array_push (& spf .args , "--recurse-submodules-default" );
753+ /* default value, "--submodule-prefix" and its value are added later */
754+
755+ calculate_changed_submodule_paths ();
756+ run_processes_parallel (max_parallel_jobs ,
757+ get_next_submodule ,
758+ fetch_start_failure ,
759+ fetch_finish ,
760+ & spf );
761+
762+ argv_array_clear (& spf .args );
709763out :
710764 string_list_clear (& changed_submodule_paths , 1 );
711- return result ;
765+ return spf . result ;
712766}
713767
714768unsigned is_submodule_modified (const char * path , int ignore_untracked )
0 commit comments