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

[PATCH 1/4] read-tree A B: do not corrupt cache-tree

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 20, 2009, 10:58 UTC
Message-ID
<1240225100-29960-2-git-send-email-gitster@pobox.com>
In-Reply-To
<1240225100-29960-1-git-send-email-gitster@pobox.com>

An earlier commit aab3b9a (read-tree A B C: do not create a bogus index and do not segfault, 2009-03-12) resurrected the support for an obscure (but useful) feature to read and overlay more than one tree into the index without the -m (merge) option. But the fix was not enough.

Exercising this feature exposes a longstanding bug in the code that primes the cache-tree in the index from the tree that was read. The intention was that when we know that the index must exactly match the tree we just read, we prime the entire cache-tree with it.

However, the logic to detect that case incorrectly triggered if you read two trees without -m. This resulted in a corrupted cache-tree, and write-tree would have produced an incorrect tree object out of such an index.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 * Meant for maint.
 builtin-read-tree.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 38fef34..e4e0e71 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -211,7 +211,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 		case 3:
 		default:
 			opts.fn = threeway_merge;
-			cache_tree_free(&active_cache_tree);
 			break;
 		}
 
@@ -221,6 +220,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 			opts.head_idx = 1;
 	}
 
+	cache_tree_free(&active_cache_tree);
 	for (i = 0; i < nr_trees; i++) {
 		struct tree *tree = trees[i];
 		parse_tree(tree);
@@ -235,10 +235,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 	 * valid cache-tree because the index must match exactly
 	 * what came from the tree.
 	 */
-	if (nr_trees && !opts.prefix && (!opts.merge || (stage == 2))) {
-		cache_tree_free(&active_cache_tree);
+	if (nr_trees == 1 && !opts.prefix)
 		prime_cache_tree();
-	}
 
 	if (write_cache(newfd, active_cache, active_nr) ||
 	    commit_locked_index(&lock_file))
-- 
1.6.3.rc1.18.g66996
Previous: Junio C HamanoNext: Junio C Hamano
Message 2 of 6 in “Revisiting cache-tree”
  1. 0/4 Revisiting cache-treeJunio C Hamano, Apr 20, 2009
  2. 1/4 read-tree A B: do not corrupt cache-treeJunio C Hamano, Apr 20, 2009
  3. 2/4 Move prime_cache_tree() to cache-tree.cJunio C Hamano, Apr 20, 2009
  4. 3/4 read-tree -m A B: prime cache-tree from the switched-to treeJunio C Hamano, Apr 20, 2009
  5. 4/4 checkout branch: prime cache-tree fullyJunio C Hamano, Apr 20, 2009
  6. Alex RiesenApr 20, 2009

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.