When using the ref-prefix feature of protocol v2, a client which sends
no prefixes at all will get the full advertisement. And so the code in
git-fetch was historically loose about setting up that list based on our
refspecs. There were cases where we needed to know about some refs, so
we just didn't add anything to the ref-prefix list.
And hence further code, like that for tag-following and updating
origin/HEAD, had to be careful about adding to an empty list. E.g., see
the bug fixed by
bd52d9a058 (fetch: fix following tags when fetching
specific OID, 2025-03-07).
But the previous commit removed the last such case, and now we know an
empty ref-prefix list (at least inside git-fetch's do_fetch() function)
means that we really don't need to see any refs. So we can drop those
extra conditionals.
This simplifies the code a little. But it also means that some cases can
now use ref prefixes when they would not otherwise. As the test shows,
fetching an exact oid into a local ref can now avoid enumerating all of
the refs. The refspec itself doesn't need to know about any remote refs,
and the tag auto-following can just ask about refs/tags/.
The same is true for asking about HEAD to update the local origin/HEAD.
I didn't add a test for that yet, though, as we can optimize it even
further.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
must_list_refs = 1;
- if (transport_ls_refs_options.ref_prefixes.nr)
- strvec_push(&transport_ls_refs_options.ref_prefixes,
- "refs/tags/");
+ strvec_push(&transport_ls_refs_options.ref_prefixes,
+ "refs/tags/");
}
if (uses_remote_tracking(transport, rs)) {
must_list_refs = 1;
- if (transport_ls_refs_options.ref_prefixes.nr)
- strvec_push(&transport_ls_refs_options.ref_prefixes,
- "HEAD");
+ strvec_push(&transport_ls_refs_options.ref_prefixes,
+ "HEAD");
}
if (must_list_refs) {
test_expect_success 'set up parent for prefix tests' '
git init prefix-parent &&
git -C prefix-parent commit --allow-empty -m foo &&
+ git -C prefix-parent tag my-tag &&
git -C prefix-parent branch unrelated-branch
'
test_grep ! unrelated-branch log
'
+test_expect_success 'exact oid fetch with tag following' '
+ git init exact-oid-tags &&
+
+ commit=$(git -C prefix-parent rev-parse --verify HEAD) &&
+
+ test_when_finished "rm -f log" &&
+ GIT_TRACE_PACKET="$(pwd)/log" \
+ git -C exact-oid-tags fetch ../prefix-parent \
+ $commit:refs/heads/exact &&
+ test_grep ! unrelated-branch log &&
+ git -C exact-oid-tags rev-parse --verify my-tag
+'
+
test_expect_success 'fetch supports various ways of have lines' '
rm -rf server client trace &&
git init server &&