]> git.ipfire.org Git - thirdparty/git.git/commitdiff
packfile: expose function to read object stream for an offset
authorPatrick Steinhardt <ps@pks.im>
Mon, 23 Feb 2026 16:00:08 +0000 (17:00 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 Feb 2026 21:19:00 +0000 (13:19 -0800)
The function `packfile_store_read_object_stream()` takes as input an
object ID and then constructs a `struct odb_read_stream` from it. In a
subsequent commit we'll want to create an object stream for a given
combination of packfile and offset though, which is not something that
can currently be done.

Extract a new function `packfile_read_object_stream()` that makes this
functionality available.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
packfile.c
packfile.h

index 402c3b5dc731318a8faed0dae320172958191558..3e61176128e548bd386eb0d9570fe9d74d998bcd 100644 (file)
@@ -2553,32 +2553,28 @@ static int close_istream_pack_non_delta(struct odb_read_stream *_st)
        return 0;
 }
 
-int packfile_store_read_object_stream(struct odb_read_stream **out,
-                                     struct packfile_store *store,
-                                     const struct object_id *oid)
+int packfile_read_object_stream(struct odb_read_stream **out,
+                               const struct object_id *oid,
+                               struct packed_git *pack,
+                               off_t offset)
 {
        struct odb_packed_read_stream *stream;
        struct pack_window *window = NULL;
-       struct object_info oi = OBJECT_INFO_INIT;
        enum object_type in_pack_type;
        unsigned long size;
 
-       oi.sizep = &size;
+       in_pack_type = unpack_object_header(pack, &window, &offset, &size);
+       unuse_pack(&window);
 
-       if (packfile_store_read_object_info(store, oid, &oi, 0) ||
-           oi.u.packed.type == PACKED_OBJECT_TYPE_REF_DELTA ||
-           oi.u.packed.type == PACKED_OBJECT_TYPE_OFS_DELTA ||
-           repo_settings_get_big_file_threshold(store->source->odb->repo) >= size)
+       if (repo_settings_get_big_file_threshold(pack->repo) >= size)
                return -1;
 
-       in_pack_type = unpack_object_header(oi.u.packed.pack,
-                                           &window,
-                                           &oi.u.packed.offset,
-                                           &size);
-       unuse_pack(&window);
        switch (in_pack_type) {
        default:
                return -1; /* we do not do deltas for now */
+       case OBJ_BAD:
+               mark_bad_packed_object(pack, oid);
+               return -1;
        case OBJ_COMMIT:
        case OBJ_TREE:
        case OBJ_BLOB:
@@ -2592,10 +2588,22 @@ int packfile_store_read_object_stream(struct odb_read_stream **out,
        stream->base.type = in_pack_type;
        stream->base.size = size;
        stream->z_state = ODB_PACKED_READ_STREAM_UNINITIALIZED;
-       stream->pack = oi.u.packed.pack;
-       stream->pos = oi.u.packed.offset;
+       stream->pack = pack;
+       stream->pos = offset;
 
        *out = &stream->base;
 
        return 0;
 }
+
+int packfile_store_read_object_stream(struct odb_read_stream **out,
+                                     struct packfile_store *store,
+                                     const struct object_id *oid)
+{
+       struct pack_entry e;
+
+       if (!find_pack_entry(store, oid, &e))
+               return -1;
+
+       return packfile_read_object_stream(out, oid, e.p, e.offset);
+}
index acc5c55ad57754eef058317a3a4254399d742f28..b9f5f1c18c1e5c30e21b3f530f805d8e33c82320 100644 (file)
@@ -436,6 +436,11 @@ off_t get_delta_base(struct packed_git *p, struct pack_window **w_curs,
                     off_t *curpos, enum object_type type,
                     off_t delta_obj_offset);
 
+int packfile_read_object_stream(struct odb_read_stream **out,
+                               const struct object_id *oid,
+                               struct packed_git *pack,
+                               off_t offset);
+
 void release_pack_memory(size_t);
 
 /* global flag to enable extra checks when accessing packed objects */