Merge branch 'jk/maint-commit-document-editmsg'
[gitweb.git] / object.c
index 3ca92c4c4def46af10556dbe9b3f48774b9a4a35..4af3451bf89471a0ab7a148aad4924a8ac8ae053 100644 (file)
--- a/object.c
+++ b/object.c
@@ -149,6 +149,8 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
                struct tree *tree = lookup_tree(sha1);
                if (tree) {
                        obj = &tree->object;
+                       if (!tree->buffer)
+                               tree->object.parsed = 0;
                        if (!tree->object.parsed) {
                                if (parse_tree_buffer(tree, buffer, size))
                                        return NULL;
@@ -174,7 +176,7 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
                        obj = &tag->object;
                }
        } else {
-               warning("object %s has unknown type id %d\n", sha1_to_hex(sha1), type);
+               warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
                obj = NULL;
        }
        if (obj && obj->type == OBJ_NONE)
@@ -188,18 +190,34 @@ struct object *parse_object(const unsigned char *sha1)
        unsigned long size;
        enum object_type type;
        int eaten;
-       const unsigned char *repl;
-       void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl);
+       const unsigned char *repl = lookup_replace_object(sha1);
+       void *buffer;
+       struct object *obj;
+
+       obj = lookup_object(sha1);
+       if (obj && obj->parsed)
+               return obj;
+
+       if ((obj && obj->type == OBJ_BLOB) ||
+           (!obj && has_sha1_file(sha1) &&
+            sha1_object_info(sha1, NULL) == OBJ_BLOB)) {
+               if (check_sha1_signature(repl, NULL, 0, NULL) < 0) {
+                       error("sha1 mismatch %s", sha1_to_hex(repl));
+                       return NULL;
+               }
+               parse_blob_buffer(lookup_blob(sha1), NULL, 0);
+               return lookup_object(sha1);
+       }
 
+       buffer = read_sha1_file(sha1, &type, &size);
        if (buffer) {
-               struct object *obj;
                if (check_sha1_signature(repl, buffer, size, typename(type)) < 0) {
                        free(buffer);
-                       error("sha1 mismatch %s\n", sha1_to_hex(repl));
+                       error("sha1 mismatch %s", sha1_to_hex(repl));
                        return NULL;
                }
 
-               obj = parse_object_buffer(repl, type, size, buffer, &eaten);
+               obj = parse_object_buffer(sha1, type, size, buffer, &eaten);
                if (!eaten)
                        free(buffer);
                return obj;
@@ -211,10 +229,10 @@ struct object_list *object_list_insert(struct object *item,
                                       struct object_list **list_p)
 {
        struct object_list *new_list = xmalloc(sizeof(struct object_list));
-        new_list->item = item;
-        new_list->next = *list_p;
-        *list_p = new_list;
-        return new_list;
+       new_list->item = item;
+       new_list->next = *list_p;
+       *list_p = new_list;
+       return new_list;
 }
 
 int object_list_contains(struct object_list *list, struct object *obj)
@@ -252,10 +270,10 @@ void add_object_array_with_mode(struct object *obj, const char *name, struct obj
 
 void object_array_remove_duplicates(struct object_array *array)
 {
-       int ref, src, dst;
+       unsigned int ref, src, dst;
        struct object_array_entry *objects = array->objects;
 
-       for (ref = 0; ref < array->nr - 1; ref++) {
+       for (ref = 0; ref + 1 < array->nr; ref++) {
                for (src = ref + 1, dst = src;
                     src < array->nr;
                     src++) {
@@ -268,3 +286,14 @@ void object_array_remove_duplicates(struct object_array *array)
                array->nr = dst;
        }
 }
+
+void clear_object_flags(unsigned flags)
+{
+       int i;
+
+       for (i=0; i < obj_hash_size; i++) {
+               struct object *obj = obj_hash[i];
+               if (obj)
+                       obj->flags &= ~flags;
+       }
+}