| #include "clar_libgit2.h" |
| #include "git2.h" |
| #include "index.h" |
| #include "tree-cache.h" |
| |
| static git_repository *g_repo; |
| |
| void test_index_cache__initialize(void) |
| { |
| g_repo = cl_git_sandbox_init("testrepo"); |
| } |
| |
| void test_index_cache__cleanup(void) |
| { |
| cl_git_sandbox_cleanup(); |
| g_repo = NULL; |
| } |
| |
| void test_index_cache__write_extension_at_root(void) |
| { |
| git_index *index; |
| git_tree *tree; |
| git_oid id; |
| const char *tree_id_str = "45dd856fdd4d89b884c340ba0e047752d9b085d6"; |
| const char *index_file = "index-tree"; |
| |
| cl_git_pass(git_index_open(&index, index_file)); |
| cl_assert(index->tree == NULL); |
| cl_git_pass(git_oid_fromstr(&id, tree_id_str)); |
| cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); |
| cl_git_pass(git_index_read_tree(index, tree)); |
| git_tree_free(tree); |
| |
| cl_assert(index->tree); |
| cl_git_pass(git_index_write(index)); |
| git_index_free(index); |
| |
| cl_git_pass(git_index_open(&index, index_file)); |
| cl_assert(index->tree); |
| |
| cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count); |
| cl_assert_equal_i(0, index->tree->children_count); |
| |
| cl_assert(git_oid_equal(&id, &index->tree->oid)); |
| |
| cl_git_pass(p_unlink(index_file)); |
| git_index_free(index); |
| } |
| |
| void test_index_cache__write_extension_invalidated_root(void) |
| { |
| git_index *index; |
| git_tree *tree; |
| git_oid id; |
| const char *tree_id_str = "45dd856fdd4d89b884c340ba0e047752d9b085d6"; |
| const char *index_file = "index-tree-invalidated"; |
| git_index_entry entry; |
| |
| cl_git_pass(git_index_open(&index, index_file)); |
| cl_assert(index->tree == NULL); |
| cl_git_pass(git_oid_fromstr(&id, tree_id_str)); |
| cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); |
| cl_git_pass(git_index_read_tree(index, tree)); |
| git_tree_free(tree); |
| |
| cl_assert(index->tree); |
| |
| memset(&entry, 0x0, sizeof(git_index_entry)); |
| git_oid_cpy(&entry.id, &git_index_get_byindex(index, 0)->id); |
| entry.mode = GIT_FILEMODE_BLOB; |
| entry.path = "some-new-file.txt"; |
| |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| cl_assert_equal_i(-1, index->tree->entry_count); |
| |
| cl_git_pass(git_index_write(index)); |
| git_index_free(index); |
| |
| cl_git_pass(git_index_open(&index, index_file)); |
| cl_assert(index->tree); |
| |
| cl_assert_equal_i(-1, index->tree->entry_count); |
| cl_assert_equal_i(0, index->tree->children_count); |
| |
| cl_assert(git_oid_cmp(&id, &index->tree->oid)); |
| |
| cl_git_pass(p_unlink(index_file)); |
| git_index_free(index); |
| } |
| |
| void test_index_cache__read_tree_no_children(void) |
| { |
| git_index *index; |
| git_index_entry entry; |
| git_tree *tree; |
| git_oid id; |
| |
| cl_git_pass(git_index_new(&index)); |
| cl_assert(index->tree == NULL); |
| cl_git_pass(git_oid_fromstr(&id, "45dd856fdd4d89b884c340ba0e047752d9b085d6")); |
| cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); |
| cl_git_pass(git_index_read_tree(index, tree)); |
| git_tree_free(tree); |
| |
| cl_assert(index->tree); |
| cl_assert(git_oid_equal(&id, &index->tree->oid)); |
| cl_assert_equal_i(0, index->tree->children_count); |
| cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count); |
| |
| memset(&entry, 0x0, sizeof(git_index_entry)); |
| entry.path = "new.txt"; |
| entry.mode = GIT_FILEMODE_BLOB; |
| git_oid_fromstr(&entry.id, "d4bcc68acd4410bf836a39f20afb2c2ece09584e"); |
| |
| cl_git_pass(git_index_add(index, &entry)); |
| cl_assert_equal_i(-1, index->tree->entry_count); |
| |
| 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(1, tree_cache->entry_count); |
| |
| git_index_free(index); |
| } |
| |
| void test_index_cache__read_tree_children(void) |
| { |
| git_index *index; |
| git_index_entry entry; |
| git_tree *tree; |
| const git_tree_cache *cache; |
| git_oid tree_id; |
| |
| cl_git_pass(git_repository_index(&index, g_repo)); |
| cl_git_pass(git_index_clear(index)); |
| cl_assert(index->tree == NULL); |
| |
| |
| /* add a bunch of entries at different levels */ |
| memset(&entry, 0x0, sizeof(git_index_entry)); |
| entry.path = "top-level"; |
| entry.mode = GIT_FILEMODE_BLOB; |
| git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| |
| entry.path = "subdir/some-file"; |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| entry.path = "subdir/even-deeper/some-file"; |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| entry.path = "subdir2/some-file"; |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| cl_git_pass(git_index_write_tree(&tree_id, index)); |
| cl_git_pass(git_index_clear(index)); |
| cl_assert(index->tree == NULL); |
| |
| 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_assert(index->tree); |
| cl_assert_equal_i(2, index->tree->children_count); |
| |
| /* override with a slightly different id, also dummy */ |
| entry.path = "subdir/some-file"; |
| git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"); |
| cl_git_pass(git_index_add(index, &entry)); |
| |
| cl_assert_equal_i(-1, index->tree->entry_count); |
| |
| cache = git_tree_cache_get(index->tree, "subdir"); |
| cl_assert(cache); |
| cl_assert_equal_i(-1, cache->entry_count); |
| |
| cache = git_tree_cache_get(index->tree, "subdir/even-deeper"); |
| cl_assert(cache); |
| cl_assert_equal_i(1, cache->entry_count); |
| |
| cache = git_tree_cache_get(index->tree, "subdir2"); |
| cl_assert(cache); |
| cl_assert_equal_i(1, cache->entry_count); |
| |
| git_index_free(index); |
| } |