]> git.ipfire.org Git - thirdparty/git.git/blobdiff - midx.c
Merge branch 'tb/midx-no-bitmap-for-no-objects'
[thirdparty/git.git] / midx.c
diff --git a/midx.c b/midx.c
index 837b46b2af5fd766b981964ca27be427225b7591..865170bad05a04f15d051fc871529022467dc6f8 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -33,6 +33,7 @@
 #define MIDX_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
 #define MIDX_CHUNKID_OBJECTOFFSETS 0x4f4f4646 /* "OOFF" */
 #define MIDX_CHUNKID_LARGEOFFSETS 0x4c4f4646 /* "LOFF" */
+#define MIDX_CHUNKID_REVINDEX 0x52494458 /* "RIDX" */
 #define MIDX_CHUNK_FANOUT_SIZE (sizeof(uint32_t) * 256)
 #define MIDX_CHUNK_OFFSET_WIDTH (2 * sizeof(uint32_t))
 #define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t))
@@ -161,6 +162,9 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
 
        pair_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS, &m->chunk_large_offsets);
 
+       if (git_env_bool("GIT_TEST_MIDX_READ_RIDX", 1))
+               pair_chunk(cf, MIDX_CHUNKID_REVINDEX, &m->chunk_revindex);
+
        m->num_objects = ntohl(m->chunk_oid_fanout[255]);
 
        CALLOC_ARRAY(m->pack_names, m->num_packs);
@@ -833,6 +837,18 @@ static int write_midx_large_offsets(struct hashfile *f,
        return 0;
 }
 
+static int write_midx_revindex(struct hashfile *f,
+                              void *data)
+{
+       struct write_midx_context *ctx = data;
+       uint32_t i;
+
+       for (i = 0; i < ctx->entries_nr; i++)
+               hashwrite_be32(f, ctx->pack_order[i]);
+
+       return 0;
+}
+
 struct midx_pack_order_data {
        uint32_t nr;
        uint32_t pack;
@@ -1061,6 +1077,9 @@ static int write_midx_bitmap(char *midx_name, unsigned char *midx_hash,
        char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name, hash_to_hex(midx_hash));
        int ret;
 
+       if (!ctx->entries_nr)
+               BUG("cannot write a bitmap without any objects");
+
        if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
                options |= BITMAP_OPT_HASH_CACHE;
 
@@ -1385,6 +1404,12 @@ static int write_midx_internal(const char *object_dir,
                goto cleanup;
        }
 
+       if (!ctx.entries_nr) {
+               if (flags & MIDX_WRITE_BITMAP)
+                       warning(_("refusing to write multi-pack .bitmap without any objects"));
+               flags &= ~(MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP);
+       }
+
        cf = init_chunkfile(f);
 
        add_chunk(cf, MIDX_CHUNKID_PACKNAMES, pack_name_concat_len,
@@ -1403,16 +1428,21 @@ static int write_midx_internal(const char *object_dir,
                        (size_t)ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH,
                        write_midx_large_offsets);
 
+       if (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP)) {
+               ctx.pack_order = midx_pack_order(&ctx);
+               add_chunk(cf, MIDX_CHUNKID_REVINDEX,
+                         ctx.entries_nr * sizeof(uint32_t),
+                         write_midx_revindex);
+       }
+
        write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);
        write_chunkfile(cf, &ctx);
 
        finalize_hashfile(f, midx_hash, CSUM_FSYNC | CSUM_HASH_IN_STREAM);
        free_chunkfile(cf);
 
-       if (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP))
-               ctx.pack_order = midx_pack_order(&ctx);
-
-       if (flags & MIDX_WRITE_REV_INDEX)
+       if (flags & MIDX_WRITE_REV_INDEX &&
+           git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
                write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
        if (flags & MIDX_WRITE_BITMAP) {
                if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,