diff --git a/builtin/cat-file.c b/builtin/cat-file.c index d6a1aa74cd..272f9fc6d7 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -262,7 +262,7 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len, strbuf_addstr(sb, data->rest); } else if (is_atom("deltabase", atom, len)) { if (data->mark_query) - data->info.delta_base_sha1 = data->delta_base_oid.hash; + data->info.delta_base_oid = &data->delta_base_oid; else strbuf_addstr(sb, oid_to_hex(&data->delta_base_oid)); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 89e7ba44c9..02aa6ee480 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -872,14 +872,15 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out, /* Convert to REF_DELTA if we must... */ if (!allow_ofs_delta) { int base_pos = find_revindex_position(reuse_packfile, base_offset); - const unsigned char *base_sha1 = - nth_packed_object_sha1(reuse_packfile, - reuse_packfile->revindex[base_pos].nr); + struct object_id base_oid; + + nth_packed_object_id(&base_oid, reuse_packfile, + reuse_packfile->revindex[base_pos].nr); len = encode_in_pack_object_header(header, sizeof(header), OBJ_REF_DELTA, size); hashwrite(out, header, len); - hashwrite(out, base_sha1, 20); + hashwrite(out, base_oid.hash, 20); copy_pack_data(out, reuse_packfile, w_curs, cur, next - cur); return; } @@ -1618,23 +1619,17 @@ static void cleanup_preferred_base(void) * deltify other objects against, in order to avoid * circular deltas. */ -static int can_reuse_delta(const unsigned char *base_sha1, +static int can_reuse_delta(const struct object_id *base_oid, struct object_entry *delta, struct object_entry **base_out) { struct object_entry *base; - struct object_id base_oid; - - if (!base_sha1) - return 0; - - oidread(&base_oid, base_sha1); /* * First see if we're already sending the base (or it's explicitly in * our "excluded" list). */ - base = packlist_find(&to_pack, &base_oid); + base = packlist_find(&to_pack, base_oid); if (base) { if (!in_same_island(&delta->idx.oid, &base->idx.oid)) return 0; @@ -1647,9 +1642,9 @@ static int can_reuse_delta(const unsigned char *base_sha1, * even if it was buried too deep in history to make it into the * packing list. */ - if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, &base_oid)) { + if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) { if (use_delta_islands) { - if (!in_same_island(&delta->idx.oid, &base_oid)) + if (!in_same_island(&delta->idx.oid, base_oid)) return 0; } *base_out = NULL; @@ -1666,7 +1661,8 @@ static void check_object(struct object_entry *entry) if (IN_PACK(entry)) { struct packed_git *p = IN_PACK(entry); struct pack_window *w_curs = NULL; - const unsigned char *base_ref = NULL; + int have_base = 0; + struct object_id base_ref; struct object_entry *base_entry; unsigned long used, used_0; unsigned long avail; @@ -1707,9 +1703,13 @@ static void check_object(struct object_entry *entry) unuse_pack(&w_curs); return; case OBJ_REF_DELTA: - if (reuse_delta && !entry->preferred_base) - base_ref = use_pack(p, &w_curs, - entry->in_pack_offset + used, NULL); + if (reuse_delta && !entry->preferred_base) { + oidread(&base_ref, + use_pack(p, &w_curs, + entry->in_pack_offset + used, + NULL)); + have_base = 1; + } entry->in_pack_header_size = used + the_hash_algo->rawsz; break; case OBJ_OFS_DELTA: @@ -1739,13 +1739,15 @@ static void check_object(struct object_entry *entry) revidx = find_pack_revindex(p, ofs); if (!revidx) goto give_up; - base_ref = nth_packed_object_sha1(p, revidx->nr); + if (!nth_packed_object_id(&base_ref, p, revidx->nr)) + have_base = 1; } entry->in_pack_header_size = used + used_0; break; } - if (can_reuse_delta(base_ref, entry, &base_entry)) { + if (have_base && + can_reuse_delta(&base_ref, entry, &base_entry)) { oe_set_type(entry, entry->in_pack_type); SET_SIZE(entry, in_pack_size); /* delta size */ SET_DELTA_SIZE(entry, in_pack_size); @@ -1755,7 +1757,7 @@ static void check_object(struct object_entry *entry) entry->delta_sibling_idx = base_entry->delta_child_idx; SET_DELTA_CHILD(base_entry, entry); } else { - SET_DELTA_EXT(entry, base_ref); + SET_DELTA_EXT(entry, &base_ref); } unuse_pack(&w_curs); @@ -3053,7 +3055,7 @@ static void add_objects_in_unpacked_packs(void) in_pack.alloc); for (i = 0; i < p->num_objects; i++) { - nth_packed_object_oid(&oid, p, i); + nth_packed_object_id(&oid, p, i); o = lookup_unknown_object(&oid); if (!(o->flags & OBJECT_ADDED)) mark_in_pack_object(o, p, &in_pack); @@ -3157,7 +3159,7 @@ static void loosen_unused_packed_objects(void) die(_("cannot open pack index")); for (i = 0; i < p->num_objects; i++) { - nth_packed_object_oid(&oid, p, i); + nth_packed_object_id(&oid, p, i); if (!packlist_find(&to_pack, &oid) && !has_sha1_pack_kept_or_nonlocal(&oid) && !loosened_object_can_be_discarded(&oid, p->mtime)) diff --git a/midx.c b/midx.c index 37ec28623a..1527e464a7 100644 --- a/midx.c +++ b/midx.c @@ -534,7 +534,7 @@ static void fill_pack_entry(uint32_t pack_int_id, uint32_t cur_object, struct pack_midx_entry *entry) { - if (!nth_packed_object_oid(&entry->oid, p, cur_object)) + if (nth_packed_object_id(&entry->oid, p, cur_object) < 0) die(_("failed to locate object %d in packfile"), cur_object); entry->pack_int_id = pack_int_id; diff --git a/object-store.h b/object-store.h index 5b047637e3..be72fee7d5 100644 --- a/object-store.h +++ b/object-store.h @@ -300,7 +300,7 @@ struct object_info { enum object_type *typep; unsigned long *sizep; off_t *disk_sizep; - unsigned char *delta_base_sha1; + struct object_id *delta_base_oid; struct strbuf *type_name; void **contentp; diff --git a/pack-bitmap.c b/pack-bitmap.c index 82bfd6672a..49a8d10d0c 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -170,7 +170,7 @@ static int load_bitmap_header(struct bitmap_index *index) static struct stored_bitmap *store_bitmap(struct bitmap_index *index, struct ewah_bitmap *root, - const unsigned char *hash, + const struct object_id *oid, struct stored_bitmap *xor_with, int flags) { @@ -182,7 +182,7 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index, stored->root = root; stored->xor = xor_with; stored->flags = flags; - oidread(&stored->oid, hash); + oidcpy(&stored->oid, oid); hash_pos = kh_put_oid_map(index->bitmaps, stored->oid, &ret); @@ -190,7 +190,7 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index, * because the SHA1 already existed on the map. this is bad, there * shouldn't be duplicated commits in the index */ if (ret == 0) { - error("Duplicate entry in bitmap index: %s", hash_to_hex(hash)); + error("Duplicate entry in bitmap index: %s", oid_to_hex(oid)); return NULL; } @@ -222,13 +222,13 @@ static int load_bitmap_entries_v1(struct bitmap_index *index) struct ewah_bitmap *bitmap = NULL; struct stored_bitmap *xor_bitmap = NULL; uint32_t commit_idx_pos; - const unsigned char *sha1; + struct object_id oid; commit_idx_pos = read_be32(index->map, &index->map_pos); xor_offset = read_u8(index->map, &index->map_pos); flags = read_u8(index->map, &index->map_pos); - sha1 = nth_packed_object_sha1(index->pack, commit_idx_pos); + nth_packed_object_id(&oid, index->pack, commit_idx_pos); bitmap = read_bitmap_1(index); if (!bitmap) @@ -245,7 +245,7 @@ static int load_bitmap_entries_v1(struct bitmap_index *index) } recent_bitmaps[i % MAX_XOR_OFFSET] = store_bitmap( - index, bitmap, sha1, xor_bitmap, flags); + index, bitmap, &oid, xor_bitmap, flags); } return 0; @@ -691,7 +691,7 @@ static void show_objects_for_type( offset += ewah_bit_ctz64(word >> offset); entry = &bitmap_git->pack->revindex[pos + offset]; - nth_packed_object_oid(&oid, bitmap_git->pack, entry->nr); + nth_packed_object_id(&oid, bitmap_git->pack, entry->nr); if (bitmap_git->hashes) hash = get_be32(bitmap_git->hashes + entry->nr); @@ -796,7 +796,7 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git, if (packed_object_info(the_repository, pack, entry->offset, &oi) < 0) { struct object_id oid; - nth_packed_object_oid(&oid, pack, entry->nr); + nth_packed_object_id(&oid, pack, entry->nr); die(_("unable to get size of %s"), oid_to_hex(&oid)); } } else { @@ -1342,7 +1342,7 @@ int rebuild_existing_bitmaps(struct bitmap_index *bitmap_git, struct object_entry *oe; entry = &bitmap_git->pack->revindex[i]; - nth_packed_object_oid(&oid, bitmap_git->pack, entry->nr); + nth_packed_object_id(&oid, bitmap_git->pack, entry->nr); oe = packlist_find(mapping, &oid); if (oe) diff --git a/pack-check.c b/pack-check.c index e4ef71c673..dad6d8ae7f 100644 --- a/pack-check.c +++ b/pack-check.c @@ -8,10 +8,6 @@ struct idx_entry { off_t offset; - union idx_entry_object { - const unsigned char *hash; - struct object_id *oid; - } oid; unsigned int nr; }; @@ -97,9 +93,6 @@ static int verify_packfile(struct repository *r, entries[nr_objects].offset = pack_sig_ofs; /* first sort entries by pack offset, since unpacking them is more efficient that way */ for (i = 0; i < nr_objects; i++) { - entries[i].oid.hash = nth_packed_object_sha1(p, i); - if (!entries[i].oid.hash) - die("internal error pack-check nth-packed-object"); entries[i].offset = nth_packed_object_offset(p, i); entries[i].nr = i; } @@ -107,11 +100,16 @@ static int verify_packfile(struct repository *r, for (i = 0; i < nr_objects; i++) { void *data; + struct object_id oid; enum object_type type; unsigned long size; off_t curpos; int data_valid; + if (nth_packed_object_id(&oid, p, entries[i].nr) < 0) + BUG("unable to get oid of object %lu from %s", + (unsigned long)entries[i].nr, p->pack_name); + if (p->index_version > 1) { off_t offset = entries[i].offset; off_t len = entries[i+1].offset - offset; @@ -119,7 +117,7 @@ static int verify_packfile(struct repository *r, if (check_pack_crc(p, w_curs, offset, len, nr)) err = error("index CRC mismatch for object %s " "from %s at offset %"PRIuMAX"", - oid_to_hex(entries[i].oid.oid), + oid_to_hex(&oid), p->pack_name, (uintmax_t)offset); } @@ -142,14 +140,14 @@ static int verify_packfile(struct repository *r, if (data_valid && !data) err = error("cannot unpack %s from %s at offset %"PRIuMAX"", - oid_to_hex(entries[i].oid.oid), p->pack_name, + oid_to_hex(&oid), p->pack_name, (uintmax_t)entries[i].offset); - else if (check_object_signature(r, entries[i].oid.oid, data, size, type_name(type))) + else if (check_object_signature(r, &oid, data, size, type_name(type))) err = error("packed %s from %s is corrupt", - oid_to_hex(entries[i].oid.oid), p->pack_name); + oid_to_hex(&oid), p->pack_name); else if (fn) { int eaten = 0; - err |= fn(entries[i].oid.oid, type, size, data, &eaten); + err |= fn(&oid, type, size, data, &eaten); if (eaten) data = NULL; } diff --git a/pack-objects.c b/pack-objects.c index 5e5a3c62d9..f2a433885a 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -203,14 +203,14 @@ struct object_entry *packlist_alloc(struct packing_data *pdata, void oe_set_delta_ext(struct packing_data *pdata, struct object_entry *delta, - const unsigned char *sha1) + const struct object_id *oid) { struct object_entry *base; ALLOC_GROW(pdata->ext_bases, pdata->nr_ext + 1, pdata->alloc_ext); base = &pdata->ext_bases[pdata->nr_ext++]; memset(base, 0, sizeof(*base)); - hashcpy(base->idx.oid.hash, sha1); + oidcpy(&base->idx.oid, oid); /* These flags mark that we are not part of the actual pack output. */ base->preferred_base = 1; diff --git a/pack-objects.h b/pack-objects.h index d3975e079b..9d88e3e518 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -292,7 +292,7 @@ static inline void oe_set_delta(struct packing_data *pack, void oe_set_delta_ext(struct packing_data *pack, struct object_entry *e, - const unsigned char *sha1); + const struct object_id *oid); static inline struct object_entry *oe_delta_child( const struct packing_data *pack, diff --git a/packfile.c b/packfile.c index 99dd1a7d09..f4e752996d 100644 --- a/packfile.c +++ b/packfile.c @@ -1225,30 +1225,32 @@ off_t get_delta_base(struct packed_git *p, * the final object lookup), but more expensive for OFS deltas (we * have to load the revidx to convert the offset back into a sha1). */ -static const unsigned char *get_delta_base_sha1(struct packed_git *p, - struct pack_window **w_curs, - off_t curpos, - enum object_type type, - off_t delta_obj_offset) +static int get_delta_base_oid(struct packed_git *p, + struct pack_window **w_curs, + off_t curpos, + struct object_id *oid, + enum object_type type, + off_t delta_obj_offset) { if (type == OBJ_REF_DELTA) { unsigned char *base = use_pack(p, w_curs, curpos, NULL); - return base; + oidread(oid, base); + return 0; } else if (type == OBJ_OFS_DELTA) { struct revindex_entry *revidx; off_t base_offset = get_delta_base(p, w_curs, &curpos, type, delta_obj_offset); if (!base_offset) - return NULL; + return -1; revidx = find_pack_revindex(p, base_offset); if (!revidx) - return NULL; + return -1; - return nth_packed_object_sha1(p, revidx->nr); + return nth_packed_object_id(oid, p, revidx->nr); } else - return NULL; + return -1; } static int retry_bad_packed_offset(struct repository *r, @@ -1261,7 +1263,7 @@ static int retry_bad_packed_offset(struct repository *r, revidx = find_pack_revindex(p, obj_offset); if (!revidx) return OBJ_BAD; - nth_packed_object_oid(&oid, p, revidx->nr); + nth_packed_object_id(&oid, p, revidx->nr); mark_bad_packed_object(p, oid.hash); type = oid_object_info(r, &oid, NULL); if (type <= OBJ_NONE) @@ -1556,20 +1558,16 @@ int packed_object_info(struct repository *r, struct packed_git *p, } } - if (oi->delta_base_sha1) { + if (oi->delta_base_oid) { if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { - const unsigned char *base; - - base = get_delta_base_sha1(p, &w_curs, curpos, - type, obj_offset); - if (!base) { + if (get_delta_base_oid(p, &w_curs, curpos, + oi->delta_base_oid, + type, obj_offset) < 0) { type = OBJ_BAD; goto out; } - - hashcpy(oi->delta_base_sha1, base); } else - hashclr(oi->delta_base_sha1); + oidclr(oi->delta_base_oid); } oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED : @@ -1693,7 +1691,7 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, off_t len = revidx[1].offset - obj_offset; if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { struct object_id oid; - nth_packed_object_oid(&oid, p, revidx->nr); + nth_packed_object_id(&oid, p, revidx->nr); error("bad packed object CRC for %s", oid_to_hex(&oid)); mark_bad_packed_object(p, oid.hash); @@ -1782,7 +1780,7 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, struct object_id base_oid; revidx = find_pack_revindex(p, obj_offset); if (revidx) { - nth_packed_object_oid(&base_oid, p, revidx->nr); + nth_packed_object_id(&base_oid, p, revidx->nr); error("failed to read delta base object %s" " at offset %"PRIuMAX" from %s", oid_to_hex(&base_oid), (uintmax_t)obj_offset, @@ -1869,36 +1867,27 @@ int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32 index_lookup, index_lookup_width, result); } -const unsigned char *nth_packed_object_sha1(struct packed_git *p, - uint32_t n) +int nth_packed_object_id(struct object_id *oid, + struct packed_git *p, + uint32_t n) { const unsigned char *index = p->index_data; const unsigned int hashsz = the_hash_algo->rawsz; if (!index) { if (open_pack_index(p)) - return NULL; + return -1; index = p->index_data; } if (n >= p->num_objects) - return NULL; + return -1; index += 4 * 256; if (p->index_version == 1) { - return index + (hashsz + 4) * n + 4; + oidread(oid, index + (hashsz + 4) * n + 4); } else { index += 8; - return index + hashsz * n; + oidread(oid, index + hashsz * n); } -} - -const struct object_id *nth_packed_object_oid(struct object_id *oid, - struct packed_git *p, - uint32_t n) -{ - const unsigned char *hash = nth_packed_object_sha1(p, n); - if (!hash) - return NULL; - hashcpy(oid->hash, hash); - return oid; + return 0; } void check_pack_index_ptr(const struct packed_git *p, const void *vptr) @@ -2077,7 +2066,7 @@ int for_each_object_in_pack(struct packed_git *p, else pos = i; - if (!nth_packed_object_oid(&oid, p, pos)) + if (nth_packed_object_id(&oid, p, pos) < 0) return error("unable to get sha1 of object %u in %s", pos, p->pack_name); diff --git a/packfile.h b/packfile.h index ec536a4ae5..240aa73b95 100644 --- a/packfile.h +++ b/packfile.h @@ -121,18 +121,11 @@ void check_pack_index_ptr(const struct packed_git *p, const void *ptr); int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result); /* - * Return the SHA-1 of the nth object within the specified packfile. - * Open the index if it is not already open. The return value points - * at the SHA-1 within the mmapped index. Return NULL if there is an - * error. + * Write the oid of the nth object within the specified packfile into the first + * parameter. Open the index if it is not already open. Returns 0 on success, + * negative otherwise. */ -const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t n); -/* - * Like nth_packed_object_sha1, but write the data into the object specified by - * the the first argument. Returns the first argument on success, and NULL on - * error. - */ -const struct object_id *nth_packed_object_oid(struct object_id *, struct packed_git *, uint32_t n); +int nth_packed_object_id(struct object_id *, struct packed_git *, uint32_t n); /* * Return the offset of the nth object within the specified packfile. diff --git a/ref-filter.c b/ref-filter.c index 6867e33648..79bb520678 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -279,9 +279,9 @@ static int deltabase_atom_parser(const struct ref_format *format, struct used_at if (arg) return strbuf_addf_ret(err, -1, _("%%(deltabase) does not take arguments")); if (*atom->name == '*') - oi_deref.info.delta_base_sha1 = oi_deref.delta_base_oid.hash; + oi_deref.info.delta_base_oid = &oi_deref.delta_base_oid; else - oi.info.delta_base_sha1 = oi.delta_base_oid.hash; + oi.info.delta_base_oid = &oi.delta_base_oid; return 0; } diff --git a/sha1-file.c b/sha1-file.c index d785de8a85..616886799e 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -1354,8 +1354,8 @@ static int loose_object_info(struct repository *r, struct strbuf hdrbuf = STRBUF_INIT; unsigned long size_scratch; - if (oi->delta_base_sha1) - hashclr(oi->delta_base_sha1); + if (oi->delta_base_oid) + oidclr(oi->delta_base_oid); /* * If we don't care about type or size, then we don't @@ -1474,8 +1474,8 @@ static int do_oid_object_info_extended(struct repository *r, *(oi->sizep) = co->size; if (oi->disk_sizep) *(oi->disk_sizep) = 0; - if (oi->delta_base_sha1) - hashclr(oi->delta_base_sha1); + if (oi->delta_base_oid) + oidclr(oi->delta_base_oid); if (oi->type_name) strbuf_addstr(oi->type_name, type_name(co->type)); if (oi->contentp) diff --git a/sha1-name.c b/sha1-name.c index f2e24ea666..5bb006e5a9 100644 --- a/sha1-name.c +++ b/sha1-name.c @@ -155,7 +155,6 @@ static void unique_in_pack(struct packed_git *p, struct disambiguate_state *ds) { uint32_t num, i, first = 0; - const struct object_id *current = NULL; if (p->multi_pack_index) return; @@ -173,10 +172,10 @@ static void unique_in_pack(struct packed_git *p, */ for (i = first; i < num && !ds->ambiguous; i++) { struct object_id oid; - current = nth_packed_object_oid(&oid, p, i); - if (!match_sha(ds->len, ds->bin_pfx.hash, current->hash)) + nth_packed_object_id(&oid, p, i); + if (!match_sha(ds->len, ds->bin_pfx.hash, oid.hash)) break; - update_candidates(ds, current); + update_candidates(ds, &oid); } } @@ -643,14 +642,14 @@ static void find_abbrev_len_for_pack(struct packed_git *p, */ mad->init_len = 0; if (!match) { - if (nth_packed_object_oid(&oid, p, first)) + if (!nth_packed_object_id(&oid, p, first)) extend_abbrev_len(&oid, mad); } else if (first < num - 1) { - if (nth_packed_object_oid(&oid, p, first + 1)) + if (!nth_packed_object_id(&oid, p, first + 1)) extend_abbrev_len(&oid, mad); } if (first > 0) { - if (nth_packed_object_oid(&oid, p, first - 1)) + if (!nth_packed_object_id(&oid, p, first - 1)) extend_abbrev_len(&oid, mad); } mad->init_len = mad->cur_len;