path: root/tree-walk.c
diff options
authorLinus Torvalds <>2008-03-06 04:06:18 (GMT)
committerJunio C Hamano <>2008-03-09 08:43:47 (GMT)
commit91e4f03604bd089e09154e95294d5d08c805ea49 (patch)
tree4e558499cc4f26afc480983d28e9a1401fac818e /tree-walk.c
parent5803c6f8a2faf8cfbbd046d9ebd682b82bb2b086 (diff)
Make 'traverse_trees()' traverse conflicting DF entries in parallel
This makes the traverse_trees() entry comparator routine use the more relaxed form of name comparison that considers files and directories with the same name identical. We pass in a separate mask for just the directory entries, so that the callback routine can decide (if it wants to) to only handle one or the other type, but generally most (all?) users are expected to really want to see the case of a name 'foo' showing up in one tree as a file and in another as a directory at the same time. In particular, moving 'unpack_trees()' over to use this tree traversal mechanism requires this. Signed-off-by: Linus Torvalds <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'tree-walk.c')
1 files changed, 6 insertions, 2 deletions
diff --git a/tree-walk.c b/tree-walk.c
index 7170e37..842cb6a 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -62,7 +62,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1)
static int entry_compare(struct name_entry *a, struct name_entry *b)
- return base_name_compare(
+ return df_name_compare(
a->path, tree_entry_len(a->path, a->sha1), a->mode,
b->path, tree_entry_len(b->path, b->sha1), b->mode);
@@ -142,6 +142,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
for (;;) {
unsigned long mask = 0;
+ unsigned long dirmask = 0;
int i, last;
last = -1;
@@ -166,10 +167,13 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
mask = 0;
mask |= 1ul << i;
+ if (S_ISDIR(entry[i].mode))
+ dirmask |= 1ul << i;
last = i;
if (!mask)
+ dirmask &= mask;
* Clear all the unused name-entries.
@@ -179,7 +183,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
entry_clear(entry + i);
- ret = info->fn(n, mask, entry, info);
+ ret = info->fn(n, mask, dirmask, entry, info);
if (ret < 0)
if (ret)