[PATCH RFC 3/5] fetch-object-info: return a status instead of dying
From: Pablo Sabater <hidden>
Date: 2026-09-30 00:21:59
Subsystem:
the rest · Maintainer:
Linus Torvalds
A subsequent commit needs fetch_object_info() not to die() when the object-info capability is not enabled on the server, so that it can fall back. Make fetch_object_info() return FETCH_OBJECT_INFO_NOT_ENABLED instead of die()'ing when the server does not advertise the object-info capability, and propagate the status through the transport layer so that callers of transport_fetch_object_info() can act on it. It is now up to them whether to die() or fall back. cat-file now dies by itself on FETCH_OBJECT_INFO_NOT_ENABLED, so its behavior is unchanged. Signed-off-by: Pablo Sabater <redacted> --- builtin/cat-file.c | 4 ++++ fetch-object-info.c | 17 +++++++++-------- fetch-object-info.h | 18 +++++++++++------- transport-helper.c | 6 +++--- transport-internal.h | 8 ++++---- transport.c | 29 +++++++++++++++-------------- transport.h | 7 ++++--- 7 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8870a210ec..f4758f2203 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c@@ -726,6 +726,10 @@ static int get_remote_info(int argc, retval = transport_fetch_object_info(gtransport, object_info_oids, results); + + if (retval == FETCH_OBJECT_INFO_NOT_ENABLED) + die(_("object-info capability is not enabled on the server")); + cleanup: transport_disconnect(gtransport); return retval;
diff --git a/fetch-object-info.c b/fetch-object-info.c
index 0a58308f9b..7e4c922d27 100644
--- a/fetch-object-info.c
+++ b/fetch-object-info.c@@ -52,13 +52,13 @@ static int parse_object_size(const char *s, size_t *res) return 0; } -void fetch_object_info(const enum protocol_version version, - const struct string_list *server_options, - const struct oid_array *oids, - struct packet_reader *reader, - struct fetch_object_info_results *results, - const int stateless_rpc, - const int fd_out) +enum fetch_object_info_status fetch_object_info(const enum protocol_version version, + const struct string_list *server_options, + const struct oid_array *oids, + struct packet_reader *reader, + struct fetch_object_info_results *results, + const int stateless_rpc, + const int fd_out) { unsigned ask_size = 0; unsigned ask_type = 0;
@@ -72,7 +72,7 @@ void fetch_object_info(const enum protocol_version version, switch (version) { case protocol_v2: if (!server_supports_v2("object-info")) - die(_("object-info capability is not enabled on the server")); + return FETCH_OBJECT_INFO_NOT_ENABLED; if (results->wants_size && server_supports_feature("object-info", "size", 0))
@@ -188,6 +188,7 @@ void fetch_object_info(const enum protocol_version version, (uintmax_t)oids->nr); check_stateless_delimiter(stateless_rpc, reader, "stateless delimiter expected"); + return FETCH_OBJECT_INFO_OK; } void free_fetch_object_info_results(struct fetch_object_info_results *results)
diff --git a/fetch-object-info.h b/fetch-object-info.h
index 663a7f3ae7..9d2750bc93 100644
--- a/fetch-object-info.h
+++ b/fetch-object-info.h@@ -32,14 +32,18 @@ struct oid_array; * the server both advertised and answered with. An array left NULL means the * attribute is not available. * Release them with free_fetch_object_info_results(). + * + * Returns FETCH_OBJECT_INFO_NOT_ENABLED if the server does not advertise the + * object-info capability, FETCH_OBJECT_INFO_OK otherwise. + * die()'s on any other error. */ -void fetch_object_info(enum protocol_version version, - const struct string_list *server_options, - const struct oid_array *oids, - struct packet_reader *reader, - struct fetch_object_info_results *results, - int stateless_rpc, - int fd_out); +enum fetch_object_info_status fetch_object_info(enum protocol_version version, + const struct string_list *server_options, + const struct oid_array *oids, + struct packet_reader *reader, + struct fetch_object_info_results *results, + int stateless_rpc, + int fd_out); void free_fetch_object_info_results(struct fetch_object_info_results *results);
diff --git a/transport-helper.c b/transport-helper.c
index d5a064d386..855b53da59 100644
--- a/transport-helper.c
+++ b/transport-helper.c@@ -786,9 +786,9 @@ static int fetch_refs(struct transport *transport, return -1; } -static int fetch_object_info_helper(struct transport *transport, - const struct oid_array *oids, - struct fetch_object_info_results *results) +static enum fetch_object_info_status fetch_object_info_helper(struct transport *transport, + const struct oid_array *oids, + struct fetch_object_info_results *results) { get_helper(transport); if (process_connect(transport, 0))
diff --git a/transport-internal.h b/transport-internal.h
index 626ceaae2b..067134081c 100644
--- a/transport-internal.h
+++ b/transport-internal.h@@ -2,13 +2,13 @@ #define TRANSPORT_INTERNAL_H #include "connect.h" +#include "fetch-object-info.h" struct ref; struct transport; struct strvec; struct transport_ls_refs_options; struct oid_array; -struct fetch_object_info_results; struct transport_vtable { /**
@@ -53,9 +53,9 @@ struct transport_vtable { * * Uses object-info capability of v2 protocol. */ - int (*fetch_object_info)(struct transport *transport, - const struct oid_array *oids, - struct fetch_object_info_results *results); + enum fetch_object_info_status (*fetch_object_info)(struct transport *transport, + const struct oid_array *oids, + struct fetch_object_info_results *results); /** * Push the objects and refs. Send the necessary objects, and
diff --git a/transport.c b/transport.c
index 25e2c14a7b..561764cb6a 100644
--- a/transport.c
+++ b/transport.c@@ -433,11 +433,11 @@ static int get_bundle_uri(struct transport *transport) transport->bundles, stateless_rpc); } -static int fetch_object_info_via_pack(struct transport *transport, - const struct oid_array *oids, - struct fetch_object_info_results *results) +static enum fetch_object_info_status fetch_object_info_via_pack(struct transport *transport, + const struct oid_array *oids, + struct fetch_object_info_results *results) { - int ret = 0; + enum fetch_object_info_status ret = FETCH_OBJECT_INFO_OK; struct git_transport_data *data = transport->data; struct packet_reader reader;
@@ -450,26 +450,27 @@ static int fetch_object_info_via_pack(struct transport *transport, data->version = discover_version(&reader); transport->hash_algo = reader.hash_algo; - fetch_object_info(data->version, - transport->server_options, - oids, - &reader, - results, - transport->stateless_rpc, data->fd[1]); + ret = fetch_object_info(data->version, + transport->server_options, + oids, + &reader, + results, + transport->stateless_rpc, + data->fd[1]); close(data->fd[0]); if (data->fd[1] >= 0) close(data->fd[1]); if (finish_connect(data->conn)) - ret = -1; + ret = FETCH_OBJECT_INFO_ERR; data->conn = NULL; return ret; } -int transport_fetch_object_info(struct transport *transport, - const struct oid_array *oids, - struct fetch_object_info_results *results) +enum fetch_object_info_status transport_fetch_object_info(struct transport *transport, + const struct oid_array *oids, + struct fetch_object_info_results *results) { if (!transport->vtable->fetch_object_info) die(_("remote does not support object-info"));
diff --git a/transport.h b/transport.h
index 39193d0077..c1671639d6 100644
--- a/transport.h
+++ b/transport.h@@ -1,6 +1,7 @@ #ifndef TRANSPORT_H #define TRANSPORT_H +#include "fetch-object-info.h" #include "run-command.h" #include "remote.h" #include "list-objects-filter-options.h"
@@ -314,9 +315,9 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs); /* * Fetch the object info from remote */ -int transport_fetch_object_info(struct transport *transport, - const struct oid_array *oids, - struct fetch_object_info_results *results); +enum fetch_object_info_status transport_fetch_object_info(struct transport *transport, + const struct oid_array *oids, + struct fetch_object_info_results *results); /* * If this flag is set, unlocking will avoid to call non-async-signal-safe
--
2.54.0