Skip to content

Commit 876094a

Browse files
derrickstoleegitster
authored andcommitted
clone: unbundle the advertised bundles
A previous change introduced the transport methods to acquire a bundle list from the 'bundle-uri' protocol v2 command, when advertised _and_ when the client has chosen to enable the feature. Teach Git to download and unbundle the data advertised by those bundles during 'git clone'. This takes place between the ref advertisement and the object data download, and stateful connections will linger while the client downloads bundles. In the future, we should consider closing the remote connection during this process. Also, since the --bundle-uri option exists, we do not want to mix the advertised bundles with the user-specified bundles. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 12b0a14 commit 876094a

File tree

3 files changed

+98
-7
lines changed

3 files changed

+98
-7
lines changed

builtin/clone.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,11 +1271,26 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12711271
if (refs)
12721272
mapped_refs = wanted_peer_refs(refs, &remote->fetch);
12731273

1274-
/*
1275-
* Populate transport->got_remote_bundle_uri and
1276-
* transport->bundle_uri. We might get nothing.
1277-
*/
1278-
transport_get_remote_bundle_uri(transport);
1274+
if (!bundle_uri) {
1275+
/*
1276+
* Populate transport->got_remote_bundle_uri and
1277+
* transport->bundle_uri. We might get nothing.
1278+
*/
1279+
transport_get_remote_bundle_uri(transport);
1280+
1281+
if (transport->bundles &&
1282+
hashmap_get_size(&transport->bundles->bundles)) {
1283+
/* At this point, we need the_repository to match the cloned repo. */
1284+
if (repo_init(the_repository, git_dir, work_tree))
1285+
warning(_("failed to initialize the repo, skipping bundle URI"));
1286+
else if (fetch_bundle_list(the_repository,
1287+
transport->bundles))
1288+
warning(_("failed to fetch advertised bundles"));
1289+
} else {
1290+
clear_bundle_list(transport->bundles);
1291+
FREE_AND_NULL(transport->bundles);
1292+
}
1293+
}
12791294

12801295
if (mapped_refs) {
12811296
int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));

t/lib-bundle-uri-protocol.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ test_expect_success "connect with $BUNDLE_URI_PROTOCOL:// using protocol v2: hav
8585
'
8686

8787
test_expect_success "clone with $BUNDLE_URI_PROTOCOL:// using protocol v2: request bundle-uris" '
88-
test_when_finished "rm -rf log cloned cloned2" &&
88+
test_when_finished "rm -rf log* cloned*" &&
8989
9090
GIT_TRACE_PACKET="$PWD/log" \
9191
git \
@@ -117,7 +117,24 @@ test_expect_success "clone with $BUNDLE_URI_PROTOCOL:// using protocol v2: reque
117117
grep "< bundle-uri" log &&
118118
119119
# Client issued bundle-uri command
120-
grep "> command=bundle-uri" log
120+
grep "> command=bundle-uri" log &&
121+
122+
GIT_TRACE_PACKET="$PWD/log3" \
123+
git \
124+
-c transfer.bundleURI=true \
125+
-c protocol.version=2 \
126+
clone --bundle-uri="$BUNDLE_URI_BUNDLE_URI" \
127+
"$BUNDLE_URI_REPO_URI" cloned3 \
128+
>actual 2>err &&
129+
130+
# Server responded using protocol v2
131+
grep "< version 2" log3 &&
132+
133+
# Server advertised bundle-uri capability
134+
grep "< bundle-uri" log3 &&
135+
136+
# Client did not issue bundle-uri command (--bundle-uri override)
137+
! grep "> command=bundle-uri" log3
121138
'
122139

123140
# The remaining tests will all assume transfer.bundleURI=true

t/t5601-clone.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,65 @@ test_expect_success 'reject cloning shallow repository using HTTP' '
772772
git clone --no-reject-shallow $HTTPD_URL/smart/repo.git repo
773773
'
774774

775+
test_expect_success 'auto-discover bundle URI from HTTP clone' '
776+
test_when_finished rm -rf trace.txt repo2 "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" &&
777+
git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/everything.bundle" --all &&
778+
git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" &&
779+
780+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
781+
uploadpack.advertiseBundleURIs true &&
782+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
783+
bundle.version 1 &&
784+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
785+
bundle.mode all &&
786+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
787+
bundle.everything.uri "$HTTPD_URL/everything.bundle" &&
788+
789+
GIT_TRACE2_EVENT="$(pwd)/trace.txt" \
790+
git -c protocol.version=2 \
791+
-c transfer.bundleURI=true clone \
792+
$HTTPD_URL/smart/repo2.git repo2 &&
793+
cat >pattern <<-EOF &&
794+
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\]
795+
EOF
796+
grep -f pattern trace.txt
797+
'
798+
799+
test_expect_success 'auto-discover multiple bundles from HTTP clone' '
800+
test_when_finished rm -rf trace.txt repo3 "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" &&
801+
802+
test_commit -C src new &&
803+
git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/new.bundle" HEAD~1..HEAD &&
804+
git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" &&
805+
806+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
807+
uploadpack.advertiseBundleURIs true &&
808+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
809+
bundle.version 1 &&
810+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
811+
bundle.mode all &&
812+
813+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
814+
bundle.everything.uri "$HTTPD_URL/everything.bundle" &&
815+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
816+
bundle.new.uri "$HTTPD_URL/new.bundle" &&
817+
818+
GIT_TRACE2_EVENT="$(pwd)/trace.txt" \
819+
git -c protocol.version=2 \
820+
-c transfer.bundleURI=true clone \
821+
$HTTPD_URL/smart/repo3.git repo3 &&
822+
823+
# We should fetch _both_ bundles
824+
cat >pattern <<-EOF &&
825+
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\]
826+
EOF
827+
grep -f pattern trace.txt &&
828+
cat >pattern <<-EOF &&
829+
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/new.bundle"\]
830+
EOF
831+
grep -f pattern trace.txt
832+
'
833+
775834
# DO NOT add non-httpd-specific tests here, because the last part of this
776835
# test script is only executed when httpd is available and enabled.
777836

0 commit comments

Comments
 (0)