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 --- fsck-objects.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'fsck-objects.c') diff --git a/fsck-objects.c b/fsck-objects.c index 1922b6d84c..5e65df436b 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -198,17 +198,16 @@ static int fsck_tree(struct tree *item) default: break; } - free(last->name); free(last); } last = entry; } - if (last) { - free(last->name); + if (last) free(last); - } item->entries = NULL; + free(item->buffer); + item->buffer = NULL; retval = 0; if (has_full_path) { -- 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 'fsck-objects.c') 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 'fsck-objects.c') 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 e9a95bef7f9648b3827813906582bb8a6d922d21 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 May 2006 12:19:02 -0700 Subject: fsck-objects: avoid unnecessary tree_entry_list usage Prime example of where the raw tree parser is easier for everybody. [jc: "Aieee" one-liner fix from the list applied. ] Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- fsck-objects.c | 57 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'fsck-objects.c') diff --git a/fsck-objects.c b/fsck-objects.c index 42778e87d0..33ce366e99 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -9,6 +9,7 @@ #include "refs.h" #include "pack.h" #include "cache-tree.h" +#include "tree-walk.h" #define REACHABLE 0x0001 #define SEEN 0x0002 @@ -116,15 +117,15 @@ static void check_connectivity(void) #define TREE_UNORDERED (-1) #define TREE_HAS_DUPS (-2) -static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b) +static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, const char *name2) { - int len1 = strlen(a->name); - int len2 = strlen(b->name); + int len1 = strlen(name1); + int len2 = strlen(name2); int len = len1 < len2 ? len1 : len2; unsigned char c1, c2; int cmp; - cmp = memcmp(a->name, b->name, len); + cmp = memcmp(name1, name2, len); if (cmp < 0) return 0; if (cmp > 0) @@ -135,8 +136,8 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b) * Now we need to order the next one, but turn * a '\0' into a '/' for a directory entry. */ - c1 = a->name[len]; - c2 = b->name[len]; + c1 = name1[len]; + c2 = name2[len]; if (!c1 && !c2) /* * git-write-tree used to write out a nonsense tree that has @@ -144,9 +145,9 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b) * sure we do not have duplicate entries. */ return TREE_HAS_DUPS; - if (!c1 && a->directory) + if (!c1 && S_ISDIR(mode1)) c1 = '/'; - if (!c2 && b->directory) + if (!c2 && S_ISDIR(mode2)) c2 = '/'; return c1 < c2 ? 0 : TREE_UNORDERED; } @@ -159,17 +160,32 @@ static int fsck_tree(struct tree *item) int has_bad_modes = 0; int has_dup_entries = 0; int not_properly_sorted = 0; - struct tree_entry_list *entry, *last; + struct tree_desc desc; + unsigned o_mode; + const char *o_name; + const unsigned char *o_sha1; - last = NULL; - for (entry = create_tree_entry_list(item); entry; entry = entry->next) { - if (strchr(entry->name, '/')) + desc.buf = item->buffer; + desc.size = item->size; + + o_mode = 0; + o_name = NULL; + o_sha1 = NULL; + while (desc.size) { + unsigned mode; + const char *name; + const unsigned char *sha1; + + sha1 = tree_entry_extract(&desc, &name, &mode); + + if (strchr(name, '/')) has_full_path = 1; - has_zero_pad |= entry->zeropad; + has_zero_pad |= *(char *)desc.buf == '0'; + update_tree_entry(&desc); - switch (entry->mode) { + switch (mode) { /* - * Standard modes.. + * Standard modes.. */ case S_IFREG | 0755: case S_IFREG | 0644: @@ -188,8 +204,8 @@ static int fsck_tree(struct tree *item) has_bad_modes = 1; } - if (last) { - switch (verify_ordered(last, entry)) { + if (o_name) { + switch (verify_ordered(o_mode, o_name, mode, name)) { case TREE_UNORDERED: not_properly_sorted = 1; break; @@ -199,13 +215,12 @@ static int fsck_tree(struct tree *item) default: break; } - free(last); } - last = entry; + o_mode = mode; + o_name = name; + o_sha1 = sha1; } - if (last) - free(last); free(item->buffer); item->buffer = NULL; -- cgit v1.3