]> git.ipfire.org Git - thirdparty/git.git/blobdiff - packfile.c
The 19th batch
[thirdparty/git.git] / packfile.c
index 79e21ab18e7844461c3743e45ebb7ccc1022caea..cf12a539eac720c17413cd6122b3ed408299c701 100644 (file)
@@ -1,4 +1,9 @@
-#include "cache.h"
+#define USE_THE_REPOSITORY_VARIABLE
+
+#include "git-compat-util.h"
+#include "environment.h"
+#include "gettext.h"
+#include "hex.h"
 #include "list.h"
 #include "pack.h"
 #include "repository.h"
 #include "mergesort.h"
 #include "packfile.h"
 #include "delta.h"
-#include "streaming.h"
 #include "hash-lookup.h"
 #include "commit.h"
 #include "object.h"
 #include "tag.h"
+#include "trace.h"
 #include "tree-walk.h"
 #include "tree.h"
-#include "object-store.h"
+#include "object-file.h"
+#include "object-store-ll.h"
 #include "midx.h"
 #include "commit-graph.h"
+#include "pack-revindex.h"
 #include "promisor-remote.h"
 
 char *odb_pack_name(struct strbuf *buf,
@@ -178,7 +185,7 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
                     */
                    (sizeof(off_t) <= 4))
                        return error("pack too large for current definition of off_t in %s", path);
-               p->crc_offset = 8 + 4 * 256 + nr * hashsz;
+               p->crc_offset = st_add(8 + 4 * 256, st_mult(nr, hashsz));
        }
 
        p->index_version = version;
@@ -237,7 +244,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
        struct packed_git *p = alloc_packed_git(alloc);
 
        memcpy(p->pack_name, path, alloc); /* includes NUL */
-       hashcpy(p->hash, sha1);
+       hashcpy(p->hash, sha1, the_repository->hash_algo);
        if (check_packed_git_idx(idx_path, p)) {
                free(p);
                return NULL;
@@ -373,7 +380,7 @@ void close_object_store(struct raw_object_store *o)
 
 void unlink_pack_path(const char *pack_name, int force_delete)
 {
-       static const char *exts[] = {".pack", ".idx", ".rev", ".keep", ".bitmap", ".promisor", ".mtimes"};
+       static const char *exts[] = {".idx", ".pack", ".rev", ".keep", ".bitmap", ".promisor", ".mtimes"};
        int i;
        struct strbuf buf = STRBUF_INIT;
        size_t plen;
@@ -591,7 +598,7 @@ static int open_packed_git_1(struct packed_git *p)
        if (read_result != hashsz)
                return error("packfile %s signature is unavailable", p->pack_name);
        idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;
-       if (!hasheq(hash, idx_hash))
+       if (!hasheq(hash, idx_hash, the_repository->hash_algo))
                return error("packfile %s does not match index", p->pack_name);
        return 0;
 }
@@ -745,8 +752,8 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
        p->pack_local = local;
        p->mtime = st.st_mtime;
        if (path_len < the_hash_algo->hexsz ||
-           get_sha1_hex(path + path_len - the_hash_algo->hexsz, p->hash))
-               hashclr(p->hash);
+           get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))
+               hashclr(p->hash, the_repository->hash_algo);
        return p;
 }
 
@@ -808,9 +815,10 @@ static void report_pack_garbage(struct string_list *list)
        report_helper(list, seen_bits, first, list->nr);
 }
 
