@@ -59,7 +59,8 @@ static int verbosity, deepen_relative, set_upstream;
59
59
static int progress = -1 ;
60
60
static int enable_auto_gc = 1 ;
61
61
static int tags = TAGS_DEFAULT , unshallow , update_shallow , deepen ;
62
- static int max_children = 1 ;
62
+ static int max_jobs = -1 , submodule_fetch_jobs_config = -1 ;
63
+ static int fetch_parallel_config = 1 ;
63
64
static enum transport_family family ;
64
65
static const char * depth ;
65
66
static const char * deepen_since ;
@@ -101,13 +102,20 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
101
102
}
102
103
103
104
if (!strcmp (k , "submodule.fetchjobs" )) {
104
- max_children = parse_submodule_fetchjobs (k , v );
105
+ submodule_fetch_jobs_config = parse_submodule_fetchjobs (k , v );
105
106
return 0 ;
106
107
} else if (!strcmp (k , "fetch.recursesubmodules" )) {
107
108
recurse_submodules = parse_fetch_recurse_submodules_arg (k , v );
108
109
return 0 ;
109
110
}
110
111
112
+ if (!strcmp (k , "fetch.parallel" )) {
113
+ fetch_parallel_config = git_config_int (k , v );
114
+ if (fetch_parallel_config < 0 )
115
+ die (_ ("fetch.parallel cannot be negative" ));
116
+ return 0 ;
117
+ }
118
+
111
119
return git_default_config (k , v , cb );
112
120
}
113
121
@@ -141,7 +149,7 @@ static struct option builtin_fetch_options[] = {
141
149
N_ ("fetch all tags and associated objects" ), TAGS_SET ),
142
150
OPT_SET_INT ('n' , NULL , & tags ,
143
151
N_ ("do not fetch all tags (--no-tags)" ), TAGS_UNSET ),
144
- OPT_INTEGER ('j' , "jobs" , & max_children ,
152
+ OPT_INTEGER ('j' , "jobs" , & max_jobs ,
145
153
N_ ("number of submodules fetched in parallel" )),
146
154
OPT_BOOL ('p' , "prune" , & prune ,
147
155
N_ ("prune remote-tracking branches no longer on remote" )),
@@ -1513,7 +1521,62 @@ static void add_options_to_argv(struct argv_array *argv)
1513
1521
1514
1522
}
1515
1523
1516
- static int fetch_multiple (struct string_list * list )
1524
+ /* Fetch multiple remotes in parallel */
1525
+
1526
+ struct parallel_fetch_state {
1527
+ const char * * argv ;
1528
+ struct string_list * remotes ;
1529
+ int next , result ;
1530
+ };
1531
+
1532
+ static int fetch_next_remote (struct child_process * cp , struct strbuf * out ,
1533
+ void * cb , void * * task_cb )
1534
+ {
1535
+ struct parallel_fetch_state * state = cb ;
1536
+ char * remote ;
1537
+
1538
+ if (state -> next < 0 || state -> next >= state -> remotes -> nr )
1539
+ return 0 ;
1540
+
1541
+ remote = state -> remotes -> items [state -> next ++ ].string ;
1542
+ * task_cb = remote ;
1543
+
1544
+ argv_array_pushv (& cp -> args , state -> argv );
1545
+ argv_array_push (& cp -> args , remote );
1546
+ cp -> git_cmd = 1 ;
1547
+
1548
+ if (verbosity >= 0 )
1549
+ printf (_ ("Fetching %s\n" ), remote );
1550
+
1551
+ return 1 ;
1552
+ }
1553
+
1554
+ static int fetch_failed_to_start (struct strbuf * out , void * cb , void * task_cb )
1555
+ {
1556
+ struct parallel_fetch_state * state = cb ;
1557
+ const char * remote = task_cb ;
1558
+
1559
+ state -> result = error (_ ("Could not fetch %s" ), remote );
1560
+
1561
+ return 0 ;
1562
+ }
1563
+
1564
+ static int fetch_finished (int result , struct strbuf * out ,
1565
+ void * cb , void * task_cb )
1566
+ {
1567
+ struct parallel_fetch_state * state = cb ;
1568
+ const char * remote = task_cb ;
1569
+
1570
+ if (result ) {
1571
+ strbuf_addf (out , _ ("could not fetch '%s' (exit code: %d)\n" ),
1572
+ remote , result );
1573
+ state -> result = -1 ;
1574
+ }
1575
+
1576
+ return 0 ;
1577
+ }
1578
+
1579
+ static int fetch_multiple (struct string_list * list , int max_children )
1517
1580
{
1518
1581
int i , result = 0 ;
1519
1582
struct argv_array argv = ARGV_ARRAY_INIT ;
@@ -1527,20 +1590,34 @@ static int fetch_multiple(struct string_list *list)
1527
1590
argv_array_pushl (& argv , "fetch" , "--append" , "--no-auto-gc" , NULL );
1528
1591
add_options_to_argv (& argv );
1529
1592
1530
- for (i = 0 ; i < list -> nr ; i ++ ) {
1531
- const char * name = list -> items [i ].string ;
1532
- argv_array_push (& argv , name );
1533
- if (verbosity >= 0 )
1534
- printf (_ ("Fetching %s\n" ), name );
1535
- if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1536
- error (_ ("Could not fetch %s" ), name );
1537
- result = 1 ;
1593
+ if (max_children != 1 && list -> nr != 1 ) {
1594
+ struct parallel_fetch_state state = { argv .argv , list , 0 , 0 };
1595
+
1596
+ argv_array_push (& argv , "--end-of-options" );
1597
+ result = run_processes_parallel_tr2 (max_children ,
1598
+ & fetch_next_remote ,
1599
+ & fetch_failed_to_start ,
1600
+ & fetch_finished ,
1601
+ & state ,
1602
+ "fetch" , "parallel/fetch" );
1603
+
1604
+ if (!result )
1605
+ result = state .result ;
1606
+ } else
1607
+ for (i = 0 ; i < list -> nr ; i ++ ) {
1608
+ const char * name = list -> items [i ].string ;
1609
+ argv_array_push (& argv , name );
1610
+ if (verbosity >= 0 )
1611
+ printf (_ ("Fetching %s\n" ), name );
1612
+ if (run_command_v_opt (argv .argv , RUN_GIT_CMD )) {
1613
+ error (_ ("Could not fetch %s" ), name );
1614
+ result = 1 ;
1615
+ }
1616
+ argv_array_pop (& argv );
1538
1617
}
1539
- argv_array_pop (& argv );
1540
- }
1541
1618
1542
1619
argv_array_clear (& argv );
1543
- return result ;
1620
+ return !! result ;
1544
1621
}
1545
1622
1546
1623
/*
@@ -1673,7 +1750,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1673
1750
for (i = 1 ; i < argc ; i ++ )
1674
1751
strbuf_addf (& default_rla , " %s" , argv [i ]);
1675
1752
1676
- fetch_config_from_gitmodules (& max_children , & recurse_submodules );
1753
+ fetch_config_from_gitmodules (& submodule_fetch_jobs_config ,
1754
+ & recurse_submodules );
1677
1755
git_config (git_fetch_config , NULL );
1678
1756
1679
1757
argc = parse_options (argc , argv , prefix ,
@@ -1739,15 +1817,27 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1739
1817
fetch_one_setup_partial (remote );
1740
1818
result = fetch_one (remote , argc , argv , prune_tags_ok );
1741
1819
} else {
1820
+ int max_children = max_jobs ;
1821
+
1742
1822
if (filter_options .choice )
1743
1823
die (_ ("--filter can only be used with the remote "
1744
1824
"configured in extensions.partialclone" ));
1825
+
1826
+ if (max_children < 0 )
1827
+ max_children = fetch_parallel_config ;
1828
+
1745
1829
/* TODO should this also die if we have a previous partial-clone? */
1746
- result = fetch_multiple (& list );
1830
+ result = fetch_multiple (& list , max_children );
1747
1831
}
1748
1832
1749
1833
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF )) {
1750
1834
struct argv_array options = ARGV_ARRAY_INIT ;
1835
+ int max_children = max_jobs ;
1836
+
1837
+ if (max_children < 0 )
1838
+ max_children = submodule_fetch_jobs_config ;
1839
+ if (max_children < 0 )
1840
+ max_children = fetch_parallel_config ;
1751
1841
1752
1842
add_options_to_argv (& options );
1753
1843
result = fetch_populated_submodules (the_repository ,
0 commit comments