Skip to content

Commit d7125e6

Browse files
committed
Merge branch 'tc/fetch-bundle-uri' into seen
Allow "git fetch" take advantage of bundleURI feature. * tc/fetch-bundle-uri: fetch: use bundle URIs when having creationToken heuristic transport: introduce transport_has_remote_bundle_uri() clone: remove double bundle list clear code
2 parents 49d41e9 + 59f439b commit d7125e6

File tree

7 files changed

+114
-25
lines changed

7 files changed

+114
-25
lines changed

builtin/clone.c

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,25 +1409,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
14091409
bundle_uri);
14101410
else if (has_heuristic)
14111411
git_config_set_gently("fetch.bundleuri", bundle_uri);
1412-
} else {
1413-
/*
1414-
* Populate transport->got_remote_bundle_uri and
1415-
* transport->bundle_uri. We might get nothing.
1416-
*/
1417-
transport_get_remote_bundle_uri(transport);
1418-
1419-
if (transport->bundles &&
1420-
hashmap_get_size(&transport->bundles->bundles)) {
1421-
/* At this point, we need the_repository to match the cloned repo. */
1422-
if (repo_init(the_repository, git_dir, work_tree))
1423-
warning(_("failed to initialize the repo, skipping bundle URI"));
1424-
else if (fetch_bundle_list(the_repository,
1425-
transport->bundles))
1426-
warning(_("failed to fetch advertised bundles"));
1427-
} else {
1428-
clear_bundle_list(transport->bundles);
1429-
FREE_AND_NULL(transport->bundles);
1430-
}
1412+
} else if (transport_has_remote_bundle_uri(transport)) {
1413+
/* At this point, we need the_repository to match the cloned repo. */
1414+
if (repo_init(the_repository, git_dir, work_tree))
1415+
warning(_("failed to initialize the repo, skipping bundle URI"));
1416+
else if (fetch_bundle_list(the_repository,
1417+
transport->bundles))
1418+
warning(_("failed to fetch advertised bundles"));
14311419
}
14321420

14331421
if (refs)

builtin/fetch.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,19 @@ static int do_fetch(struct transport *transport,
16951695
retcode = 1;
16961696
}
16971697

1698+
if (transport_has_remote_bundle_uri(transport)) {
1699+
/*
1700+
* Only use bundle-URIs when they use the creationToken
1701+
* heuristic, this allows us to ensure not downloading bundles
1702+
* we don't need. You can read the comments in
1703+
* fetch_bundles_by_token() to understand how this works.
1704+
*/
1705+
if (transport->bundles->heuristic == BUNDLE_HEURISTIC_CREATIONTOKEN) {
1706+
if (fetch_bundle_list(the_repository, transport->bundles))
1707+
warning(_("failed to fetch advertised bundles"));
1708+
}
1709+
}
1710+
16981711
if (fetch_and_consume_refs(&display_state, transport, transaction, ref_map,
16991712
&fetch_head, config)) {
17001713
retcode = 1;

t/helper/test-bundle-uri.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static int cmd_ls_remote(int argc, const char **argv)
9090
}
9191

