Thread (112 messages) flat view 112 messages, 5 authors, 3d ago
WARM3d

[PATCH GSoC v5 08/10] fetch-object-info: parse type from server response

From: Pablo Sabater <hidden>
Date: 2026-08-07 22:07:28
Subsystem: the rest · Maintainer: Linus Torvalds

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 type capability.

Mentored-by: Karthik Nayak [off-list ref]
Mentored-by: Chandra Pratap [off-list ref]
Signed-off-by: Pablo Sabater <redacted>
---
 builtin/cat-file.c  |  7 +++++++
 fetch-object-info.c | 38 +++++++++++++++++++++++++++++++++++---
 fetch-object-info.h |  3 +++
 3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8dcad2f5eb..8502020083 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -842,6 +842,8 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
 
 	if (data->info.sizep)
 		results.wants_size = 1;
+	if (data->info.typep)
+		results.wants_type = 1;
 
 	if (get_remote_info(count, argv, &results, &object_info_oids))
 		die(_("failed to get object info from the remote: %s"), argv[0]);
@@ -850,6 +852,8 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
 	string_list_append(&data->remote_allowed_atoms, "objectname");
 	if (results.sizes)
 		string_list_append(&data->remote_allowed_atoms, "objectsize");
+	if (results.types)
+		string_list_append(&data->remote_allowed_atoms, "objecttype");
 
 	data->skip_object_info = 1;
 	for (size_t i = 0; i < results.nr; i++) {
@@ -868,6 +872,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
 		if (results.sizes)
 			data->size = results.sizes[i];
 
+		if (results.types)
+			data->type = results.types[i];
+
 		opt->batch_mode = BATCH_MODE_INFO;
 		data->is_remote = 1;
 		batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
diff --git a/fetch-object-info.c b/fetch-object-info.c
index f269a5d8a8..ba0540853e 100644
--- a/fetch-object-info.c
+++ b/fetch-object-info.c
@@ -1,6 +1,7 @@
 #include "git-compat-util.h"
 #include "gettext.h"
 #include "hex.h"
+#include "object.h"
 #include "pkt-line.h"
 #include "connect.h"
 #include "oid-array.h"
@@ -12,7 +13,8 @@
 static void send_object_info_request(const int fd_out,
 				     const struct string_list *server_options,
 				     const struct oid_array *oids,
-				     unsigned ask_size)
+				     unsigned ask_size,
+				     unsigned ask_type)
 {
 	struct strbuf req_buf = STRBUF_INIT;
 
@@ -21,6 +23,9 @@ static void send_object_info_request(const int fd_out,
 	if (ask_size)
 		packet_buf_write(&req_buf, "size");
 
+	if (ask_type)
+		packet_buf_write(&req_buf, "type");
+
 	if (oids)
 		for (size_t i = 0; i < oids->nr; i++)
 			packet_buf_write(&req_buf, "oid %s",
@@ -56,7 +61,9 @@ void fetch_object_info(const enum protocol_version version,
 		       const int fd_out)
 {
 	unsigned ask_size = 0;
+	unsigned ask_type = 0;
 	int size_index = -1;
+	int type_index = -1;
 	size_t wanted;
 
 	results->nr = oids->nr;
@@ -71,11 +78,16 @@ void fetch_object_info(const enum protocol_version version,
 		    server_supports_feature("object-info", "size", 0))
 			ask_size = 1;
 
+		if (results->wants_type &&
+		    server_supports_feature("object-info", "type", 0))
+			ask_type = 1;
+
 		/*
 		 * Even if no options are left, we still send the oid so we get
 		 * at least an existence check.
 		 */
-		send_object_info_request(fd_out, server_options, oids, ask_size);
+		send_object_info_request(fd_out, server_options, oids, ask_size,
+					 ask_type);
 		break;
 	case protocol_v1:
 	case protocol_v0:
@@ -83,7 +95,7 @@ void fetch_object_info(const enum protocol_version version,
 	case protocol_unknown_version:
 		BUG("unknown protocol version");
 	}
-	wanted = ask_size;
+	wanted = ask_size + ask_type;
 
 	for (size_t i = 0; i < wanted; i++) {
 		if (packet_reader_read(reader) != PACKET_READ_NORMAL) {
@@ -100,6 +112,13 @@ void fetch_object_info(const enum protocol_version version,
 				die(_("object-info: duplicate 'size' attribute"));
 			size_index = (int)i;
 			CALLOC_ARRAY(results->sizes, results->nr);
+		} else if (!strcmp(reader->line, "type")) {
+			if (!ask_type)
+				die(_("object-info: unrequested 'type' attribute"));
+			if (results->types)
+				die(_("object-info: duplicate 'type' attribute"));
+			type_index = (int)i;
+			CALLOC_ARRAY(results->types, results->nr);
 		} else {
 			die(_("object-info: unknown attribute '%s'"),
 			    reader->line);
@@ -149,6 +168,18 @@ void fetch_object_info(const enum protocol_version version,
 			    object_info_values.items[0].string,
 			    object_info_values.items[size_index + 1].string);
 
+		if (results->types) {
+			const char *type_str =
+				object_info_values.items[type_index + 1].string;
+			int type = type_from_string_gently(type_str, -1, 1);
+
+			if (type < 0)
+				die(_("object-info: object %s has invalid type '%s'"),
+				    object_info_values.items[0].string, type_str);
+
+			results->types[i] = type;
+		}
+
 		string_list_clear(&object_info_values, 0);
 	}
 
@@ -162,6 +193,7 @@ void fetch_object_info(const enum protocol_version version,
 void free_fetch_object_info_results(struct fetch_object_info_results *results)
 {
 	free(results->sizes);
+	free(results->types);
 	free(results->unrecognized);
 	memset(results, 0, sizeof(*results));
 }
diff --git a/fetch-object-info.h b/fetch-object-info.h
index 10cf9f5f63..2fba96c6f7 100644
--- a/fetch-object-info.h
+++ b/fetch-object-info.h
@@ -1,14 +1,17 @@
 #ifndef FETCH_OBJECT_INFO_H
 #define FETCH_OBJECT_INFO_H
 
+#include "object.h"
 #include "pkt-line.h"
 #include "protocol.h"
 
 struct fetch_object_info_results {
 	size_t *sizes;
+	enum object_type *types;
 	uint8_t *unrecognized;
 	size_t nr;
 	unsigned wants_size:1;
+	unsigned wants_type:1;
 };
 
 #define FETCH_OBJECT_INFO_RESULTS_INIT { 0 }
-- 
2.54.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help