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:
parent
40d934df72
commit
5803c6f8a2
@ -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)
|
||||
|
22
tree-walk.c
22
tree-walk.c
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user