git-tar-tree: no more void pointer arithmetic
[git.git] / pack-check.c
index 511f294..e575879 100644 (file)
@@ -16,9 +16,9 @@ static int verify_packfile(struct packed_git *p)
        hdr = p->pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                return error("Packfile %s signature mismatch", p->pack_name);
-       if (hdr->hdr_version != htonl(PACK_VERSION))
-               return error("Packfile version %d different from ours %d",
-                            ntohl(hdr->hdr_version), PACK_VERSION);
+       if (!pack_version_ok(hdr->hdr_version))
+               return error("Packfile version %d unsupported",
+                            ntohl(hdr->hdr_version));
        nr_objects = ntohl(hdr->hdr_entries);
        if (num_packed_objects(p) != nr_objects)
                return error("Packfile claims to have %d objects, "
@@ -29,12 +29,12 @@ static int verify_packfile(struct packed_git *p)
        pack_base = p->pack_base;
        SHA1_Update(&ctx, pack_base, pack_size - 20);
        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))
                return error("Packfile %s SHA1 mismatch with itself",
                             p->pack_name);
+       if (memcmp(sha1, index_base + index_size - 40, 20))
+               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,
@@ -70,13 +70,17 @@ static int verify_packfile(struct packed_git *p)
 }
 
 
+#define MAX_CHAIN 40
+
 static void show_pack_info(struct packed_git *p)
 {
        struct pack_header *hdr;
        int nr_objects, i;
+       unsigned int chain_histogram[MAX_CHAIN];
 
        hdr = p->pack_base;
        nr_objects = ntohl(hdr->hdr_entries);
+       memset(chain_histogram, 0, sizeof(chain_histogram));
 
        for (i = 0; i < nr_objects; i++) {
                unsigned char sha1[20], base_sha1[20];
@@ -84,7 +88,7 @@ static void show_pack_info(struct packed_git *p)
                char type[20];
                unsigned long size;
                unsigned long store_size;
-               int delta_chain_length;
+               unsigned int delta_chain_length;
 
                if (nth_packed_object_sha1(p, i, sha1))
                        die("internal error pack-check nth-packed-object");
@@ -97,11 +101,25 @@ static void show_pack_info(struct packed_git *p)
                printf("%s ", sha1_to_hex(sha1));
                if (!delta_chain_length)
                        printf("%-6s %lu %u\n", type, size, e.offset);
-               else
-                       printf("%-6s %lu %u %d %s\n", type, size, e.offset,
+               else {
+                       printf("%-6s %lu %u %u %s\n", type, size, e.offset,
                               delta_chain_length, sha1_to_hex(base_sha1));
+                       if (delta_chain_length < MAX_CHAIN)
+                               chain_histogram[delta_chain_length]++;
+                       else
+                               chain_histogram[0]++;
+               }
        }
 
+       for (i = 0; i < MAX_CHAIN; i++) {
+               if (!chain_histogram[i])
+                       continue;
+               printf("chain length %s %d: %d object%s\n",
+                      i ? "=" : ">=",
+                      i ? i : MAX_CHAIN,
+                      chain_histogram[i],
+                      1 < chain_histogram[i] ? "s" : "");
+       }
 }
 
 int verify_pack(struct packed_git *p, int verbose)