@matheusbsbs / matheus-bagliano / commits / 5803c6f8a2
Fork 0

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>

Linus Torvalds committed Mar 5, 2008 at 19:44 UTC 5803c6f8a2faf8cfbbd046d9ebd682b82bb2b086
3 files changed +22 -13
merge-tree.c
+5 -4
@@ -287,31 +287,32 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3])
287 * The successful merge rules are the same as for the three-way merge
288 * in git-read-tree.
289 */
290 -static void threeway_callback(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *info)
290 +static int threeway_callback(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *info)
291 {
292 /* Same in both? */
293 if (same_entry(entry+1, entry+2)) {
294 if (entry[0].sha1) {
295 resolve(info, NULL, entry+1);
296 - return;
296 + return mask;
297 }
298 }
299
300 if (same_entry(entry+0, entry+1)) {
301 if (entry[2].sha1 && !S_ISDIR(entry[2].mode)) {
302 resolve(info, entry+1, entry+2);
303 - return;
303 + return mask;
304 }
305 }
306
307 if (same_entry(entry+0, entry+2)) {
308 if (entry[1].sha1 && !S_ISDIR(entry[1].mode)) {
309 resolve(info, NULL, entry+1);
310 - return;
310 + return mask;
311 }
312 }
313
314 unresolved(info, entry);
315 + return mask;
316 }
317
318 static void merge_trees(struct tree_desc t[3], const char *base)
tree-walk.c
+15 -7
@@ -135,8 +135,9 @@ char *make_traverse_path(char *path, const struct traverse_info *info, const str
135 return path;
136 }
137
138 -void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
138 +int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
139 {
140 + int ret = 0;
141 struct name_entry *entry = xmalloc(n*sizeof(*entry));
142
143 for (;;) {
@@ -171,19 +172,26 @@ void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
172 break;
173
174 /*
174 - * Update the tree entries we've walked, and clear
175 - * all the unused name-entries.
175 + * Clear all the unused name-entries.
176 */
177 for (i = 0; i < n; i++) {
178 - if (mask & (1ul << i)) {
179 - update_tree_entry(t+i);
178 + if (mask & (1ul << i))
179 continue;
181 - }
180 entry_clear(entry + i);
181 }
184 - info->fn(n, mask, entry, info);
182 + ret = info->fn(n, mask, entry, info);
183 + if (ret < 0)
184 + break;
185 + if (ret)
186 + mask &= ret;
187 + ret = 0;
188 + for (i = 0; i < n; i++) {
189 + if (mask & (1ul << i))
190 + update_tree_entry(t + i);
191 + }
192 }
193 free(entry);
194 + return ret;
195 }
196
197 static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode)
tree-walk.h
+2 -2
@@ -34,8 +34,8 @@ int tree_entry(struct tree_desc *, struct name_entry *);
34 void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1);
35
36 struct traverse_info;
37 -typedef void (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *);
38 -void traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);
37 +typedef int (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, struct traverse_info *);
38 +int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);
39
40 struct traverse_info {
41 struct traverse_info *prev;