packfile: extend `is_delta` field to allow for "unknown" state

The `struct object_info::u::packed::is_delta` field determines whether or not a specific object is stored as a delta. It only stores whether or not the object is stored as delta, so it is treated as a boolean value. This boolean is insufficient though: when reading a packed object via `packfile_store_read_object_info()` we know to skip parsing the actual object when the user didn't request any object-specific data. In that case we won't read the object itself, but will only look up its position in the packfile. Consequently, we do not know whether it is a delta or not. This isn't really an issue right now, as the check for an empty request is broken. But a subsequent commit will fix it, and once we do we will have the need to also represent an "unknown" delta state. Prepare for this change by introducing a new enum that encodes the object type. We don't use the "unknown" state just yet, but will start to do so in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 12, 2026 at 10:00 UTC 27d9486cbc37a44565e4a97a84089c85741d4cd8
2 files changed +20 -4
odb.h
+6 -1
@@ -343,7 +343,12 @@ struct object_info {
343 struct {
344 struct packed_git *pack;
345 off_t offset;
346 - unsigned int is_delta;
346 + enum packed_object_type {
347 + PACKED_OBJECT_TYPE_UNKNOWN,
348 + PACKED_OBJECT_TYPE_FULL,
349 + PACKED_OBJECT_TYPE_OFS_DELTA,
350 + PACKED_OBJECT_TYPE_REF_DELTA,
351 + } type;
352 } packed;
353 } u;
354 };
packfile.c
+14 -3
@@ -2159,8 +2159,18 @@ int packfile_store_read_object_info(struct packfile_store *store,
2159 if (oi->whence == OI_PACKED) {
2160 oi->u.packed.offset = e.offset;
2161 oi->u.packed.pack = e.p;
2162 - oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
2163 - rtype == OBJ_OFS_DELTA);
2162 +
2163 + switch (rtype) {
2164 + case OBJ_REF_DELTA:
2165 + oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
2166 + break;
2167 + case OBJ_OFS_DELTA:
2168 + oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
2169 + break;
2170 + default:
2171 + oi->u.packed.type = PACKED_OBJECT_TYPE_FULL;
2172 + break;
2173 + }
2174 }
2175
2176 return 0;
@@ -2531,7 +2541,8 @@ int packfile_store_read_object_stream(struct odb_read_stream **out,
2541 oi.sizep = &size;
2542
2543 if (packfile_store_read_object_info(store, oid, &oi, 0) ||
2534 - oi.u.packed.is_delta ||
2544 + oi.u.packed.type == PACKED_OBJECT_TYPE_REF_DELTA ||
2545 + oi.u.packed.type == PACKED_OBJECT_TYPE_OFS_DELTA ||
2546 repo_settings_get_big_file_threshold(store->odb->repo) >= size)
2547 return -1;
2548