summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-04-20 10:58:17 (GMT)
committerJunio C Hamano <gitster@pobox.com>2009-04-20 11:16:40 (GMT)
commit8cc21ce78c2f3781024117047c0650861f890213 (patch)
treee0d6ba9e39e77bf56d5977a26b60b50bc351ddb7
parent1f9b620fdbf27835f54b11008d64c4014b8f4c32 (diff)
downloadgit-8cc21ce78c2f3781024117047c0650861f890213.zip
git-8cc21ce78c2f3781024117047c0650861f890213.tar.gz
git-8cc21ce78c2f3781024117047c0650861f890213.tar.bz2
read-tree A B: do not corrupt cache-tree
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>
-rw-r--r--builtin-read-tree.c6
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))