diff --git a/src/attr.c b/src/attr.c index ddcc3dcf0..17571f6a8 100644 --- a/src/attr.c +++ b/src/attr.c @@ -210,6 +210,13 @@ int git_attr_add_macro( return error; } +int git_attr_cache__is_cached(git_repository *repo, const char *path) +{ + const char *cache_key = path; + if (repo && git__prefixcmp(cache_key, git_repository_workdir(repo)) == 0) + cache_key += strlen(git_repository_workdir(repo)); + return (git_hashtable_lookup(repo->attrcache.files, cache_key) == NULL); +} /* add git_attr_file to vector of files, loading if needed */ int git_attr_cache__push_file( diff --git a/src/attr.h b/src/attr.h index a758cc4bd..ea27259f1 100644 --- a/src/attr.h +++ b/src/attr.h @@ -27,4 +27,7 @@ extern int git_attr_cache__push_file( const char *filename, int (*loader)(git_repository *, const char *, git_attr_file *)); +/* returns GIT_SUCCESS if path is in cache */ +extern int git_attr_cache__is_cached(git_repository *repo, const char *path); + #endif diff --git a/tests-clar/attr/repo.c b/tests-clar/attr/repo.c index 6fc36d2b6..7a716042a 100644 --- a/tests-clar/attr/repo.c +++ b/tests-clar/attr/repo.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "fileops.h" #include "git2/attr.h" +#include "attr.h" static git_repository *g_repo = NULL; @@ -89,6 +90,10 @@ void test_attr_repo__get_one(void) git_buf_free(&b); } + + cl_git_pass(git_attr_cache__is_cached(g_repo, ".git/info/attributes")); + cl_git_pass(git_attr_cache__is_cached(g_repo, ".gitattributes")); + cl_git_pass(git_attr_cache__is_cached(g_repo, "sub/.gitattributes")); } void test_attr_repo__get_many(void) diff --git a/tests-clar/status/ignore.c b/tests-clar/status/ignore.c index 3a66b3a7a..67aecba31 100644 --- a/tests-clar/status/ignore.c +++ b/tests-clar/status/ignore.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "fileops.h" #include "git2/attr.h" +#include "attr.h" static git_repository *g_repo = NULL; @@ -29,6 +30,7 @@ void test_status_ignore__0(void) const char *path; int expected; } test_cases[] = { + /* patterns "sub" and "ign" from .gitignore */ { "file", 0 }, { "ign", 1 }, { "sub", 1 }, @@ -38,6 +40,12 @@ void test_status_ignore__0(void) { "sub/sub/file", 0 }, { "sub/sub/ign", 1 }, { "sub/sub/sub", 1 }, + /* pattern "dir/" from .gitignore */ + { "dir", 1 }, + { "dir/", 1 }, + { "sub/dir", 1 }, + { "sub/dir/", 1 }, + { "sub/sub/dir", 0 }, /* dir is not actually a dir, but a file */ { NULL, 0 } }, *one_test; @@ -46,4 +54,8 @@ void test_status_ignore__0(void) cl_git_pass(git_status_should_ignore(g_repo, one_test->path, &ignored)); cl_assert_(ignored == one_test->expected, one_test->path); } + + /* confirm that ignore files were cached */ + cl_git_pass(git_attr_cache__is_cached(g_repo, ".git/info/exclude")); + cl_git_pass(git_attr_cache__is_cached(g_repo, ".gitignore")); } diff --git a/tests/resources/attr/dir/file b/tests/resources/attr/dir/file new file mode 100644 index 000000000..e69de29bb diff --git a/tests/resources/attr/gitignore b/tests/resources/attr/gitignore index 66f77694e..546d48f3a 100644 Binary files a/tests/resources/attr/gitignore and b/tests/resources/attr/gitignore differ diff --git a/tests/resources/attr/sub/dir/file b/tests/resources/attr/sub/dir/file new file mode 100644 index 000000000..e69de29bb diff --git a/tests/resources/attr/sub/sub/dir b/tests/resources/attr/sub/sub/dir new file mode 100644 index 000000000..e69de29bb