t2300: use documented technique to invoke git-sh-setup
[gitweb.git] / object.c
index 5a5ebe27b0db0506dc1a6606d30e328c53275c18..fe8eaaf19f71b48d9acba83594d918fc4875f5c4 100644 (file)
--- a/object.c
+++ b/object.c
@@ -45,13 +45,14 @@ int type_from_string(const char *str)
 
 static unsigned int hash_obj(struct object *obj, unsigned int n)
 {
-       unsigned int hash = *(unsigned int *)obj->sha1;
+       unsigned int hash;
+       memcpy(&hash, obj->sha1, sizeof(unsigned int));
        return hash % n;
 }
 
 static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
 {
-       int j = hash_obj(obj, size);
+       unsigned int j = hash_obj(obj, size);
 
        while (hash[j]) {
                j++;
@@ -61,16 +62,16 @@ static void insert_obj_hash(struct object *obj, struct object **hash, unsigned i
        hash[j] = obj;
 }
 
-static int hashtable_index(const unsigned char *sha1)
+static unsigned int hashtable_index(const unsigned char *sha1)
 {
        unsigned int i;
        memcpy(&i, sha1, sizeof(unsigned int));
-       return (int)(i % obj_hash_size);
+       return i % obj_hash_size;
 }
 
 struct object *lookup_object(const unsigned char *sha1)
 {
-       int i;
+       unsigned int i;
        struct object *obj;
 
        if (!obj_hash)
@@ -140,7 +141,8 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
        if (type == OBJ_BLOB) {
                struct blob *blob = lookup_blob(sha1);
                if (blob) {
-                       parse_blob_buffer(blob, buffer, size);
+                       if (parse_blob_buffer(blob, buffer, size))
+                               return NULL;
                        obj = &blob->object;
                }
        } else if (type == OBJ_TREE) {
@@ -148,14 +150,16 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
                if (tree) {
                        obj = &tree->object;
                        if (!tree->object.parsed) {
-                               parse_tree_buffer(tree, buffer, size);
+                               if (parse_tree_buffer(tree, buffer, size))
+                                       return NULL;
                                eaten = 1;
                        }
                }
        } else if (type == OBJ_COMMIT) {
                struct commit *commit = lookup_commit(sha1);
                if (commit) {
-                       parse_commit_buffer(commit, buffer, size);
+                       if (parse_commit_buffer(commit, buffer, size))
+                               return NULL;
                        if (!commit->buffer) {
                                commit->buffer = buffer;
                                eaten = 1;
@@ -165,7 +169,8 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
        } else if (type == OBJ_TAG) {
                struct tag *tag = lookup_tag(sha1);
                if (tag) {
-                       parse_tag_buffer(tag, buffer, size);
+                       if (parse_tag_buffer(tag, buffer, size))
+                              return NULL;
                        obj = &tag->object;
                }
        } else {
@@ -183,17 +188,18 @@ struct object *parse_object(const unsigned char *sha1)
        unsigned long size;
        enum object_type type;
        int eaten;
-       void *buffer = read_sha1_file(sha1, &type, &size);
+       const unsigned char *repl;
+       void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl);
 
        if (buffer) {
                struct object *obj;
-               if (check_sha1_signature(sha1, buffer, size, typename(type)) < 0) {
+               if (check_sha1_signature(repl, buffer, size, typename(type)) < 0) {
                        free(buffer);
-                       error("sha1 mismatch %s\n", sha1_to_hex(sha1));
+                       error("sha1 mismatch %s\n", sha1_to_hex(repl));
                        return NULL;
                }
 
-               obj = parse_object_buffer(sha1, type, size, buffer, &eaten);
+               obj = parse_object_buffer(repl, type, size, buffer, &eaten);
                if (!eaten)
                        free(buffer);
                return obj;
@@ -264,3 +270,22 @@ void add_object_array_with_mode(struct object *obj, const char *name, struct obj
        objects[nr].mode = mode;
        array->nr = ++nr;
 }
+
+void object_array_remove_duplicates(struct object_array *array)
+{
+       int ref, src, dst;
+       struct object_array_entry *objects = array->objects;
+
+       for (ref = 0; ref < array->nr - 1; ref++) {
+               for (src = ref + 1, dst = src;
+                    src < array->nr;
+                    src++) {
+                       if (!strcmp(objects[ref].name, objects[src].name))
+                               continue;
+                       if (src != dst)
+                               objects[dst] = objects[src];
+                       dst++;
+               }
+               array->nr = dst;
+       }
+}