diff options
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 99 |
1 files changed, 64 insertions, 35 deletions
@@ -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) @@ -148,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; @@ -173,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) @@ -187,13 +190,30 @@ 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 = 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(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", sha1_to_hex(repl)); return NULL; } @@ -209,31 +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; -} - -void object_list_append(struct object *item, - struct object_list **list_p) -{ - while (*list_p) { - list_p = &((*list_p)->next); - } - *list_p = xmalloc(sizeof(struct object_list)); - (*list_p)->next = NULL; - (*list_p)->item = item; -} - -unsigned object_list_length(struct object_list *list) -{ - unsigned ret = 0; - while (list) { - list = list->next; - ret++; - } - return ret; + 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) @@ -268,3 +267,33 @@ 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) +{ + unsigned int ref, src, dst; + struct object_array_entry *objects = array->objects; + + for (ref = 0; ref + 1 < array->nr; 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; + } +} + +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; + } +} |