Skip to content

Commit 68c048c

Browse files
committed
Merge branch 'cc/lop-remote'
Bugfix in newly introduced large-object-promisor remote support. * cc/lop-remote: promisor-remote: compare remote names case sensitively promisor-remote: fix possible issue when no URL is advertised promisor-remote: fix segfault when remote URL is missing t5710: arrange to delete the client before cloning
2 parents 477cc3b + 2c0dcb9 commit 68c048c

File tree

3 files changed

+86
-20
lines changed

3 files changed

+86
-20
lines changed

Documentation/config/promisor.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ promisor.acceptFromServer::
2626
server will be accepted. By accepting a promisor remote, the
2727
client agrees that the server might omit objects that are
2828
lazily fetchable from this promisor remote from its responses
29-
to "fetch" and "clone" requests from the client. See
30-
linkgit:gitprotocol-v2[5].
29+
to "fetch" and "clone" requests from the client. Name and URL
30+
comparisons are case sensitive. See linkgit:gitprotocol-v2[5].

promisor-remote.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -323,13 +323,15 @@ static void promisor_info_vecs(struct repository *repo,
323323
promisor_remote_init(repo);
324324

325325
for (r = repo->promisor_remote_config->promisors; r; r = r->next) {
326-
char *url;
326+
const char *url;
327327
char *url_key = xstrfmt("remote.%s.url", r->name);
328328

329-
strvec_push(names, r->name);
330-
strvec_push(urls, git_config_get_string(url_key, &url) ? NULL : url);
329+
/* Only add remotes with a non empty URL */
330+
if (!git_config_get_string_tmp(url_key, &url) && *url) {
331+
strvec_push(names, r->name);
332+
strvec_push(urls, url);
333+
}
331334

332-
free(url);
333335
free(url_key);
334336
}
335337
}
@@ -356,10 +358,8 @@ char *promisor_remote_info(struct repository *repo)
356358
strbuf_addch(&sb, ';');
357359
strbuf_addstr(&sb, "name=");
358360
strbuf_addstr_urlencode(&sb, names.v[i], allow_unsanitized);
359-
if (urls.v[i]) {
360-
strbuf_addstr(&sb, ",url=");
361-
strbuf_addstr_urlencode(&sb, urls.v[i], allow_unsanitized);
362-
}
361+
strbuf_addstr(&sb, ",url=");
362+
strbuf_addstr_urlencode(&sb, urls.v[i], allow_unsanitized);
363363
}
364364

365365
strvec_clear(&names);
@@ -370,13 +370,13 @@ char *promisor_remote_info(struct repository *repo)
370370

