git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/5] Add return value to 'traverse_tree()' callback

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Mar 6, 2008, 03:44 UTC
Message-ID
<b76bfb983fb30e3f9b6a7391ed2c11ac7e131f01.1204777699.git.torvalds@linux-foundation.org>
In-Reply-To
<cover.1204777699.git.torvalds@linux-foundation.org>

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>
---
 merge-tree.c |    9 +++++----
 tree-walk.c  |   22 +++++++++++++++-------
 tree-walk.h  |    4 ++--
 3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/merge-tree.c b/merge-tree.c
index a3511b7..8be0b9f 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -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)
diff --git a/tree-walk.c b/tree-walk.c
index f9f7d22..7170e37 100644
--- a/tree-walk.c
+++ b/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)
diff --git a/tree-walk.h b/tree-walk.h
index 7c4ae64..c123cfe 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -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;
-- 
1.5.4.3.452.g67136
Previous: Linus TorvaldsNext: Linus Torvalds
Message 7 of 12 in “Split-up "unpack_trees()" cleanup series”
  1. 0/5 Split-up "unpack_trees()" cleanup seriesLinus Torvalds, Mar 6, 2008
  2. 1/5 Add 'df_name_compare()' helper functionLinus Torvalds, Mar 6, 2008
  3. David KastrupMar 6, 2008
  4. Linus TorvaldsMar 6, 2008
  5. David KastrupMar 6, 2008
  6. 2/5 Make 'traverse_tree()' use linked structure rather than 'const char *base'Linus Torvalds, Mar 6, 2008
  7. 3/5 Add return value to 'traverse_tree()' callbackLinus Torvalds, Mar 6, 2008
  8. 4/5 Make 'traverse_trees()' traverse conflicting DF entries in parallelLinus Torvalds, Mar 6, 2008
  9. 5/5 Move 'unpack_trees()' over to 'traverse_trees()' interfaceLinus Torvalds, Mar 6, 2008
  10. Linus TorvaldsMar 6, 2008
  11. Daniel BarkalowMar 7, 2008
  12. Linus TorvaldsMar 7, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.