diff --git a/src/tree-cache.c b/src/tree-cache.c index 48dc46a40..bf52b5530 100644 --- a/src/tree-cache.c +++ b/src/tree-cache.c @@ -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]); diff --git a/tests/index/cache.c b/tests/index/cache.c index ba2d51fa2..17a61a9f5 100644 --- a/tests/index/cache.c +++ b/tests/index/cache.c @@ -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;