Skip to content

Commit

Permalink
Make 'traverse_trees()' traverse conflicting DF entries in parallel
Browse files Browse the repository at this point in the history
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 <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Mar 9, 2008
1 parent 5803c6f commit 91e4f03
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 4 deletions.
2 changes: 1 addition & 1 deletion merge-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3])
* The successful merge rules are the same as for the three-way merge
* in git-read-tree.
*/
static int threeway_callback(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *info)
static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *info)
{
/* Same in both? */
if (same_entry(entry+1, entry+2)) {
Expand Down
8 changes: 6 additions & 2 deletions tree-walk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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)
break;
dirmask &= mask;

/*
* Clear all the unused name-entries.
Expand All @@ -179,7 +183,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
continue;
entry_clear(entry + i);
}
ret = info->fn(n, mask, entry, info);
ret = info->fn(n, mask, dirmask, entry, info);
if (ret < 0)
break;
if (ret)
Expand Down
3 changes: 2 additions & 1 deletion tree-walk.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ int tree_entry(struct tree_desc *, struct name_entry *);
void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1);

struct traverse_info;
typedef int (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *);
typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *);
int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);

struct traverse_info {
struct traverse_info *prev;
struct name_entry name;
int pathlen;

unsigned long conflicts;
traverse_callback_t fn;
void *data;
};
Expand Down

0 comments on commit 91e4f03

Please sign in to comment.