fetch: send "refs/tags/" prefix upon CLI refspecs

When performing tag following, in addition to using the server's "include-tag" capability to send tag objects (and emulating it if the server does not support that capability), "git fetch" relies upon the presence of refs/tags/* entries in the initial ref advertisement to locally create refs pointing to the aforementioned tag objects. When using protocol v2, refs/tags/* entries in the initial ref advertisement may be suppressed by a ref-prefix argument, leading to the tag object being downloaded, but the ref not being created. Commit dcc73cf7ff ("fetch: generate ref-prefixes when using a configured refspec", 2018-05-18) ensured that "refs/tags/" is always sent as a ref prefix when "git fetch" is invoked with no refspecs, but not when "git fetch" is invoked with refspecs. Extend that functionality to make it work in both situations. This also necessitates a change another test which tested ref advertisement filtering using tag refs - since tag refs are sent by default now, the test has been switched to using branch refs instead. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Jun 5, 2018 at 14:40 UTC 2b554353a5f0463dec44b827e2d1423b698d06d3
2 files changed +22 -4
builtin/fetch.c
+1 -1
@@ -359,7 +359,7 @@ static struct ref *get_ref_map(struct transport *transport,
359 refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
360
361 if (ref_prefixes.argc &&
362 - (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) {
362 + (tags == TAGS_SET || tags == TAGS_DEFAULT)) {
363 argv_array_push(&ref_prefixes, "refs/tags/");
364 }
365
t/t5702-protocol-v2.sh
+21 -3
@@ -204,6 +204,7 @@ test_expect_success 'ref advertisment is filtered during fetch using protocol v2
204 test_when_finished "rm -f log" &&
205
206 test_commit -C file_parent three &&
207 + git -C file_parent branch unwanted-branch three &&
208
209 GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
210 fetch origin master &&
@@ -212,9 +213,8 @@ test_expect_success 'ref advertisment is filtered during fetch using protocol v2
213 git -C file_parent log -1 --format=%s >expect &&
214 test_cmp expect actual &&
215
215 - ! grep "refs/tags/one" log &&
216 - ! grep "refs/tags/two" log &&
217 - ! grep "refs/tags/three" log
216 + grep "refs/heads/master" log &&
217 + ! grep "refs/heads/unwanted-branch" log
218 '
219
220 test_expect_success 'server-options are sent when fetching' '
@@ -406,6 +406,24 @@ test_expect_success 'fetch supports various ways of have lines' '
406 $(git -C server rev-parse completely-unrelated)
407 '
408
409 +test_expect_success 'fetch supports include-tag and tag following' '
410 + rm -rf server client trace &&
411 + git init server &&
412 +
413 + test_commit -C server to_fetch &&
414 + git -C server tag -a annotated_tag -m message &&
415 +
416 + git init client &&
417 + GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
418 + fetch "$(pwd)/server" to_fetch:to_fetch &&
419 +
420 + grep "fetch> ref-prefix to_fetch" trace &&
421 + grep "fetch> ref-prefix refs/tags/" trace &&
422 + grep "fetch> include-tag" trace &&
423 +
424 + git -C client cat-file -e $(git -C client rev-parse annotated_tag)
425 +'
426 +
427 # Test protocol v2 with 'http://' transport
428 #
429 . "$TEST_DIRECTORY"/lib-httpd.sh