@@ -54,7 +54,8 @@ static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosit
5454static int progress = -1 ;
5555static int enable_auto_gc = 1 ;
5656static int tags = TAGS_DEFAULT , unshallow , update_shallow , deepen ;
57- static int max_children = 1 ;
57+ static int max_jobs = -1 , submodule_fetch_jobs_config = -1 ;
58+ static int fetch_parallel_config = 1 ;
5859static enum transport_family family ;
5960static const char * depth ;
6061static const char * deepen_since ;
@@ -96,13 +97,20 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
9697 }
9798
9899 if (!strcmp (k , "submodule.fetchjobs" )) {
99- max_children = parse_submodule_fetchjobs (k , v );
100+ submodule_fetch_jobs_config = parse_submodule_fetchjobs (k , v );
100101 return 0 ;
101102 } else if (!strcmp (k , "fetch.recursesubmodules" )) {
102103 recurse_submodules = parse_fetch_recurse_submodules_arg (k , v );
103104 return 0 ;
104105 }
105106
107+ if (!strcmp (k , "fetch.parallel" )) {
108+ fetch_parallel_config = git_config_int (k , v );
109+ if (fetch_parallel_config < 0 )
110+ die (_ ("fetch.parallel cannot be negative" ));
111+ return 0 ;
112+ }
113+
106114 return git_default_config (k , v , cb );
107115}
108116
@@ -134,7 +142,7 @@ static struct option builtin_fetch_options[] = {
134142 N_ ("fetch all tags and associated objects" ), TAGS_SET ),
135143 OPT_SET_INT ('n' , NULL , & tags ,
136144 N_ ("do not fetch all tags (--no-tags)" ), TAGS_UNSET ),
137- OPT_INTEGER ('j' , "jobs" , & max_children ,
145+ OPT_INTEGER ('j' , "jobs" , & max_jobs ,
138146 N_ ("number of submodules fetched in parallel" )),
139147 OPT_BOOL ('p' , "prune" , & prune ,
140148 N_ ("prune remote-tracking branches no longer on remote" )),
@@ -1456,7 +1464,62 @@ static void add_options_to_argv(struct argv_array *argv)
14561464
14571465}
14581466
1459- static int fetch_multiple (struct string_list * list )
1467+ /* Fetch multiple remotes in parallel */
1468+
1469+ struct parallel_fetch_state {
1470+ const char * * argv ;
1471+ struct string_list * remotes ;
1472+ int next , result ;
1473+ };
1474+
1475+ static int fetch_next_remote (struct child_process * cp , struct strbuf * out ,
1476+ void * cb , void * * task_cb )
1477+ {
1478+ struct parallel_fetch_state * state = cb ;
1479+ char * remote ;
1480+
1481+ if (state -> next < 0 || state -> next >= state -> remotes -> nr )
1482+ return 0 ;
1483+
1484+ remote = state -> remotes -> items [state -> next ++ ].string ;
1485+ * task_cb = remote ;
1486+
1487+ argv_array_pushv (& cp -> args , state -> argv );
1488+ argv_array_push (& cp -> args , remote );
1489+ cp -> git_cmd = 1 ;
1490+
1491+ if (verbosity >= 0 )
1492+ printf (_ ("Fetching %s\n" ), remote );
1493+
1494+ return 1 ;
1495+ }
1496+
1497+ static int fetch_failed_to_start (struct strbuf * out , void * cb , void * task_cb )
1498+ {
1499+ struct parallel_fetch_state * state = cb ;
1500+ const char * remote = task_cb ;
1501+
1502+ state -> result = error (_ ("Could not fetch %s" ), remote );
1503+
1504+ return 0 ;
1505+ }
1506+
1507+ static int fetch_finished (int result , struct strbuf * out ,
1508+ void * cb , void * task_cb )
1509+ {
1510+ struct parallel_fetch_state * state = cb ;
1511+ const char * remote = task_cb ;
1512+
1513+ if (result ) {
1514+ strbuf_addf (out , _ ("could not fetch '%s' (exit code: %d)\n" ),
1515+ remote , result );
1516+ state -> result = -1 ;
1517+ }
1518+
1519+ return 0 ;
1520+ }
1521+
1522+ static int fetch_multiple (struct string_list * list , int max_children )
14601523{
14611524 int i , result = 0 ;
14621525 struct argv_array argv = ARGV_ARRAY_INIT ;
@@ -1470,20 +1533,34 @@ static int fetch_multiple(struct string_list *list)
14701533 argv_array_pushl (& argv , "fetch" , "--append" , "--no-auto-gc" , NULL );
14711534 add_options_to_argv (& argv );
14721535
1473- for (i = 0 ; i < list -> nr ; i ++ ) {
1474- const char * name = list -> items [i ].string ;
1475- argv_array_push (& argv , name );
1476- if (verbosity >= 0 )
1477- printf (_ ("Fetching %s\n" ), name );
1478- if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1479- error (_ ("Could not fetch %s" ), name );
1480- result = 1 ;
1536+ if (max_children != 1 && list -> nr != 1 ) {
1537+ struct parallel_fetch_state state = { argv .argv , list , 0 , 0 };
1538+
1539+ argv_array_push (& argv , "--end-of-options" );
1540+ result = run_processes_parallel_tr2 (max_children ,
1541+ & fetch_next_remote ,
1542+ & fetch_failed_to_start ,
1543+ & fetch_finished ,
1544+ & state ,
1545+ "fetch" , "parallel/fetch" );
1546+
1547+ if (!result )
1548+ result = state .result ;
1549+ } else
1550+ for (i = 0 ; i < list -> nr ; i ++ ) {
1551+ const char * name = list -> items [i ].string ;
1552+ argv_array_push (& argv , name );
1553+ if (verbosity >= 0 )
1554+ printf (_ ("Fetching %s\n" ), name );
1555+ if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1556+ error (_ ("Could not fetch %s" ), name );
1557+ result = 1 ;
1558+ }
1559+ argv_array_pop (& argv );
14811560 }
1482- argv_array_pop (& argv );
1483- }
14841561
14851562 argv_array_clear (& argv );
1486- return result ;
1563+ return !! result ;
14871564}
14881565
14891566/*
@@ -1626,7 +1703,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
16261703 for (i = 1 ; i < argc ; i ++ )
16271704 strbuf_addf (& default_rla , " %s" , argv [i ]);
16281705
1629- fetch_config_from_gitmodules (& max_children , & recurse_submodules );
1706+ fetch_config_from_gitmodules (& submodule_fetch_jobs_config ,
1707+ & recurse_submodules );
16301708 git_config (git_fetch_config , NULL );
16311709
16321710 argc = parse_options (argc , argv , prefix ,
@@ -1692,15 +1770,27 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
16921770 fetch_one_setup_partial (remote );
16931771 result = fetch_one (remote , argc , argv , prune_tags_ok );
16941772 } else {
1773+ int max_children = max_jobs ;
1774+
16951775 if (filter_options .choice )
16961776 die (_ ("--filter can only be used with the remote "
16971777 "configured in extensions.partialclone" ));
1778+
1779+ if (max_children < 0 )
1780+ max_children = fetch_parallel_config ;
1781+
16981782 /* TODO should this also die if we have a previous partial-clone? */
1699- result = fetch_multiple (& list );
1783+ result = fetch_multiple (& list , max_children );
17001784 }
17011785
17021786 if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF )) {
17031787 struct argv_array options = ARGV_ARRAY_INIT ;
1788+ int max_children = max_jobs ;
1789+
1790+ if (max_children < 0 )
1791+ max_children = submodule_fetch_jobs_config ;
1792+ if (max_children < 0 )
1793+ max_children = fetch_parallel_config ;
17041794
17051795 add_options_to_argv (& options );
17061796 result = fetch_populated_submodules (the_repository ,
0 commit comments