diff options
Diffstat (limited to 'packfile.c')
| -rw-r--r-- | packfile.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/packfile.c b/packfile.c index 3ffd6c7240..402c3b5dc7 100644 --- a/packfile.c +++ b/packfile.c @@ -1578,24 +1578,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); } @@ -1605,12 +1606,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 { @@ -1623,7 +1624,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; } @@ -1632,12 +1633,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; } } @@ -1647,19 +1648,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, @@ -2133,7 +2152,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, oid, &e)) return 1; @@ -2145,19 +2164,12 @@ int packfile_store_read_object_info(struct packfile_store *store, if (!oi) return 0; - rtype = packed_object_info(store->source->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; } @@ -2554,7 +2566,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->source->odb->repo) >= size) return -1; |
