diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-05 18:59:29 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-03-09 00:43:47 -0800 |
commit | 40d934df72eaf244c826d5c26da0896ce7185cb6 (patch) | |
tree | ee461fff98614c9a4593f16944a2ff0b05d00a78 /merge-tree.c | |
parent | 0ab9e1e8cdaefdd33bf24bb0be0ec766483f8bbe (diff) | |
download | git-40d934df72eaf244c826d5c26da0896ce7185cb6.tar.gz |
Make 'traverse_tree()' use linked structure rather than 'const char *base'
This makes the calling convention a bit less obvious, but a lot more
flexible. Instead of allocating and extending a new 'base' string, we
just link the top-most name into a linked list of the 'info' structure
when traversing a subdirectory, and we can generate the basename by
following the list.
Perhaps even more importantly, the linked list of info structures also
gives us a place to naturally save off other information than just the
directory name.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'merge-tree.c')
-rw-r--r-- | merge-tree.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/merge-tree.c b/merge-tree.c index e08324686c..a3511b76ca 100644 --- a/merge-tree.c +++ b/merge-tree.c @@ -168,7 +168,13 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsi return res; } -static void resolve(const char *base, struct name_entry *branch1, struct name_entry *result) +static char *traverse_path(const struct traverse_info *info, const struct name_entry *n) +{ + char *path = xmalloc(traverse_path_len(info, n) + 1); + return make_traverse_path(path, info, n); +} + +static void resolve(const struct traverse_info *info, struct name_entry *branch1, struct name_entry *result) { struct merge_list *orig, *final; const char *path; @@ -177,7 +183,7 @@ static void resolve(const char *base, struct name_entry *branch1, struct name_en if (!branch1) return; - path = xstrdup(mkpath("%s%s", base, result->path)); + path = traverse_path(info, result); orig = create_entry(2, branch1->mode, branch1->sha1, path); final = create_entry(0, result->mode, result->sha1, path); @@ -186,9 +192,8 @@ static void resolve(const char *base, struct name_entry *branch1, struct name_en add_merge_entry(final); } -static int unresolved_directory(const char *base, struct name_entry n[3]) +static int unresolved_directory(const struct traverse_info *info, struct name_entry n[3]) { - int baselen, pathlen; char *newbase; struct name_entry *p; struct tree_desc t[3]; @@ -204,13 +209,7 @@ static int unresolved_directory(const char *base, struct name_entry n[3]) } if (!S_ISDIR(p->mode)) return 0; - baselen = strlen(base); - pathlen = tree_entry_len(p->path, p->sha1); - newbase = xmalloc(baselen + pathlen + 2); - memcpy(newbase, base, baselen); - memcpy(newbase + baselen, p->path, pathlen); - memcpy(newbase + baselen + pathlen, "/", 2); - + newbase = traverse_path(info, p); buf0 = fill_tree_descriptor(t+0, n[0].sha1); buf1 = fill_tree_descriptor(t+1, n[1].sha1); buf2 = fill_tree_descriptor(t+2, n[2].sha1); @@ -224,7 +223,7 @@ static int unresolved_directory(const char *base, struct name_entry n[3]) } -static struct merge_list *link_entry(unsigned stage, const char *base, struct name_entry *n, struct merge_list *entry) +static struct merge_list *link_entry(unsigned stage, const struct traverse_info *info, struct name_entry *n, struct merge_list *entry) { const char *path; struct merge_list *link; @@ -234,17 +233,17 @@ static struct merge_list *link_entry(unsigned stage, const char *base, struct na if (entry) path = entry->path; else - path = xstrdup(mkpath("%s%s", base, n->path)); + path = traverse_path(info, n); link = create_entry(stage, n->mode, n->sha1, path); link->link = entry; return link; } -static void unresolved(const char *base, struct name_entry n[3]) +static void unresolved(const struct traverse_info *info, struct name_entry n[3]) { struct merge_list *entry = NULL; - if (unresolved_directory(base, n)) + if (unresolved_directory(info, n)) return; /* @@ -252,9 +251,9 @@ static void unresolved(const char *base, struct name_entry n[3]) * list has the stages in order - link_entry adds new * links at the front. */ - entry = link_entry(3, base, n + 2, entry); - entry = link_entry(2, base, n + 1, entry); - entry = link_entry(1, base, n + 0, entry); + entry = link_entry(3, info, n + 2, entry); + entry = link_entry(2, info, n + 1, entry); + entry = link_entry(1, info, n + 0, entry); add_merge_entry(entry); } @@ -288,36 +287,40 @@ static void unresolved(const char *base, struct name_entry n[3]) * The successful merge rules are the same as for the three-way merge * in git-read-tree. */ -static void threeway_callback(int n, unsigned long mask, struct name_entry *entry, const char *base) +static void threeway_callback(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *info) { /* Same in both? */ if (same_entry(entry+1, entry+2)) { if (entry[0].sha1) { - resolve(base, NULL, entry+1); + resolve(info, NULL, entry+1); return; } } if (same_entry(entry+0, entry+1)) { if (entry[2].sha1 && !S_ISDIR(entry[2].mode)) { - resolve(base, entry+1, entry+2); + resolve(info, entry+1, entry+2); return; } } if (same_entry(entry+0, entry+2)) { if (entry[1].sha1 && !S_ISDIR(entry[1].mode)) { - resolve(base, NULL, entry+1); + resolve(info, NULL, entry+1); return; } } - unresolved(base, entry); + unresolved(info, entry); } static void merge_trees(struct tree_desc t[3], const char *base) { - traverse_trees(3, t, base, threeway_callback); + struct traverse_info info; + + setup_traverse_info(&info, base); + info.fn = threeway_callback; + traverse_trees(3, t, &info); } static void *get_tree_descriptor(struct tree_desc *desc, const char *rev) |