371371
/*
372372
* Find first index of 'nicks' where there is 'nick'. 'nick' is
373-
* compared case insensitively to the strings in 'nicks'. If not found
373+
* compared case sensitively to the strings in 'nicks'. If not found
374374
* 'nicks->nr' is returned.
375375
*/
376376
static size_t remote_nick_find(struct strvec *nicks, const char *nick)
377377
{
378378
for (size_t i = 0; i < nicks->nr; i++)
379-
if (!strcasecmp(nicks->v[i], nick))
379+
if (!strcmp(nicks->v[i], nick))
380380
return i;
381381
return nicks->nr;
382382
}
@@ -409,10 +409,15 @@ static int should_accept_remote(enum accept_promisor accept,
409409
if (accept != ACCEPT_KNOWN_URL)
410410
BUG("Unhandled 'enum accept_promisor' value '%d'", accept);
411411

412+
if (!remote_url || !*remote_url) {
413+
warning(_("no or empty URL advertised for remote '%s'"), remote_name);
414+
return 0;
415+
}
416+
412417
if (!strcmp(urls->v[i], remote_url))
413418
return 1;
414419

415-
warning(_("known remote named '%s' but with url '%s' instead of '%s'"),
420+
warning(_("known remote named '%s' but with URL '%s' instead of '%s'"),
416421
remote_name, urls->v[i], remote_url);
417422

418423
return 0;

t/t5710-promisor-remote-capability.sh

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,29 +93,29 @@ test_expect_success "setup for testing promisor remote advertisement" '
9393

9494
test_expect_success "clone with promisor.advertise set to 'true'" '
9595
git -C server config promisor.advertise true &&
96+
test_when_finished "rm -rf client" &&
9697
9798
# Clone from server to create a client
9899
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
99100
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
100101
-c remote.lop.url="file://$(pwd)/lop" \
101102
-c promisor.acceptfromserver=All \
102103
--no-local --filter="blob:limit=5k" server client &&
103-
test_when_finished "rm -rf client" &&
104104
105105
# Check that the largest object is still missing on the server
106106
check_missing_objects server 1 "$oid"
107107
'
108108

109109
test_expect_success "clone with promisor.advertise set to 'false'" '
110110
git -C server config promisor.advertise false &&
111+
test_when_finished "rm -rf client" &&
111112
112113
# Clone from server to create a client
113114
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
114115
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
115116
-c remote.lop.url="file://$(pwd)/lop" \
116117
-c promisor.acceptfromserver=All \
117118
--no-local --filter="blob:limit=5k" server client &&
118-
test_when_finished "rm -rf client" &&
119119
120120
# Check that the largest object is not missing on the server
121121
check_missing_objects server 0 "" &&
@@ -126,14 +126,14 @@ test_expect_success "clone with promisor.advertise set to 'false'" '
126126

127127
test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
128128
git -C server config promisor.advertise true &&
129+
test_when_finished "rm -rf client" &&
129130
130131
# Clone from server to create a client
131132
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
132133
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
133134
-c remote.lop.url="file://$(pwd)/lop" \
134135
-c promisor.acceptfromserver=None \
135136
--no-local --filter="blob:limit=5k" server client &&
136-
test_when_finished "rm -rf client" &&
137137
138138
# Check that the largest object is not missing on the server
139139
check_missing_objects server 0 "" &&
@@ -144,8 +144,8 @@ test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
144144

145145
test_expect_success "init + fetch with promisor.advertise set to 'true'" '
146146
git -C server config promisor.advertise true &&
147-
148147
test_when_finished "rm -rf client" &&
148+
149149
mkdir client &&
150150
git -C client init &&
151151
git -C client config remote.lop.promisor true &&
@@ -162,30 +162,49 @@ test_expect_success "init + fetch with promisor.advertise set to 'true'" '
162162

163163
test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
164164
git -C server config promisor.advertise true &&
165+
test_when_finished "rm -rf client" &&
165166
166167
# Clone from server to create a client
167168
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
168169
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
169170
-c remote.lop.url="file://$(pwd)/lop" \
170171
-c promisor.acceptfromserver=KnownName \
171172
--no-local --filter="blob:limit=5k" server client &&
172-
test_when_finished "rm -rf client" &&
173173
174174
# Check that the largest object is still missing on the server
175175
check_missing_objects server 1 "$oid"
176176
'
177177

178178
test_expect_success "clone with 'KnownName' and different remote names" '
179179
git -C server config promisor.advertise true &&
180+
test_when_finished "rm -rf client" &&
180181
181182
# Clone from server to create a client
182183
GIT_NO_LAZY_FETCH=0 git clone -c remote.serverTwo.promisor=true \
183184
-c remote.serverTwo.fetch="+refs/heads/*:refs/remotes/lop/*" \
184185
-c remote.serverTwo.url="file://$(pwd)/lop" \
185186
-c promisor.acceptfromserver=KnownName \
186187
--no-local --filter="blob:limit=5k" server client &&
188+
189+
# Check that the largest object is not missing on the server
190+
check_missing_objects server 0 "" &&
191+
192+
# Reinitialize server so that the largest object is missing again
193+
initialize_server 1 "$oid"
194+
'
195+
196+
test_expect_success "clone with 'KnownName' and missing URL in the config" '
197+
git -C server config promisor.advertise true &&
187198
test_when_finished "rm -rf client" &&
188199
200+
# Clone from server to create a client
201+
# Lazy fetching by the client from the LOP will fail because of the
202+
# missing URL in the client config, so the server will have to lazy
203+
# fetch from the LOP.
204+
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
205+
-c promisor.acceptfromserver=KnownName \
206+
--no-local --filter="blob:limit=5k" server client &&
207+
189208
# Check that the largest object is not missing on the server
190209
check_missing_objects server 0 "" &&
191210
@@ -195,14 +214,14 @@ test_expect_success "clone with 'KnownName' and different remote names" '
195214

196215
test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" '
197216
git -C server config promisor.advertise true &&
217+
test_when_finished "rm -rf client" &&
198218
199219
# Clone from server to create a client
200220
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
201221
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
202222
-c remote.lop.url="file://$(pwd)/lop" \
203223
-c promisor.acceptfromserver=KnownUrl \
204224
--no-local --filter="blob:limit=5k" server client &&
205-
test_when_finished "rm -rf client" &&
206225
207226
# Check that the largest object is still missing on the server
208227
check_missing_objects server 1 "$oid"
@@ -212,14 +231,14 @@ test_expect_success "clone with 'KnownUrl' and different remote urls" '
212231
ln -s lop serverTwo &&
213232
214233
git -C server config promisor.advertise true &&
234+
test_when_finished "rm -rf client" &&
215235
216236
# Clone from server to create a client
217237
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
218238
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
219239
-c remote.lop.url="file://$(pwd)/serverTwo" \
220240
-c promisor.acceptfromserver=KnownUrl \
221241
--no-local --filter="blob:limit=5k" server client &&
222-
test_when_finished "rm -rf client" &&
223242
224243
# Check that the largest object is not missing on the server
225244
check_missing_objects server 0 "" &&
@@ -228,6 +247,48 @@ test_expect_success "clone with 'KnownUrl' and different remote urls" '
228247
initialize_server 1 "$oid"
229248
'
230249

250+
test_expect_success "clone with 'KnownUrl' and url not configured on the server" '
251+
git -C server config promisor.advertise true &&
252+
test_when_finished "rm -rf client" &&
253+
254+
test_when_finished "git -C server config set remote.lop.url \"file://$(pwd)/lop\"" &&
255+
git -C server config unset remote.lop.url &&
256+
257+
# Clone from server to create a client
258+
# It should fail because the client will reject the LOP as URLs are
259+
# different, and the server cannot lazy fetch as the LOP URL is
260+
# missing, so the remote name will be used instead which will fail.
261+
test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
262+
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
263+
-c remote.lop.url="file://$(pwd)/lop" \
264+
-c promisor.acceptfromserver=KnownUrl \
265+
--no-local --filter="blob:limit=5k" server client &&
266+
267+
# Check that the largest object is still missing on the server
268+
check_missing_objects server 1 "$oid"
269+
'
270+
271+
test_expect_success "clone with 'KnownUrl' and empty url, so not advertised" '
272+
git -C server config promisor.advertise true &&
273+
test_when_finished "rm -rf client" &&
274+
275+
test_when_finished "git -C server config set remote.lop.url \"file://$(pwd)/lop\"" &&
276+
git -C server config set remote.lop.url "" &&
277+
278+
# Clone from server to create a client
279+
# It should fail because the client will reject the LOP as an empty URL is
280+
# not advertised, and the server cannot lazy fetch as the LOP URL is empty,
281+
# so the remote name will be used instead which will fail.
282+
test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
283+
-c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
284+
-c remote.lop.url="file://$(pwd)/lop" \
285+
-c promisor.acceptfromserver=KnownUrl \
286+
--no-local --filter="blob:limit=5k" server client &&
287+
288+
# Check that the largest object is still missing on the server
289+
check_missing_objects server 1 "$oid"
290+
'
291+
231292
test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
232293
git -C server config promisor.advertise true &&
233294

0 commit comments

Comments
 (0)