upload-pack: teach deepen-relative in protocol v2

Commit 685fbd3291 ("fetch-pack: perform a fetch using v2", 2018-03-15) attempted to teach Git deepen-relative in protocol v2 (among other things), but it didn't work: (1) fetch-pack.c needs to emit "deepen-relative". (2) upload-pack.c needs to ensure that the correct deepen_relative variable is passed to deepen() (there are two - the static variable and the one in struct upload_pack_data). (3) Before deepen() computes the list of reachable shallows, it first needs to mark all "our" refs as OUR_REF. v2 currently does not do this, because unlike v0, it is not needed otherwise. Fix all this and include a test demonstrating that it works now. For (2), the static variable deepen_relative is also eliminated, removing a source of confusion. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Dec 18, 2018 at 13:24 UTC 5056cf4a62338c013a723e37cbe1f525f1dcc29d
3 files changed +46 -2
fetch-pack.c
+2
@@ -1007,6 +1007,8 @@ static void add_shallow_requests(struct strbuf *req_buf,
1007 packet_buf_write(req_buf, "deepen-not %s", s->string);
1008 }
1009 }
1010 + if (args->deepen_relative)
1011 + packet_buf_write(req_buf, "deepen-relative\n");
1012 }
1013
1014 static void add_wants(int no_dependents, const struct ref *wants, struct strbuf *req_buf)
t/t5702-protocol-v2.sh
+29
@@ -489,6 +489,35 @@ test_expect_success 'ensure that multiple fetches in same process from a shallow
489 grep "fetch< version 2" trace
490 '
491
492 +test_expect_success 'deepen-relative' '
493 + rm -rf server client trace &&
494 +
495 + test_create_repo server &&
496 + test_commit -C server one &&
497 + test_commit -C server two &&
498 + test_commit -C server three &&
499 + git clone --depth 1 "file://$(pwd)/server" client &&
500 + test_commit -C server four &&
501 +
502 + # Sanity check that only "three" is downloaded
503 + git -C client log --pretty=tformat:%s master >actual &&
504 + echo three >expected &&
505 + test_cmp expected actual &&
506 +
507 + GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
508 + fetch --deepen=1 origin &&
509 + # Ensure that protocol v2 is used
510 + grep "fetch< version 2" trace &&
511 +
512 + git -C client log --pretty=tformat:%s origin/master >actual &&
513 + cat >expected <<-\EOF &&
514 + four
515 + three
516 + two
517 + EOF
518 + test_cmp expected actual
519 +'
520 +
521 # Test protocol v2 with 'http://' transport
522 #
523 . "$TEST_DIRECTORY"/lib-httpd.sh
upload-pack.c
+15 -2
@@ -43,7 +43,6 @@
43
44 static timestamp_t oldest_have;
45
46 -static int deepen_relative;
46 static int multi_ack;
47 static int no_done;
48 static int use_thin_pack, use_ofs_delta, use_include_tag;
@@ -662,6 +661,9 @@ static void send_unshallow(const struct object_array *shallows,
661 }
662 }
663
664 +static int check_ref(const char *refname_full, const struct object_id *oid,
665 + int flag, void *cb_data);
666 +
667 static void deepen(int depth, int deepen_relative,
668 struct object_array *shallows, struct object_array *want_obj)
669 {
@@ -676,6 +678,13 @@ static void deepen(int depth, int deepen_relative,
678 struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
679 struct commit_list *result;
680
681 + /*
682 + * Checking for reachable shallows requires that our refs be
683 + * marked with OUR_REF.
684 + */
685 + head_ref_namespaced(check_ref, NULL);
686 + for_each_namespaced_ref(check_ref, NULL);
687 +
688 get_reachable_list(shallows, &reachable_shallows);
689 result = get_shallow_commits(&reachable_shallows,
690 depth + 1,
@@ -712,6 +721,7 @@ static void deepen_by_rev_list(int ac, const char **av,
721 static int send_shallow_list(int depth, int deepen_rev_list,
722 timestamp_t deepen_since,
723 struct string_list *deepen_not,
724 + int deepen_relative,
725 struct object_array *shallows,
726 struct object_array *want_obj)
727 {
@@ -834,6 +844,7 @@ static void receive_needs(struct object_array *want_obj)
844 int has_non_tip = 0;
845 timestamp_t deepen_since = 0;
846 int deepen_rev_list = 0;
847 + int deepen_relative = 0;
848
849 shallow_nr = 0;
850 for (;;) {
@@ -925,7 +936,8 @@ static void receive_needs(struct object_array *want_obj)
936 return;
937
938 if (send_shallow_list(depth, deepen_rev_list, deepen_since,
928 - &deepen_not, &shallows, want_obj))
939 + &deepen_not, deepen_relative, &shallows,
940 + want_obj))
941 packet_flush(1);
942 object_array_clear(&shallows);
943 }
@@ -1398,6 +1410,7 @@ static void send_shallow_info(struct upload_pack_data *data,
1410
1411 if (!send_shallow_list(data->depth, data->deepen_rev_list,
1412 data->deepen_since, &data->deepen_not,
1413 + data->deepen_relative,
1414 &data->shallows, want_obj) &&
1415 is_repository_shallow(the_repository))
1416 deepen(INFINITE_DEPTH, data->deepen_relative, &data->shallows,