From 136f2e548a34f1f504b0f062f87ddf33e8d6e83b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:16:12 -0700 Subject: Make "struct tree" contain the pointer to the tree buffer This allows us to avoid allocating information for names etc, because we can just use the information from the tree buffer directly. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- tree.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tree.h') diff --git a/tree.h b/tree.h index 330ab64bbd..066ac5d5bf 100644 --- a/tree.h +++ b/tree.h @@ -12,7 +12,7 @@ struct tree_entry_list { unsigned symlink : 1; unsigned zeropad : 1; unsigned int mode; - char *name; + const char *name; union { struct object *any; struct tree *tree; @@ -22,6 +22,8 @@ struct tree_entry_list { struct tree { struct object object; + void *buffer; + unsigned long size; struct tree_entry_list *entries; }; -- cgit v1.3 From 3a7c352bd0ecac4b4c96c0995d61de9ef8d814f9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:16:46 -0700 Subject: Make "tree_entry" have a SHA1 instead of a union of object pointers This is preparatory work for further cleanups, where we try to make tree_entry look more like the more efficient tree-walk descriptor. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- blame.c | 4 ++-- builtin-read-tree.c | 9 +++++---- builtin-rev-list.c | 4 ++-- fsck-objects.c | 1 + http-push.c | 4 ++-- object.c | 2 +- revision.c | 4 ++-- tree.c | 25 ++++++++++++++----------- tree.h | 8 ++------ 9 files changed, 31 insertions(+), 30 deletions(-) (limited to 'tree.h') diff --git a/blame.c b/blame.c index 99ceea81df..88bfec262f 100644 --- a/blame.c +++ b/blame.c @@ -149,7 +149,7 @@ static void free_patch(struct patch *p) free(p); } -static int get_blob_sha1_internal(unsigned char *sha1, const char *base, +static int get_blob_sha1_internal(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage); @@ -178,7 +178,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname, return 0; } -static int get_blob_sha1_internal(unsigned char *sha1, const char *base, +static int get_blob_sha1_internal(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 6876f3d793..5e513c85ca 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -161,9 +161,10 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len, } if (posns[i]->directory) { + struct tree *tree = lookup_tree(posns[i]->sha1); any_dirs = 1; - parse_tree(posns[i]->item.tree); - subposns[i] = posns[i]->item.tree->entries; + parse_tree(tree); + subposns[i] = tree->entries; posns[i] = posns[i]->next; src[i + merge] = &df_conflict_entry; continue; @@ -187,7 +188,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len, any_files = 1; - memcpy(ce->sha1, posns[i]->item.any->sha1, 20); + memcpy(ce->sha1, posns[i]->sha1, 20); src[i + merge] = ce; subposns[i] = &df_conflict_list; posns[i] = posns[i]->next; @@ -783,7 +784,7 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) cnt++; else { struct cache_tree_sub *sub; - struct tree *subtree = (struct tree *)ent->item.tree; + struct tree *subtree = lookup_tree(ent->sha1); if (!subtree->object.parsed) parse_tree(subtree); sub = cache_tree_sub(it, ent->name); diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 72c1549c70..94f520b908 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -133,9 +133,9 @@ static struct object_list **process_tree(struct tree *tree, while (entry) { struct tree_entry_list *next = entry->next; if (entry->directory) - p = process_tree(entry->item.tree, p, &me, entry->name); + p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name); else - p = process_blob(entry->item.blob, p, &me, entry->name); + p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name); free(entry); entry = next; } diff --git a/fsck-objects.c b/fsck-objects.c index 5e65df436b..ed2eb278ec 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -464,6 +464,7 @@ int main(int argc, char **argv) { int i, heads; + track_object_refs = 1; setup_git_directory(); for (i = 1; i < argc; i++) { diff --git a/http-push.c b/http-push.c index b4327d9243..f492a5d366 100644 --- a/http-push.c +++ b/http-push.c @@ -1733,9 +1733,9 @@ static struct object_list **process_tree(struct tree *tree, while (entry) { struct tree_entry_list *next = entry->next; if (entry->directory) - p = process_tree(entry->item.tree, p, &me, entry->name); + p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name); else - p = process_blob(entry->item.blob, p, &me, entry->name); + p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name); free(entry); entry = next; } diff --git a/object.c b/object.c index 1a7823c234..9adc87479b 100644 --- a/object.c +++ b/object.c @@ -9,7 +9,7 @@ struct object **objs; static int nr_objs; int obj_allocs; -int track_object_refs = 1; +int track_object_refs = 0; static int hashtable_index(const unsigned char *sha1) { diff --git a/revision.c b/revision.c index 42c077a4cb..8d70a6f77a 100644 --- a/revision.c +++ b/revision.c @@ -68,9 +68,9 @@ void mark_tree_uninteresting(struct tree *tree) while (entry) { struct tree_entry_list *next = entry->next; if (entry->directory) - mark_tree_uninteresting(entry->item.tree); + mark_tree_uninteresting(lookup_tree(entry->sha1)); else - mark_blob_uninteresting(entry->item.blob); + mark_blob_uninteresting(lookup_blob(entry->sha1)); free(entry); entry = next; } diff --git a/tree.c b/tree.c index 1e76d9cc11..88c2219030 100644 --- a/tree.c +++ b/tree.c @@ -8,7 +8,7 @@ const char *tree_type = "tree"; -static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) +static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { int len; unsigned int size; @@ -89,7 +89,7 @@ int read_tree_recursive(struct tree *tree, current->mode, match)) continue; - switch (fn(current->item.any->sha1, base, baselen, + switch (fn(current->sha1, base, baselen, current->name, current->mode, stage)) { case 0: continue; @@ -107,7 +107,7 @@ int read_tree_recursive(struct tree *tree, memcpy(newbase, base, baselen); memcpy(newbase + baselen, current->name, pathlen); newbase[baselen + pathlen] = '/'; - retval = read_tree_recursive(current->item.tree, + retval = read_tree_recursive(lookup_tree(current->sha1), newbase, baselen + pathlen + 1, stage, match, fn); @@ -170,6 +170,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) entry = xmalloc(sizeof(struct tree_entry_list)); entry->name = path; + entry->sha1 = sha1; entry->mode = mode; entry->directory = S_ISDIR(mode) != 0; entry->executable = (mode & S_IXUSR) != 0; @@ -178,12 +179,6 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) entry->next = NULL; update_tree_entry(&desc); - - if (entry->directory) { - entry->item.tree = lookup_tree(sha1); - } else { - entry->item.blob = lookup_blob(sha1); - } n_refs++; *list_p = entry; list_p = &entry->next; @@ -193,8 +188,16 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) struct tree_entry_list *entry; unsigned i = 0; struct object_refs *refs = alloc_object_refs(n_refs); - for (entry = item->entries; entry; entry = entry->next) - refs->ref[i++] = entry->item.any; + for (entry = item->entries; entry; entry = entry->next) { + struct object *obj; + + if (entry->directory) + obj = &lookup_tree(entry->sha1)->object; + else + obj = &lookup_blob(entry->sha1)->object; + refs->ref[i++] = obj; + } + set_object_refs(&item->object, refs); } diff --git a/tree.h b/tree.h index 066ac5d5bf..a27bae41ba 100644 --- a/tree.h +++ b/tree.h @@ -13,11 +13,7 @@ struct tree_entry_list { unsigned zeropad : 1; unsigned int mode; const char *name; - union { - struct object *any; - struct tree *tree; - struct blob *blob; - } item; + const unsigned char *sha1; }; struct tree { @@ -37,7 +33,7 @@ int parse_tree(struct tree *tree); struct tree *parse_tree_indirect(const unsigned char *sha1); #define READ_TREE_RECURSIVE 1 -typedef int (*read_tree_fn_t)(unsigned char *, const char *, int, const char *, unsigned int, int); +typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int); extern int read_tree_recursive(struct tree *tree, const char *base, int baselen, -- cgit v1.3 From 2d9c58c69d1bab601e67b036d0546e85abcee7eb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:18:33 -0700 Subject: Remove "tree->entries" tree-entry list from tree parser Instead, just use the tree buffer directly, and use the tree-walk infrastructure to walk the buffers instead of the tree-entry list. The tree-entry list is inefficient, and generates tons of small allocations for no good reason. The tree-walk infrastructure is generally no harder to use than following a linked list, and allows us to do most tree parsing in-place. Some programs still use the old tree-entry lists, and are a bit painful to convert without major surgery. For them we have a helper function that creates a temporary tree-entry list on demand. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-ls-tree.c | 2 +- builtin-read-tree.c | 4 +-- builtin-rev-list.c | 26 ++++++++++------- fetch.c | 16 +++++++---- fsck-objects.c | 7 +++-- http-push.c | 30 +++++++++++++------- revision.c | 3 +- tree.c | 81 +++++++++++++++++++++++++++++++++++++---------------- tree.h | 4 ++- 9 files changed, 116 insertions(+), 57 deletions(-) (limited to 'tree.h') diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c index 48385d59f6..b8d0d88ba8 100644 --- a/builtin-ls-tree.c +++ b/builtin-ls-tree.c @@ -53,7 +53,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname) } } -static int show_tree(unsigned char *sha1, const char *base, int baselen, +static int show_tree(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { int retval = 0; diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 67492bfb45..480e6ed372 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -165,7 +165,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len, struct tree *tree = lookup_tree(posns[i]->sha1); any_dirs = 1; parse_tree(tree); - subposns[i] = tree->entries; + subposns[i] = create_tree_entry_list(tree); posns[i] = posns[i]->next; src[i + merge] = &df_conflict_entry; continue; @@ -370,7 +370,7 @@ static int unpack_trees(merge_fn_t fn) if (len) { posns = xmalloc(len * sizeof(struct tree_entry_list *)); for (i = 0; i < len; i++) { - posns[i] = ((struct tree *) posn->item)->entries; + posns[i] = create_tree_entry_list((struct tree *) posn->item); posn = posn->next; } if (unpack_trees_rec(posns, len, "", fn, &indpos)) diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 94f520b908..6e2b898cca 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -113,7 +113,7 @@ static struct object_list **process_tree(struct tree *tree, const char *name) { struct object *obj = &tree->object; - struct tree_entry_list *entry; + struct tree_desc desc; struct name_path me; if (!revs.tree_objects) @@ -128,16 +128,22 @@ static struct object_list **process_tree(struct tree *tree, me.up = path; me.elem = name; me.elem_len = strlen(name); - entry = tree->entries; - tree->entries = NULL; - while (entry) { - struct tree_entry_list *next = entry->next; - if (entry->directory) - p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name); + + desc.buf = tree->buffer; + desc.size = tree->size; + + while (desc.size) { + unsigned mode; + const char *name; + const unsigned char *sha1; + + sha1 = tree_entry_extract(&desc, &name, &mode); + update_tree_entry(&desc); + + if (S_ISDIR(mode)) + p = process_tree(lookup_tree(sha1), p, &me, name); else - p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name); - free(entry); - entry = next; + p = process_blob(lookup_blob(sha1), p, &me, name); } free(tree->buffer); tree->buffer = NULL; diff --git a/fetch.c b/fetch.c index f7f8902580..d9fe41f34f 100644 --- a/fetch.c +++ b/fetch.c @@ -41,16 +41,22 @@ static int process_tree(struct tree *tree) if (parse_tree(tree)) return -1; - entry = tree->entries; - tree->entries = NULL; + entry = create_tree_entry_list(tree); while (entry) { struct tree_entry_list *next = entry->next; - if (process(entry->item.any)) - return -1; - free(entry->name); + + if (entry->directory) { + struct tree *tree = lookup_tree(entry->sha1); + process_tree(tree); + } else { + struct blob *blob = lookup_blob(entry->sha1); + process(&blob->object); + } free(entry); entry = next; } + free(tree->buffer); + tree->buffer = NULL; return 0; } diff --git a/fsck-objects.c b/fsck-objects.c index ed2eb278ec..42778e87d0 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -11,6 +11,7 @@ #include "cache-tree.h" #define REACHABLE 0x0001 +#define SEEN 0x0002 static int show_root = 0; static int show_tags = 0; @@ -161,7 +162,7 @@ static int fsck_tree(struct tree *item) struct tree_entry_list *entry, *last; last = NULL; - for (entry = item->entries; entry; entry = entry->next) { + for (entry = create_tree_entry_list(item); entry; entry = entry->next) { if (strchr(entry->name, '/')) has_full_path = 1; has_zero_pad |= entry->zeropad; @@ -205,7 +206,6 @@ static int fsck_tree(struct tree *item) } if (last) free(last); - item->entries = NULL; free(item->buffer); item->buffer = NULL; @@ -277,6 +277,9 @@ static int fsck_sha1(unsigned char *sha1) struct object *obj = parse_object(sha1); if (!obj) return error("%s: object not found", sha1_to_hex(sha1)); + if (obj->flags & SEEN) + return 0; + obj->flags |= SEEN; if (obj->type == blob_type) return 0; if (obj->type == tree_type) diff --git a/http-push.c b/http-push.c index f492a5d366..72ad89ce11 100644 --- a/http-push.c +++ b/http-push.c @@ -1704,6 +1704,7 @@ static struct object_list **process_blob(struct blob *blob, return p; obj->flags |= SEEN; + name = strdup(name); return add_object(obj, p, path, name); } @@ -1713,7 +1714,7 @@ static struct object_list **process_tree(struct tree *tree, const char *name) { struct object *obj = &tree->object; - struct tree_entry_list *entry; + struct tree_desc desc; struct name_path me; obj->flags |= LOCAL; @@ -1724,21 +1725,30 @@ static struct object_list **process_tree(struct tree *tree, die("bad tree object %s", sha1_to_hex(obj->sha1)); obj->flags |= SEEN; + name = strdup(name); p = add_object(obj, p, NULL, name); me.up = path; me.elem = name; me.elem_len = strlen(name); - entry = tree->entries; - tree->entries = NULL; - while (entry) { - struct tree_entry_list *next = entry->next; - if (entry->directory) - p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name); + + desc.buf = tree->buffer; + desc.size = tree->size; + + while (desc.size) { + unsigned mode; + const char *name; + const unsigned char *sha1; + + sha1 = tree_entry_extract(&desc, &name, &mode); + update_tree_entry(&desc); + + if (S_ISDIR(mode)) + p = process_tree(lookup_tree(sha1), p, &me, name); else - p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name); - free(entry); - entry = next; + p = process_blob(lookup_blob(sha1), p, &me, name); } + free(tree->buffer); + tree->buffer = NULL; return p; } diff --git a/revision.c b/revision.c index 8d70a6f77a..c51ea833f9 100644 --- a/revision.c +++ b/revision.c @@ -63,8 +63,7 @@ void mark_tree_uninteresting(struct tree *tree) return; if (parse_tree(tree) < 0) die("bad tree %s", sha1_to_hex(obj->sha1)); - entry = tree->entries; - tree->entries = NULL; + entry = create_tree_entry_list(tree); while (entry) { struct tree_entry_list *next = entry->next; if (entry->directory) diff --git a/tree.c b/tree.c index 88f8fd5892..db6e59f20e 100644 --- a/tree.c +++ b/tree.c @@ -151,22 +151,65 @@ struct tree *lookup_tree(const unsigned char *sha1) return (struct tree *) obj; } -int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) +static int track_tree_refs(struct tree *item) { + int n_refs = 0, i; + struct object_refs *refs; struct tree_desc desc; - struct tree_entry_list **list_p; - int n_refs = 0; + /* Count how many entries there are.. */ + desc.buf = item->buffer; + desc.size = item->size; + while (desc.size) { + n_refs++; + update_tree_entry(&desc); + } + + /* Allocate object refs and walk it again.. */ + i = 0; + refs = alloc_object_refs(n_refs); + desc.buf = item->buffer; + desc.size = item->size; + while (desc.size) { + unsigned mode; + const char *name; + const unsigned char *sha1; + struct object *obj; + + sha1 = tree_entry_extract(&desc, &name, &mode); + update_tree_entry(&desc); + if (S_ISDIR(mode)) + obj = &lookup_tree(sha1)->object; + else + obj = &lookup_blob(sha1)->object; + refs->ref[i++] = obj; + } + set_object_refs(&item->object, refs); + return 0; +} + +int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) +{ if (item->object.parsed) return 0; item->object.parsed = 1; item->buffer = buffer; item->size = size; - desc.buf = buffer; - desc.size = size; + if (track_object_refs) + track_tree_refs(item); + return 0; +} + +struct tree_entry_list *create_tree_entry_list(struct tree *tree) +{ + struct tree_desc desc; + struct tree_entry_list *ret = NULL; + struct tree_entry_list **list_p = &ret; + + desc.buf = tree->buffer; + desc.size = tree->size; - list_p = &item->entries; while (desc.size) { unsigned mode; const char *path; @@ -186,29 +229,19 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) entry->next = NULL; update_tree_entry(&desc); - n_refs++; *list_p = entry; list_p = &entry->next; } + return ret; +} - if (track_object_refs) { - struct tree_entry_list *entry; - unsigned i = 0; - struct object_refs *refs = alloc_object_refs(n_refs); - for (entry = item->entries; entry; entry = entry->next) { - struct object *obj; - - if (entry->directory) - obj = &lookup_tree(entry->sha1)->object; - else - obj = &lookup_blob(entry->sha1)->object; - refs->ref[i++] = obj; - } - - set_object_refs(&item->object, refs); +void free_tree_entry_list(struct tree_entry_list *list) +{ + while (list) { + struct tree_entry_list *next = list->next; + free(list); + list = next; } - - return 0; } int parse_tree(struct tree *item) diff --git a/tree.h b/tree.h index a27bae41ba..c7b524861b 100644 --- a/tree.h +++ b/tree.h @@ -20,9 +20,11 @@ struct tree { struct object object; void *buffer; unsigned long size; - struct tree_entry_list *entries; }; +struct tree_entry_list *create_tree_entry_list(struct tree *); +void free_tree_entry_list(struct tree_entry_list *); + struct tree *lookup_tree(const unsigned char *sha1); int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size); -- cgit v1.3 From 3bc1eca91e5230739cfb488e63fae35a166a07de Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:19:37 -0700 Subject: Remove unused "zeropad" entry from tree_list_entry That was a hack, only needed because 'git fsck-objects' didn't look at the raw tree format. Now that fsck traverses the tree itself, we can drop it. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- tree.c | 3 +-- tree.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'tree.h') diff --git a/tree.c b/tree.c index db6e59f20e..47318ef890 100644 --- a/tree.c +++ b/tree.c @@ -217,6 +217,7 @@ struct tree_entry_list *create_tree_entry_list(struct tree *tree) struct tree_entry_list *entry; sha1 = tree_entry_extract(&desc, &path, &mode); + update_tree_entry(&desc); entry = xmalloc(sizeof(struct tree_entry_list)); entry->name = path; @@ -225,10 +226,8 @@ struct tree_entry_list *create_tree_entry_list(struct tree *tree) entry->directory = S_ISDIR(mode) != 0; entry->executable = (mode & S_IXUSR) != 0; entry->symlink = S_ISLNK(mode) != 0; - entry->zeropad = *(const char *)(desc.buf) == '0'; entry->next = NULL; - update_tree_entry(&desc); *list_p = entry; list_p = &entry->next; } diff --git a/tree.h b/tree.h index c7b524861b..6a875464b0 100644 --- a/tree.h +++ b/tree.h @@ -10,7 +10,6 @@ struct tree_entry_list { unsigned directory : 1; unsigned executable : 1; unsigned symlink : 1; - unsigned zeropad : 1; unsigned int mode; const char *name; const unsigned char *sha1; -- cgit v1.3 From 15b5536ee47c6684806edd7725adbbdede9fb95c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:21:28 -0700 Subject: Remove last vestiges of generic tree_entry_list The old tree_entry_list is dead, long live the unified single tree parser. Yes, we now still have a compatibility function to create a bogus tree_entry_list in builtin-read-tree.c, but that is now entirely local to that very messy piece of code. I'd love to clean read-tree.c up too, but I'm too scared right now, so the best I can do is to just contain the damage, and try to make sure that no new users of the tree_entry_list sprout up by not having it as an exported interface any more. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-read-tree.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- tree.c | 42 ------------------------------------------ tree.h | 13 ------------- 3 files changed, 44 insertions(+), 56 deletions(-) (limited to 'tree.h') diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 480e6ed372..00cdb5a6d9 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -30,7 +30,17 @@ static int merge_size = 0; static struct object_list *trees = NULL; -static struct cache_entry df_conflict_entry = { +static struct cache_entry df_conflict_entry = { +}; + +struct tree_entry_list { + struct tree_entry_list *next; + unsigned directory : 1; + unsigned executable : 1; + unsigned symlink : 1; + unsigned int mode; + const char *name; + const unsigned char *sha1; }; static struct tree_entry_list df_conflict_list = { @@ -40,6 +50,39 @@ static struct tree_entry_list df_conflict_list = { typedef int (*merge_fn_t)(struct cache_entry **src); +static struct tree_entry_list *create_tree_entry_list(struct tree *tree) +{ + struct tree_desc desc; + struct tree_entry_list *ret = NULL; + struct tree_entry_list **list_p = &ret; + + desc.buf = tree->buffer; + desc.size = tree->size; + + while (desc.size) { + unsigned mode; + const char *path; + const unsigned char *sha1; + struct tree_entry_list *entry; + + sha1 = tree_entry_extract(&desc, &path, &mode); + update_tree_entry(&desc); + + entry = xmalloc(sizeof(struct tree_entry_list)); + entry->name = path; + entry->sha1 = sha1; + entry->mode = mode; + entry->directory = S_ISDIR(mode) != 0; + entry->executable = (mode & S_IXUSR) != 0; + entry->symlink = S_ISLNK(mode) != 0; + entry->next = NULL; + + *list_p = entry; + list_p = &entry->next; + } + return ret; +} + static int entcmp(const char *name1, int dir1, const char *name2, int dir2) { int len1 = strlen(name1); diff --git a/tree.c b/tree.c index 47318ef890..fb18724259 100644 --- a/tree.c +++ b/tree.c @@ -201,48 +201,6 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) return 0; } -struct tree_entry_list *create_tree_entry_list(struct tree *tree) -{ - struct tree_desc desc; - struct tree_entry_list *ret = NULL; - struct tree_entry_list **list_p = &ret; - - desc.buf = tree->buffer; - desc.size = tree->size; - - while (desc.size) { - unsigned mode; - const char *path; - const unsigned char *sha1; - struct tree_entry_list *entry; - - sha1 = tree_entry_extract(&desc, &path, &mode); - update_tree_entry(&desc); - - entry = xmalloc(sizeof(struct tree_entry_list)); - entry->name = path; - entry->sha1 = sha1; - entry->mode = mode; - entry->directory = S_ISDIR(mode) != 0; - entry->executable = (mode & S_IXUSR) != 0; - entry->symlink = S_ISLNK(mode) != 0; - entry->next = NULL; - - *list_p = entry; - list_p = &entry->next; - } - return ret; -} - -void free_tree_entry_list(struct tree_entry_list *list) -{ - while (list) { - struct tree_entry_list *next = list->next; - free(list); - list = next; - } -} - int parse_tree(struct tree *item) { char type[20]; diff --git a/tree.h b/tree.h index 6a875464b0..dd25c539ef 100644 --- a/tree.h +++ b/tree.h @@ -5,25 +5,12 @@ extern const char *tree_type; -struct tree_entry_list { - struct tree_entry_list *next; - unsigned directory : 1; - unsigned executable : 1; - unsigned symlink : 1; - unsigned int mode; - const char *name; - const unsigned char *sha1; -}; - struct tree { struct object object; void *buffer; unsigned long size; }; -struct tree_entry_list *create_tree_entry_list(struct tree *); -void free_tree_entry_list(struct tree_entry_list *); - struct tree *lookup_tree(const unsigned char *sha1); int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size); -- cgit v1.3