Skip to content

Commit

Permalink
clone: unbundle the advertised bundles
Browse files Browse the repository at this point in the history
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'.

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 <derrickstolee@github.com>
  • Loading branch information
derrickstolee committed Dec 5, 2022
1 parent 69bf154 commit 7e18191
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 7 deletions.
26 changes: 21 additions & 5 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -1266,11 +1266,27 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (refs)
mapped_refs = wanted_peer_refs(refs, &remote->fetch);

/*
* Populate transport->got_remote_bundle_uri and
* transport->bundle_uri. We might get nothing.
*/
transport_get_remote_bundle_uri(transport);
if (!bundle_uri) {
/*
* Populate transport->got_remote_bundle_uri and
* transport->bundle_uri. We might get nothing.
*/
transport_get_remote_bundle_uri(transport);

if (transport->bundles &&
hashmap_get_size(&transport->bundles->bundles)) {
/* At this point, we need the_repository to match the cloned repo. */
if (repo_init(the_repository, git_dir, work_tree))
warning(_("failed to initialize the repo, skipping bundle URI"));
else if (fetch_bundle_list(the_repository,
remote->url[0],
transport->bundles))
warning(_("failed to fetch advertised bundles"));
} else {
clear_bundle_list(transport->bundles);
FREE_AND_NULL(transport->bundles);
}
}

if (mapped_refs) {
int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
Expand Down
21 changes: 19 additions & 2 deletions t/lib-bundle-uri-protocol.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ test_expect_success "connect with $BUNDLE_URI_PROTOCOL:// using protocol v2: hav
'

test_expect_success "clone with $BUNDLE_URI_PROTOCOL:// using protocol v2: request bundle-uris" '
test_when_finished "rm -rf log cloned cloned2" &&
test_when_finished "rm -rf log* cloned*" &&
GIT_TRACE_PACKET="$PWD/log" \
GIT_TEST_BUNDLE_URI=0 \
Expand Down Expand Up @@ -117,7 +117,24 @@ test_expect_success "clone with $BUNDLE_URI_PROTOCOL:// using protocol v2: reque
grep "< bundle-uri" log &&
# Client issued bundle-uri command
grep "> command=bundle-uri" log
grep "> command=bundle-uri" log &&
GIT_TRACE_PACKET="$PWD/log3" \
git \
-c transfer.bundleURI=true \
-c protocol.version=2 \
clone --bundle-uri="$BUNDLE_URI_BUNDLE_URI" \
"$BUNDLE_URI_REPO_URI" cloned3 \
>actual 2>err &&
# Server responded using protocol v2
grep "< version 2" log3 &&
# Server advertised bundle-uri capability
grep "< bundle-uri" log3 &&
# Client did not issue bundle-uri command (--bundle-uri override)
! grep "> command=bundle-uri" log3
'

test_expect_success "test bundle-uri with $BUNDLE_URI_PROTOCOL:// using protocol v2" '
Expand Down
59 changes: 59 additions & 0 deletions t/t5601-clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,65 @@ test_expect_success 'reject cloning shallow repository using HTTP' '
git clone --no-reject-shallow $HTTPD_URL/smart/repo.git repo
'

test_expect_success 'auto-discover bundle URI from HTTP clone' '
test_when_finished rm -rf trace.txt repo2 "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" &&
git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/everything.bundle" --all &&
git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
uploadpack.advertiseBundleURIs true &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
bundle.version 1 &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
bundle.mode all &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \
bundle.everything.uri "$HTTPD_URL/everything.bundle" &&
GIT_TEST_BUNDLE_URI=1 \
GIT_TRACE2_EVENT="$(pwd)/trace.txt" \
git -c protocol.version=2 clone \
$HTTPD_URL/smart/repo2.git repo2 &&
cat >pattern <<-EOF &&
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\]
EOF
grep -f pattern trace.txt
'

test_expect_success 'auto-discover multiple bundles from HTTP clone' '
test_when_finished rm -rf trace.txt repo3 "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" &&
test_commit -C src new &&
git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/new.bundle" HEAD~1..HEAD &&
git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
uploadpack.advertiseBundleURIs true &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
bundle.version 1 &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
bundle.mode all &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
bundle.everything.uri "$HTTPD_URL/everything.bundle" &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \
bundle.new.uri "$HTTPD_URL/new.bundle" &&
GIT_TEST_BUNDLE_URI=1 \
GIT_TRACE2_EVENT="$(pwd)/trace.txt" \
git -c protocol.version=2 clone \
$HTTPD_URL/smart/repo3.git repo3 &&
# We should fetch _both_ bundles
cat >pattern <<-EOF &&
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\]
EOF
grep -f pattern trace.txt &&
cat >pattern <<-EOF &&
"event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/new.bundle"\]
EOF
grep -f pattern trace.txt
'

# DO NOT add non-httpd-specific tests here, because the last part of this
# test script is only executed when httpd is available and enabled.

Expand Down

0 comments on commit 7e18191

Please sign in to comment.