promisor-remote: parse remote.*.partialclonefilter

This makes it possible to specify a different partial clone filter for each promisor remote. 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 fa3d1b63e866d6b893934ab69da10b4516150cdc
8 files changed +40 -17
builtin/fetch.c
+1 -1
@@ -1491,7 +1491,7 @@ static inline void fetch_one_setup_partial(struct remote *remote)
1491 * the config.
1492 */
1493 if (!filter_options.choice)
1494 - partial_clone_get_default_filter_spec(&filter_options);
1494 + partial_clone_get_default_filter_spec(&filter_options, remote->name);
1495 return;
1496 }
1497
list-objects-filter-options.c
+15 -12
@@ -30,6 +30,9 @@ static int gently_parse_list_objects_filter(
30 {
31 const char *v0;
32
33 + if (!arg)
34 + return 0;
35 +
36 if (filter_options->choice) {
37 if (errbuf) {
38 strbuf_addstr(
@@ -148,6 +151,7 @@ void partial_clone_register(
151 const struct list_objects_filter_options *filter_options)
152 {
153 char *cfg_name;
154 + char *filter_name;
155
156 /* Check if it is already registered */
157 if (!promisor_remote_find(remote)) {
@@ -162,27 +166,26 @@ void partial_clone_register(
166 /*
167 * Record the initial filter-spec in the config as
168 * the default for subsequent fetches from this remote.
165 - *
166 - * TODO: record it into remote.<name>.partialclonefilter
169 */
168 - core_partial_clone_filter_default =
169 - xstrdup(filter_options->filter_spec);
170 - git_config_set("core.partialclonefilter",
171 - core_partial_clone_filter_default);
170 + filter_name = xstrfmt("remote.%s.partialclonefilter", remote);
171 + git_config_set(filter_name, filter_options->filter_spec);
172 + free(filter_name);
173
174 /* Make sure the config info are reset */
175 promisor_remote_reinit();
176 }
177
178 void partial_clone_get_default_filter_spec(
178 - struct list_objects_filter_options *filter_options)
179 + struct list_objects_filter_options *filter_options,
180 + const char *remote)
181 {
182 + struct promisor_remote *promisor = promisor_remote_find(remote);
183 +
184 /*
185 * Parse default value, but silently ignore it if it is invalid.
186 */
183 - if (!core_partial_clone_filter_default)
184 - return;
185 - gently_parse_list_objects_filter(filter_options,
186 - core_partial_clone_filter_default,
187 - NULL);
187 + if (promisor)
188 + gently_parse_list_objects_filter(filter_options,
189 + promisor->partial_clone_filter,
190 + NULL);
191 }
list-objects-filter-options.h
+2 -1
@@ -87,6 +87,7 @@ void partial_clone_register(
87 const char *remote,
88 const struct list_objects_filter_options *filter_options);
89 void partial_clone_get_default_filter_spec(
90 - struct list_objects_filter_options *filter_options);
90 + struct list_objects_filter_options *filter_options,
91 + const char *remote);
92
93 #endif /* LIST_OBJECTS_FILTER_OPTIONS_H */
promisor-remote.c
+15
@@ -75,6 +75,21 @@ static int promisor_remote_config(const char *var, const char *value, void *data
75 free(remote_name);
76 return 0;
77 }
78 + if (!strcmp(subkey, "partialclonefilter")) {
79 + struct promisor_remote *r;
80 + char *remote_name = xmemdupz(name, namelen);
81 +
82 + r = promisor_remote_lookup(remote_name, NULL);
83 + if (!r)
84 + r = promisor_remote_new(remote_name);
85 +
86 + free(remote_name);
87 +
88 + if (!r)
89 + return 0;
90 +
91 + return git_config_string(&r->partial_clone_filter, var, value);
92 + }
93
94 return 0;
95 }
promisor-remote.h
+4 -1
@@ -5,10 +5,13 @@ struct object_id;
5
6 /*
7 * Promisor remote linked list
8 - * Its information come from remote.XXX config entries.
8 + *
9 + * Information in its fields come from remote.XXX config entries or
10 + * from extensions.partialclone or core.partialclonefilter.
11 */
12 struct promisor_remote {
13 struct promisor_remote *next;
14 + const char *partial_clone_filter;
15 const char name[FLEX_ARRAY];
16 };
17
t/t0410-partial-clone.sh
+1 -1
@@ -26,7 +26,7 @@ promise_and_delete () {
26 test_expect_success 'extensions.partialclone without filter' '
27 test_create_repo server &&
28 git clone --filter="blob:none" "file://$(pwd)/server" client &&
29 - git -C client config --unset core.partialclonefilter &&
29 + git -C client config --unset remote.origin.partialclonefilter &&
30 git -C client fetch origin
31 '
32
t/t5601-clone.sh
+1
@@ -655,6 +655,7 @@ partial_clone () {
655
656 # Ensure that unneeded blobs are not inadvertently fetched.
657 test_config -C client remote.origin.promisor "false" &&
658 + git -C client config --unset remote.origin.partialclonefilter &&
659 test_must_fail git -C client cat-file -e "$HASH1" &&
660
661 # But this blob was fetched, because clone performs an initial checkout
t/t5616-partial-clone.sh
+1 -1
@@ -43,7 +43,7 @@ test_expect_success 'do partial clone 1' '
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 remote.origin.promisor)" = "true" &&
46 - test "$(git -C pc1 config --local core.partialclonefilter)" = "blob:none"
46 + test "$(git -C pc1 config --local remote.origin.partialclonefilter)" = "blob:none"
47 '
48
49 # checkout master to force dynamic object fetch of blobs at HEAD.