]> git.proxmox.com Git - libgit2.git/commitdiff
index: make sure to write cached subtrees if parent is invalidated
authorCarlos Martín Nieto <cmn@dwim.me>
Mon, 29 Sep 2014 06:03:22 +0000 (08:03 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Fri, 10 Oct 2014 17:43:42 +0000 (19:43 +0200)
If e.g. the root tree is invalidated, we still want to write out
its children, since those may still have valid cache entries.

src/tree-cache.c
tests/index/cache.c

index 48dc46a40bcfbc7ea1f8222eedcbb0fa9dafb13e..bf52b55307c9b5a0ea4d7bc08f3ef9ceaf3d4b0f 100644 (file)
@@ -280,10 +280,8 @@ static void write_tree(git_buf *out, git_tree_cache *tree)
 
        git_buf_printf(out, "%s%c%zd %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count);
 
-       if (tree->entry_count == -1)
-               return;
-
-       git_buf_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ);
+       if (tree->entry_count != -1)
+               git_buf_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ);
 
        for (i = 0; i < tree->children_count; i++)
                write_tree(out, tree->children[i]);
index ba2d51fa264b374e92ce4df1ec0dea044c2c718e..17a61a9f5a1dee730a834f0fba4e2552951c7005 100644 (file)
@@ -119,6 +119,59 @@ void test_index_cache__read_tree_no_children(void)
        git_index_free(index);
 }
 
+void test_index_cache__two_levels(void)
+{
+       git_tree *tree;
+       git_oid tree_id;
+       git_index *index;
+       git_index_entry entry;
+       const git_tree_cache *tree_cache;
+
+       cl_git_pass(git_repository_index(&index, g_repo));
+       cl_git_pass(git_index_clear(index));
+
+       memset(&entry, 0x0, sizeof(entry));
+       entry.mode = GIT_FILEMODE_BLOB;
+       cl_git_pass(git_oid_fromstr(&entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+       entry.path = "top-level.txt";
+       cl_git_pass(git_index_add(index, &entry));
+
+       entry.path = "subdir/file.txt";
+       cl_git_pass(git_index_add(index, &entry));
+
+       /* the read-tree fills the tree cache */
+       cl_git_pass(git_index_write_tree(&tree_id, index));
+       cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+       cl_git_pass(git_index_read_tree(index, tree));
+       git_tree_free(tree);
+       cl_git_pass(git_index_write(index));
+
+       /* we now must have cache entries for "" and "subdir" */
+       cl_assert(index->tree);
+       cl_assert(git_tree_cache_get(index->tree, "subdir"));
+
+       cl_git_pass(git_index_read(index, true));
+       /* we must still have cache entries for "" and "subdir", since we wrote it out */
+       cl_assert(index->tree);
+       cl_assert(git_tree_cache_get(index->tree, "subdir"));
+
+       entry.path = "top-level.txt";
+       cl_git_pass(git_oid_fromstr(&entry.id, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc"));
+       cl_git_pass(git_index_add(index, &entry));
+
+       /* writ out the index after we invalidate the root */
+       cl_git_pass(git_index_write(index));
+       cl_git_pass(git_index_read(index, true));
+
+       /* the cache for the subtree must still be valid, even if the root isn't */
+       cl_assert(index->tree);
+       cl_assert_equal_i(-1, index->tree->entry_count);
+       cl_assert_equal_i(1, index->tree->children_count);
+       tree_cache = git_tree_cache_get(index->tree, "subdir");
+       cl_assert(tree_cache);
+       cl_assert_equal_i(0, tree_cache->entry_count);
+}
+
 void test_index_cache__read_tree_children(void)
 {
        git_index *index;