Use promisor_remote_get_direct() and has_promisor_remote()

Instead of using the repository_format_partial_clone global and fetch_objects() directly, let's use has_promisor_remote() and promisor_remote_get_direct(). This way all the configured promisor remotes will be taken into account, not only the one specified by extensions.partialClone. Also when cloning or fetching using a partial clone filter, remote.origin.promisor will be set to "true" instead of setting extensions.partialClone to "origin". This makes it possible to use many promisor remote just by fetching from them. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Jun 25, 2019 at 15:40 UTC b14ed5adaf87c5943433fd6b1d2cbe8c060f9264
14 files changed +56 -47
builtin/cat-file.c
+3 -2
@@ -15,6 +15,7 @@
15 #include "sha1-array.h"
16 #include "packfile.h"
17 #include "object-store.h"
18 +#include "promisor-remote.h"
19
20 struct batch_options {
21 int enabled;
@@ -523,8 +524,8 @@ static int batch_objects(struct batch_options *opt)
524 if (opt->all_objects) {
525 struct object_cb_data cb;
526
526 - if (repository_format_partial_clone)
527 - warning("This repository has extensions.partialClone set. Some objects may not be loaded.");
527 + if (has_promisor_remote())
528 + warning("This repository uses promisor remotes. Some objects may not be loaded.");
529
530 cb.opt = opt;
531 cb.expand = &data;
builtin/fetch.c
+6 -5
@@ -23,6 +23,7 @@
23 #include "packfile.h"
24 #include "list-objects-filter-options.h"
25 #include "commit-reach.h"
26 +#include "promisor-remote.h"
27
28 static const char * const builtin_fetch_usage[] = {
29 N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -1460,7 +1461,7 @@ static inline void fetch_one_setup_partial(struct remote *remote)
1461 * If no prior partial clone/fetch and the current fetch DID NOT
1462 * request a partial-fetch, do a normal fetch.
1463 */
1463 - if (!repository_format_partial_clone && !filter_options.choice)
1464 + if (!has_promisor_remote() && !filter_options.choice)
1465 return;
1466
1467 /*
@@ -1468,7 +1469,7 @@ static inline void fetch_one_setup_partial(struct remote *remote)
1469 * on this repo and remember the given filter-spec as the default
1470 * for subsequent fetches to this remote.
1471 */
1471 - if (!repository_format_partial_clone && filter_options.choice) {
1472 + if (!has_promisor_remote() && filter_options.choice) {
1473 partial_clone_register(remote->name, &filter_options);
1474 return;
1475 }
@@ -1477,7 +1478,7 @@ static inline void fetch_one_setup_partial(struct remote *remote)
1478 * We are currently limited to only ONE promisor remote and only
1479 * allow partial-fetches from the promisor remote.
1480 */
1480 - if (strcmp(remote->name, repository_format_partial_clone)) {
1481 + if (!promisor_remote_find(remote->name)) {
1482 if (filter_options.choice)
1483 die(_("--filter can only be used with the remote "
1484 "configured in extensions.partialClone"));
@@ -1611,7 +1612,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1612 if (depth || deepen_since || deepen_not.nr)
1613 deepen = 1;
1614
1614 - if (filter_options.choice && !repository_format_partial_clone)
1615 + if (filter_options.choice && !has_promisor_remote())
1616 die("--filter can only be used when extensions.partialClone is set");
1617
1618 if (all) {
@@ -1645,7 +1646,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1646 }
1647
1648 if (remote) {
1648 - if (filter_options.choice || repository_format_partial_clone)
1649 + if (filter_options.choice || has_promisor_remote())
1650 fetch_one_setup_partial(remote);
1651 result = fetch_one(remote, argc, argv, prune_tags_ok);
1652 } else {
builtin/gc.c
+2 -1
@@ -27,6 +27,7 @@
27 #include "pack-objects.h"
28 #include "blob.h"
29 #include "tree.h"
30 +#include "promisor-remote.h"
31
32 #define FAILED_RUN "failed to run %s"
33
@@ -661,7 +662,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
662 argv_array_push(&prune, prune_expire);
663 if (quiet)
664 argv_array_push(&prune, "--no-progress");
664 - if (repository_format_partial_clone)
665 + if (has_promisor_remote())
666 argv_array_push(&prune,
667 "--exclude-promisor-objects");
668 if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
builtin/index-pack.c
+4 -4
@@ -14,7 +14,7 @@
14 #include "thread-utils.h"
15 #include "packfile.h"
16 #include "object-store.h"
17 -#include "fetch-object.h"
17 +#include "promisor-remote.h"
18
19 static const char index_pack_usage[] =
20 "git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
@@ -1352,7 +1352,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
1352 sorted_by_pos[i] = &ref_deltas[i];
1353 QSORT(sorted_by_pos, nr_ref_deltas, delta_pos_compare);
1354
1355 - if (repository_format_partial_clone) {
1355 + if (has_promisor_remote()) {
1356 /*
1357 * Prefetch the delta bases.
1358 */
@@ -1366,8 +1366,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
1366 oid_array_append(&to_fetch, &d->oid);
1367 }
1368 if (to_fetch.nr)
1369 - fetch_objects(repository_format_partial_clone,
1370 - to_fetch.oid, to_fetch.nr);
1369 + promisor_remote_get_direct(the_repository,
1370 + to_fetch.oid, to_fetch.nr);
1371 oid_array_clear(&to_fetch);
1372 }
1373
builtin/repack.c
+2 -1
@@ -11,6 +11,7 @@
11 #include "midx.h"
12 #include "packfile.h"
13 #include "object-store.h"
14 +#include "promisor-remote.h"
15
16 static int delta_base_offset = 1;
17 static int pack_kept_objects = -1;
@@ -369,7 +370,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
370 argv_array_push(&cmd.args, "--all");
371 argv_array_push(&cmd.args, "--reflog");
372 argv_array_push(&cmd.args, "--indexed-objects");
372 - if (repository_format_partial_clone)
373 + if (has_promisor_remote())
374 argv_array_push(&cmd.args, "--exclude-promisor-objects");
375 if (write_bitmaps)
376 argv_array_push(&cmd.args, "--write-bitmap-index");
cache-tree.c
+2 -1
@@ -5,6 +5,7 @@
5 #include "cache-tree.h"
6 #include "object-store.h"
7 #include "replace-object.h"
8 +#include "promisor-remote.h"
9
10 #ifndef DEBUG
11 #define DEBUG 0
@@ -357,7 +358,7 @@ static int update_one(struct cache_tree *it,
358 }
359
360 ce_missing_ok = mode == S_IFGITLINK || missing_ok ||
360 - (repository_format_partial_clone &&
361 + (has_promisor_remote() &&
362 ce_skip_worktree(ce));
363 if (is_null_oid(oid) ||
364 (!ce_missing_ok && !has_object_file(oid))) {
connected.c
+2 -1
@@ -5,6 +5,7 @@
5 #include "connected.h"
6 #include "transport.h"
7 #include "packfile.h"
8 +#include "promisor-remote.h"
9
10 /*
11 * If we feed all the commits we want to verify to this command
@@ -73,7 +74,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
74 argv_array_push(&rev_list.args,"rev-list");
75 argv_array_push(&rev_list.args, "--objects");
76 argv_array_push(&rev_list.args, "--stdin");
76 - if (repository_format_partial_clone)
77 + if (has_promisor_remote())
78 argv_array_push(&rev_list.args, "--exclude-promisor-objects");
79 if (!opt->is_deepening_fetch) {
80 argv_array_push(&rev_list.args, "--not");
diff.c
+4 -5
@@ -25,7 +25,7 @@
25 #include "packfile.h"
26 #include "parse-options.h"
27 #include "help.h"
28 -#include "fetch-object.h"
28 +#include "promisor-remote.h"
29
30 #ifdef NO_FAST_WORKING_DIRECTORY
31 #define FAST_WORKING_DIRECTORY 0
@@ -6514,8 +6514,7 @@ static void add_if_missing(struct repository *r,
6514
6515 void diffcore_std(struct diff_options *options)
6516 {
6517 - if (options->repo == the_repository &&
6518 - repository_format_partial_clone) {
6517 + if (options->repo == the_repository && has_promisor_remote()) {
6518 /*
6519 * Prefetch the diff pairs that are about to be flushed.
6520 */
@@ -6532,8 +6531,8 @@ void diffcore_std(struct diff_options *options)
6531 /*
6532 * NEEDSWORK: Consider deduplicating the OIDs sent.
6533 */
6535 - fetch_objects(repository_format_partial_clone,
6536 - to_fetch.oid, to_fetch.nr);
6534 + promisor_remote_get_direct(options->repo,
6535 + to_fetch.oid, to_fetch.nr);
6536 oid_array_clear(&to_fetch);
6537 }
6538
list-objects-filter-options.c
+15 -13
@@ -6,6 +6,7 @@
6 #include "list-objects.h"
7 #include "list-objects-filter.h"
8 #include "list-objects-filter-options.h"
9 +#include "promisor-remote.h"
10
11 /*
12 * Parse value of the argument to the "filter" keyword.
@@ -146,30 +147,31 @@ void partial_clone_register(
147 const char *remote,
148 const struct list_objects_filter_options *filter_options)
149 {
149 - /*
150 - * Record the name of the partial clone remote in the
151 - * config and in the global variable -- the latter is
152 - * used throughout to indicate that partial clone is
153 - * enabled and to expect missing objects.
154 - */
155 - if (repository_format_partial_clone &&
156 - *repository_format_partial_clone &&
157 - strcmp(remote, repository_format_partial_clone))
158 - die(_("cannot change partial clone promisor remote"));
150 + char *cfg_name;
151
160 - git_config_set("core.repositoryformatversion", "1");
161 - git_config_set("extensions.partialclone", remote);
152 + /* Check if it is already registered */
153 + if (!promisor_remote_find(remote)) {
154 + git_config_set("core.repositoryformatversion", "1");
155
163 - repository_format_partial_clone = xstrdup(remote);
156 + /* Add promisor config for the remote */
157 + cfg_name = xstrfmt("remote.%s.promisor", remote);
158 + git_config_set(cfg_name, "true");
159 + free(cfg_name);
160 + }
161
162 /*
163 * Record the initial filter-spec in the config as
164 * the default for subsequent fetches from this remote.
165 + *
166 + * TODO: record it into remote.<name>.partialclonefilter
167 */
168 core_partial_clone_filter_default =
169 xstrdup(filter_options->filter_spec);
170 git_config_set("core.partialclonefilter",
171 core_partial_clone_filter_default);
172 +
173 + /* Make sure the config info are reset */
174 + promisor_remote_reinit();
175 }
176
177 void partial_clone_get_default_filter_spec(
packfile.c
+2 -1
@@ -16,6 +16,7 @@
16 #include "tree.h"
17 #include "object-store.h"
18 #include "midx.h"
19 +#include "promisor-remote.h"
20
21 char *odb_pack_name(struct strbuf *buf,
22 const unsigned char *sha1,
@@ -2119,7 +2120,7 @@ int is_promisor_object(const struct object_id *oid)
2120 static int promisor_objects_prepared;
2121
2122 if (!promisor_objects_prepared) {
2122 - if (repository_format_partial_clone) {
2123 + if (has_promisor_remote()) {
2124 for_each_packed_object(add_promisor_object,
2125 &promisor_objects,
2126 FOR_EACH_OBJECT_PROMISOR_ONLY);
sha1-file.c
+8 -7
@@ -30,8 +30,8 @@
30 #include "mergesort.h"
31 #include "quote.h"
32 #include "packfile.h"
33 -#include "fetch-object.h"
33 #include "object-store.h"
34 +#include "promisor-remote.h"
35
36 /* The maximum size for an object header. */
37 #define MAX_HEADER_LEN 32
@@ -1377,16 +1377,17 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
1377 }
1378
1379 /* Check if it is a missing object */
1380 - if (fetch_if_missing && repository_format_partial_clone &&
1380 + if (fetch_if_missing && has_promisor_remote() &&
1381 !already_retried && r == the_repository &&
1382 !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
1383 /*
1384 - * TODO Investigate checking fetch_object() return
1385 - * TODO value and stopping on error here.
1386 - * TODO Pass a repository struct through fetch_object,
1387 - * such that arbitrary repositories work.
1384 + * TODO Investigate checking promisor_remote_get_direct()
1385 + * TODO return value and stopping on error here.
1386 + * TODO Pass a repository struct through
1387 + * promisor_remote_get_direct(), such that arbitrary
1388 + * repositories work.
1389 */
1389 - fetch_objects(repository_format_partial_clone, real, 1);
1390 + promisor_remote_get_direct(r, real, 1);
1391 already_retried = 1;
1392 continue;
1393 }
t/t5601-clone.sh
+1 -1
@@ -654,7 +654,7 @@ partial_clone () {
654 git -C client fsck &&
655
656 # Ensure that unneeded blobs are not inadvertently fetched.
657 - test_config -C client extensions.partialclone "not a remote" &&
657 + test_config -C client remote.origin.promisor "false" &&
658 test_must_fail git -C client cat-file -e "$HASH1" &&
659
660 # But this blob was fetched, because clone performs an initial checkout
t/t5616-partial-clone.sh
+1 -1
@@ -42,7 +42,7 @@ test_expect_success 'do partial clone 1' '
42
43 test_cmp expect_1.oids observed.oids &&
44 test "$(git -C pc1 config --local core.repositoryformatversion)" = "1" &&
45 - test "$(git -C pc1 config --local extensions.partialclone)" = "origin" &&
45 + test "$(git -C pc1 config --local remote.origin.promisor)" = "true" &&
46 test "$(git -C pc1 config --local core.partialclonefilter)" = "blob:none"
47 '
48
unpack-trees.c
+4 -4
@@ -16,7 +16,7 @@
16 #include "submodule-config.h"
17 #include "fsmonitor.h"
18 #include "object-store.h"
19 -#include "fetch-object.h"
19 +#include "promisor-remote.h"
20
21 /*
22 * Error messages expected by scripts out of plumbing commands such as
@@ -400,7 +400,7 @@ static int check_updates(struct unpack_trees_options *o)
400 load_gitmodules_file(index, &state);
401
402 enable_delayed_checkout(&state);
403 - if (repository_format_partial_clone && o->update && !o->dry_run) {
403 + if (has_promisor_remote() && o->update && !o->dry_run) {
404 /*
405 * Prefetch the objects that are to be checked out in the loop
406 * below.
@@ -419,8 +419,8 @@ static int check_updates(struct unpack_trees_options *o)
419 oid_array_append(&to_fetch, &ce->oid);
420 }
421 if (to_fetch.nr)
422 - fetch_objects(repository_format_partial_clone,
423 - to_fetch.oid, to_fetch.nr);
422 + promisor_remote_get_direct(the_repository,
423 + to_fetch.oid, to_fetch.nr);
424 oid_array_clear(&to_fetch);
425 }
426 for (i = 0; i < index->cache_nr; i++) {