* 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)
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 (;;) {
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)
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;