aboutsummaryrefslogtreecommitdiff
path: root/packfile.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-01-15 05:47:47 -0800
committerJunio C Hamano <gitster@pobox.com>2026-01-15 05:47:47 -0800
commitc8e1706e8dbe7a511c1fd85d5147a1722b4080f1 (patch)
treedcab6ef9ff4e3e9359454a6b1c04e7dc59d87317 /packfile.c
parent8745eae506f700657882b9e32b2aa00f234a6fb6 (diff)
parent12d3b58b5552750f351ded7166b347446d9543f3 (diff)
downloadgit-c8e1706e8dbe7a511c1fd85d5147a1722b4080f1.tar.xz
Merge branch 'ps/read-object-info-improvements' into ps/odb-for-each-object
* ps/read-object-info-improvements: packfile: drop repository parameter from `packed_object_info()` packfile: skip unpacking object header for disk size requests packfile: disentangle return value of `packed_object_info()` packfile: always populate pack-specific info when reading object info packfile: extend `is_delta` field to allow for "unknown" state packfile: always declare object info to be OI_PACKED object-file: always set OI_LOOSE when reading object info
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/packfile.c b/packfile.c
index 23a7f8a191..79cea97f35 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1580,24 +1580,25 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
hashmap_add(&delta_base_cache, &ent->ent);
}
-int packed_object_info(struct repository *r, struct packed_git *p,
+int packed_object_info(struct packed_git *p,
off_t obj_offset, struct object_info *oi)
{
struct pack_window *w_curs = NULL;
unsigned long size;
off_t curpos = obj_offset;
- enum object_type type;
+ enum object_type type = OBJ_NONE;
+ int ret;
/*
* We always get the representation type, but only convert it to
* a "real" type later if the caller is interested.
*/
if (oi->contentp) {
- *oi->contentp = cache_or_unpack_entry(r, p, obj_offset, oi->sizep,
+ *oi->contentp = cache_or_unpack_entry(p->repo, p, obj_offset, oi->sizep,
&type);
if (!*oi->contentp)
type = OBJ_BAD;
- } else {
+ } else if (oi->sizep || oi->typep || oi->delta_base_oid) {
type = unpack_object_header(p, &w_curs, &curpos, &size);
}
@@ -1607,12 +1608,12 @@ int packed_object_info(struct repository *r, struct packed_git *p,
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
type, obj_offset);
if (!base_offset) {
- type = OBJ_BAD;
+ ret = -1;
goto out;
}
*oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
if (*oi->sizep == 0) {
- type = OBJ_BAD;
+ ret = -1;
goto out;
}
} else {
@@ -1625,7 +1626,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
if (offset_to_pack_pos(p, obj_offset, &pos) < 0) {
error("could not find object at offset %"PRIuMAX" "
"in pack %s", (uintmax_t)obj_offset, p->pack_name);
- type = OBJ_BAD;
+ ret = -1;
goto out;
}
@@ -1634,12 +1635,12 @@ int packed_object_info(struct repository *r, struct packed_git *p,
if (oi->typep) {
enum object_type ptot;
- ptot = packed_to_object_type(r, p, obj_offset,
+ ptot = packed_to_object_type(p->repo, p, obj_offset,
type, &w_curs, curpos);
if (oi->typep)
*oi->typep = ptot;
if (ptot < 0) {
- type = OBJ_BAD;
+ ret = -1;
goto out;
}
}
@@ -1649,19 +1650,37 @@ int packed_object_info(struct repository *r, struct packed_git *p,
if (get_delta_base_oid(p, &w_curs, curpos,
oi->delta_base_oid,
type, obj_offset) < 0) {
- type = OBJ_BAD;
+ ret = -1;
goto out;
}
} else
oidclr(oi->delta_base_oid, p->repo->hash_algo);
}
- oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :
- OI_PACKED;
+ oi->whence = OI_PACKED;
+ oi->u.packed.offset = obj_offset;
+ oi->u.packed.pack = p;
+
+ switch (type) {
+ case OBJ_NONE:
+ oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
+ break;
+ 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;
+ }
+
+ ret = 0;
out:
unuse_pack(&w_curs);
- return type;
+ return ret;
}
static void *unpack_compressed_entry(struct packed_git *p,
@@ -2139,7 +2158,7 @@ int packfile_store_read_object_info(struct packfile_store *store,
unsigned flags UNUSED)
{
struct pack_entry e;
- int rtype;
+ int ret;
if (!find_pack_entry(store->odb->repo, oid, &e))
return 1;
@@ -2151,19 +2170,12 @@ int packfile_store_read_object_info(struct packfile_store *store,
if (!oi)
return 0;
- rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi);
- if (rtype < 0) {
+ ret = packed_object_info(e.p, e.offset, oi);
+ if (ret < 0) {
mark_bad_packed_object(e.p, oid);
return -1;
}
- 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);
- }
-
return 0;
}
@@ -2533,7 +2545,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;