Code

Add return value to 'traverse_tree()' callback
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Mar 2008 03:44:06 +0000 (19:44 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 9 Mar 2008 08:43:47 +0000 (00:43 -0800)
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>
merge-tree.c
tree-walk.c
tree-walk.h

index a3511b76ca5f619024ac5fedd17e66ef75f717ab..8be0b9f910b7c2fa9506ffe5fb31bd4632eaa1a1 100644 (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)
index f9f7d225e976a7da5c3a83aef08ed070aa492eb9..7170e375b3473aaced9b639d915c93ff931be859 100644 (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)
index 7c4ae646be201ce17e30eb1c935ad9acb6f4a0e9..c123cfeef4abeff5e750d7faa23481619d995ce6 100644 (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;