Skip to content

Commit 4074d3c

Browse files
derrickstoleegitster
authored andcommitted
clone: set fetch.bundleURI if appropriate
Bundle providers may organize their bundle lists in a way that is intended to improve incremental fetches, not just initial clones. However, they do need to state that they have organized with that in mind, or else the client will not expect to save time by downloading bundles after the initial clone. This is done by specifying a bundle.heuristic value. There are two types of bundle lists: those at a static URI and those that are advertised from a Git remote over protocol v2. The new fetch.bundleURI config value applies for static bundle URIs that are not advertised over protocol v2. If the user specifies a static URI via 'git clone --bundle-uri', then Git can set this config as a reminder for future 'git fetch' operations to check the bundle list before connecting to the remote(s). For lists provided over protocol v2, we will want to take a different approach and create a property of the remote itself by creating a remote.<id>.* type config key. That is not implemented in this change. Later changes will update 'git fetch' to consume this option. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7903efb commit 4074d3c

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

Documentation/config/fetch.txt

+8
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,11 @@ fetch.writeCommitGraph::
9696
merge and the write may take longer. Having an updated commit-graph
9797
file helps performance of many Git commands, including `git merge-base`,
9898
`git push -f`, and `git log --graph`. Defaults to false.
99+
100+
fetch.bundleURI::
101+
This value stores a URI for downloading Git object data from a bundle
102+
URI before performing an incremental fetch from the origin Git server.
103+
This is similar to how the `--bundle-uri` option behaves in
104+
linkgit:git-clone[1]. `git clone --bundle-uri` will set the
105+
`fetch.bundleURI` value if the supplied bundle URI contains a bundle
106+
list that is organized for incremental fetches.

builtin/clone.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1248,12 +1248,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12481248
* data from the --bundle-uri option.
12491249
*/
12501250
if (bundle_uri) {
1251+
int has_heuristic = 0;
1252+
12511253
/* At this point, we need the_repository to match the cloned repo. */
12521254
if (repo_init(the_repository, git_dir, work_tree))
12531255
warning(_("failed to initialize the repo, skipping bundle URI"));
1254-
else if (fetch_bundle_uri(the_repository, bundle_uri))
1256+
else if (fetch_bundle_uri(the_repository, bundle_uri, &has_heuristic))
12551257
warning(_("failed to fetch objects from bundle URI '%s'"),
12561258
bundle_uri);
1259+
else if (has_heuristic)
1260+
git_config_set_gently("fetch.bundleuri", bundle_uri);
12571261
}
12581262

12591263
strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");

bundle-uri.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,8 @@ static int unlink_bundle(struct remote_bundle_info *info, void *data)
736736
return 0;
737737
}
738738

739-
int fetch_bundle_uri(struct repository *r, const char *uri)
739+
int fetch_bundle_uri(struct repository *r, const char *uri,
740+
int *has_heuristic)
740741
{
741742
int result;
742743
struct bundle_list list;
@@ -756,6 +757,8 @@ int fetch_bundle_uri(struct repository *r, const char *uri)
756757
result = unbundle_all_bundles(r, &list);
757758

758759
cleanup:
760+
if (has_heuristic)
761+
*has_heuristic = (list.heuristic != BUNDLE_HEURISTIC_NONE);
759762
for_all_bundles_in_list(&list, unlink_bundle, NULL);
760763
clear_bundle_list(&list);
761764
clear_remote_bundle_info(&bundle, NULL);

bundle-uri.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,14 @@ int bundle_uri_parse_config_format(const char *uri,
124124
* based on that information.
125125
*
126126
* Returns non-zero if no bundle information is found at the given 'uri'.
127+
*
128+
* If the pointer 'has_heuristic' is non-NULL, then the value it points to
129+
* will be set to be non-zero if and only if the fetched list has a
130+
* heuristic value. Such a value indicates that the list was designed for
131+
* incremental fetches.
127132
*/
128-
int fetch_bundle_uri(struct repository *r, const char *uri);
133+
int fetch_bundle_uri(struct repository *r, const char *uri,
134+
int *has_heuristic);
129135

130136
/**
131137
* Given a bundle list that was already advertised (likely by the

t/t5558-clone-bundle-uri.sh

+39
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ test_expect_success 'clone incomplete bundle list (http, creationToken)' '
432432
--single-branch --branch=base --no-tags \
433433
"$HTTPD_URL/smart/fetch.git" clone-token-http &&
434434
435+
test_cmp_config -C clone-token-http "$HTTPD_URL/bundle-list" fetch.bundleuri &&
436+
435437
cat >expect <<-EOF &&
436438
$HTTPD_URL/bundle-list
437439
$HTTPD_URL/bundle-1.bundle
@@ -441,6 +443,43 @@ test_expect_success 'clone incomplete bundle list (http, creationToken)' '
441443
test_cmp expect actual
442444
'
443445

446+
test_expect_success 'http clone with bundle.heuristic creates fetch.bundleURI' '
447+
test_when_finished rm -rf fetch-http-4 trace*.txt &&
448+
449+
cat >"$HTTPD_DOCUMENT_ROOT_PATH/bundle-list" <<-EOF &&
450+
[bundle]
451+
version = 1
452+
mode = all
453+
heuristic = creationToken
454+
455+
[bundle "bundle-1"]
456+
uri = bundle-1.bundle
457+
creationToken = 1
458+
EOF
459+
460+
GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \
461+
git clone --single-branch --branch=base \
462+
--bundle-uri="$HTTPD_URL/bundle-list" \
463+
"$HTTPD_URL/smart/fetch.git" fetch-http-4 &&
464+
465+
test_cmp_config -C fetch-http-4 "$HTTPD_URL/bundle-list" fetch.bundleuri &&
466+
467+
cat >expect <<-EOF &&
468+
$HTTPD_URL/bundle-list
469+
$HTTPD_URL/bundle-1.bundle
470+
EOF
471+
472+
test_remote_https_urls <trace-clone.txt >actual &&
473+
test_cmp expect actual &&
474+
475+
# only received base ref from bundle-1
476+
git -C fetch-http-4 for-each-ref --format="%(refname)" "refs/bundles/*" >refs &&
477+
cat >expect <<-\EOF &&
478+
refs/bundles/base
479+
EOF
480+
test_cmp expect refs
481+
'
482+
444483
# Do not add tests here unless they use the HTTP server, as they will
445484
# not run unless the HTTP dependencies exist.
446485

0 commit comments

Comments
 (0)