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;