aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-04-07 14:23:17 -0700
committerJunio C Hamano <gitster@pobox.com>2025-04-07 14:23:17 -0700
commit68c048c84cf07fd29513cf1fa23290279d518cbb (patch)
treeb229c929cb58a7e32f1c0a076b07da6ec31b65bb
parent477cc3b6c7fd777e38f587f1e0e323683ad1923d (diff)
parent2c0dcb9754959c9b917634313fb448fce5052642 (diff)
downloadgit-68c048c84cf07fd29513cf1fa23290279d518cbb.tar.gz
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
-rw-r--r--Documentation/config/promisor.adoc4
-rw-r--r--promisor-remote.c27
-rwxr-xr-xt/t5710-promisor-remote-capability.sh75
3 files changed, 86 insertions, 20 deletions
diff --git a/Documentation/config/promisor.adoc b/Documentation/config/promisor.adoc
index 9192acfd24..2638b01f83 100644
--- a/Documentation/config/promisor.adoc
+++ b/Documentation/config/promisor.adoc
@@ -26,5 +26,5 @@ promisor.acceptFromServer::
server will be accepted. By accepting a promisor remote, the
client agrees that the server might omit objects that are
lazily fetchable from this promisor remote from its responses
- to "fetch" and "clone" requests from the client. See
- linkgit:gitprotocol-v2[5].
+ to "fetch" and "clone" requests from the client. Name and URL
+ comparisons are case sensitive. See linkgit:gitprotocol-v2[5].
diff --git a/promisor-remote.c b/promisor-remote.c
index 6a0a61382f..5801ebfd9b 100644
--- a/promisor-remote.c
+++ b/promisor-remote.c
@@ -323,13 +323,15 @@ static void promisor_info_vecs(struct repository *repo,
promisor_remote_init(repo);
for (r = repo->promisor_remote_config->promisors; r; r = r->next) {
- char *url;
+ const char *url;
char *url_key = xstrfmt("remote.%s.url", r->name);
- strvec_push(names, r->name);
- strvec_push(urls, git_config_get_string(url_key, &url) ? NULL : url);
+ /* Only add remotes with a non empty URL */
+ if (!git_config_get_string_tmp(url_key, &url) && *url) {
+ strvec_push(names, r->name);
+ strvec_push(urls, url);
+ }
- free(url);
free(url_key);
}
}
@@ -356,10 +358,8 @@ char *promisor_remote_info(struct repository *repo)
strbuf_addch(&sb, ';');
strbuf_addstr(&sb, "name=");
strbuf_addstr_urlencode(&sb, names.v[i], allow_unsanitized);
- if (urls.v[i]) {
- strbuf_addstr(&sb, ",url=");
- strbuf_addstr_urlencode(&sb, urls.v[i], allow_unsanitized);
- }
+ strbuf_addstr(&sb, ",url=");
+ strbuf_addstr_urlencode(&sb, urls.v[i], allow_unsanitized);
}
strvec_clear(&names);
@@ -370,13 +370,13 @@ char *promisor_remote_info(struct repository *repo)
/*
* Find first index of 'nicks' where there is 'nick'. 'nick' is
- * compared case insensitively to the strings in 'nicks'. If not found
+ * compared case sensitively to the strings in 'nicks'. If not found
* 'nicks->nr' is returned.
*/
static size_t remote_nick_find(struct strvec *nicks, const char *nick)
{
for (size_t i = 0; i < nicks->nr; i++)
- if (!strcasecmp(nicks->v[i], nick))
+ if (!strcmp(nicks->v[i], nick))
return i;
return nicks->nr;
}
@@ -409,10 +409,15 @@ static int should_accept_remote(enum accept_promisor accept,
if (accept != ACCEPT_KNOWN_URL)
BUG("Unhandled 'enum accept_promisor' value '%d'", accept);
+ if (!remote_url || !*remote_url) {
+ warning(_("no or empty URL advertised for remote '%s'"), remote_name);
+ return 0;
+ }
+
if (!strcmp(urls->v[i], remote_url))
return 1;
- warning(_("known remote named '%s' but with url '%s' instead of '%s'"),
+ warning(_("known remote named '%s' but with URL '%s' instead of '%s'"),
remote_name, urls->v[i], remote_url);
return 0;
diff --git a/t/t5710-promisor-remote-capability.sh b/t/t5710-promisor-remote-capability.sh
index d2cc69a17e..b35b774235 100755
--- a/t/t5710-promisor-remote-capability.sh
+++ b/t/t5710-promisor-remote-capability.sh
@@ -93,6 +93,7 @@ test_expect_success "setup for testing promisor remote advertisement" '
test_expect_success "clone with promisor.advertise set to 'true'" '
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -100,7 +101,6 @@ test_expect_success "clone with promisor.advertise set to 'true'" '
-c remote.lop.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=All \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is still missing on the server
check_missing_objects server 1 "$oid"
@@ -108,6 +108,7 @@ test_expect_success "clone with promisor.advertise set to 'true'" '
test_expect_success "clone with promisor.advertise set to 'false'" '
git -C server config promisor.advertise false &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -115,7 +116,6 @@ test_expect_success "clone with promisor.advertise set to 'false'" '
-c remote.lop.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=All \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is not missing on the server
check_missing_objects server 0 "" &&
@@ -126,6 +126,7 @@ test_expect_success "clone with promisor.advertise set to 'false'" '
test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -133,7 +134,6 @@ test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
-c remote.lop.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=None \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is not missing on the server
check_missing_objects server 0 "" &&
@@ -144,8 +144,8 @@ test_expect_success "clone with promisor.acceptfromserver set to 'None'" '
test_expect_success "init + fetch with promisor.advertise set to 'true'" '
git -C server config promisor.advertise true &&
-
test_when_finished "rm -rf client" &&
+
mkdir client &&
git -C client init &&
git -C client config remote.lop.promisor true &&
@@ -162,6 +162,7 @@ test_expect_success "init + fetch with promisor.advertise set to 'true'" '
test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -169,7 +170,6 @@ test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
-c remote.lop.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=KnownName \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is still missing on the server
check_missing_objects server 1 "$oid"
@@ -177,6 +177,7 @@ test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" '
test_expect_success "clone with 'KnownName' and different remote names" '
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.serverTwo.promisor=true \
@@ -184,8 +185,26 @@ test_expect_success "clone with 'KnownName' and different remote names" '
-c remote.serverTwo.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=KnownName \
--no-local --filter="blob:limit=5k" server client &&
+
+ # Check that the largest object is not missing on the server
+ check_missing_objects server 0 "" &&
+
+ # Reinitialize server so that the largest object is missing again
+ initialize_server 1 "$oid"
+'
+
+test_expect_success "clone with 'KnownName' and missing URL in the config" '
+ git -C server config promisor.advertise true &&
test_when_finished "rm -rf client" &&
+ # Clone from server to create a client
+ # Lazy fetching by the client from the LOP will fail because of the
+ # missing URL in the client config, so the server will have to lazy
+ # fetch from the LOP.
+ GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
+ -c promisor.acceptfromserver=KnownName \
+ --no-local --filter="blob:limit=5k" server client &&
+
# Check that the largest object is not missing on the server
check_missing_objects server 0 "" &&
@@ -195,6 +214,7 @@ test_expect_success "clone with 'KnownName' and different remote names" '
test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" '
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -202,7 +222,6 @@ test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" '
-c remote.lop.url="file://$(pwd)/lop" \
-c promisor.acceptfromserver=KnownUrl \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is still missing on the server
check_missing_objects server 1 "$oid"
@@ -212,6 +231,7 @@ test_expect_success "clone with 'KnownUrl' and different remote urls" '
ln -s lop serverTwo &&
git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
# Clone from server to create a client
GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
@@ -219,7 +239,6 @@ test_expect_success "clone with 'KnownUrl' and different remote urls" '
-c remote.lop.url="file://$(pwd)/serverTwo" \
-c promisor.acceptfromserver=KnownUrl \
--no-local --filter="blob:limit=5k" server client &&
- test_when_finished "rm -rf client" &&
# Check that the largest object is not missing on the server
check_missing_objects server 0 "" &&
@@ -228,6 +247,48 @@ test_expect_success "clone with 'KnownUrl' and different remote urls" '
initialize_server 1 "$oid"
'
+test_expect_success "clone with 'KnownUrl' and url not configured on the server" '
+ git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
+
+ test_when_finished "git -C server config set remote.lop.url \"file://$(pwd)/lop\"" &&
+ git -C server config unset remote.lop.url &&
+
+ # Clone from server to create a client
+ # It should fail because the client will reject the LOP as URLs are
+ # different, and the server cannot lazy fetch as the LOP URL is
+ # missing, so the remote name will be used instead which will fail.
+ test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
+ -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
+ -c remote.lop.url="file://$(pwd)/lop" \
+ -c promisor.acceptfromserver=KnownUrl \
+ --no-local --filter="blob:limit=5k" server client &&
+
+ # Check that the largest object is still missing on the server
+ check_missing_objects server 1 "$oid"
+'
+
+test_expect_success "clone with 'KnownUrl' and empty url, so not advertised" '
+ git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client" &&
+
+ test_when_finished "git -C server config set remote.lop.url \"file://$(pwd)/lop\"" &&
+ git -C server config set remote.lop.url "" &&
+
+ # Clone from server to create a client
+ # It should fail because the client will reject the LOP as an empty URL is
+ # not advertised, and the server cannot lazy fetch as the LOP URL is empty,
+ # so the remote name will be used instead which will fail.
+ test_must_fail env GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \
+ -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \
+ -c remote.lop.url="file://$(pwd)/lop" \
+ -c promisor.acceptfromserver=KnownUrl \
+ --no-local --filter="blob:limit=5k" server client &&
+
+ # Check that the largest object is still missing on the server
+ check_missing_objects server 1 "$oid"
+'
+
test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
git -C server config promisor.advertise true &&