Add return value to 'traverse_tree()' callback

This allows the callback to return an error value, but it can also
specify which of the tree entries that it actually used up by returning
a positive mask value.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Linus Torvalds 2008-03-05 19:44:06 -08:00 committed by Junio C Hamano
parent 40d934df72
commit 5803c6f8a2
3 changed files with 22 additions and 13 deletions

View File

@ -287,31 +287,32 @@ 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 void threeway_callback(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *info)
static int 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(info, NULL, entry+1);
return;
return mask;
}
}
if (same_entry(entry+0, entry+1)) {
if (entry[2].sha1 && !S_ISDIR(entry[2].mode)) {
resolve(info, entry+1, entry+2);
return;
return mask;
}
}
if (same_entry(entry+0, entry+2)) {
if (entry[1].sha1 && !S_ISDIR(entry[1].mode)) {
resolve(info, NULL, entry+1);
return;
return mask;
}
}
unresolved(info, entry);
return mask;
}
static void merge_trees(struct tree_desc t[3], const char *base)

View File

@ -135,8 +135,9 @@ char *make_traverse_path(char *path, const struct traverse_info *info, const str
return path;
}
void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
{
int ret = 0;
struct name_entry *entry = xmalloc(n*sizeof(*entry));
for (;;) {
@ -171,19 +172,26 @@ void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
break;
/*
* Update the tree entries we've walked, and clear
* all the unused name-entries.
* Clear all the unused name-entries.
*/
for (i = 0; i < n; i++) {
if (mask & (1ul << i)) {
update_tree_entry(t+i);
if (mask & (1ul << i))
continue;
}
entry_clear(entry + i);
}
info->fn(n, mask, entry, info);
ret = info->fn(n, mask, entry, info);
if (ret < 0)
break;
if (ret)
mask &= ret;
ret = 0;
for (i = 0; i < n; i++) {
if (mask & (1ul << i))
update_tree_entry(t + i);
}
}
free(entry);
return ret;
}
static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode)

View File

@ -34,8 +34,8 @@ 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 void (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *);
void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);
typedef int (*traverse_callback_t)(int n, unsigned long mask, 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;