Thread (361 messages) 361 messages, 13 authors, 1d ago

Re: [PATCH v8 5/6] transport: add client support for object-info

From: Peijian Ju <hidden>
Date: 2025-01-08 15:55:50

On Tue, Jan 7, 2025 at 1:31 PM Calvin Wan [off-list ref] wrote:
Thanks for picking up this series btw!

On Mon, Dec 23, 2024 at 3:25 PM Eric Ju [off-list ref] wrote:
quoted
From: Calvin Wan <redacted>

Sometimes, it is beneficial to retrieve information about an object
without downloading it entirely. The server-side logic for this
functionality was implemented in commit "a2ba162cda (object-info:
support for retrieving object info, 2021-04-20)."

This commit introduces client functions to interact with the server.

Currently, the client supports requesting a list of object IDs with
the ‘size’ feature from a v2 server. If the server does not advertise
this feature (i.e., transfer.advertiseobjectinfo is set to false),
the client will return an error and exit.

Helped-by: Jonathan Tan [off-list ref]
Helped-by: Christian Couder [off-list ref]
Signed-off-by: Calvin Wan <redacted>
Signed-off-by: Eric Ju  <redacted>
---
 Makefile            |  1 +
 fetch-object-info.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
 fetch-object-info.h | 18 +++++++++
 fetch-pack.c        |  3 ++
 fetch-pack.h        |  2 +
 transport-helper.c  | 11 +++++-
 transport.c         | 28 +++++++++++++-
 transport.h         | 11 ++++++
 8 files changed, 163 insertions(+), 3 deletions(-)
 create mode 100644 fetch-object-info.c
 create mode 100644 fetch-object-info.h
diff --git a/Makefile b/Makefile
index 3fa4bf0d06..70e9ec0464 100644
--- a/Makefile
+++ b/Makefile
@@ -1020,6 +1020,7 @@ LIB_OBJS += ewah/ewah_rlw.o
 LIB_OBJS += exec-cmd.o
 LIB_OBJS += fetch-negotiator.o
 LIB_OBJS += fetch-pack.o
+LIB_OBJS += fetch-object-info.o
 LIB_OBJS += fmt-merge-msg.o
 LIB_OBJS += fsck.o
 LIB_OBJS += fsmonitor.o
diff --git a/fetch-object-info.c b/fetch-object-info.c
new file mode 100644
index 0000000000..2aa9f2b70d
--- /dev/null
+++ b/fetch-object-info.c
@@ -0,0 +1,92 @@
+#include "git-compat-util.h"
+#include "gettext.h"
+#include "hex.h"
+#include "pkt-line.h"
+#include "connect.h"
+#include "oid-array.h"
+#include "object-store-ll.h"
+#include "fetch-object-info.h"
+#include "string-list.h"
+
+/**
+ * send_object_info_request sends git-cat-file object-info command and its
+ * arguments into the request buffer.
+ */
+static void send_object_info_request(const int fd_out, struct object_info_args *args)
+{
+       struct strbuf req_buf = STRBUF_INIT;
+
+       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");
+
+       if (args->oids) {
+               for (size_t i = 0; i < args->oids->nr; i++)
+                       packet_buf_write(&req_buf, "oid %s", oid_to_hex(&args->oids->oid[i]));
+       }
+
+       packet_buf_flush(&req_buf);
+       if (write_in_full(fd_out, req_buf.buf, req_buf.len) < 0)
+               die_errno(_("unable to write request to remote"));
+
+       strbuf_release(&req_buf);
+}
+
+/**
+ * fetch_object_info sends git-cat-file object-info command into the request buf
+ * and read the results from packets.
+ */
+int fetch_object_info(const enum protocol_version version, struct object_info_args *args,
+                     struct packet_reader *reader, struct object_info *object_info_data,
+                     const int stateless_rpc, const int fd_out)
+{
+       int size_index = -1;
+
+       switch (version) {
+       case protocol_v2:
+               if (!server_supports_v2("object-info"))
+                       die(_("object-info capability is not enabled on the server"));
+               send_object_info_request(fd_out, args);
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               die(_("wrong protocol version. expected v2"));
s/wrong/unsupported
Thank you. Fixing it in v9.
quoted
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
+
+       for (size_t i = 0; i < args->object_info_options->nr; i++) {
+               if (packet_reader_read(reader) != PACKET_READ_NORMAL) {
+                       check_stateless_delimiter(stateless_rpc, reader, "stateless delimiter expected");
+                       return -1;
+               }
+               if (unsorted_string_list_has_string(args->object_info_options, reader->line)) {
+                       if (!strcmp(reader->line, "size")) {
+                               size_index = i;
+                               for (size_t j = 0; j < args->oids->nr; j++)
+                                       object_info_data[j].sizep = xcalloc(1, sizeof(long));
+                       }
+                       continue;
+               }
+               return -1;
+       }
I think we can flatten this logic a bit more here to make it more intuitive.

if (!unsorted_string_list_has_string(args->object_info_options, reader->line))
        return -1;
if (!strcmp(reader->line, "size")) {
        size_index = i;
        for (size_t j = 0; j < args->oids->nr; j++)
                object_info_data[j].sizep = xcalloc(1, sizeof(long));
}
Thank you. Revising it in v9.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help