]> git.ipfire.org Git - thirdparty/git.git/commitdiff
streaming: propagate final object type via the stream
authorPatrick Steinhardt <ps@pks.im>
Sun, 23 Nov 2025 18:59:28 +0000 (19:59 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 23 Nov 2025 20:56:44 +0000 (12:56 -0800)
When opening the read stream for a specific object the caller is also
expected to pass in a pointer to the object type. This type is passed
down via multiple levels and will eventually be populated with the type
of the looked-up object.

The way we propagate down the pointer though is somewhat non-obvious.
While `istream_source()` still expects the pointer and looks it up via
`odb_read_object_info_extended()`, we also pass it down even further
into the format-specific callbacks that perform another lookup. This is
quite confusing overall.

Refactor the code so that the responsibility to populate the object type
rests solely with the format-specific callbacks. This will allow us to
drop the call to `odb_read_object_info_extended()` in `istream_source()`
entirely in a subsequent patch.

Furthermore, instead of propagating the type via an in-pointer, we now
propagate the type via a new field in the object stream. It already has
a `size` field, so it's only natural to have a second field that
contains the object type.

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

index 1bb3f393b875190b672da5fe57373ef44afa062b..665624ddc0494e1af2323ea877676cd3155a6d6e 100644 (file)
@@ -33,6 +33,7 @@ struct odb_read_stream {
        close_istream_fn close;
        read_istream_fn read;
 
+       enum object_type type;
        unsigned long size; /* inflated size of full object */
        git_zstream z;
        enum { z_unused, z_used, z_done, z_error } z_state;
@@ -159,6 +160,7 @@ static struct odb_read_stream *attach_stream_filter(struct odb_read_stream *st,
        fs->o_end = fs->o_ptr = 0;
        fs->input_finished = 0;
        ifs->size = -1; /* unknown */
+       ifs->type = st->type;
        return ifs;
 }
 
@@ -221,14 +223,13 @@ static int close_istream_loose(struct odb_read_stream *st)
 }
 
 static int open_istream_loose(struct odb_read_stream *st, struct repository *r,
-                             const struct object_id *oid,
-                             enum object_type *type)
+                             const struct object_id *oid)
 {
        struct object_info oi = OBJECT_INFO_INIT;
        struct odb_source *source;
 
        oi.sizep = &st->size;
-       oi.typep = type;
+       oi.typep = &st->type;
 
        odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
@@ -249,7 +250,7 @@ static int open_istream_loose(struct odb_read_stream *st, struct repository *r,
        case ULHR_TOO_LONG:
                goto error;
        }
-       if (parse_loose_header(st->u.loose.hdr, &oi) < 0 || *type < 0)
+       if (parse_loose_header(st->u.loose.hdr, &oi) < 0 || st->type < 0)
                goto error;
 
        st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
@@ -339,8 +340,7 @@ static int close_istream_pack_non_delta(struct odb_read_stream *st)
 
 static int open_istream_pack_non_delta(struct odb_read_stream *st,
                                       struct repository *r UNUSED,
-                                      const struct object_id *oid UNUSED,
-                                      enum object_type *type UNUSED)
+                                      const struct object_id *oid UNUSED)
 {
        struct pack_window *window;
        enum object_type in_pack_type;
@@ -361,6 +361,7 @@ static int open_istream_pack_non_delta(struct odb_read_stream *st,
        case OBJ_TAG:
                break;
        }
+       st->type = in_pack_type;
        st->z_state = z_unused;
        st->close = close_istream_pack_non_delta;
        st->read = read_istream_pack_non_delta;
@@ -396,7 +397,7 @@ static ssize_t read_istream_incore(struct odb_read_stream *st, char *buf, size_t
 }
 
 static int open_istream_incore(struct odb_read_stream *st, struct repository *r,
-                              const struct object_id *oid, enum object_type *type)
+                              const struct object_id *oid)
 {
        struct object_info oi = OBJECT_INFO_INIT;
 
@@ -404,7 +405,7 @@ static int open_istream_incore(struct odb_read_stream *st, struct repository *r,
        st->close = close_istream_incore;
        st->read = read_istream_incore;
 
-       oi.typep = type;
+       oi.typep = &st->type;
        oi.sizep = &st->size;
        oi.contentp = (void **)&st->u.incore.buf;
        return odb_read_object_info_extended(r->objects, oid, &oi,
@@ -417,14 +418,12 @@ static int open_istream_incore(struct odb_read_stream *st, struct repository *r,
 
 static int istream_source(struct odb_read_stream *st,
                          struct repository *r,
-                         const struct object_id *oid,
-                         enum object_type *type)
+                         const struct object_id *oid)
 {
        unsigned long size;
        int status;
        struct object_info oi = OBJECT_INFO_INIT;
 
-       oi.typep = type;
        oi.sizep = &size;
        status = odb_read_object_info_extended(r->objects, oid, &oi, 0);
        if (status < 0)
@@ -432,7 +431,7 @@ static int istream_source(struct odb_read_stream *st,
 
        switch (oi.whence) {
        case OI_LOOSE:
-               if (open_istream_loose(st, r, oid, type) < 0)
+               if (open_istream_loose(st, r, oid) < 0)
                        break;
                return 0;
        case OI_PACKED:
@@ -442,7 +441,7 @@ static int istream_source(struct odb_read_stream *st,
 
                st->u.in_pack.pack = oi.u.packed.pack;
                st->u.in_pack.pos = oi.u.packed.offset;
-               if (open_istream_pack_non_delta(st, r, oid, type) < 0)
+               if (open_istream_pack_non_delta(st, r, oid) < 0)
                        break;
 
                return 0;
@@ -450,7 +449,7 @@ static int istream_source(struct odb_read_stream *st,
                break;
        }
 
-       return open_istream_incore(st, r, oid, type);
+       return open_istream_incore(st, r, oid);
 }
 
 /****************************************************************
@@ -477,7 +476,7 @@ struct odb_read_stream *open_istream(struct repository *r,
 {
        struct odb_read_stream *st = xmalloc(sizeof(*st));
        const struct object_id *real = lookup_replace_object(r, oid);
-       int ret = istream_source(st, r, real, type);
+       int ret = istream_source(st, r, real);
 
        if (ret) {
                free(st);
@@ -495,6 +494,7 @@ struct odb_read_stream *open_istream(struct repository *r,
        }
 
        *size = st->size;
+       *type = st->type;
        return st;
 }