@@ -60,7 +60,8 @@ static int verbosity, deepen_relative, set_upstream;
60
60
static int progress = -1 ;
61
61
static int enable_auto_gc = 1 ;
62
62
static int tags = TAGS_DEFAULT , unshallow , update_shallow , deepen ;
63
- static int max_children = 1 ;
63
+ static int max_jobs = -1 , submodule_fetch_jobs_config = -1 ;
64
+ static int fetch_parallel_config = 1 ;
64
65
static enum transport_family family ;
65
66
static const char * depth ;
66
67
static const char * deepen_since ;
@@ -102,13 +103,20 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
102
103
}
103
104
104
105
if (!strcmp (k , "submodule.fetchjobs" )) {
105
- max_children = parse_submodule_fetchjobs (k , v );
106
+ submodule_fetch_jobs_config = parse_submodule_fetchjobs (k , v );
106
107
return 0 ;
107
108
} else if (!strcmp (k , "fetch.recursesubmodules" )) {
108
109
recurse_submodules = parse_fetch_recurse_submodules_arg (k , v );
109
110
return 0 ;
110
111
}
111
112
113
+ if (!strcmp (k , "fetch.parallel" )) {
114
+ fetch_parallel_config = git_config_int (k , v );
115
+ if (fetch_parallel_config < 0 )
116
+ die (_ ("fetch.parallel cannot be negative" ));
117
+ return 0 ;
118
+ }
119
+
112
120
return git_default_config (k , v , cb );
113
121
}
114
122
@@ -142,7 +150,7 @@ static struct option builtin_fetch_options[] = {
142
150
N_ ("fetch all tags and associated objects" ), TAGS_SET ),
143
151
OPT_SET_INT ('n' , NULL , & tags ,
144
152
N_ ("do not fetch all tags (--no-tags)" ), TAGS_UNSET ),
145
- OPT_INTEGER ('j' , "jobs" , & max_children ,
153
+ OPT_INTEGER ('j' , "jobs" , & max_jobs ,
146
154
N_ ("number of submodules fetched in parallel" )),
147
155
OPT_BOOL ('p' , "prune" , & prune ,
148
156
N_ ("prune remote-tracking branches no longer on remote" )),
@@ -1526,7 +1534,62 @@ static void add_options_to_argv(struct argv_array *argv)
1526
1534
1527
1535
}
1528
1536
1529
- static int fetch_multiple (struct string_list * list )
1537
+ /* Fetch multiple remotes in parallel */
1538
+
1539
+ struct parallel_fetch_state {
1540
+ const char * * argv ;
1541
+ struct string_list * remotes ;
1542
+ int next , result ;
1543
+ };
1544
+
1545
+ static int fetch_next_remote (struct child_process * cp , struct strbuf * out ,
1546
+ void * cb , void * * task_cb )
1547
+ {
1548
+ struct parallel_fetch_state * state = cb ;
1549
+ char * remote ;
1550
+
1551
+ if (state -> next < 0 || state -> next >= state -> remotes -> nr )
1552
+ return 0 ;
1553
+
1554
+ remote = state -> remotes -> items [state -> next ++ ].string ;
1555
+ * task_cb = remote ;
1556
+
1557
+ argv_array_pushv (& cp -> args , state -> argv );
1558
+ argv_array_push (& cp -> args , remote );
1559
+ cp -> git_cmd = 1 ;
1560
+
1561
+ if (verbosity >= 0 )
1562
+ printf (_ ("Fetching %s\n" ), remote );
1563
+
1564
+ return 1 ;
1565
+ }
1566
+
1567
+ static int fetch_failed_to_start (struct strbuf * out , void * cb , void * task_cb )
1568
+ {
1569
+ struct parallel_fetch_state * state = cb ;
1570
+ const char * remote = task_cb ;
1571
+
1572
+ state -> result = error (_ ("Could not fetch %s" ), remote );
1573
+
1574
+ return 0 ;
1575
+ }
1576
+
1577
+ static int fetch_finished (int result , struct strbuf * out ,
1578
+ void * cb , void * task_cb )
1579
+ {
1580
+ struct parallel_fetch_state * state = cb ;
1581
+ const char * remote = task_cb ;
1582
+
1583
+ if (result ) {
1584
+ strbuf_addf (out , _ ("could not fetch '%s' (exit code: %d)\n" ),
1585
+ remote , result );
1586
+ state -> result = -1 ;
1587
+ }
1588
+
1589
+ return 0 ;
1590
+ }
1591
+
1592
+ static int fetch_multiple (struct string_list * list , int max_children )
1530
1593
{
1531
1594
int i , result = 0 ;
1532
1595
struct argv_array argv = ARGV_ARRAY_INIT ;
@@ -1540,20 +1603,34 @@ static int fetch_multiple(struct string_list *list)
1540
1603
argv_array_pushl (& argv , "fetch" , "--append" , "--no-auto-gc" , NULL );
1541
1604
add_options_to_argv (& argv );
1542
1605
1543
- for (i = 0 ; i < list -> nr ; i ++ ) {
1544
- const char * name = list -> items [i ].string ;
1545
- argv_array_push (& argv , name );
1546
- if (verbosity >= 0 )
1547
- printf (_ ("Fetching %s\n" ), name );
1548
- if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1549
- error (_ ("Could not fetch %s" ), name );
1550
- result = 1 ;
1606
+ if (max_children != 1 && list -> nr != 1 ) {
1607
+ struct parallel_fetch_state state = { argv .argv , list , 0 , 0 };
1608
+
1609
+ argv_array_push (& argv , "--end-of-options" );
1610
+ result = run_processes_parallel_tr2 (max_children ,
1611
+ & fetch_next_remote ,
1612
+ & fetch_failed_to_start ,
1613
+ & fetch_finished ,
1614
+ & state ,
1615
+ "fetch" , "parallel/fetch" );
1616
+
1617
+ if (!result )
1618
+ result = state .result ;
1619
+ } else
1620
+ for (i = 0 ; i < list -> nr ; i ++ ) {
1621
+ const char * name = list -> items [i ].string ;
1622
+ argv_array_push (& argv , name );
1623
+ if (verbosity >= 0 )
1624
+ printf (_ ("Fetching %s\n" ), name );
1625
+ if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1626
+ error (_ ("Could not fetch %s" ), name );
1627
+ result = 1 ;
1628
+ }
1629
+ argv_array_pop (& argv );
1551
1630
}
1552
- argv_array_pop (& argv );
1553
- }
1554
1631
1555
1632
argv_array_clear (& argv );
1556
- return result ;
1633
+ return !! result ;
1557
1634
}
1558
1635
1559
1636
/*
@@ -1690,7 +1767,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1690
1767
for (i = 1 ; i < argc ; i ++ )
1691
1768
strbuf_addf (& default_rla , " %s" , argv [i ]);
1692
1769
1693
- fetch_config_from_gitmodules (& max_children , & recurse_submodules );
1770
+ fetch_config_from_gitmodules (& submodule_fetch_jobs_config ,
1771
+ & recurse_submodules );
1694
1772
git_config (git_fetch_config , NULL );
1695
1773
1696
1774
argc = parse_options (argc , argv , prefix ,
@@ -1756,15 +1834,27 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1756
1834
fetch_one_setup_partial (remote );
1757
1835
result = fetch_one (remote , argc , argv , prune_tags_ok );
1758
1836
} else {
1837
+ int max_children = max_jobs ;
1838
+
1759
1839
if (filter_options .choice )
1760
1840
die (_ ("--filter can only be used with the remote "
1761
1841
"configured in extensions.partialclone" ));
1842
+
1843
+ if (max_children < 0 )
1844
+ max_children = fetch_parallel_config ;
1845
+
1762
1846
/* TODO should this also die if we have a previous partial-clone? */
1763
- result = fetch_multiple (& list );
1847
+ result = fetch_multiple (& list , max_children );
1764
1848
}
1765
1849
1766
1850
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF )) {
1767
1851
struct argv_array options = ARGV_ARRAY_INIT ;
1852
+ int max_children = max_jobs ;
1853
+
1854
+ if (max_children < 0 )
1855
+ max_children = submodule_fetch_jobs_config ;
1856
+ if (max_children < 0 )
1857
+ max_children = fetch_parallel_config ;
1768
1858
1769
1859
add_options_to_argv (& options );
1770
1860
result = fetch_populated_submodules (the_repository ,
0 commit comments