From: Junio C Hamano Date: Sun, 4 Jun 2006 06:59:27 +0000 (-0700) Subject: Merge branch 'lt/tree-2' X-Git-Tag: v1.4.0-rc1~10 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/16a4c6ee0d9a3d07d4d0afbbc4e3467e78065eca?ds=inline;hp=-c Merge branch 'lt/tree-2' * lt/tree-2: fetch.c: do not call process_tree() from process_tree(). tree_entry(): new tree-walking helper function adjust to the rebased series by Linus. Remove "tree->entries" tree-entry list from tree parser Switch "read_tree_recursive()" over to tree-walk functionality Make "tree_entry" have a SHA1 instead of a union of object pointers Add raw tree buffer info to "struct tree" Remove last vestiges of generic tree_entry_list Convert fetch.c: process_tree() to raw tree walker Convert "mark_tree_uninteresting()" to raw tree walker Remove unused "zeropad" entry from tree_list_entry fsck-objects: avoid unnecessary tree_entry_list usage Remove "tree->entries" tree-entry list from tree parser builtin-read-tree.c: avoid tree_entry_list in prime_cache_tree_rec() Switch "read_tree_recursive()" over to tree-walk functionality Make "tree_entry" have a SHA1 instead of a union of object pointers Make "struct tree" contain the pointer to the tree buffer --- 16a4c6ee0d9a3d07d4d0afbbc4e3467e78065eca diff --combined builtin-read-tree.c index 21361dff42,10afd46968..085e11e7c4 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@@ -9,6 -9,7 +9,7 @@@ #include "object.h" #include "tree.h" + #include "tree-walk.h" #include "cache-tree.h" #include #include @@@ -29,7 -30,17 +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 = { @@@ -39,7 -50,35 +50,35 @@@ typedef int (*merge_fn_t)(struct cache_entry **src); - static int entcmp(char *name1, int dir1, char *name2, int dir2) + static struct tree_entry_list *create_tree_entry_list(struct tree *tree) + { + struct tree_desc desc; + struct name_entry one; + struct tree_entry_list *ret = NULL; + struct tree_entry_list **list_p = &ret; + + desc.buf = tree->buffer; + desc.size = tree->size; + + while (tree_entry(&desc, &one)) { + struct tree_entry_list *entry; + + entry = xmalloc(sizeof(struct tree_entry_list)); + entry->name = one.path; + entry->sha1 = one.sha1; + entry->mode = one.mode; + entry->directory = S_ISDIR(one.mode) != 0; + entry->executable = (one.mode & S_IXUSR) != 0; + entry->symlink = S_ISLNK(one.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); int len2 = strlen(name2); @@@ -67,7 -106,7 +106,7 @@@ static int unpack_trees_rec(struct tree int src_size = len + 1; do { int i; - char *first; + const char *first; int firstdir = 0; int pathlen; unsigned ce_size; @@@ -161,9 -200,10 +200,10 @@@ } 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] = create_tree_entry_list(tree); posns[i] = posns[i]->next; src[i + merge] = &df_conflict_entry; continue; @@@ -187,7 -227,7 +227,7 @@@ 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; @@@ -368,7 -408,7 +408,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)) @@@ -751,43 -791,46 +791,47 @@@ static int oneway_merge(struct cache_en static int read_cache_unmerged(void) { - int i, deleted; + int i; struct cache_entry **dst; + struct cache_entry *last = NULL; read_cache(); dst = active_cache; - deleted = 0; for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; if (ce_stage(ce)) { - deleted++; + if (last && !strcmp(ce->name, last->name)) + continue; invalidate_ce_path(ce); - continue; + last = ce; + ce->ce_mode = 0; + ce->ce_flags &= ~htons(CE_STAGEMASK); } - if (deleted) - *dst = ce; - dst++; + *dst++ = ce; } - active_nr -= deleted; - return deleted; + active_nr = dst - active_cache; + return !!last; } static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) { - struct tree_entry_list *ent; + struct tree_desc desc; + struct name_entry entry; int cnt; memcpy(it->sha1, tree->object.sha1, 20); - for (cnt = 0, ent = tree->entries; ent; ent = ent->next) { - if (!ent->directory) + desc.buf = tree->buffer; + desc.size = tree->size; + cnt = 0; + while (tree_entry(&desc, &entry)) { + if (!S_ISDIR(entry.mode)) cnt++; else { struct cache_tree_sub *sub; - struct tree *subtree = (struct tree *)ent->item.tree; + struct tree *subtree = lookup_tree(entry.sha1); if (!subtree->object.parsed) parse_tree(subtree); - sub = cache_tree_sub(it, ent->name); + sub = cache_tree_sub(it, entry.path); sub->cache_tree = cache_tree(); prime_cache_tree_rec(sub->cache_tree, subtree); cnt += sub->cache_tree->entry_count; @@@ -851,10 -894,7 +895,10 @@@ int cmd_read_tree(int argc, const char continue; } - /* This differs from "-m" in that we'll silently ignore unmerged entries */ + /* This differs from "-m" in that we'll silently ignore + * unmerged entries and overwrite working tree files that + * correspond to them. + */ if (!strcmp(arg, "--reset")) { if (stage || merge) usage(read_tree_usage); diff --combined fetch.c index cc6013e7af,107504b72b..e040ef97b6 --- a/fetch.c +++ b/fetch.c @@@ -3,12 -3,12 +3,13 @@@ #include "cache.h" #include "commit.h" #include "tree.h" + #include "tree-walk.h" #include "tag.h" #include "blob.h" #include "refs.h" const char *write_ref = NULL; +const char *write_ref_log_details = NULL; int get_tree = 0; int get_history = 0; @@@ -37,21 -37,33 +38,33 @@@ static int process(struct object *obj) static int process_tree(struct tree *tree) { - struct tree_entry_list *entry; + struct tree_desc desc; + struct name_entry entry; if (parse_tree(tree)) return -1; - entry = tree->entries; - tree->entries = NULL; - while (entry) { - struct tree_entry_list *next = entry->next; - if (process(entry->item.any)) + desc.buf = tree->buffer; + desc.size = tree->size; + while (tree_entry(&desc, &entry)) { + struct object *obj = NULL; + + if (S_ISDIR(entry.mode)) { + struct tree *tree = lookup_tree(entry.sha1); + if (tree) + obj = &tree->object; + } + else { + struct blob *blob = lookup_blob(entry.sha1); + if (blob) + obj = &blob->object; + } + if (!obj || process(obj)) return -1; - free(entry->name); - free(entry); - entry = next; } + free(tree->buffer); + tree->buffer = NULL; + tree->size = 0; return 0; } @@@ -203,51 -215,23 +216,51 @@@ static int mark_complete(const char *pa int pull(char *target) { + struct ref_lock *lock = NULL; unsigned char sha1[20]; + char *msg; + int ret; save_commit_buffer = 0; track_object_refs = 0; + if (write_ref) { + lock = lock_ref_sha1(write_ref, NULL, 0); + if (!lock) { + error("Can't lock ref %s", write_ref); + return -1; + } + } if (!get_recover) for_each_ref(mark_complete); - if (interpret_target(target, sha1)) - return error("Could not interpret %s as something to pull", - target); - if (process(lookup_unknown_object(sha1))) + if (interpret_target(target, sha1)) { + error("Could not interpret %s as something to pull", target); + if (lock) + unlock_ref(lock); return -1; - if (loop()) + } + if (process(lookup_unknown_object(sha1))) { + if (lock) + unlock_ref(lock); return -1; - - if (write_ref) - write_ref_sha1_unlocked(write_ref, sha1); + } + if (loop()) { + if (lock) + unlock_ref(lock); + return -1; + } + + if (write_ref) { + if (write_ref_log_details) { + msg = xmalloc(strlen(write_ref_log_details) + 12); + sprintf(msg, "fetch from %s", write_ref_log_details); + } else + msg = NULL; + ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)"); + if (msg) + free(msg); + return ret; + } return 0; }