* [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype)
@ 2026-07-25 11:55 Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 1/5] protocol-caps: add type support to object-info Pablo Sabater
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
"%(objecttype)" is already known by the client's allow-list, but neither
the client nor the server knows how to handle type. This series continues
the work for git cat-file --batch-command extending remote-object-info
to support "%(objecttype)" end to end. It is based on its predecessor
series "cat-file: add remote-object-info to batch-command" [1].
Type is the last property that is identical on the server and on the
client once fetched.
Whether to support more metadata such as:
- objectsize:disk
- deltabase
- objectmode (needs context)
should be discussed, unlike size and type, the rest depend on how things
are packed on the server and on what the client already has, so they
cannot reliably match local once fetched. IMO they are not worth
supporting, I can't find a use case for them.
Adding new placeholders has become trivial.
To add a new placeholder, follow the steps in this series and add it to
the client's allow-list at 'builtin/cat-file.c'.
Based-on: <20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com>
Github CI: https://github.com/pabloosabaterr/git/actions/runs/30155586279
[1]: https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
Pablo Sabater (5):
protocol-caps: add type support to object-info
fetch-object-info: parse type from server response
fetch-object-info: request all supported options dynamically
serve: advertise type capability
cat-file: unify default format
Documentation/git-cat-file.adoc | 17 +++-----
Documentation/gitprotocol-v2.adoc | 15 +++++--
builtin/cat-file.c | 7 ---
fetch-object-info.c | 23 +++++++---
protocol-caps.c | 21 +++++++--
serve.c | 4 +-
t/t1017-cat-file-remote-object-info.sh | 80 +++++++++++++---------------------
t/t5701-git-serve.sh | 27 ++++++++++++
8 files changed, 113 insertions(+), 81 deletions(-)
---
base-commit: 71e19e8d2713f385c3fcef59cf6f29bcbd93d91f
change-id: 20260724-objecttype-support-ea1ef6941d07
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH GSoC 1/5] protocol-caps: add type support to object-info
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
@ 2026-07-25 11:55 ` Pablo Sabater
2026-07-29 9:53 ` Chandra Pratap
2026-07-25 11:55 ` [PATCH GSoC 2/5] fetch-object-info: parse type from server response Pablo Sabater
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
Teach the server-side object-info handler to accept type as a requested
field. When the client includes type in its object-info request, the
server returns the requested object type.
While at it, fix requested_info->size bit field style.
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
protocol-caps.c | 21 ++++++++++++++++++---
t/t5701-git-serve.sh | 27 +++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/protocol-caps.c b/protocol-caps.c
index 02261be14d..5531d388f0 100644
--- a/protocol-caps.c
+++ b/protocol-caps.c
@@ -11,7 +11,8 @@
#include "strbuf.h"
struct requested_info {
- unsigned size : 1;
+ unsigned size:1;
+ unsigned type:1;
};
/*
@@ -73,15 +74,20 @@ static void send_info(struct repository *r, struct packet_writer *writer,
if (info->size)
packet_writer_write(writer, "size");
+ if (info->type)
+ packet_writer_write(writer, "type");
+
for_each_string_list_item (item, oid_str_list) {
const char *oid_str = item->string;
struct object_id oid;
size_t object_size;
+ enum object_type object_type;
if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
packet_writer_error(
writer,
- "object-info: protocol error, expected to get oid, not '%s'",
+ "object-info: protocol error, expected to get "
+ "oid, not '%s'",
oid_str);
continue;
}
@@ -93,7 +99,8 @@ static void send_info(struct repository *r, struct packet_writer *writer,
* 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) {
+ object_type = get_object_info(r->objects, &oid, &object_size);
+ if (object_type <= OBJ_NONE) {
strbuf_addstr(&send_buffer, " ");
goto write;
}
@@ -103,6 +110,9 @@ static void send_info(struct repository *r, struct packet_writer *writer,
(uintmax_t)object_size);
}
+ if (info->type)
+ strbuf_addf(&send_buffer, " %s", type_name(object_type));
+
write:
packet_writer_write(writer, "%s", send_buffer.buf);
strbuf_reset(&send_buffer);
@@ -124,6 +134,11 @@ int cap_object_info(struct repository *r, struct packet_reader *request)
continue;
}
+ if (!strcmp("type", request->line)) {
+ info.type = 1;
+ continue;
+ }
+
if (parse_oid(request->line, &oid_str_list))
continue;
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
index 9a575aa098..d7c93b5b55 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -366,6 +366,33 @@ test_expect_success 'basics of object-info' '
test_cmp expect actual
'
+test_expect_success 'type' '
+ test_config transfer.advertiseObjectInfo true &&
+
+ test-tool pkt-line pack >in <<-EOF &&
+ command=object-info
+ object-format=$(test_oid algo)
+ 0001
+ size
+ type
+ oid $(git rev-parse two:two.t)
+ oid $(git rev-parse two:two.t)
+ 0000
+ EOF
+
+ cat >expect <<-EOF &&
+ size
+ type
+ $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
+ $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
+ 0000
+ EOF
+
+ test-tool serve-v2 --stateless-rpc <in >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'bare OID request' '
test_config transfer.advertiseObjectInfo true &&
--
2.54.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH GSoC 2/5] fetch-object-info: parse type from server response
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 1/5] protocol-caps: add type support to object-info Pablo Sabater
@ 2026-07-25 11:55 ` Pablo Sabater
2026-07-29 9:57 ` Chandra Pratap
2026-07-25 11:55 ` [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically Pablo Sabater
` (3 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
The server can handle type requests but does not advertise the
capability yet. Prepare the client to know how to parse the server
response once the server advertises the capability.
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
fetch-object-info.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fetch-object-info.c b/fetch-object-info.c
index ba7e179c44..cf6b94afb8 100644
--- a/fetch-object-info.c
+++ b/fetch-object-info.c
@@ -50,6 +50,7 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
const int stateless_rpc, const int fd_out)
{
int size_index = -1;
+ int type_index = -1;
switch (version) {
case protocol_v2:
@@ -101,8 +102,13 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
for (size_t j = 0; j < args->oids->nr; j++)
object_info_data[j].sizep =
xcalloc(1, sizeof(*object_info_data[j].sizep));
+ } else if (!strcmp(reader->line, "type")) {
+ type_index = (int)i;
+ for (size_t j = 0; j < args->oids->nr; j++)
+ object_info_data[j].typep =
+ xcalloc(1, sizeof(*object_info_data[j].typep));
} else {
- BUG("only size is supported");
+ BUG("unexpected object-info option: %s", reader->line);
}
}
@@ -148,6 +154,10 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
object_info_values.items[0].string,
object_info_values.items[size_index + 1].string);
+ if (type_index >= 0)
+ *object_info_data[i].typep =
+ type_from_string(object_info_values.items[type_index + 1].string);
+
string_list_clear(&object_info_values, 0);
}
check_stateless_delimiter(stateless_rpc, reader, "stateless delimiter expected");
--
2.54.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 1/5] protocol-caps: add type support to object-info Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 2/5] fetch-object-info: parse type from server response Pablo Sabater
@ 2026-07-25 11:55 ` Pablo Sabater
2026-07-29 9:57 ` Chandra Pratap
2026-07-25 11:55 ` [PATCH GSoC 4/5] serve: advertise type capability Pablo Sabater
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
In send_object_info_request(), size is hardcoded to be the only option
sent. In order to support type and future capabilities, replace the
hardcoded size with a loop that requests everything on
object_info_options list.
This is safe because the list has already been trimmed previously in
fetch_object_info() to only contain options that the server supports.
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
fetch-object-info.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/fetch-object-info.c b/fetch-object-info.c
index cf6b94afb8..e5cfdafe68 100644
--- a/fetch-object-info.c
+++ b/fetch-object-info.c
@@ -15,10 +15,13 @@ static void send_object_info_request(const int fd_out, struct object_info_args *
write_command_and_capabilities(&req_buf, "object-info", args->server_options);
- if (unsorted_string_list_has_string(args->object_info_options, "size"))
- packet_buf_write(&req_buf, "size");
- else if (args->object_info_options->nr)
- BUG("only size should be in object_info_options");
+ /*
+ * The list is already checked to only request valid and supported fields
+ * no need to check, just request everything left on the list
+ */
+ for (size_t i = 0; i < args->object_info_options->nr; i++)
+ packet_buf_write(&req_buf, "%s",
+ args->object_info_options->items[i].string);
if (args->oids)
for (size_t i = 0; i < args->oids->nr; i++)
--
2.54.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH GSoC 4/5] serve: advertise type capability
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
` (2 preceding siblings ...)
2026-07-25 11:55 ` [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically Pablo Sabater
@ 2026-07-25 11:55 ` Pablo Sabater
2026-07-29 9:58 ` Chandra Pratap
2026-07-25 11:55 ` [PATCH GSoC 5/5] cat-file: unify default format Pablo Sabater
2026-07-29 9:52 ` [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Chandra Pratap
5 siblings, 1 reply; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
The server and the client can handle type requests but the client won't
ask for it until the server advertises it.
Add type to the advertised capabilities so the client knows that it can
request it.
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
serve.c | 4 ++--
t/t1017-cat-file-remote-object-info.sh | 10 ++++++----
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/serve.c b/serve.c
index 2b07d922b3..2ce513cf2d 100644
--- a/serve.c
+++ b/serve.c
@@ -97,9 +97,9 @@ static int object_info_advertise(struct repository *r, struct strbuf *value)
/* disabled by default */
advertise_object_info = 0;
}
- /* Currently only size is supported */
+ /* Currently only size and type are supported */
if (value && advertise_object_info)
- strbuf_addstr(value, "size");
+ strbuf_addstr(value, "size type");
return advertise_object_info;
}
diff --git a/t/t1017-cat-file-remote-object-info.sh b/t/t1017-cat-file-remote-object-info.sh
index 116862f9d0..175f778cc9 100755
--- a/t/t1017-cat-file-remote-object-info.sh
+++ b/t/t1017-cat-file-remote-object-info.sh
@@ -7,6 +7,7 @@ test_description='git cat-file --batch-command with remote-object-info command'
hello_content="Hello World"
hello_size=$(strlen "$hello_content")
+hello_type="blob"
hello_oid=$(echo_without_newline "$hello_content" | git hash-object --stdin)
hello_short_oid=$(git rev-parse --short "$hello_oid")
@@ -19,6 +20,7 @@ unstored_oid=$(echo_without_newline "$unstored_content" | git hash-object --stdi
# file name is hello, which is 5 characters
# a space is 1 character and a null is 1 character
tree_size=$(($(test_oid rawsz) + 13))
+tree_type="tree"
commit_message="Initial commit"
@@ -31,6 +33,7 @@ commit_message="Initial commit"
# An easier way to calculate is: 1. use `git cat-file commit <commit hash> | wc -c`,
# to get 177, 2. then deduct 40 hex characters to get 137
commit_size=$(($(test_oid hexsz) + 137))
+commit_type="commit"
tag_header_without_oid="type blob
tag hellotag
@@ -44,6 +47,7 @@ $tag_description"
tag_oid=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
tag_size=$(strlen "$tag_content")
+tag_type="tag"
set_transport_variables () {
hello_oid=$(echo_without_newline "$hello_content" | git hash-object --stdin)
@@ -256,14 +260,12 @@ test_expect_success 'remote-object-info does not die on missing oid like info' '
)
'
-# This tests depends on %(objecttype) not being supported yet, once supported
-# it needs to be updated.
-test_expect_success 'unsupported placeholder on remote returns empty string' '
+test_expect_success 'objecttype is supported by remote-object-info' '
(
set_transport_variables "$daemon_parent" &&
cd "$daemon_parent/daemon_client_empty" &&
- echo "" >expect &&
+ echo $hello_type >expect &&
git cat-file --batch-command="%(objecttype)" >actual <<-EOF &&
remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
EOF
--
2.54.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH GSoC 5/5] cat-file: unify default format
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
` (3 preceding siblings ...)
2026-07-25 11:55 ` [PATCH GSoC 4/5] serve: advertise type capability Pablo Sabater
@ 2026-07-25 11:55 ` Pablo Sabater
2026-07-29 9:59 ` Chandra Pratap
2026-07-29 9:52 ` [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Chandra Pratap
5 siblings, 1 reply; 19+ messages in thread
From: Pablo Sabater @ 2026-07-25 11:55 UTC (permalink / raw)
To: git; +Cc: chandrapratap3519, karthik.188, gitster, Pablo Sabater
%(objecttype) is supported both by the client and by the server.
Change the temporary default format to the unified version that other
commands use.
Update documentation to remove %(objecttype) from the caveats of
remote-object-info.
Update tests that used the default format to expect type.
Update documentation to show %(objecttype) support.
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
Documentation/git-cat-file.adoc | 17 ++++-----
Documentation/gitprotocol-v2.adoc | 15 ++++++--
builtin/cat-file.c | 7 ----
t/t1017-cat-file-remote-object-info.sh | 70 ++++++++++++----------------------
4 files changed, 42 insertions(+), 67 deletions(-)
diff --git a/Documentation/git-cat-file.adoc b/Documentation/git-cat-file.adoc
index ac3b528c6f..514bfc0032 100644
--- a/Documentation/git-cat-file.adoc
+++ b/Documentation/git-cat-file.adoc
@@ -348,15 +348,12 @@ newline. The available atoms are:
after that first run of whitespace (i.e., the "rest" of the
line) are output in place of the `%(rest)` atom.
-The command `remote-object-info` only supports the `%(objectname)` and
-`%(objectsize)` placeholders. See `CAVEATS` below for more information.
+The command `remote-object-info` only supports the `%(objectname)`,
+`%(objectsize)` and `%(objecttype)` placeholders. See `CAVEATS` below for more
+information.
If no format is specified, the default format is `%(objectname)
-%(objecttype) %(objectsize)`, except for `remote-object-info` commands which
-use `%(objectname) %(objectsize)` because `%(objecttype)` is not supported yet.
-
-WARNING: When "%(objecttype)" is supported, the default format WILL be unified,
-so DO NOT RELY on the current default format to stay the same!!!
+%(objecttype) %(objectsize)`.
If `--batch` is specified, or if `--batch-command` is used with the `contents`
command, the object information is followed by the object contents (consisting
@@ -453,9 +450,9 @@ scripting purposes.
CAVEATS
-------
-Note that only `%(objectname)` and `%(objectsize)` are currently
-supported by the `remote-object-info` command. Using any other placeholder in
-the format string will return an empty string in its position.
+Note that only `%(objectname)`, `%(objectsize)` and `%(objecttype)` are
+currently supported by the `remote-object-info` command. Using any other
+placeholder in the format string will return an empty string in its position.
Note that the sizes of objects on disk are reported accurately, but care
should be taken in drawing conclusions about which refs or objects are
diff --git a/Documentation/gitprotocol-v2.adoc b/Documentation/gitprotocol-v2.adoc
index 7bf62014c3..de4bfb776e 100644
--- a/Documentation/gitprotocol-v2.adoc
+++ b/Documentation/gitprotocol-v2.adoc
@@ -558,14 +558,17 @@ object-info
`object-info` is the command to retrieve information about one or more objects.
Its main purpose is to allow a client to make decisions based on this
-information without having to fully fetch objects. Object size is the only
-information that is currently supported.
+information without having to fully fetch objects. Object size and type are the
+only information that is currently supported.
An `object-info` request takes the following arguments:
size
Requests size information to be returned for each listed object id.
+ type
+ Requests type information to be returned for each listed object id.
+
oid <oid>
Indicates to the server an object which the client wants to obtain
information for. They must be full OIDs.
@@ -580,11 +583,15 @@ space.
info = *PKT-LINE(attr LF)
*PKT-LINE(obj-info LF)
- attr = "size"
+ attr = "size" | "type"
obj-size = 1*DIGIT
- obj-info = obj-id [SP [obj-size]]
+ obj-type = "blob" | "tree" | "commit" | "tag"
+
+ obj-val = obj-size | obj-type
+
+ obj-info = obj-id [SP [obj-val *(SP obj-val)]]
If the server does not recognize the OID, the response will be `<oid> SP`
regardless of the number of attributes requested.
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 884b6d5ad3..8288511b19 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -841,15 +841,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
struct object_info *remote_object_info = NULL;
struct oid_array object_info_oids = OID_ARRAY_INIT;
struct string_list object_info_options = STRING_LIST_INIT_NODUP;
- const char *saved_format = opt->format;
if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
die(_("remote-object-info command too long"));
- /*
- * TODO: Use the default format once %(objecttype) is supported.
- */
- if (!opt->format)
- opt->format = "%(objectname) %(objectsize)";
line_to_split = xstrdup(line);
count = split_cmdline(line_to_split, &argv);
@@ -904,7 +898,6 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
data->is_remote = 0;
}
data->skip_object_info = 0;
- opt->format = saved_format;
for (size_t i = 0; i < object_info_oids.nr; i++)
free_object_info_contents(&remote_object_info[i]);
diff --git a/t/t1017-cat-file-remote-object-info.sh b/t/t1017-cat-file-remote-object-info.sh
index 175f778cc9..741bdf34a0 100755
--- a/t/t1017-cat-file-remote-object-info.sh
+++ b/t/t1017-cat-file-remote-object-info.sh
@@ -139,10 +139,10 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
set_transport_variables "$daemon_parent" &&
cd "$daemon_parent/daemon_client_empty" &&
- echo "$hello_oid $hello_size" >expect &&
- echo "$tree_oid $tree_size" >>expect &&
- echo "$commit_oid $commit_size" >>expect &&
- echo "$tag_oid $tag_size" >>expect &&
+ echo "$hello_oid $hello_type $hello_size" >expect &&
+ echo "$tree_oid $tree_type $tree_size" >>expect &&
+ echo "$commit_oid $commit_type $commit_size" >>expect &&
+ echo "$tag_oid $tag_type $tag_size" >>expect &&
git cat-file --batch-command >actual <<-EOF &&
remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid $tree_oid
@@ -152,28 +152,6 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
)
'
-test_expect_success 'remote-object-info does not change the default format of info' '
- (
- set_transport_variables "$daemon_parent" &&
- cd "$daemon_parent/daemon_client_empty" &&
-
- local_content="local object" &&
- local_oid=$(echo_without_newline "$local_content" | git hash-object -w --stdin) &&
- local_size=$(strlen "$local_content") &&
-
- echo "$local_oid blob $local_size" >expect &&
- echo "$hello_oid $hello_size" >>expect &&
- echo "$local_oid blob $local_size" >>expect &&
-
- git cat-file --batch-command >actual <<-EOF &&
- info $local_oid
- remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
- info $local_oid
- EOF
- test_cmp expect actual
- )
-'
-
test_expect_success 'batch-command --buffer remote-object-info git://' '
(
set_transport_variables "$daemon_parent" &&
@@ -209,10 +187,10 @@ test_expect_success 'batch-command -Z remote-object-info git:// default filter'
set_transport_variables "$daemon_parent" &&
cd "$daemon_parent/daemon_client_empty" &&
- printf "%s\0" "$hello_oid $hello_size" >expect &&
- printf "%s\0" "$tree_oid $tree_size" >>expect &&
- printf "%s\0" "$commit_oid $commit_size" >>expect &&
- printf "%s\0" "$tag_oid $tag_size" >>expect &&
+ printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
+ printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
+ printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
+ printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
printf "%s\0" "$hello_oid missing" >>expect &&
printf "%s\0" "$tree_oid missing" >>expect &&
@@ -432,10 +410,10 @@ test_expect_success 'batch-command remote-object-info file:// default filter' '
server_path="$(pwd)/server" &&
cd file_client_empty &&
- echo "$hello_oid $hello_size" >expect &&
- echo "$tree_oid $tree_size" >>expect &&
- echo "$commit_oid $commit_size" >>expect &&
- echo "$tag_oid $tag_size" >>expect &&
+ echo "$hello_oid $hello_type $hello_size" >expect &&
+ echo "$tree_oid $tree_type $tree_size" >>expect &&
+ echo "$commit_oid $commit_type $commit_size" >>expect &&
+ echo "$tag_oid $tag_type $tag_size" >>expect &&
git cat-file --batch-command >actual <<-EOF &&
remote-object-info "file://${server_path}" $hello_oid $tree_oid
@@ -451,10 +429,10 @@ test_expect_success 'batch-command -Z remote-object-info file:// default filter'
server_path="$(pwd)/server" &&
cd file_client_empty &&
- printf "%s\0" "$hello_oid $hello_size" >expect &&
- printf "%s\0" "$tree_oid $tree_size" >>expect &&
- printf "%s\0" "$commit_oid $commit_size" >>expect &&
- printf "%s\0" "$tag_oid $tag_size" >>expect &&
+ printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
+ printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
+ printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
+ printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
printf "%s\0" "$hello_oid missing" >>expect &&
printf "%s\0" "$tree_oid missing" >>expect &&
@@ -602,10 +580,10 @@ test_expect_success 'batch-command remote-object-info http:// default filter' '
set_transport_variables "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
cd "$HTTPD_DOCUMENT_ROOT_PATH/http_client_empty" &&
- echo "$hello_oid $hello_size" >expect &&
- echo "$tree_oid $tree_size" >>expect &&
- echo "$commit_oid $commit_size" >>expect &&
- echo "$tag_oid $tag_size" >>expect &&
+ echo "$hello_oid $hello_type $hello_size" >expect &&
+ echo "$tree_oid $tree_type $tree_size" >>expect &&
+ echo "$commit_oid $commit_type $commit_size" >>expect &&
+ echo "$tag_oid $tag_type $tag_size" >>expect &&
git cat-file --batch-command >actual <<-EOF &&
remote-object-info "$HTTPD_URL/smart/http_parent" $hello_oid $tree_oid
@@ -620,10 +598,10 @@ test_expect_success 'batch-command -Z remote-object-info http:// default filter'
set_transport_variables "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
cd "$HTTPD_DOCUMENT_ROOT_PATH/http_client_empty" &&
- printf "%s\0" "$hello_oid $hello_size" >expect &&
- printf "%s\0" "$tree_oid $tree_size" >>expect &&
- printf "%s\0" "$commit_oid $commit_size" >>expect &&
- printf "%s\0" "$tag_oid $tag_size" >>expect &&
+ printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
+ printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
+ printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
+ printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
batch_input="remote-object-info $HTTPD_URL/smart/http_parent $hello_oid $tree_oid
remote-object-info $HTTPD_URL/smart/http_parent $commit_oid $tag_oid
--
2.54.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype)
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
` (4 preceding siblings ...)
2026-07-25 11:55 ` [PATCH GSoC 5/5] cat-file: unify default format Pablo Sabater
@ 2026-07-29 9:52 ` Chandra Pratap
2026-07-29 12:34 ` Pablo Sabater
5 siblings, 1 reply; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:52 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>
> "%(objecttype)" is already known by the client's allow-list, but neither
> the client nor the server knows how to handle type. This series continues
> the work for git cat-file --batch-command extending remote-object-info
> to support "%(objecttype)" end to end. It is based on its predecessor
> series "cat-file: add remote-object-info to batch-command" [1].
>
> Type is the last property that is identical on the server and on the
> client once fetched.
>
> Whether to support more metadata such as:
>
> - objectsize:disk
> - deltabase
> - objectmode (needs context)
>
> should be discussed, unlike size and type, the rest depend on how things
> are packed on the server and on what the client already has, so they
> cannot reliably match local once fetched. IMO they are not worth
> supporting, I can't find a use case for them.
Makes sense to me. The metadata you listed depends on the local packfile
storage where the repository lives.
`objectmode` depends on the tree pointing to the blob, so it wouldn't be
accessible using the current infrastructure anyway.
> Adding new placeholders has become trivial.
> To add a new placeholder, follow the steps in this series and add it to
> the client's allow-list at 'builtin/cat-file.c'.
>
> Based-on: <20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com>
>
> Github CI: https://github.com/pabloosabaterr/git/actions/runs/30155586279
>
> [1]: https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/
>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
> Pablo Sabater (5):
> protocol-caps: add type support to object-info
> fetch-object-info: parse type from server response
> fetch-object-info: request all supported options dynamically
> serve: advertise type capability
> cat-file: unify default format
The current incremental approach is safe and ensures every commit
compiles and passes tests. However, from a storytelling perspective for
the reviewers, I believe it's better to do any 'preparatory refactoring' before
starting the new feature.
Patch 3 (dynamically requesting supported options) doesn't actually depend
on type existing yet. I suggest bumping Patch 3 to be Patch 1 in V2.
That way, the client is already dynamic and ready, and the feature patches
can strictly focus on adding type:
- fetch-object-info: request all supported options dynamically (Current Patch 3)
- protocol-caps: add type support to object-info (Current Patch 1)
- fetch-object-info: parse type from server response (Current Patch 2)
- serve: advertise type capability (Current Patch 4)
- cat-file: unify default format (Current Patch 5)
> Documentation/git-cat-file.adoc | 17 +++-----
> Documentation/gitprotocol-v2.adoc | 15 +++++--
> builtin/cat-file.c | 7 ---
> fetch-object-info.c | 23 +++++++---
> protocol-caps.c | 21 +++++++--
> serve.c | 4 +-
> t/t1017-cat-file-remote-object-info.sh | 80 +++++++++++++---------------------
> t/t5701-git-serve.sh | 27 ++++++++++++
> 8 files changed, 113 insertions(+), 81 deletions(-)
This series is definitely a lot smaller than I thought it would be. Looks like
most of the heavy lifting was already done with the previous series.
Good for us!
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 1/5] protocol-caps: add type support to object-info
2026-07-25 11:55 ` [PATCH GSoC 1/5] protocol-caps: add type support to object-info Pablo Sabater
@ 2026-07-29 9:53 ` Chandra Pratap
2026-07-29 11:18 ` Pablo Sabater
2026-07-29 15:40 ` Junio C Hamano
0 siblings, 2 replies; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:53 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>
> Teach the server-side object-info handler to accept type as a requested
> field. When the client includes type in its object-info request, the
> server returns the requested object type.
>
> While at it, fix requested_info->size bit field style.
>
> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
> protocol-caps.c | 21 ++++++++++++++++++---
> t/t5701-git-serve.sh | 27 +++++++++++++++++++++++++++
> 2 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/protocol-caps.c b/protocol-caps.c
> index 02261be14d..5531d388f0 100644
> --- a/protocol-caps.c
> +++ b/protocol-caps.c
> @@ -11,7 +11,8 @@
> #include "strbuf.h"
>
> struct requested_info {
> - unsigned size : 1;
> + unsigned size:1;
> + unsigned type:1;
> };
>
> /*
> @@ -73,15 +74,20 @@ static void send_info(struct repository *r, struct packet_writer *writer,
> if (info->size)
> packet_writer_write(writer, "size");
>
> + if (info->type)
> + packet_writer_write(writer, "type");
> +
> for_each_string_list_item (item, oid_str_list) {
> const char *oid_str = item->string;
> struct object_id oid;
> size_t object_size;
> + enum object_type object_type;
>
> if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
> packet_writer_error(
> writer,
> - "object-info: protocol error, expected to get oid, not '%s'",
> + "object-info: protocol error, expected to get "
> + "oid, not '%s'",
I assume this is a style change? The original line doesn't seem
long enough to wrap though.
Also, this would break the grep-ability of this error string.
> oid_str);
> continue;
> }
> @@ -93,7 +99,8 @@ static void send_info(struct repository *r, struct packet_writer *writer,
> * 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) {
> + object_type = get_object_info(r->objects, &oid, &object_size);
> + if (object_type <= OBJ_NONE) {
> strbuf_addstr(&send_buffer, " ");
> goto write;
> }
> @@ -103,6 +110,9 @@ static void send_info(struct repository *r, struct packet_writer *writer,
> (uintmax_t)object_size);
> }
>
> + if (info->type)
> + strbuf_addf(&send_buffer, " %s", type_name(object_type));
> +
> write:
> packet_writer_write(writer, "%s", send_buffer.buf);
> strbuf_reset(&send_buffer);
> @@ -124,6 +134,11 @@ int cap_object_info(struct repository *r, struct packet_reader *request)
> continue;
> }
>
> + if (!strcmp("type", request->line)) {
> + info.type = 1;
> + continue;
> + }
> +
> if (parse_oid(request->line, &oid_str_list))
> continue;
>
> diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
> index 9a575aa098..d7c93b5b55 100755
> --- a/t/t5701-git-serve.sh
> +++ b/t/t5701-git-serve.sh
> @@ -366,6 +366,33 @@ test_expect_success 'basics of object-info' '
> test_cmp expect actual
> '
>
> +test_expect_success 'type' '
> + test_config transfer.advertiseObjectInfo true &&
> +
> + test-tool pkt-line pack >in <<-EOF &&
> + command=object-info
> + object-format=$(test_oid algo)
> + 0001
> + size
> + type
> + oid $(git rev-parse two:two.t)
> + oid $(git rev-parse two:two.t)
> + 0000
> + EOF
> +
> + cat >expect <<-EOF &&
> + size
> + type
> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
Can we not use the `test_file_size` tool to do this instead?
That should also be much more portable.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 2/5] fetch-object-info: parse type from server response
2026-07-25 11:55 ` [PATCH GSoC 2/5] fetch-object-info: parse type from server response Pablo Sabater
@ 2026-07-29 9:57 ` Chandra Pratap
2026-07-29 12:05 ` Pablo Sabater
0 siblings, 1 reply; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:57 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>
> The server can handle type requests but does not advertise the
> capability yet. Prepare the client to know how to parse the server
> response once the server advertises the capability.
>
> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
> fetch-object-info.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/fetch-object-info.c b/fetch-object-info.c
> index ba7e179c44..cf6b94afb8 100644
> --- a/fetch-object-info.c
> +++ b/fetch-object-info.c
> @@ -50,6 +50,7 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
> const int stateless_rpc, const int fd_out)
> {
> int size_index = -1;
> + int type_index = -1;
>
> switch (version) {
> case protocol_v2:
> @@ -101,8 +102,13 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
> for (size_t j = 0; j < args->oids->nr; j++)
> object_info_data[j].sizep =
> xcalloc(1, sizeof(*object_info_data[j].sizep));
> + } else if (!strcmp(reader->line, "type")) {
> + type_index = (int)i;
> + for (size_t j = 0; j < args->oids->nr; j++)
> + object_info_data[j].typep =
> + xcalloc(1, sizeof(*object_info_data[j].typep));
> } else {
> - BUG("only size is supported");
> + BUG("unexpected object-info option: %s", reader->line);
> }
> }
>
> @@ -148,6 +154,10 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
> object_info_values.items[0].string,
> object_info_values.items[size_index + 1].string);
>
> + if (type_index >= 0)
> + *object_info_data[i].typep =
> + type_from_string(object_info_values.items[type_index + 1].string);
> +
> string_list_clear(&object_info_values, 0);
Is there a risk of an out-of-bounds array access here if the server
responds with a truncated or malformed packet?
If object_info_values.nr <= type_index + 1, this will segfault.
If there isn't a bounds check slightly higher up in this loop, we should
add one. Either way, we should definitely add a test using a mocked
server response (e.g., via test-tool pkt-line) to ensure the client
gracefully dies with a protocol error rather than segfaulting when it
receives a malformed packet.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically
2026-07-25 11:55 ` [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically Pablo Sabater
@ 2026-07-29 9:57 ` Chandra Pratap
2026-07-29 12:07 ` Pablo Sabater
0 siblings, 1 reply; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:57 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>
> In send_object_info_request(), size is hardcoded to be the only option
> sent. In order to support type and future capabilities, replace the
> hardcoded size with a loop that requests everything on
> object_info_options list.
>
> This is safe because the list has already been trimmed previously in
> fetch_object_info() to only contain options that the server supports.
>
> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
> fetch-object-info.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/fetch-object-info.c b/fetch-object-info.c
> index cf6b94afb8..e5cfdafe68 100644
> --- a/fetch-object-info.c
> +++ b/fetch-object-info.c
> @@ -15,10 +15,13 @@ static void send_object_info_request(const int fd_out, struct object_info_args *
>
> write_command_and_capabilities(&req_buf, "object-info", args->server_options);
>
> - if (unsorted_string_list_has_string(args->object_info_options, "size"))
> - packet_buf_write(&req_buf, "size");
> - else if (args->object_info_options->nr)
> - BUG("only size should be in object_info_options");
> + /*
> + * The list is already checked to only request valid and supported fields
> + * no need to check, just request everything left on the list
Nit: ...valid and supported fields no need to check.. -> valid and
supported fields.
Just request everything remaining on the list.
> + */
> + for (size_t i = 0; i < args->object_info_options->nr; i++)
> + packet_buf_write(&req_buf, "%s",
> + args->object_info_options->items[i].string);
Perfect place to use `for_each_string_list_item()`.
> if (args->oids)
> for (size_t i = 0; i < args->oids->nr; i++)
>
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 4/5] serve: advertise type capability
2026-07-25 11:55 ` [PATCH GSoC 4/5] serve: advertise type capability Pablo Sabater
@ 2026-07-29 9:58 ` Chandra Pratap
2026-07-29 12:15 ` Pablo Sabater
0 siblings, 1 reply; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:58 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
[snip]
> -# This tests depends on %(objecttype) not being supported yet, once supported
> -# it needs to be updated.
> -test_expect_success 'unsupported placeholder on remote returns empty string' '
> +test_expect_success 'objecttype is supported by remote-object-info' '
> (
> set_transport_variables "$daemon_parent" &&
> cd "$daemon_parent/daemon_client_empty" &&
>
> - echo "" >expect &&
> + echo $hello_type >expect &&
> git cat-file --batch-command="%(objecttype)" >actual <<-EOF &&
> remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
> EOF
Instead of this, what about creating a single test that verifies
'type' is supported,
and modifying this test to verify that the other options are not?
That would actually preserve this test's behaviour and make it easier
to extend in the future. Something like:
+ test_expect_success 'type is supported by remote-object-info'
+ test_expect_success 'unsupported placeholder on remote returns empty string'
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 5/5] cat-file: unify default format
2026-07-25 11:55 ` [PATCH GSoC 5/5] cat-file: unify default format Pablo Sabater
@ 2026-07-29 9:59 ` Chandra Pratap
2026-07-29 12:23 ` Pablo Sabater
0 siblings, 1 reply; 19+ messages in thread
From: Chandra Pratap @ 2026-07-29 9:59 UTC (permalink / raw)
To: Pablo Sabater; +Cc: git, karthik.188, gitster
On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>
> %(objecttype) is supported both by the client and by the server.
> Change the temporary default format to the unified version that other
> commands use.
s/other/the other
> Update documentation to remove %(objecttype) from the caveats of
> remote-object-info.
>
> Update tests that used the default format to expect type.
Not super accurate. We're updating the tests to expect the new default
format.
> Update documentation to show %(objecttype) support.
>
> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
> ---
> Documentation/git-cat-file.adoc | 17 ++++-----
> Documentation/gitprotocol-v2.adoc | 15 ++++++--
> builtin/cat-file.c | 7 ----
> t/t1017-cat-file-remote-object-info.sh | 70 ++++++++++++----------------------
> 4 files changed, 42 insertions(+), 67 deletions(-)
>
> diff --git a/Documentation/git-cat-file.adoc b/Documentation/git-cat-file.adoc
> index ac3b528c6f..514bfc0032 100644
> --- a/Documentation/git-cat-file.adoc
> +++ b/Documentation/git-cat-file.adoc
> @@ -348,15 +348,12 @@ newline. The available atoms are:
> after that first run of whitespace (i.e., the "rest" of the
> line) are output in place of the `%(rest)` atom.
>
> -The command `remote-object-info` only supports the `%(objectname)` and
> -`%(objectsize)` placeholders. See `CAVEATS` below for more information.
> +The command `remote-object-info` only supports the `%(objectname)`,
> +`%(objectsize)` and `%(objecttype)` placeholders. See `CAVEATS` below for more
> +information.
>
> If no format is specified, the default format is `%(objectname)
> -%(objecttype) %(objectsize)`, except for `remote-object-info` commands which
> -use `%(objectname) %(objectsize)` because `%(objecttype)` is not supported yet.
> -
> -WARNING: When "%(objecttype)" is supported, the default format WILL be unified,
> -so DO NOT RELY on the current default format to stay the same!!!
> +%(objecttype) %(objectsize)`.
>
> If `--batch` is specified, or if `--batch-command` is used with the `contents`
> command, the object information is followed by the object contents (consisting
> @@ -453,9 +450,9 @@ scripting purposes.
> CAVEATS
> -------
>
> -Note that only `%(objectname)` and `%(objectsize)` are currently
> -supported by the `remote-object-info` command. Using any other placeholder in
> -the format string will return an empty string in its position.
> +Note that only `%(objectname)`, `%(objectsize)` and `%(objecttype)` are
> +currently supported by the `remote-object-info` command. Using any other
> +placeholder in the format string will return an empty string in its position.
>
> Note that the sizes of objects on disk are reported accurately, but care
> should be taken in drawing conclusions about which refs or objects are
> diff --git a/Documentation/gitprotocol-v2.adoc b/Documentation/gitprotocol-v2.adoc
> index 7bf62014c3..de4bfb776e 100644
> --- a/Documentation/gitprotocol-v2.adoc
> +++ b/Documentation/gitprotocol-v2.adoc
> @@ -558,14 +558,17 @@ object-info
>
> `object-info` is the command to retrieve information about one or more objects.
> Its main purpose is to allow a client to make decisions based on this
> -information without having to fully fetch objects. Object size is the only
> -information that is currently supported.
> +information without having to fully fetch objects. Object size and type are the
> +only information that is currently supported.
s/is currently/are currently
> An `object-info` request takes the following arguments:
>
> size
> Requests size information to be returned for each listed object id.
>
> + type
> + Requests type information to be returned for each listed object id.
> +
> oid <oid>
> Indicates to the server an object which the client wants to obtain
> information for. They must be full OIDs.
> @@ -580,11 +583,15 @@ space.
> info = *PKT-LINE(attr LF)
> *PKT-LINE(obj-info LF)
>
> - attr = "size"
> + attr = "size" | "type"
>
> obj-size = 1*DIGIT
>
> - obj-info = obj-id [SP [obj-size]]
> + obj-type = "blob" | "tree" | "commit" | "tag"
> +
> + obj-val = obj-size | obj-type
> +
> + obj-info = obj-id [SP [obj-val *(SP obj-val)]]
>
> If the server does not recognize the OID, the response will be `<oid> SP`
> regardless of the number of attributes requested.
> diff --git a/builtin/cat-file.c b/builtin/cat-file.c
> index 884b6d5ad3..8288511b19 100644
> --- a/builtin/cat-file.c
> +++ b/builtin/cat-file.c
> @@ -841,15 +841,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
> struct object_info *remote_object_info = NULL;
> struct oid_array object_info_oids = OID_ARRAY_INIT;
> struct string_list object_info_options = STRING_LIST_INIT_NODUP;
> - const char *saved_format = opt->format;
>
> if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
> die(_("remote-object-info command too long"));
> - /*
> - * TODO: Use the default format once %(objecttype) is supported.
> - */
> - if (!opt->format)
> - opt->format = "%(objectname) %(objectsize)";
>
> line_to_split = xstrdup(line);
> count = split_cmdline(line_to_split, &argv);
> @@ -904,7 +898,6 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
> data->is_remote = 0;
> }
> data->skip_object_info = 0;
> - opt->format = saved_format;
>
> for (size_t i = 0; i < object_info_oids.nr; i++)
> free_object_info_contents(&remote_object_info[i]);
> diff --git a/t/t1017-cat-file-remote-object-info.sh b/t/t1017-cat-file-remote-object-info.sh
> index 175f778cc9..741bdf34a0 100755
> --- a/t/t1017-cat-file-remote-object-info.sh
> +++ b/t/t1017-cat-file-remote-object-info.sh
> @@ -139,10 +139,10 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
> set_transport_variables "$daemon_parent" &&
> cd "$daemon_parent/daemon_client_empty" &&
>
> - echo "$hello_oid $hello_size" >expect &&
> - echo "$tree_oid $tree_size" >>expect &&
> - echo "$commit_oid $commit_size" >>expect &&
> - echo "$tag_oid $tag_size" >>expect &&
> + echo "$hello_oid $hello_type $hello_size" >expect &&
> + echo "$tree_oid $tree_type $tree_size" >>expect &&
> + echo "$commit_oid $commit_type $commit_size" >>expect &&
> + echo "$tag_oid $tag_type $tag_size" >>expect &&
>
> git cat-file --batch-command >actual <<-EOF &&
> remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid $tree_oid
> @@ -152,28 +152,6 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
> )
> '
>
> -test_expect_success 'remote-object-info does not change the default format of info' '
> - (
> - set_transport_variables "$daemon_parent" &&
> - cd "$daemon_parent/daemon_client_empty" &&
> -
> - local_content="local object" &&
> - local_oid=$(echo_without_newline "$local_content" | git hash-object -w --stdin) &&
> - local_size=$(strlen "$local_content") &&
> -
> - echo "$local_oid blob $local_size" >expect &&
> - echo "$hello_oid $hello_size" >>expect &&
> - echo "$local_oid blob $local_size" >>expect &&
> -
> - git cat-file --batch-command >actual <<-EOF &&
> - info $local_oid
> - remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
> - info $local_oid
> - EOF
> - test_cmp expect actual
> - )
> -'
> -
I feel like deleting this test removes the only test in this file that validates
calling info and remote-object-info in the same cat-file --batch-command
session.
Instead of deleting it, we should update it. Perhaps something like this:
test "remote-object-info and info can be mixed using the unified
default format":
// 1. Environment setup
// 2. Prepare a local object for the 'info' command
// 3. Construct the expected output. Since the default format is
now unified,
// both commands should output exactly: <OID> <TYPE> <SIZE>
// 4. Execute the batch command
// 5. Validate
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 1/5] protocol-caps: add type support to object-info
2026-07-29 9:53 ` Chandra Pratap
@ 2026-07-29 11:18 ` Pablo Sabater
2026-07-29 15:40 ` Junio C Hamano
1 sibling, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 11:18 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:53 AM CEST, Chandra Pratap wrote:
> On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>>
>> Teach the server-side object-info handler to accept type as a requested
>> field. When the client includes type in its object-info request, the
>> server returns the requested object type.
>>
>> While at it, fix requested_info->size bit field style.
>>
>> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
>> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
>> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
>> ---
>> protocol-caps.c | 21 ++++++++++++++++++---
>> t/t5701-git-serve.sh | 27 +++++++++++++++++++++++++++
>> 2 files changed, 45 insertions(+), 3 deletions(-)
>>
>> diff --git a/protocol-caps.c b/protocol-caps.c
>> index 02261be14d..5531d388f0 100644
>> --- a/protocol-caps.c
>> +++ b/protocol-caps.c
>> @@ -11,7 +11,8 @@
>> #include "strbuf.h"
>>
>> struct requested_info {
>> - unsigned size : 1;
>> + unsigned size:1;
>> + unsigned type:1;
>> };
>>
>> /*
>> @@ -73,15 +74,20 @@ static void send_info(struct repository *r, struct packet_writer *writer,
>> if (info->size)
>> packet_writer_write(writer, "size");
>>
>> + if (info->type)
>> + packet_writer_write(writer, "type");
>> +
>> for_each_string_list_item (item, oid_str_list) {
>> const char *oid_str = item->string;
>> struct object_id oid;
>> size_t object_size;
>> + enum object_type object_type;
>>
>> if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
>> packet_writer_error(
>> writer,
>> - "object-info: protocol error, expected to get oid, not '%s'",
>> + "object-info: protocol error, expected to get "
>> + "oid, not '%s'",
>
> I assume this is a style change? The original line doesn't seem
> long enough to wrap though.
>
> Also, this would break the grep-ability of this error string.
Yes It is a style change and it's ~60columns long, I'll drop the change.
Turns out my nvim settings is showing the vertical guide at ~60 columns instead
of 80, but that's on me.
>
>> oid_str);
>> continue;
>> }
>> @@ -93,7 +99,8 @@ static void send_info(struct repository *r, struct packet_writer *writer,
>> * 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) {
>> + object_type = get_object_info(r->objects, &oid, &object_size);
>> + if (object_type <= OBJ_NONE) {
>> strbuf_addstr(&send_buffer, " ");
>> goto write;
>> }
>> @@ -103,6 +110,9 @@ static void send_info(struct repository *r, struct packet_writer *writer,
>> (uintmax_t)object_size);
>> }
>>
>> + if (info->type)
>> + strbuf_addf(&send_buffer, " %s", type_name(object_type));
>> +
>> write:
>> packet_writer_write(writer, "%s", send_buffer.buf);
>> strbuf_reset(&send_buffer);
>> @@ -124,6 +134,11 @@ int cap_object_info(struct repository *r, struct packet_reader *request)
>> continue;
>> }
>>
>> + if (!strcmp("type", request->line)) {
>> + info.type = 1;
>> + continue;
>> + }
>> +
>> if (parse_oid(request->line, &oid_str_list))
>> continue;
>>
>> diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
>> index 9a575aa098..d7c93b5b55 100755
>> --- a/t/t5701-git-serve.sh
>> +++ b/t/t5701-git-serve.sh
>> @@ -366,6 +366,33 @@ test_expect_success 'basics of object-info' '
>> test_cmp expect actual
>> '
>>
>> +test_expect_success 'type' '
>> + test_config transfer.advertiseObjectInfo true &&
>> +
>> + test-tool pkt-line pack >in <<-EOF &&
>> + command=object-info
>> + object-format=$(test_oid algo)
>> + 0001
>> + size
>> + type
>> + oid $(git rev-parse two:two.t)
>> + oid $(git rev-parse two:two.t)
>> + 0000
>> + EOF
>> +
>> + cat >expect <<-EOF &&
>> + size
>> + type
>> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
>> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
>
> Can we not use the `test_file_size` tool to do this instead?
> That should also be much more portable.
Yes, I will use it, I didn't know about it.
A test on top of this one does the same pattern, I will fix it too.
Thanks for the feedback,
Pablo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 2/5] fetch-object-info: parse type from server response
2026-07-29 9:57 ` Chandra Pratap
@ 2026-07-29 12:05 ` Pablo Sabater
0 siblings, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 12:05 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:57 AM CEST, Chandra Pratap wrote:
> On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>>
>> The server can handle type requests but does not advertise the
>> capability yet. Prepare the client to know how to parse the server
>> response once the server advertises the capability.
>>
>> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
>> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
>> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
>> ---
>> fetch-object-info.c | 12 +++++++++++-
>> 1 file changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/fetch-object-info.c b/fetch-object-info.c
>> index ba7e179c44..cf6b94afb8 100644
>> --- a/fetch-object-info.c
>> +++ b/fetch-object-info.c
>> @@ -50,6 +50,7 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
>> const int stateless_rpc, const int fd_out)
>> {
>> int size_index = -1;
>> + int type_index = -1;
>>
>> switch (version) {
>> case protocol_v2:
>> @@ -101,8 +102,13 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
>> for (size_t j = 0; j < args->oids->nr; j++)
>> object_info_data[j].sizep =
>> xcalloc(1, sizeof(*object_info_data[j].sizep));
>> + } else if (!strcmp(reader->line, "type")) {
>> + type_index = (int)i;
>> + for (size_t j = 0; j < args->oids->nr; j++)
>> + object_info_data[j].typep =
>> + xcalloc(1, sizeof(*object_info_data[j].typep));
>> } else {
>> - BUG("only size is supported");
>> + BUG("unexpected object-info option: %s", reader->line);
>> }
>> }
>>
>> @@ -148,6 +154,10 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
>> object_info_values.items[0].string,
>> object_info_values.items[size_index + 1].string);
>>
>> + if (type_index >= 0)
>> + *object_info_data[i].typep =
>> + type_from_string(object_info_values.items[type_index + 1].string);
>> +
>> string_list_clear(&object_info_values, 0);
>
> Is there a risk of an out-of-bounds array access here if the server
> responds with a truncated or malformed packet?
>
> If object_info_values.nr <= type_index + 1, this will segfault.
This shouldn't be a possible case because of:
fetch_object_info()
for (size_t i = 0; i < args->object_info_options->nr; i++) {
[snip]
} else if (!strcmp(reader->line, "type")) {
type_index = (int)i;
[snip]
type_index is set based of the range of object_info_options->nr so:
type_index < object_info_options->nr
and a few lines below:
if (args->object_info_options->nr + 1 != object_info_values.nr)
die("object-info: unexpected number of attributes: %s",
reader->line);
so we also know that type_index + 1 < object_info_values.nr.
After that we get to those lines that this patch introduced:
+ if (type_index >= 0)
+ *object_info_data[i].typep =
+ type_from_string(object_info_values.items[type_index + 1].string);
And because type_index + 1 < object_info_values.nr we can be sure that
this cannot segfault once we reach this code.
>
> If there isn't a bounds check slightly higher up in this loop, we should
> add one. Either way, we should definitely add a test using a mocked
> server response (e.g., via test-tool pkt-line) to ensure the client
> gracefully dies with a protocol error rather than segfaulting when it
> receives a malformed packet.
Ok, that's sounds a good test, I think there's none where a malicious
server is simulated, in part because I don't know how and I think I
haven't seen a test that does that yet.
test-tool and pkt-line are used for the opposite: simulating the
client to test the real server.
I'll see what I can do about it.
Thanks for the feedback,
Pablo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically
2026-07-29 9:57 ` Chandra Pratap
@ 2026-07-29 12:07 ` Pablo Sabater
0 siblings, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 12:07 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:57 AM CEST, Chandra Pratap wrote:
> On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>>
>> In send_object_info_request(), size is hardcoded to be the only option
>> sent. In order to support type and future capabilities, replace the
>> hardcoded size with a loop that requests everything on
>> object_info_options list.
>>
>> This is safe because the list has already been trimmed previously in
>> fetch_object_info() to only contain options that the server supports.
>>
>> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
>> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
>> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
>> ---
>> fetch-object-info.c | 11 +++++++----
>> 1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/fetch-object-info.c b/fetch-object-info.c
>> index cf6b94afb8..e5cfdafe68 100644
>> --- a/fetch-object-info.c
>> +++ b/fetch-object-info.c
>> @@ -15,10 +15,13 @@ static void send_object_info_request(const int fd_out, struct object_info_args *
>>
>> write_command_and_capabilities(&req_buf, "object-info", args->server_options);
>>
>> - if (unsorted_string_list_has_string(args->object_info_options, "size"))
>> - packet_buf_write(&req_buf, "size");
>> - else if (args->object_info_options->nr)
>> - BUG("only size should be in object_info_options");
>> + /*
>> + * The list is already checked to only request valid and supported fields
>> + * no need to check, just request everything left on the list
>
> Nit: ...valid and supported fields no need to check.. -> valid and
> supported fields.
> Just request everything remaining on the list.
Ok, will fix it, thanks.
>
>> + */
>> + for (size_t i = 0; i < args->object_info_options->nr; i++)
>> + packet_buf_write(&req_buf, "%s",
>> + args->object_info_options->items[i].string);
>
> Perfect place to use `for_each_string_list_item()`.
Didn't think of that, I will change it, thanks.
>
>
>> if (args->oids)
>> for (size_t i = 0; i < args->oids->nr; i++)
>>
>> --
>> 2.54.0
>>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 4/5] serve: advertise type capability
2026-07-29 9:58 ` Chandra Pratap
@ 2026-07-29 12:15 ` Pablo Sabater
0 siblings, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 12:15 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:58 AM CEST, Chandra Pratap wrote:
> [snip]
>> -# This tests depends on %(objecttype) not being supported yet, once supported
>> -# it needs to be updated.
>> -test_expect_success 'unsupported placeholder on remote returns empty string' '
>> +test_expect_success 'objecttype is supported by remote-object-info' '
>> (
>> set_transport_variables "$daemon_parent" &&
>> cd "$daemon_parent/daemon_client_empty" &&
>>
>> - echo "" >expect &&
>> + echo $hello_type >expect &&
>> git cat-file --batch-command="%(objecttype)" >actual <<-EOF &&
>> remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
>> EOF
>
> Instead of this, what about creating a single test that verifies
> 'type' is supported,
> and modifying this test to verify that the other options are not?
>
> That would actually preserve this test's behaviour and make it easier
> to extend in the future. Something like:
>
> + test_expect_success 'type is supported by remote-object-info'
> + test_expect_success 'unsupported placeholder on remote returns empty string'
Hmmm, it is true that after this test there are no test with the git://
that test for known but unsupported placeholders returning empty
strings, but there are tests from the previous series that does test for
others that are still unsupported like objectmode, deltabase,
objectsize:disk.
I think on more test grouping all the one that remain unsupported will
be good and document.
I'll do exactly what you proposed, thanks,
Pablo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 5/5] cat-file: unify default format
2026-07-29 9:59 ` Chandra Pratap
@ 2026-07-29 12:23 ` Pablo Sabater
0 siblings, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 12:23 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:59 AM CEST, Chandra Pratap wrote:
> On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>>
>> %(objecttype) is supported both by the client and by the server.
>> Change the temporary default format to the unified version that other
>> commands use.
>
> s/other/the other
Will fix thanks.
>
>> Update documentation to remove %(objecttype) from the caveats of
>> remote-object-info.
>>
>> Update tests that used the default format to expect type.
>
> Not super accurate. We're updating the tests to expect the new default
> format.
I will reword it to something like:
Now that type is supported and the default format unified, update the
tests to expect the new default format.
>
>> Update documentation to show %(objecttype) support.
>>
>> Mentored-by: Karthik Nayak <karthik.188@gmail.com>
>> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
>> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
>> ---
>> Documentation/git-cat-file.adoc | 17 ++++-----
>> Documentation/gitprotocol-v2.adoc | 15 ++++++--
>> builtin/cat-file.c | 7 ----
>> t/t1017-cat-file-remote-object-info.sh | 70 ++++++++++++----------------------
>> 4 files changed, 42 insertions(+), 67 deletions(-)
>>
>> diff --git a/Documentation/git-cat-file.adoc b/Documentation/git-cat-file.adoc
>> index ac3b528c6f..514bfc0032 100644
>> --- a/Documentation/git-cat-file.adoc
>> +++ b/Documentation/git-cat-file.adoc
>> @@ -348,15 +348,12 @@ newline. The available atoms are:
>> after that first run of whitespace (i.e., the "rest" of the
>> line) are output in place of the `%(rest)` atom.
>>
>> -The command `remote-object-info` only supports the `%(objectname)` and
>> -`%(objectsize)` placeholders. See `CAVEATS` below for more information.
>> +The command `remote-object-info` only supports the `%(objectname)`,
>> +`%(objectsize)` and `%(objecttype)` placeholders. See `CAVEATS` below for more
>> +information.
>>
>> If no format is specified, the default format is `%(objectname)
>> -%(objecttype) %(objectsize)`, except for `remote-object-info` commands which
>> -use `%(objectname) %(objectsize)` because `%(objecttype)` is not supported yet.
>> -
>> -WARNING: When "%(objecttype)" is supported, the default format WILL be unified,
>> -so DO NOT RELY on the current default format to stay the same!!!
>> +%(objecttype) %(objectsize)`.
>>
>> If `--batch` is specified, or if `--batch-command` is used with the `contents`
>> command, the object information is followed by the object contents (consisting
>> @@ -453,9 +450,9 @@ scripting purposes.
>> CAVEATS
>> -------
>>
>> -Note that only `%(objectname)` and `%(objectsize)` are currently
>> -supported by the `remote-object-info` command. Using any other placeholder in
>> -the format string will return an empty string in its position.
>> +Note that only `%(objectname)`, `%(objectsize)` and `%(objecttype)` are
>> +currently supported by the `remote-object-info` command. Using any other
>> +placeholder in the format string will return an empty string in its position.
>>
>> Note that the sizes of objects on disk are reported accurately, but care
>> should be taken in drawing conclusions about which refs or objects are
>> diff --git a/Documentation/gitprotocol-v2.adoc b/Documentation/gitprotocol-v2.adoc
>> index 7bf62014c3..de4bfb776e 100644
>> --- a/Documentation/gitprotocol-v2.adoc
>> +++ b/Documentation/gitprotocol-v2.adoc
>> @@ -558,14 +558,17 @@ object-info
>>
>> `object-info` is the command to retrieve information about one or more objects.
>> Its main purpose is to allow a client to make decisions based on this
>> -information without having to fully fetch objects. Object size is the only
>> -information that is currently supported.
>> +information without having to fully fetch objects. Object size and type are the
>> +only information that is currently supported.
>
> s/is currently/are currently
Will fix.
>
>> An `object-info` request takes the following arguments:
>>
>> size
>> Requests size information to be returned for each listed object id.
>>
>> + type
>> + Requests type information to be returned for each listed object id.
>> +
>> oid <oid>
>> Indicates to the server an object which the client wants to obtain
>> information for. They must be full OIDs.
>> @@ -580,11 +583,15 @@ space.
>> info = *PKT-LINE(attr LF)
>> *PKT-LINE(obj-info LF)
>>
>> - attr = "size"
>> + attr = "size" | "type"
>>
>> obj-size = 1*DIGIT
>>
>> - obj-info = obj-id [SP [obj-size]]
>> + obj-type = "blob" | "tree" | "commit" | "tag"
>> +
>> + obj-val = obj-size | obj-type
>> +
>> + obj-info = obj-id [SP [obj-val *(SP obj-val)]]
>>
>> If the server does not recognize the OID, the response will be `<oid> SP`
>> regardless of the number of attributes requested.
>> diff --git a/builtin/cat-file.c b/builtin/cat-file.c
>> index 884b6d5ad3..8288511b19 100644
>> --- a/builtin/cat-file.c
>> +++ b/builtin/cat-file.c
>> @@ -841,15 +841,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
>> struct object_info *remote_object_info = NULL;
>> struct oid_array object_info_oids = OID_ARRAY_INIT;
>> struct string_list object_info_options = STRING_LIST_INIT_NODUP;
>> - const char *saved_format = opt->format;
>>
>> if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
>> die(_("remote-object-info command too long"));
>> - /*
>> - * TODO: Use the default format once %(objecttype) is supported.
>> - */
>> - if (!opt->format)
>> - opt->format = "%(objectname) %(objectsize)";
>>
>> line_to_split = xstrdup(line);
>> count = split_cmdline(line_to_split, &argv);
>> @@ -904,7 +898,6 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
>> data->is_remote = 0;
>> }
>> data->skip_object_info = 0;
>> - opt->format = saved_format;
>>
>> for (size_t i = 0; i < object_info_oids.nr; i++)
>> free_object_info_contents(&remote_object_info[i]);
>> diff --git a/t/t1017-cat-file-remote-object-info.sh b/t/t1017-cat-file-remote-object-info.sh
>> index 175f778cc9..741bdf34a0 100755
>> --- a/t/t1017-cat-file-remote-object-info.sh
>> +++ b/t/t1017-cat-file-remote-object-info.sh
>> @@ -139,10 +139,10 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
>> set_transport_variables "$daemon_parent" &&
>> cd "$daemon_parent/daemon_client_empty" &&
>>
>> - echo "$hello_oid $hello_size" >expect &&
>> - echo "$tree_oid $tree_size" >>expect &&
>> - echo "$commit_oid $commit_size" >>expect &&
>> - echo "$tag_oid $tag_size" >>expect &&
>> + echo "$hello_oid $hello_type $hello_size" >expect &&
>> + echo "$tree_oid $tree_type $tree_size" >>expect &&
>> + echo "$commit_oid $commit_type $commit_size" >>expect &&
>> + echo "$tag_oid $tag_type $tag_size" >>expect &&
>>
>> git cat-file --batch-command >actual <<-EOF &&
>> remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid $tree_oid
>> @@ -152,28 +152,6 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
>> )
>> '
>>
>> -test_expect_success 'remote-object-info does not change the default format of info' '
>> - (
>> - set_transport_variables "$daemon_parent" &&
>> - cd "$daemon_parent/daemon_client_empty" &&
>> -
>> - local_content="local object" &&
>> - local_oid=$(echo_without_newline "$local_content" | git hash-object -w --stdin) &&
>> - local_size=$(strlen "$local_content") &&
>> -
>> - echo "$local_oid blob $local_size" >expect &&
>> - echo "$hello_oid $hello_size" >>expect &&
>> - echo "$local_oid blob $local_size" >>expect &&
>> -
>> - git cat-file --batch-command >actual <<-EOF &&
>> - info $local_oid
>> - remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
>> - info $local_oid
>> - EOF
>> - test_cmp expect actual
>> - )
>> -'
>> -
>
> I feel like deleting this test removes the only test in this file that validates
> calling info and remote-object-info in the same cat-file --batch-command
> session.
>
> Instead of deleting it, we should update it. Perhaps something like this:
>
> test "remote-object-info and info can be mixed using the unified
> default format":
> // 1. Environment setup
> // 2. Prepare a local object for the 'info' command
> // 3. Construct the expected output. Since the default format is
> now unified,
> // both commands should output exactly: <OID> <TYPE> <SIZE>
> // 4. Execute the batch command
> // 5. Validate
This test was because we were modifying the default format whenever
remote-object-info was used. The workaround to have them work together
was to store the previous format, save the format as the capped one for
remote-object-info and at the end restore it.
Now that it has been unified for both it is implicit that they can work
together. However, no harm in having a test explicitly proving it. I will
make what you suggest.
Thanks for the feedback,
Pablo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype)
2026-07-29 9:52 ` [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Chandra Pratap
@ 2026-07-29 12:34 ` Pablo Sabater
0 siblings, 0 replies; 19+ messages in thread
From: Pablo Sabater @ 2026-07-29 12:34 UTC (permalink / raw)
To: Chandra Pratap, Pablo Sabater; +Cc: git, karthik.188, gitster
On Wed Jul 29, 2026 at 11:52 AM CEST, Chandra Pratap wrote:
> On Sat, 25 Jul 2026 at 17:25, Pablo Sabater <pabloosabaterr@gmail.com> wrote:
>>
>> "%(objecttype)" is already known by the client's allow-list, but neither
>> the client nor the server knows how to handle type. This series continues
>> the work for git cat-file --batch-command extending remote-object-info
>> to support "%(objecttype)" end to end. It is based on its predecessor
>> series "cat-file: add remote-object-info to batch-command" [1].
>>
>> Type is the last property that is identical on the server and on the
>> client once fetched.
>>
>> Whether to support more metadata such as:
>>
>> - objectsize:disk
>> - deltabase
>> - objectmode (needs context)
>>
>> should be discussed, unlike size and type, the rest depend on how things
>> are packed on the server and on what the client already has, so they
>> cannot reliably match local once fetched. IMO they are not worth
>> supporting, I can't find a use case for them.
>
> Makes sense to me. The metadata you listed depends on the local packfile
> storage where the repository lives.
>
> `objectmode` depends on the tree pointing to the blob, so it wouldn't be
> accessible using the current infrastructure anyway.
Yup, sounds like this will be it (for now) for remote-object-info placeholders.
>
>> Adding new placeholders has become trivial.
>> To add a new placeholder, follow the steps in this series and add it to
>> the client's allow-list at 'builtin/cat-file.c'.
>>
>> Based-on: <20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com>
>>
>> Github CI: https://github.com/pabloosabaterr/git/actions/runs/30155586279
>>
>> [1]: https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/
>>
>> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
>> ---
>> Pablo Sabater (5):
>> protocol-caps: add type support to object-info
>> fetch-object-info: parse type from server response
>> fetch-object-info: request all supported options dynamically
>> serve: advertise type capability
>> cat-file: unify default format
>
> The current incremental approach is safe and ensures every commit
> compiles and passes tests. However, from a storytelling perspective for
> the reviewers, I believe it's better to do any 'preparatory refactoring' before
> starting the new feature.
>
> Patch 3 (dynamically requesting supported options) doesn't actually depend
> on type existing yet. I suggest bumping Patch 3 to be Patch 1 in V2.
> That way, the client is already dynamic and ready, and the feature patches
> can strictly focus on adding type:
True, I'll move patch 3 to be the first, thanks for noticing.
>
> - fetch-object-info: request all supported options dynamically (Current Patch 3)
> - protocol-caps: add type support to object-info (Current Patch 1)
> - fetch-object-info: parse type from server response (Current Patch 2)
> - serve: advertise type capability (Current Patch 4)
> - cat-file: unify default format (Current Patch 5)
>
>> Documentation/git-cat-file.adoc | 17 +++-----
>> Documentation/gitprotocol-v2.adoc | 15 +++++--
>> builtin/cat-file.c | 7 ---
>> fetch-object-info.c | 23 +++++++---
>> protocol-caps.c | 21 +++++++--
>> serve.c | 4 +-
>> t/t1017-cat-file-remote-object-info.sh | 80 +++++++++++++---------------------
>> t/t5701-git-serve.sh | 27 ++++++++++++
>> 8 files changed, 113 insertions(+), 81 deletions(-)
>
> This series is definitely a lot smaller than I thought it would be. Looks like
> most of the heavy lifting was already done with the previous series.
Yes I also got surprised by how little I had to do in order to make this
series happen (I expected a lot more) but it turned out to be very brief.
>
> Good for us!
Yay! :)
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH GSoC 1/5] protocol-caps: add type support to object-info
2026-07-29 9:53 ` Chandra Pratap
2026-07-29 11:18 ` Pablo Sabater
@ 2026-07-29 15:40 ` Junio C Hamano
1 sibling, 0 replies; 19+ messages in thread
From: Junio C Hamano @ 2026-07-29 15:40 UTC (permalink / raw)
To: Chandra Pratap; +Cc: Pablo Sabater, git, karthik.188
Chandra Pratap <chandrapratap3519@gmail.com> writes:
>> if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
>> packet_writer_error(
>> writer,
>> - "object-info: protocol error, expected to get oid, not '%s'",
>> + "object-info: protocol error, expected to get "
>> + "oid, not '%s'",
>
> I assume this is a style change? The original line doesn't seem
> long enough to wrap though.
A 92-column line is much wider than our usual ~70 column limit.
> Also, this would break the grep-ability of this error string.
I've heard this a few times, but so what? You can still grep for
"object-info: protocol error," and will find it just fine.
>> + cat >expect <<-EOF &&
>> + size
>> + type
>> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
>> + $(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
>
> Can we not use the `test_file_size` tool to do this instead?
> That should also be much more portable.
Well spotted.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-07-29 15:40 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-25 11:55 [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 1/5] protocol-caps: add type support to object-info Pablo Sabater
2026-07-29 9:53 ` Chandra Pratap
2026-07-29 11:18 ` Pablo Sabater
2026-07-29 15:40 ` Junio C Hamano
2026-07-25 11:55 ` [PATCH GSoC 2/5] fetch-object-info: parse type from server response Pablo Sabater
2026-07-29 9:57 ` Chandra Pratap
2026-07-29 12:05 ` Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 3/5] fetch-object-info: request all supported options dynamically Pablo Sabater
2026-07-29 9:57 ` Chandra Pratap
2026-07-29 12:07 ` Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 4/5] serve: advertise type capability Pablo Sabater
2026-07-29 9:58 ` Chandra Pratap
2026-07-29 12:15 ` Pablo Sabater
2026-07-25 11:55 ` [PATCH GSoC 5/5] cat-file: unify default format Pablo Sabater
2026-07-29 9:59 ` Chandra Pratap
2026-07-29 12:23 ` Pablo Sabater
2026-07-29 9:52 ` [PATCH GSoC 0/5] cat-file: extend remote-object-info to support %(objecttype) Chandra Pratap
2026-07-29 12:34 ` Pablo Sabater
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.