diff-format.txt: Combined diff format documentation supplement
[gitweb.git] / index-pack.c
index 785fe71a6fb5e518f92d62bace43cdd13f3c37ae..80bc6cb45b1a91c31dbdf18b48399b7a7a6b2737 100644 (file)
@@ -2,6 +2,10 @@
 #include "delta.h"
 #include "pack.h"
 #include "csum-file.h"
+#include "blob.h"
+#include "commit.h"
+#include "tag.h"
+#include "tree.h"
 
 static const char index_pack_usage[] =
 "git-index-pack [-o index-file] pack-file";
@@ -68,9 +72,9 @@ static void parse_pack_header(void)
        hdr = (void *)pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                die("packfile '%s' signature mismatch", pack_name);
-       if (hdr->hdr_version != htonl(PACK_VERSION))
-               die("packfile '%s' version %d different from ours %d",
-                   pack_name, ntohl(hdr->hdr_version), PACK_VERSION);
+       if (!pack_version_ok(hdr->hdr_version))
+               die("packfile '%s' version %d unsupported",
+                   pack_name, ntohl(hdr->hdr_version));
 
        nr_objects = ntohl(hdr->hdr_entries);
 
@@ -78,7 +82,7 @@ static void parse_pack_header(void)
        SHA1_Init(&ctx);
        SHA1_Update(&ctx, pack_base, pack_size - 20);
        SHA1_Final(sha1, &ctx);
-       if (memcmp(sha1, pack_base + pack_size - 20, 20))
+       if (hashcmp(sha1, pack_base + pack_size - 20))
                die("packfile '%s' SHA1 mismatch", pack_name);
 }
 
@@ -157,7 +161,7 @@ static void *unpack_raw_entry(unsigned long offset,
        case OBJ_DELTA:
                if (pos + 20 >= pack_limit)
                        bad_object(offset, "object extends past end of pack");
-               memcpy(delta_base, pack_base + pos, 20);
+               hashcpy(delta_base, pack_base + pos);
                pos += 20;
                /* fallthru */
        case OBJ_COMMIT:
@@ -185,7 +189,7 @@ static int find_delta(const unsigned char *base_sha1)
                 struct delta_entry *delta = &deltas[next];
                 int cmp;
 
-                cmp = memcmp(base_sha1, delta->base_sha1, 20);
+                cmp = hashcmp(base_sha1, delta->base_sha1);
                 if (!cmp)
                         return next;
                 if (cmp < 0) {
@@ -206,9 +210,9 @@ static int find_deltas_based_on_sha1(const unsigned char *base_sha1,
 
        if (first < 0)
                return -1;
-       while (first > 0 && !memcmp(deltas[first-1].base_sha1, base_sha1, 20))
+       while (first > 0 && !hashcmp(deltas[first - 1].base_sha1, base_sha1))
                --first;
-       while (last < end && !memcmp(deltas[last+1].base_sha1, base_sha1, 20))
+       while (last < end && !hashcmp(deltas[last + 1].base_sha1, base_sha1))
                ++last;
        *first_index = first;
        *last_index = last;
@@ -224,10 +228,10 @@ static void sha1_object(const void *data, unsigned long size,
        const char *type_str;
 
        switch (type) {
-       case OBJ_COMMIT: type_str = "commit"; break;
-       case OBJ_TREE:   type_str = "tree"; break;
-       case OBJ_BLOB:   type_str = "blob"; break;
-       case OBJ_TAG:    type_str = "tag"; break;
+       case OBJ_COMMIT: type_str = commit_type; break;
+       case OBJ_TREE:   type_str = tree_type; break;
+       case OBJ_BLOB:   type_str = blob_type; break;
+       case OBJ_TAG:    type_str = tag_type; break;
        default:
                die("bad type %d", type);
        }
@@ -274,7 +278,7 @@ static int compare_delta_entry(const void *a, const void *b)
 {
        const struct delta_entry *delta_a = a;
        const struct delta_entry *delta_b = b;
-       return memcmp(delta_a->base_sha1, delta_b->base_sha1, 20);
+       return hashcmp(delta_a->base_sha1, delta_b->base_sha1);
 }
 
 static void parse_pack_objects(void)
@@ -300,7 +304,7 @@ static void parse_pack_objects(void)
                if (obj->type == OBJ_DELTA) {
                        struct delta_entry *delta = &deltas[nr_deltas++];
                        delta->obj = obj;
-                       memcpy(delta->base_sha1, base_sha1, 20);
+                       hashcpy(delta->base_sha1, base_sha1);
                } else
                        sha1_object(data, data_size, obj->type, obj->sha1);
                free(data);
@@ -346,24 +350,30 @@ static int sha1_compare(const void *_a, const void *_b)
 {
        struct object_entry *a = *(struct object_entry **)_a;
        struct object_entry *b = *(struct object_entry **)_b;
-       return memcmp(a->sha1, b->sha1, 20);
+       return hashcmp(a->sha1, b->sha1);
 }
 
 static void write_index_file(const char *index_name, unsigned char *sha1)
 {
        struct sha1file *f;
-       struct object_entry **sorted_by_sha =
-               xcalloc(nr_objects, sizeof(struct object_entry *));
-       struct object_entry **list = sorted_by_sha;
-       struct object_entry **last = sorted_by_sha + nr_objects;
+       struct object_entry **sorted_by_sha, **list, **last;
        unsigned int array[256];
        int i;
        SHA_CTX ctx;
 
-       for (i = 0; i < nr_objects; ++i)
-               sorted_by_sha[i] = &objects[i];
-       qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
-             sha1_compare);
+       if (nr_objects) {
+               sorted_by_sha =
+                       xcalloc(nr_objects, sizeof(struct object_entry *));
+               list = sorted_by_sha;
+               last = sorted_by_sha + nr_objects;
+               for (i = 0; i < nr_objects; ++i)
+                       sorted_by_sha[i] = &objects[i];
+               qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
+                     sha1_compare);
+
+       }
+       else
+               sorted_by_sha = list = last = NULL;
 
        unlink(index_name);
        f = sha1create("%s", index_name);
@@ -437,10 +447,10 @@ int main(int argc, char **argv)
                usage(index_pack_usage);
        if (!index_name) {
                int len = strlen(pack_name);
-               if (len < 5 || strcmp(pack_name + len - 5, ".pack"))
+               if (!has_extension(pack_name, ".pack"))
                        die("packfile name '%s' does not end with '.pack'",
                            pack_name);
-               index_name_buf = xmalloc(len - 1);
+               index_name_buf = xmalloc(len);
                memcpy(index_name_buf, pack_name, len - 5);
                strcpy(index_name_buf + len - 5, ".idx");
                index_name = index_name_buf;