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>
This commit is contained in:
Patrick Steinhardt 2026-01-12 10:00:43 +01:00 committed by Junio C Hamano
parent 7a4bd1b836
commit 27d9486cbc
2 changed files with 20 additions and 4 deletions

7
odb.h
View File

@ -343,7 +343,12 @@ struct object_info {
struct {
struct packed_git *pack;
off_t offset;
unsigned int is_delta;
enum packed_object_type {
PACKED_OBJECT_TYPE_UNKNOWN,
PACKED_OBJECT_TYPE_FULL,
PACKED_OBJECT_TYPE_OFS_DELTA,
PACKED_OBJECT_TYPE_REF_DELTA,
} type;
} packed;
} u;
};

View File

@ -2159,8 +2159,18 @@ int packfile_store_read_object_info(struct packfile_store *store,
if (oi->whence == OI_PACKED) {
oi->u.packed.offset = e.offset;
oi->u.packed.pack = e.p;
oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
rtype == OBJ_OFS_DELTA);
switch (rtype) {
case OBJ_REF_DELTA:
oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
break;
case OBJ_OFS_DELTA:
oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
break;
default:
oi->u.packed.type = PACKED_OBJECT_TYPE_FULL;
break;
}
}
return 0;
@ -2531,7 +2541,8 @@ int packfile_store_read_object_stream(struct odb_read_stream **out,
oi.sizep = &size;
if (packfile_store_read_object_info(store, oid, &oi, 0) ||
oi.u.packed.is_delta ||
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->odb->repo) >= size)
return -1;