9292
transport = transport_get(remote, NULL);
93-
if (transport_get_remote_bundle_uri(transport) < 0) {
93+
if (!transport_has_remote_bundle_uri(transport)) {
9494
error(_("could not get the bundle-uri list"));
9595
status = 1;
9696
goto cleanup;

t/t5558-clone-bundle-uri.sh

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
test_description='test fetching bundles with --bundle-uri'
3+
test_description='test clone with use of bundle-uri'
44

55
. ./test-lib.sh
66
. "$TEST_DIRECTORY"/lib-bundle.sh
@@ -438,6 +438,32 @@ test_expect_success 'negotiation: bundle list with all wanted commits' '
438438
test_grep ! "clone> want " trace-packet.txt
439439
'
440440

441+
test_expect_success 'bundles advertised by the server' '
442+
test_when_finished rm -f trace*.txt &&
443+
git clone clone-from clone-advertiser &&
444+
git -C clone-advertiser config uploadpack.advertiseBundleURIs true &&
445+
git -C clone-advertiser config bundle.version 1 &&
446+
git -C clone-advertiser config bundle.mode all &&
447+
git -C clone-advertiser config bundle.bundle-1.uri "file://$(pwd)/clone-from/bundle-1.bundle" &&
448+
git -C clone-advertiser config bundle.bundle-2.uri "file://$(pwd)/clone-from/bundle-2.bundle" &&
449+
git -C clone-advertiser config bundle.bundle-3.uri "file://$(pwd)/clone-from/bundle-3.bundle" &&
450+
git -C clone-advertiser config bundle.bundle-4.uri "file://$(pwd)/clone-from/bundle-4.bundle" &&
451+
452+
GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
453+
git -c transfer.bundleURI=true clone clone-advertiser clone-advertised &&
454+
git -C clone-advertised for-each-ref --format="%(refname)" >refs &&
455+
grep "refs/bundles/" refs >actual &&
456+
cat >expect <<-\EOF &&
457+
refs/bundles/base
458+
refs/bundles/left
459+
refs/bundles/merge
460+
refs/bundles/right
461+
EOF
462+
test_cmp expect actual &&
463+
# We already have all needed commits so no "want" needed.
464+
test_grep ! "clone> want " trace-packet.txt
465+
'
466+
441467
#########################################################################
442468
# HTTP tests begin here
443469

t/t5584-fetch-bundle-uri.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/sh
2+
3+
test_description='test use of bundle URI in "git fetch"'
4+
5+
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6+
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7+
8+
. ./test-lib.sh
9+
10+
test_expect_success 'set up repos and bundles' '
11+
git init source &&
12+
test_commit -C source A &&
13+
git clone --no-local source go-A-to-C &&
14+
test_commit -C source B &&
15+
git clone --no-local source go-B-to-C &&
16+
git clone --no-local source go-B-to-D &&
17+
git -C source bundle create B.bundle main &&
18+
test_commit -C source C &&
19+
git -C source bundle create B-to-C.bundle B..main &&
20+
git -C source config uploadpack.advertiseBundleURIs true &&
21+
git -C source config bundle.version 1 &&
22+
git -C source config bundle.mode all &&
23+
git -C source config bundle.heuristic creationToken &&
24+
git -C source config bundle.bundle-B.uri "file://$(pwd)/source/B.bundle" &&
25+
git -C source config bundle.bundle-B.creationToken 1 &&
26+
git -C source config bundle.bundle-B-to-C.uri "file://$(pwd)/source/B-to-C.bundle" &&
27+
git -C source config bundle.bundle-B-to-C.creationToken 2
28+
'
29+
30+
test_expect_success 'fetches one bundle URI to get up-to-date' '
31+
git -C go-B-to-C -c transfer.bundleURI=true fetch origin &&
32+
test 1 = $(ls go-B-to-C/.git/objects/bundles | wc -l) &&
33+
test 2 = $(git -C go-B-to-C config fetch.bundleCreationToken)
34+
'
35+
36+
test_expect_success 'fetches two bundle URIs to get up-to-date' '
37+
git -C go-A-to-C -c transfer.bundleURI=true fetch origin &&
38+
test 2 = $(ls go-A-to-C/.git/objects/bundles | wc -l) &&
39+
test 2 = $(git -C go-A-to-C config fetch.bundleCreationToken)
40+
'
41+
42+
test_expect_success 'fetches one bundle URI and objects from remote' '
43+
test_commit -C source D &&
44+
git -C go-B-to-D -c transfer.bundleURI=true fetch origin &&
45+
test 1 = $(ls go-B-to-D/.git/objects/bundles | wc -l) &&
46+
test 2 = $(git -C go-B-to-D config fetch.bundleCreationToken)
47+
'
48+
49+
test_done

transport.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
15381538
return rc;
15391539
}
15401540

1541-
int transport_get_remote_bundle_uri(struct transport *transport)
1541+
static int transport_get_remote_bundle_uri(struct transport *transport)
15421542
{
15431543
int value = 0;
15441544
const struct transport_vtable *vtable = transport->vtable;
@@ -1563,6 +1563,18 @@ int transport_get_remote_bundle_uri(struct transport *transport)
15631563

15641564
if (vtable->get_bundle_uri(transport) < 0)
15651565
return error(_("could not retrieve server-advertised bundle-uri list"));
1566+
1567+
return 0;
1568+
}
1569+
1570+
int transport_has_remote_bundle_uri(struct transport *transport)
1571+
{
1572+
transport_get_remote_bundle_uri(transport);
1573+
1574+
if (transport->bundles &&
1575+
hashmap_get_size(&transport->bundles->bundles))
1576+
return 1;
1577+
15661578
return 0;
15671579
}
15681580

transport.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,11 @@ const struct ref *transport_get_remote_refs(struct transport *transport,
294294
struct transport_ls_refs_options *transport_options);
295295

296296
/**
297-
* Retrieve bundle URI(s) from a remote. Populates "struct
298-
* transport"'s "bundle_uri" and "got_remote_bundle_uri".
297+
* Try fetch bundle URI(s) from a remote and returns 1 if one or more
298+
* bundle URI(s) are received from the server.
299+
* Populates "struct transport"'s "bundles" and "got_remote_bundle_uri".
299300
*/
300-
int transport_get_remote_bundle_uri(struct transport *transport);
301+
int transport_has_remote_bundle_uri(struct transport *transport);
301302

302303
/*
303304
* Fetch the hash algorithm used by a remote.

0 commit comments

Comments
 (0)