Re: [PATCH v3 2/8] upload-pack: implement ref-in-want
From: Jonathan Tan <hidden>
Date: 2018-06-25 17:41:04
+ wanted-refs section + * This section is only included if the client has requested a + ref using a 'want-ref' line and if a packfile section is also + included in the response. + + * Always begins with the section header "wanted-refs"
Add a period at the end to be consistent with the others.
+ * The server will send a ref listing ("<oid> <refname>") for
+ each reference requested using 'want-ref' lines.
+
+ * The server MUST NOT send any refs which were not requested
+ using 'want-ref' lines.We might want tag following refs to be included here in the future, but at that time, I think we can amend this to say that if include-tag-ref is sent by the user, the server may send additional refs, otherwise the server must not do so. So this is fine.
+test_expect_success 'mix want and want-ref' ' + cat >expected_refs <<-EOF && + $(git rev-parse f) refs/heads/master + EOF + git rev-parse e f | sort >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/master + want $(git rev-parse e) + have $(git rev-parse a) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +'
Overall the tests look good, although I might be a bit biased since they are based on what I wrote a while ago [1]. I was wondering about the behavior when the client mixes "want" and "want-ref" (as will happen if they fetch both a ref by name and an exact SHA-1), and this test indeed shows the expected behavior. [1] https://public-inbox.org/git/d0d42b3bb4cf755f122591e191354c53848f197d.1485381677.git.jonathantanmy@google.com/
+test_expect_success 'want-ref with ref we already have commit for' ' + cat >expected_refs <<-EOF && + $(git rev-parse c) refs/heads/o/foo + EOF + >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/o/foo + have $(git rev-parse c) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +'
Likewise for this test - the ref is still reported, but the packfile does not contain the requested object.
struct upload_pack_data {
struct object_array wants;
+ struct string_list wanted_refs;Document here that this is a map from ref names to owned struct object_id instances.
+static int parse_want_ref(const char *line, struct string_list *wanted_refs)
+{
+ const char *arg;
+ if (skip_prefix(line, "want-ref ", &arg)) {
+ struct object_id oid;
+ struct string_list_item *item;
+ struct object *o;
+
+ if (read_ref(arg, &oid))
+ die("unknown ref %s", arg);
+
+ item = string_list_append(wanted_refs, arg);
+ item->util = oiddup(&oid);
+
+ o = parse_object_or_die(&oid, arg);
+ if (!(o->flags & WANTED)) {
+ o->flags |= WANTED;
+ add_object_array(o, NULL, &want_obj);
+ }Makes sense - besides adding it to wanted_refs, this adds the object to want_obj, just like how the other code paths for "want" adds it.
+static void send_wanted_ref_info(struct upload_pack_data *data)
+{
+ const struct string_list_item *item;
+
+ if (!data->wanted_refs.nr)
+ return;
+
+ packet_write_fmt(1, "wanted-refs\n");
+
+ for_each_string_list_item(item, &data->wanted_refs) {
+ packet_write_fmt(1, "%s %s\n",
+ oid_to_hex(item->util),
+ item->string);
+ }
+
+ packet_delim(1);
+}The documentation states that the "wanted-refs" section is only sent if there is at least one "want-ref" from the client, and each "want-ref" causes one entry to be added to data->wanted_refs, so this is correct. Thanks - besides adding the period in the documentation, this patch looks good to me.