@@ -54,7 +54,8 @@ static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosit
54
54
static int progress = -1 ;
55
55
static int enable_auto_gc = 1 ;
56
56
static 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 ;
58
59
static enum transport_family family ;
59
60
static const char * depth ;
60
61
static const char * deepen_since ;
@@ -96,13 +97,20 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
96
97
}
97
98
98
99
if (!strcmp (k , "submodule.fetchjobs" )) {
99
- max_children = parse_submodule_fetchjobs (k , v );
100
+ submodule_fetch_jobs_config = parse_submodule_fetchjobs (k , v );
100
101
return 0 ;
101
102
} else if (!strcmp (k , "fetch.recursesubmodules" )) {
102
103
recurse_submodules = parse_fetch_recurse_submodules_arg (k , v );
103
104
return 0 ;
104
105
}
105
106
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
+
106
114
return git_default_config (k , v , cb );
107
115
}
108
116
@@ -134,7 +142,7 @@ static struct option builtin_fetch_options[] = {
134
142
N_ ("fetch all tags and associated objects" ), TAGS_SET ),
135
143
OPT_SET_INT ('n' , NULL , & tags ,
136
144
N_ ("do not fetch all tags (--no-tags)" ), TAGS_UNSET ),
137
- OPT_INTEGER ('j' , "jobs" , & max_children ,
145
+ OPT_INTEGER ('j' , "jobs" , & max_jobs ,
138
146
N_ ("number of submodules fetched in parallel" )),
139
147
OPT_BOOL ('p' , "prune" , & prune ,
140
148
N_ ("prune remote-tracking branches no longer on remote" )),
@@ -1456,7 +1464,62 @@ static void add_options_to_argv(struct argv_array *argv)
1456
1464
1457
1465
}
1458
1466
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 )
1460
1523
{
1461
1524
int i , result = 0 ;
1462
1525
struct argv_array argv = ARGV_ARRAY_INIT ;
@@ -1470,20 +1533,34 @@ static int fetch_multiple(struct string_list *list)
1470
1533
argv_array_pushl (& argv , "fetch" , "--append" , "--no-auto-gc" , NULL );
1471
1534
add_options_to_argv (& argv );
1472
1535
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 );
1481
1560
}
1482
- argv_array_pop (& argv );
1483
- }
1484
1561
1485
1562
argv_array_clear (& argv );
1486
- return result ;
1563
+ return !! result ;
1487
1564
}
1488
1565
1489
1566
/*
@@ -1626,7 +1703,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1626
1703
for (i = 1 ; i < argc ; i ++ )
1627
1704
strbuf_addf (& default_rla , " %s" , argv [i ]);
1628
1705
1629
- fetch_config_from_gitmodules (& max_children , & recurse_submodules );
1706
+ fetch_config_from_gitmodules (& submodule_fetch_jobs_config ,
1707
+ & recurse_submodules );
1630
1708
git_config (git_fetch_config , NULL );
1631
1709
1632
1710
argc = parse_options (argc , argv , prefix ,
@@ -1692,15 +1770,27 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1692
1770
fetch_one_setup_partial (remote );
1693
1771
result = fetch_one (remote , argc , argv , prune_tags_ok );
1694
1772
} else {
1773
+ int max_children = max_jobs ;
1774
+
1695
1775
if (filter_options .choice )
1696
1776
die (_ ("--filter can only be used with the remote "
1697
1777
"configured in extensions.partialclone" ));
1778
+
1779
+ if (max_children < 0 )
1780
+ max_children = fetch_parallel_config ;
1781
+
1698
1782
/* TODO should this also die if we have a previous partial-clone? */
1699
- result = fetch_multiple (& list );
1783
+ result = fetch_multiple (& list , max_children );
1700
1784
}
1701
1785
1702
1786
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF )) {
1703
1787
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 ;
1704
1794
1705
1795
add_options_to_argv (& options );
1706
1796
result = fetch_populated_submodules (the_repository ,
0 commit comments