packfile: close multi-pack-index in close_all_packs
[gitweb.git] / midx.c
diff --git a/midx.c b/midx.c
index 6824acf5f8937910edfc74ca0827cec1f4416cfb..1a6fa96cdaab5a61a0a93742bc11f553f4f564b9 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -180,9 +180,13 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
        return NULL;
 }
 
-static void close_midx(struct multi_pack_index *m)
+void close_midx(struct multi_pack_index *m)
 {
        uint32_t i;
+
+       if (!m)
+               return;
+
        munmap((unsigned char *)m->data, m->data_len);
        close(m->fd);
        m->fd = -1;
@@ -190,14 +194,14 @@ static void close_midx(struct multi_pack_index *m)
        for (i = 0; i < m->num_packs; i++) {
                if (m->packs[i]) {
                        close_pack(m->packs[i]);
-                       free(m->packs);
+                       free(m->packs[i]);
                }
        }
        FREE_AND_NULL(m->packs);
        FREE_AND_NULL(m->pack_names);
 }
 
-static int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
+int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
 {
        struct strbuf pack_name = STRBUF_INIT;
 
@@ -280,6 +284,16 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *
        if (!is_pack_valid(p))
                return 0;
 
+       if (p->num_bad_objects) {
+               uint32_t i;
+               struct object_id oid;
+               nth_midxed_object_oid(&oid, m, pos);
+               for (i = 0; i < p->num_bad_objects; i++)
+                       if (!hashcmp(oid.hash,
+                                    p->bad_object_sha1 + the_hash_algo->rawsz * i))
+                               return 0;
+       }
+
        e->offset = nth_midxed_offset(m, pos);
        e->p = p;
 
@@ -321,22 +335,28 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_name)
 
 int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local)
 {
-       struct multi_pack_index *m = r->objects->multi_pack_index;
+       struct multi_pack_index *m;
        struct multi_pack_index *m_search;
        int config_value;
+       static int env_value = -1;
+
+       if (env_value < 0)
+               env_value = git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0);
 
-       if (repo_config_get_bool(r, "core.multipackindex", &config_value) ||
-           !config_value)
+       if (!env_value &&
+           (repo_config_get_bool(r, "core.multipackindex", &config_value) ||
+           !config_value))
                return 0;
 
-       for (m_search = m; m_search; m_search = m_search->next)
+       for (m_search = r->objects->multi_pack_index; m_search; m_search = m_search->next)
                if (!strcmp(object_dir, m_search->object_dir))
                        return 1;
 
-       r->objects->multi_pack_index = load_multi_pack_index(object_dir, local);
+       m = load_multi_pack_index(object_dir, local);
 
-       if (r->objects->multi_pack_index) {
-               r->objects->multi_pack_index->next = m;
+       if (m) {
+               m->next = r->objects->multi_pack_index;
+               r->objects->multi_pack_index = m;
                return 1;
        }
 
@@ -906,9 +926,14 @@ int write_midx_file(const char *object_dir)
        return 0;
 }
 
-void clear_midx_file(const char *object_dir)
+void clear_midx_file(struct repository *r)
 {
-       char *midx = get_midx_filename(object_dir);
+       char *midx = get_midx_filename(r->objects->objectdir);
+
+       if (r->objects && r->objects->multi_pack_index) {
+               close_midx(r->objects->multi_pack_index);
+               r->objects->multi_pack_index = NULL;
+       }
 
        if (remove_path(midx)) {
                UNLEAK(midx);