-void for_each_file_in_pack_dir(const char *objdir,
-                              each_file_in_pack_dir_fn fn,
-                              void *data)
+void for_each_file_in_pack_subdir(const char *objdir,
+                                 const char *subdir,
+                                 each_file_in_pack_dir_fn fn,
+                                 void *data)
 {
        struct strbuf path = STRBUF_INIT;
        size_t dirnamelen;
@@ -819,6 +827,8 @@ void for_each_file_in_pack_dir(const char *objdir,
 
        strbuf_addstr(&path, objdir);
        strbuf_addstr(&path, "/pack");
+       if (subdir)
+               strbuf_addf(&path, "/%s", subdir);
        dir = opendir(path.buf);
        if (!dir) {
                if (errno != ENOENT)
@@ -840,6 +850,13 @@ void for_each_file_in_pack_dir(const char *objdir,
        strbuf_release(&path);
 }
 
+void for_each_file_in_pack_dir(const char *objdir,
+                              each_file_in_pack_dir_fn fn,
+                              void *data)
+{
+       for_each_file_in_pack_subdir(objdir, NULL, fn, data);
+}
+
 struct prepare_pack_data {
        struct repository *r;
        struct string_list *garbage;
@@ -873,7 +890,8 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
        if (!report_garbage)
                return;
 
-       if (!strcmp(file_name, "multi-pack-index"))
+       if (!strcmp(file_name, "multi-pack-index") ||
+           !strcmp(file_name, "multi-pack-index.d"))
                return;
        if (starts_with(file_name, "multi-pack-index") &&
            (ends_with(file_name, ".bitmap") || ends_with(file_name, ".rev")))
@@ -1008,6 +1026,16 @@ void reprepare_packed_git(struct repository *r)
        struct object_directory *odb;
 
        obj_read_lock();
+
+       /*
+        * Reprepare alt odbs, in case the alternates file was modified
+        * during the course of this process. This only _adds_ odbs to
+        * the linked list, so existing odbs will continue to exist for
+        * the lifetime of the process.
+        */
+       r->objects->loaded_alternates = 0;
+       prepare_alt_odb(r);
+
        for (odb = r->objects->odb; odb; odb = odb->next)
                odb_clear_loose_cache(odb);
 
@@ -1047,7 +1075,7 @@ struct packed_git *get_all_packs(struct repository *r)
        prepare_packed_git(r);
        for (m = r->objects->multi_pack_index; m; m = m->next) {
                uint32_t i;
-               for (i = 0; i < m->num_packs; i++)
+               for (i = 0; i < m->num_packs + m->num_packs_in_base; i++)
                        prepare_midx_pack(r, m, i);
        }
 
@@ -1236,7 +1264,7 @@ static int get_delta_base_oid(struct packed_git *p,
 {
        if (type == OBJ_REF_DELTA) {
                unsigned char *base = use_pack(p, w_curs, curpos, NULL);
-               oidread(oid, base);
+               oidread(oid, base, the_repository->hash_algo);
                return 0;
        } else if (type == OBJ_OFS_DELTA) {
                uint32_t base_pos;
@@ -1578,7 +1606,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,
                                goto out;
                        }
                } else
-                       oidclr(oi->delta_base_oid);
+                       oidclr(oi->delta_base_oid, the_repository->hash_algo);
        }
 
        oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :
@@ -1902,10 +1930,12 @@ int nth_packed_object_id(struct object_id *oid,
                return -1;
        index += 4 * 256;
        if (p->index_version == 1) {
-               oidread(oid, index + (hashsz + 4) * n + 4);
+               oidread(oid, index + st_add(st_mult(hashsz + 4, n), 4),
+                       the_repository->hash_algo);
        } else {
                index += 8;
-               oidread(oid, index + hashsz * n);
+               oidread(oid, index + st_mult(hashsz, n),
+                       the_repository->hash_algo);
        }
        return 0;
 }
@@ -1930,14 +1960,15 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
        const unsigned int hashsz = the_hash_algo->rawsz;
        index += 4 * 256;
        if (p->index_version == 1) {
-               return ntohl(*((uint32_t *)(index + (hashsz + 4) * (size_t)n)));
+               return ntohl(*((uint32_t *)(index + st_mult(hashsz + 4, n))));
        } else {
                uint32_t off;
-               index += 8 + (size_t)p->num_objects * (hashsz + 4);
-               off = ntohl(*((uint32_t *)(index + 4 * n)));
+               index += st_add(8, st_mult(p->num_objects, hashsz + 4));
+               off = ntohl(*((uint32_t *)(index + st_mult(4, n))));
                if (!(off & 0x80000000))
                        return off;
-               index += (size_t)p->num_objects * 4 + (off & 0x7fffffff) * 8;
+               index += st_add(st_mult(p->num_objects, 4),
+                               st_mult(off & 0x7fffffff, 8));
                check_pack_index_ptr(p, index);
                return get_be64(index);
        }
@@ -1955,7 +1986,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,
                        return 0;
        }
 
-       hashcpy(oid.hash, sha1);
+       hashcpy(oid.hash, sha1, the_repository->hash_algo);
        if (bsearch_pack(&oid, p, &result))
                return nth_packed_object_offset(p, result);
        return 0;
@@ -2136,7 +2167,7 @@ int for_each_object_in_pack(struct packed_git *p,
        int r = 0;
 
        if (flags & FOR_EACH_OBJECT_PACK_ORDER) {
-               if (load_pack_revindex(p))
+               if (load_pack_revindex(the_repository, p))
                        return -1;
        }
 
@@ -2204,8 +2235,8 @@ int for_each_packed_object(each_packed_object_fn cb, void *data,
 }
 
 static int add_promisor_object(const struct object_id *oid,
-                              struct packed_git *pack,
-                              uint32_t pos,
+                              struct packed_git *pack UNUSED,
+                              uint32_t pos UNUSED,
                               void *set_)
 {
        struct oidset *set = set_;
@@ -2233,7 +2264,8 @@ static int add_promisor_object(const struct object_id *oid,
                struct tree *tree = (struct tree *)obj;
                struct tree_desc desc;
                struct name_entry entry;
-               if (init_tree_desc_gently(&desc, tree->buffer, tree->size, 0))
+               if (init_tree_desc_gently(&desc, &tree->object.oid,
+                                         tree->buffer, tree->size, 0))
                        /*
                         * Error messages are given when packs are
                         * verified, so do not print any here.
@@ -2263,7 +2295,7 @@ int is_promisor_object(const struct object_id *oid)
        static int promisor_objects_prepared;
 
        if (!promisor_objects_prepared) {
-               if (has_promisor_remote()) {
+               if (repo_has_promisor_remote(the_repository)) {
                        for_each_packed_object(add_promisor_object,
                                               &promisor_objects,
                                               FOR_EACH_OBJECT_PROMISOR_ONLY |