54
static int progress = -1;
55
static int enable_auto_gc = 1;
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;
59
static enum transport_family family;
60
static const char *depth;
61
static const char *deepen_since;
97
}
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);
101
return 0;
102
} else if (!strcmp(k, "fetch.recursesubmodules")) {
103
recurse_submodules = parse_fetch_recurse_submodules_arg(k, v);
104
return 0;
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
+
114
return git_default_config(k, v, cb);
115
}
116
142
N_("fetch all tags and associated objects"), TAGS_SET),
143
OPT_SET_INT('n', NULL, &tags,
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,
146
N_("number of submodules fetched in parallel")),
147
OPT_BOOL('p', "prune", &prune,
148
N_("prune remote-tracking branches no longer on remote")),
1464
1465
}
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)
1523
{
1524
int i, result = 0;
1525
struct argv_array argv = ARGV_ARRAY_INIT;
1533
argv_array_pushl(&argv, "fetch", "--append", "--no-auto-gc", NULL);
1534
add_options_to_argv(&argv);
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);
1560
}
1482
- argv_array_pop(&argv);
1483
- }
1561
1562
argv_array_clear(&argv);
1486
- return result;
1563
+ return !!result;
1564
}
1565
1566
/*
1703
for (i = 1; i < argc; i++)
1704
strbuf_addf(&default_rla, " %s", argv[i]);
1705
1629
- fetch_config_from_gitmodules(&max_children, &recurse_submodules);
1706
+ fetch_config_from_gitmodules(&submodule_fetch_jobs_config,
1707
+ &recurse_submodules);
1708
git_config(git_fetch_config, NULL);
1709
1710
argc = parse_options(argc, argv, prefix,
1770
fetch_one_setup_partial(remote);
1771
result = fetch_one(remote, argc, argv, prune_tags_ok);
1772
} else {
1773
+ int max_children = max_jobs;
1774
+
1775
if (filter_options.choice)
1776
die(_("--filter can only be used with the remote "
1777
"configured in extensions.partialclone"));
1778
+
1779
+ if (max_children < 0)
1780
+ max_children = fetch_parallel_config;
1781
+
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);
1784
}
1785
1786
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
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;
1794
1795
add_options_to_argv(&options);
1796
result = fetch_populated_submodules(the_repository,