user-manual: replace init-db by init
[gitweb.git] / pack-check.c
index 84ed90d36912fc4ad6589cd2792e85a470418d04..8e123b71ed7898d2054ed9ef729c70ed40422bc3 100644 (file)
@@ -1,16 +1,18 @@
 #include "cache.h"
 #include "pack.h"
 
+#define BATCH (1u<<20)
+
 static int verify_packfile(struct packed_git *p)
 {
        unsigned long index_size = p->index_size;
        void *index_base = p->index_base;
        SHA_CTX ctx;
        unsigned char sha1[20];
-       unsigned long pack_size = p->pack_size;
-       void *pack_base;
        struct pack_header *hdr;
        int nr_objects, err, i;
+       unsigned char *packdata;
+       unsigned long datasize;
 
        /* Header consistency check */
        hdr = p->pack_base;
@@ -25,16 +27,24 @@ static int verify_packfile(struct packed_git *p)
                             "while idx size expects %d", nr_objects,
                             num_packed_objects(p));
 
+       /* Check integrity of pack data with its SHA-1 checksum */
        SHA1_Init(&ctx);
-       pack_base = p->pack_base;
-       SHA1_Update(&ctx, pack_base, pack_size - 20);
+       packdata = p->pack_base;
+       datasize = p->pack_size - 20;
+       while (datasize) {
+               unsigned long batch = (datasize < BATCH) ? datasize : BATCH;
+               SHA1_Update(&ctx, packdata, batch);
+               datasize -= batch;
+               packdata += batch;
+       }
        SHA1_Final(sha1, &ctx);
-       if (memcmp(sha1, index_base + index_size - 40, 20))
-               return error("Packfile %s SHA1 mismatch with idx",
-                            p->pack_name);
-       if (memcmp(sha1, pack_base + pack_size - 20, 20))
+
+       if (hashcmp(sha1, (unsigned char *)(p->pack_base) + p->pack_size - 20))
                return error("Packfile %s SHA1 mismatch with itself",
                             p->pack_name);
+       if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
+               return error("Packfile %s SHA1 mismatch with idx",
+                            p->pack_name);
 
        /* Make sure everything reachable from idx is valid.  Since we
         * have verified that nr_objects matches between idx and pack,
@@ -42,16 +52,16 @@ static int verify_packfile(struct packed_git *p)
         */
        for (i = err = 0; i < nr_objects; i++) {
                unsigned char sha1[20];
-               struct pack_entry e;
                void *data;
                char type[20];
-               unsigned long size;
+               unsigned long size, offset;
 
                if (nth_packed_object_sha1(p, i, sha1))
                        die("internal error pack-check nth-packed-object");
-               if (!find_pack_entry_one(sha1, &e, p))
+               offset = find_pack_entry_one(sha1, p);
+               if (!offset)
                        die("internal error pack-check find-pack-entry-one");
-               data = unpack_entry_gently(&e, type, &size);
+               data = unpack_entry_gently(p, offset, type, &size);
                if (!data) {
                        err = error("cannot unpack %s from %s",
                                    sha1_to_hex(sha1), p->pack_name);
@@ -84,25 +94,26 @@ static void show_pack_info(struct packed_git *p)
 
        for (i = 0; i < nr_objects; i++) {
                unsigned char sha1[20], base_sha1[20];
-               struct pack_entry e;
                char type[20];
                unsigned long size;
                unsigned long store_size;
+               unsigned long offset;
                unsigned int delta_chain_length;
 
                if (nth_packed_object_sha1(p, i, sha1))
                        die("internal error pack-check nth-packed-object");
-               if (!find_pack_entry_one(sha1, &e, p))
+               offset = find_pack_entry_one(sha1, p);
+               if (!offset)
                        die("internal error pack-check find-pack-entry-one");
 
-               packed_object_info_detail(&e, type, &size, &store_size,
+               packed_object_info_detail(p, offset, type, &size, &store_size,
                                          &delta_chain_length,
                                          base_sha1);
                printf("%s ", sha1_to_hex(sha1));
                if (!delta_chain_length)
-                       printf("%-6s %lu %u\n", type, size, e.offset);
+                       printf("%-6s %lu %lu\n", type, size, offset);
                else {
-                       printf("%-6s %lu %u %u %s\n", type, size, e.offset,
+                       printf("%-6s %lu %lu %u %s\n", type, size, offset,
                               delta_chain_length, sha1_to_hex(base_sha1));
                        if (delta_chain_length < MAX_CHAIN)
                                chain_histogram[delta_chain_length]++;
@@ -135,7 +146,7 @@ int verify_pack(struct packed_git *p, int verbose)
        SHA1_Init(&ctx);
        SHA1_Update(&ctx, index_base, index_size - 20);
        SHA1_Final(sha1, &ctx);
-       if (memcmp(sha1, index_base + index_size - 20, 20))
+       if (hashcmp(sha1, (unsigned char *)index_base + index_size - 20))
                ret = error("Packfile index for %s SHA1 mismatch",
                            p->pack_name);