oid <oid>
Indicates to the server an object which the client wants to obtain
- information for.
+ information for. They must be full OIDs.
-The response of `object-info` is a list of the requested object ids
-and associated requested information, each separated by a single space.
+The response of `object-info` consists of one pkt-line per requested attribute,
+echoing the attributes the server will report, followed by one pkt-line per
+requested object id with its information, each field separated by a single
+space.
output = info flush-pkt
- info = PKT-LINE(attrs) LF)
- *PKT-LINE(obj-info LF)
-
- attrs = attr | attrs SP attrs
+ info = *PKT-LINE(attr LF)
+ *PKT-LINE(obj-info LF)
attr = "size"
- obj-info = obj-id SP obj-size
+ obj-size = 1*DIGIT
+
+ obj-info = obj-id [SP [obj-size]]
+
+If the server does not recognize the OID, the response will be `<oid> SP`
+regardless of the number of attributes requested.
bundle-uri
~~~~~~~~~~
return 1;
}
+/*
+ * odb_read_object_info_extended() wrapper. Similar to odb_read_object_info()
+ * but uses the flags:
+ *
+ * - OBJECT_INFO_SKIP_FETCH_OBJECT so a server won't fetch an object when a
+ * object-info request asks for an OID that it doesn't have.
+ *
+ * - OBJECT_INFO_QUICK to avoid re-scanning packs when the object is not found.
+ */
+static enum object_type get_object_info(struct object_database *odb,
+ const struct object_id *oid,
+ size_t *sizep)
+{
+ enum object_type type;
+ struct object_info oi = OBJECT_INFO_INIT;
+
+ oi.typep = &type;
+ oi.sizep = sizep;
+ if (odb_read_object_info_extended(odb, oid, &oi,
+ OBJECT_INFO_LOOKUP_REPLACE |
+ OBJECT_INFO_SKIP_FETCH_OBJECT |
+ OBJECT_INFO_QUICK) < 0)
+ return OBJ_BAD;
+ return type;
+}
+
/*
* Validates and send requested info back to the client. Any errors detected
* are returned as they are detected.
strbuf_addstr(&send_buffer, oid_str);
+ /*
+ * Check the existence of the object first.
+ * If an object is not recognized by the server append SP to
+ * the response.
+ */
+ if (get_object_info(r->objects, &oid, &object_size) <= OBJ_NONE) {
+ strbuf_addstr(&send_buffer, " ");
+ goto write;
+ }
+
if (info->size) {
- if (odb_read_object_info(r->objects, &oid, &object_size) < 0) {
- strbuf_addstr(&send_buffer, " ");
- } else {
- strbuf_addf(&send_buffer, " %"PRIuMAX,
- (uintmax_t)object_size);
- }
+ strbuf_addf(&send_buffer, " %"PRIuMAX,
+ (uintmax_t)object_size);
}
+write:
packet_writer_write(writer, "%s", send_buffer.buf);
strbuf_reset(&send_buffer);
}
. ./test-lib.sh
+unknown_oid=$(printf "test" | git hash-object --stdin)
+
test_expect_success 'setup to generate files with expected content' '
printf "agent=git/%s" "$(git version | cut -d" " -f3)" >agent_capability &&
test_cmp expect actual
'
+test_expect_success 'bare OID request' '
+ test_config transfer.advertiseObjectInfo true &&
+
+ test-tool pkt-line pack >in <<-EOF &&
+ command=object-info
+ object-format=$(test_oid algo)
+ 0001
+ oid $(git rev-parse two:two.t)
+ 0000
+ EOF
+
+ cat >expect <<-EOF &&
+ $(git rev-parse two:two.t)
+ 0000
+ EOF
+
+ test-tool serve-v2 --stateless-rpc <in >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'object-info with bare unrecognized OID' '
+ test_config transfer.advertiseObjectInfo true &&
+
+ test-tool pkt-line pack >in <<-EOF &&
+ command=object-info
+ object-format=$(test_oid algo)
+ 0001
+ oid $unknown_oid
+ 0000
+ EOF
+
+ printf "%s \n" "$unknown_oid" >expect &&
+ printf "0000\n" >>expect &&
+
+ test-tool serve-v2 --stateless-rpc <in >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'object-info with size for unrecognized OID' '
+ test_config transfer.advertiseObjectInfo true &&
+
+ test-tool pkt-line pack >in <<-EOF &&
+ command=object-info
+ object-format=$(test_oid algo)
+ 0001
+ size
+ oid $unknown_oid
+ 0000
+ EOF
+
+ printf "size\n" >expect &&
+ printf "%s \n" "$unknown_oid" >>expect &&
+ printf "0000\n" >>expect &&
+
+ test-tool serve-v2 --stateless-rpc <in >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'test capability advertisement with uploadpack.advertiseBundleURIs' '
test_config uploadpack.advertiseBundleURIs true &&