diff options
author | Russell Belfer <arrbee@arrbee.com> | 2012-01-16 16:58:27 -0800 |
---|---|---|
committer | Russell Belfer <arrbee@arrbee.com> | 2012-01-16 16:58:27 -0800 |
commit | a51cd8e6f6724079a552b75e014f792f3f68e158 (patch) | |
tree | fcf526f2a7575e215d95589d1a8e07277981fd18 | |
parent | 6e03b12f5715cb3f5cb5c8be6512e041cdf44a05 (diff) | |
download | libgit2-a51cd8e6f6724079a552b75e014f792f3f68e158.tar.gz |
Fix handling of relative paths for attrs
Per issue #533, the handling of relative paths in attribute
and ignore files was not right. Fixed this by pre-joining
the relative path of the attribute/ignore file onto the match
string when a full path match is required.
Unfortunately, fixing this required a bit more code than I
would have liked because I had to juggle things around so that
the fnmatch parser would have sufficient information to prepend
the relative path when it was needed.
24 files changed, 232 insertions, 105 deletions
diff --git a/src/attr.c b/src/attr.c index dc42379ff..3fe76d124 100644 --- a/src/attr.c +++ b/src/attr.c @@ -214,7 +214,7 @@ int git_attr_cache__push_file( git_vector *stack, const char *base, const char *filename, - int (*loader)(git_repository *, const char *, git_attr_file **)) + int (*loader)(git_repository *, const char *, git_attr_file *)) { int error = GIT_SUCCESS; git_attr_cache *cache = &repo->attrcache; @@ -231,11 +231,12 @@ int git_attr_cache__push_file( /* either get attr_file from cache or read from disk */ file = git_hashtable_lookup(cache->files, filename); if (file == NULL && git_futils_exists(filename) == GIT_SUCCESS) { - error = (*loader)(repo, filename, &file); + if ((error = git_attr_file__new(&file)) == GIT_SUCCESS) + error = (*loader)(repo, filename, file); add_to_cache = (error == GIT_SUCCESS); } - if (file != NULL) { + if (error == GIT_SUCCESS && file != NULL) { /* add file to vector, if we found it */ error = git_vector_insert(stack, file); diff --git a/src/attr.h b/src/attr.h index 5edff30d1..a758cc4bd 100644 --- a/src/attr.h +++ b/src/attr.h @@ -25,6 +25,6 @@ extern int git_attr_cache__push_file( git_vector *stack, const char *base, const char *filename, - int (*loader)(git_repository *, const char *, git_attr_file **)); + int (*loader)(git_repository *, const char *, git_attr_file *)); #endif diff --git a/src/attr_file.c b/src/attr_file.c index 5ea07c984..f6eaad69d 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -31,21 +31,46 @@ int git_attr_file__new(git_attr_file **attrs_ptr) return error; } +int git_attr_file__set_path( + git_repository *repo, const char *path, git_attr_file *file) +{ + if (file->path != NULL) { + git__free(file->path); + file->path = NULL; + } + + if (repo == NULL) + file->path = git__strdup(path); + else { + const char *workdir = git_repository_workdir(repo); + + if (workdir && git__prefixcmp(path, workdir) == 0) + file->path = git__strdup(path + strlen(workdir)); + else + file->path = git__strdup(path); + } + + return (file->path == NULL) ? GIT_ENOMEM : GIT_SUCCESS; +} + int git_attr_file__from_buffer( - git_repository *repo, const char *buffer, git_attr_file **out) + git_repository *repo, const char *buffer, git_attr_file *attrs) { int error = GIT_SUCCESS; - git_attr_file *attrs = NULL; const char *scan = NULL; + char *context = NULL; git_attr_rule *rule = NULL; - *out = NULL; - - if ((error = git_attr_file__new(&attrs)) < GIT_SUCCESS) - goto cleanup; + assert(buffer && attrs); scan = buffer; + if (attrs->path && git__suffixcmp(attrs->path, GIT_ATTR_FILE) == 0) { + context = git__strndup(attrs->path, + strlen(attrs->path) - strlen(GIT_ATTR_FILE)); + if (!context) error = GIT_ENOMEM; + } + while (error == GIT_SUCCESS && *scan) { /* allocate rule if needed */ if (!rule && !(rule = git__calloc(1, sizeof(git_attr_rule)))) { @@ -54,7 +79,7 @@ int git_attr_file__from_buffer( } /* parse the next "pattern attr attr attr" line */ - if (!(error = git_attr_fnmatch__parse(&rule->match, &scan)) && + if (!(error = git_attr_fnmatch__parse(&rule->match, context, &scan)) && !(error = git_attr_assignment__parse(repo, &rule->assigns, &scan))) { if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO) @@ -76,35 +101,30 @@ int git_attr_file__from_buffer( } } -cleanup: - if (error != GIT_SUCCESS) { - git_attr_rule__free(rule); - git_attr_file__free(attrs); - } else { - *out = attrs; - } + git_attr_rule__free(rule); + git__free(context); return error; } int git_attr_file__from_file( - git_repository *repo, const char *path, git_attr_file **out) + git_repository *repo, const char *path, git_attr_file *file) { int error = GIT_SUCCESS; git_fbuffer fbuf = GIT_FBUFFER_INIT; - *out = NULL; + assert(path && file); - if ((error = git_futils_readbuffer(&fbuf, path)) < GIT_SUCCESS || - (error = git_attr_file__from_buffer(repo, fbuf.data, out)) < GIT_SUCCESS) - { - git__rethrow(error, "Could not open attribute file '%s'", path); - } else { - /* save path (okay to fail) */ - (*out)->path = git__strdup(path); - } + if (file->path == NULL) + error = git_attr_file__set_path(repo, path, file); + + if (error == GIT_SUCCESS && + (error = git_futils_readbuffer(&fbuf, path)) == GIT_SUCCESS) + error = git_attr_file__from_buffer(repo, fbuf.data, file); git_futils_freebuffer(&fbuf); + if (error != GIT_SUCCESS) + git__rethrow(error, "Could not open attribute file '%s'", path); return error; } @@ -267,6 +287,7 @@ int git_attr_path__init( */ int git_attr_fnmatch__parse( git_attr_fnmatch *spec, + const char *source, const char **base) { const char *pattern, *scan; @@ -312,32 +333,40 @@ int git_attr_fnmatch__parse( *base = scan; spec->length = scan - pattern; - spec->pattern = git__strndup(pattern, spec->length); - - if (!spec->pattern) { - *base = git__next_line(pattern); - return GIT_ENOMEM; - } else { - /* remove '\' that might have be used for internal whitespace */ - char *from = spec->pattern, *to = spec->pattern; - while (*from) { - if (*from == '\\') { - from++; - spec->length--; - } - *to++ = *from++; - } - *to = '\0'; - } if (pattern[spec->length - 1] == '/') { spec->length--; - spec->pattern[spec->length] = '\0'; spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY; if (--slash_count <= 0) spec->flags = spec->flags & ~GIT_ATTR_FNMATCH_FULLPATH; } + if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 && + source != NULL && git_path_root(pattern) < 0) + { + size_t sourcelen = strlen(source); + /* given an unrooted fullpath match from a file inside a repo, + * prefix the pattern with the relative directory of the source file + */ + spec->pattern = git__malloc(sourcelen + spec->length + 1); + if (spec->pattern) { + memcpy(spec->pattern, source, sourcelen); + memcpy(spec->pattern + sourcelen, pattern, spec->length); + spec->length += sourcelen; + spec->pattern[spec->length] = '\0'; + } + } else { + spec->pattern = git__strndup(pattern, spec->length); + } + + if (!spec->pattern) { + *base = git__next_line(pattern); + return GIT_ENOMEM; + } else { + /* remove '\' that might have be used for internal whitespace */ + spec->length = git__removechar(spec->pattern, '\\'); + } + return GIT_SUCCESS; } diff --git a/src/attr_file.h b/src/attr_file.h index 7190c4c7b..304c7a854 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -62,13 +62,16 @@ typedef struct { * git_attr_file API */ +extern int git_attr_file__new(git_attr_file **attrs_ptr); +extern void git_attr_file__free(git_attr_file *file); + extern int git_attr_file__from_buffer( - git_repository *repo, const char *buf, git_attr_file **out); + git_repository *repo, const char *buf, git_attr_file *file); extern int git_attr_file__from_file( - git_repository *repo, const char *path, git_attr_file **out); + git_repository *repo, const char *path, git_attr_file *file); -extern int git_attr_file__new(git_attr_file **attrs_ptr); -extern void git_attr_file__free(git_attr_file *file); +extern int git_attr_file__set_path( + git_repository *repo, const char *path, git_attr_file *file); extern int git_attr_file__lookup_one( git_attr_file *file, @@ -90,6 +93,7 @@ extern unsigned long git_attr_file__name_hash(const char *name); extern int git_attr_fnmatch__parse( git_attr_fnmatch *spec, + const char *source, const char **base); extern int git_attr_fnmatch__match( diff --git a/src/ignore.c b/src/ignore.c index 1040574d7..388a4b280 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -8,22 +8,25 @@ #define GIT_IGNORE_CONFIG "core.excludesfile" static int load_ignore_file( - git_repository *GIT_UNUSED(repo), const char *path, git_attr_file **out) + git_repository *repo, const char *path, git_attr_file *ignores) { int error = GIT_SUCCESS; git_fbuffer fbuf = GIT_FBUFFER_INIT; - git_attr_file *ignores = NULL; git_attr_fnmatch *match = NULL; const char *scan = NULL; + char *context = NULL; - GIT_UNUSED_ARG(repo); + if (ignores->path == NULL) + error = git_attr_file__set_path(repo, path, ignores); - *out = NULL; - - if ((error = git_futils_readbuffer(&fbuf, path)) == GIT_SUCCESS) - error = git_attr_file__new(&ignores); + if (git__suffixcmp(ignores->path, GIT_IGNORE_FILE) == 0) { + context = git__strndup(ignores->path, + strlen(ignores->path) - strlen(GIT_IGNORE_FILE)); + if (!context) error = GIT_ENOMEM; + } - ignores->path = git__strdup(path); + if (error == GIT_SUCCESS) + error = git_futils_readbuffer(&fbuf, path); scan = fbuf.data; @@ -33,7 +36,7 @@ static int load_ignore_file( break; } - if (!(error = git_attr_fnmatch__parse(match, &scan))) { + if (!(error = git_attr_fnmatch__parse(match, context, &scan))) { match->flags = match->flags | GIT_ATTR_FNMATCH_IGNORE; scan = git__next_line(scan); error = git_vector_insert(&ignores->rules, match); @@ -52,13 +55,10 @@ static int load_ignore_file( git_futils_freebuffer(&fbuf); git__free(match); + git__free(context); - if (error != GIT_SUCCESS) { + if (error != GIT_SUCCESS) git__rethrow(error, "Could not open ignore file '%s'", path); - git_attr_file__free(ignores); - } else { - *out = ignores; - } return error; } diff --git a/src/util.c b/src/util.c index 1ca9d850c..f47de9e53 100644 --- a/src/util.c +++ b/src/util.c @@ -156,6 +156,23 @@ void git__strtolower(char *str) git__strntolower(str, strlen(str)); } +size_t git__removechar(char *str, char remove) +{ + char *from = str, *to = str; + + while (*from) { + if (*from == remove) + from++; + if (to != from) + *to = *from; + to++; + from++; + } + *to = '\0'; + + return (to - str); +} + int git__prefixcmp(const char *str, const char *prefix) { for (;;) { diff --git a/src/util.h b/src/util.h index 6c929cf0a..818e6f0f2 100644 --- a/src/util.h +++ b/src/util.h @@ -102,6 +102,8 @@ extern char *git__strtok(char **end, const char *sep); extern void git__strntolower(char *str, size_t len); extern void git__strtolower(char *str); +extern size_t git__removechar(char *str, char remove); + GIT_INLINE(const char *) git__next_line(const char *s) { while (*s && *s != '\n') s++; diff --git a/tests-clay/attr/file.c b/tests-clay/attr/file.c index acca0c653..652ee273c 100644 --- a/tests-clay/attr/file.c +++ b/tests-clay/attr/file.c @@ -6,11 +6,12 @@ void test_attr_file__simple_read(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_assignment *assign; git_attr_rule *rule; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), file)); cl_assert_strequal(cl_fixture("attr/attr0"), file->path); cl_assert(file->rules.length == 1); @@ -32,11 +33,12 @@ void test_attr_file__simple_read(void) void test_attr_file__match_variants(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_rule *rule; git_attr_assignment *assign; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), file)); cl_assert_strequal(cl_fixture("attr/attr1"), file->path); cl_assert(file->rules.length == 10); @@ -119,11 +121,12 @@ static void check_one_assign( void test_attr_file__assign_variants(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_rule *rule; git_attr_assignment *assign; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), file)); cl_assert_strequal(cl_fixture("attr/attr2"), file->path); cl_assert(file->rules.length == 11); @@ -184,11 +187,12 @@ void test_attr_file__assign_variants(void) void test_attr_file__check_attr_examples(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_rule *rule; git_attr_assignment *assign; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), file)); cl_assert_strequal(cl_fixture("attr/attr3"), file->path); cl_assert(file->rules.length == 3); diff --git a/tests-clay/attr/lookup.c b/tests-clay/attr/lookup.c index fcade5225..b251562ba 100644 --- a/tests-clay/attr/lookup.c +++ b/tests-clay/attr/lookup.c @@ -3,11 +3,12 @@ void test_attr_lookup__simple(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_path path; const char *value = NULL; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), file)); cl_assert_strequal(cl_fixture("attr/attr0"), file->path); cl_assert(file->rules.length == 1); @@ -60,7 +61,7 @@ static void run_test_cases(git_attr_file *file, test_case *cases) void test_attr_lookup__match_variants(void) { - git_attr_file *file = NULL; + git_attr_file *file; git_attr_path path; test_case cases[] = { /* pat0 -> simple match */ @@ -132,7 +133,8 @@ void test_attr_lookup__match_variants(void) { NULL, NULL, NULL, 0, 0 } }; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), file)); cl_assert_strequal(cl_fixture("attr/attr1"), file->path); cl_assert(file->rules.length == 10); @@ -146,7 +148,7 @@ void test_attr_lookup__match_variants(void) void test_attr_lookup__assign_variants(void) { - git_attr_file *file = NULL; + git_attr_file *file; test_case cases[] = { /* pat0 -> simple assign */ { "pat0", "simple", GIT_ATTR_TRUE, 0, 0 }, @@ -190,7 +192,8 @@ void test_attr_lookup__assign_variants(void) { NULL, NULL, NULL, 0, 0 } }; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), file)); cl_assert(file->rules.length == 11); run_test_cases(file, cases); @@ -200,7 +203,7 @@ void test_attr_lookup__assign_variants(void) void test_attr_lookup__check_attr_examples(void) { - git_attr_file *file = NULL; + git_attr_file *file; test_case cases[] = { { "foo.java", "diff", "java", 1, 0 }, { "foo.java", "crlf", GIT_ATTR_FALSE, 0, 0 }, @@ -224,7 +227,8 @@ void test_attr_lookup__check_attr_examples(void) { NULL, NULL, NULL, 0, 0 } }; - cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), file)); cl_assert(file->rules.length == 3); run_test_cases(file, cases); @@ -234,7 +238,7 @@ void test_attr_lookup__check_attr_examples(void) void test_attr_lookup__from_buffer(void) { - git_attr_file *file = NULL; + git_attr_file *file; test_case cases[] = { { "abc", "foo", GIT_ATTR_TRUE, 0, 0 }, { "abc", "bar", GIT_ATTR_TRUE, 0, 0 }, @@ -248,7 +252,8 @@ void test_attr_lookup__from_buffer(void) { NULL, NULL, NULL, 0, 0 } }; - cl_git_pass(git_attr_file__from_buffer(NULL, "a* foo\nabc bar\n* baz", &file)); + cl_git_pass(git_attr_file__new(&file)); + cl_git_pass(git_attr_file__from_buffer(NULL, "a* foo\nabc bar\n* baz", file)); cl_assert(file->rules.length == 3); run_test_cases(file, cases); diff --git a/tests-clay/attr/repo.c b/tests-clay/attr/repo.c index 3e9b9de1b..13f28ca84 100644 --- a/tests-clay/attr/repo.c +++ b/tests-clay/attr/repo.c @@ -45,19 +45,24 @@ void test_attr_repo__get_one(void) { "root_test3", "rootattr", NULL }, { "root_test3", "multiattr", "3" }, { "root_test3", "multi2", NULL }, - { "subdir/subdir_test1", "repoattr", GIT_ATTR_TRUE }, - { "subdir/subdir_test1", "rootattr", GIT_ATTR_TRUE }, - { "subdir/subdir_test1", "missingattr", NULL }, - { "subdir/subdir_test1", "subattr", "yes" }, - { "subdir/subdir_test1", "negattr", GIT_ATTR_FALSE }, - { "subdir/subdir_test1", "another", NULL }, - { "subdir/subdir_test2.txt", "repoattr", GIT_ATTR_TRUE }, - { "subdir/subdir_test2.txt", "rootattr", GIT_ATTR_TRUE }, - { "subdir/subdir_test2.txt", "missingattr", NULL }, - { "subdir/subdir_test2.txt", "subattr", "yes" }, - { "subdir/subdir_test2.txt", "negattr", GIT_ATTR_FALSE }, - { "subdir/subdir_test2.txt", "another", "one" }, + { "sub/subdir_test1", "repoattr", GIT_ATTR_TRUE }, + { "sub/subdir_test1", "rootattr", GIT_ATTR_TRUE }, + { "sub/subdir_test1", "missingattr", NULL }, + { "sub/subdir_test1", "subattr", "yes" }, + { "sub/subdir_test1", "negattr", GIT_ATTR_FALSE }, + { "sub/subdir_test1", "another", NULL }, + { "sub/subdir_test2.txt", "repoattr", GIT_ATTR_TRUE }, + { "sub/subdir_test2.txt", "rootattr", GIT_ATTR_TRUE }, + { "sub/subdir_test2.txt", "missingattr", NULL }, + { "sub/subdir_test2.txt", "subattr", "yes" }, + { "sub/subdir_test2.txt", "negattr", GIT_ATTR_FALSE }, + { "sub/subdir_test2.txt", "another", "zero" }, + { "sub/subdir_test2.txt", "reposub", GIT_ATTR_TRUE }, + { "sub/sub/subdir.txt", "another", "one" }, + { "sub/sub/subdir.txt", "reposubsub", GIT_ATTR_TRUE }, + { "sub/sub/subdir.txt", "reposub", NULL }, { "does-not-exist", "foo", "yes" }, + { "sub/deep/file", "deepdeep", GIT_ATTR_TRUE }, { NULL, NULL, NULL } }, *scan; @@ -105,7 +110,7 @@ void test_attr_repo__get_many(void) cl_assert(values[2] == NULL); cl_assert(values[3] == NULL); - cl_git_pass(git_attr_get_many(g_repo, "subdir/subdir_test1", 4, names, values)); + cl_git_pass(git_attr_get_many(g_repo, "sub/subdir_test1", 4, names, values)); cl_assert(values[0] == GIT_ATTR_TRUE); cl_assert(values[1] == GIT_ATTR_TRUE); @@ -136,33 +141,33 @@ void test_attr_repo__foreach(void) cl_assert(count == 2); count = 0; - cl_git_pass(git_attr_foreach(g_repo, "subdir/subdir_test1", + cl_git_pass(git_attr_foreach(g_repo, "sub/subdir_test1", &count_attrs, &count)); cl_assert(count == 4); /* repoattr, rootattr, subattr, negattr */ count = 0; - cl_git_pass(git_attr_foreach(g_repo, "subdir/subdir_test2.txt", + cl_git_pass(git_attr_foreach(g_repo, "sub/subdir_test2.txt", &count_attrs, &count)); - cl_assert(count == 5); /* repoattr, rootattr, subattr, negattr, another */ + cl_assert(count == 6); /* repoattr, rootattr, subattr, reposub, negattr, another */ } void test_attr_repo__manpage_example(void) { const char *value; - cl_git_pass(git_attr_get(g_repo, "subdir/abc", "foo", &value)); + cl_git_pass(git_attr_get(g_repo, "sub/abc", "foo", &value)); cl_assert(value == GIT_ATTR_TRUE); - cl_git_pass(git_attr_get(g_repo, "subdir/abc", "bar", &value)); + cl_git_pass(git_attr_get(g_repo, "sub/abc", "bar", &value)); cl_assert(value == NULL); - cl_git_pass(git_attr_get(g_repo, "subdir/abc", "baz", &value)); + cl_git_pass(git_attr_get(g_repo, "sub/abc", "baz", &value)); cl_assert(value == GIT_ATTR_FALSE); - cl_git_pass(git_attr_get(g_repo, "subdir/abc", "merge", &value)); + cl_git_pass(git_attr_get(g_repo, "sub/abc", "merge", &value)); cl_assert_strequal("filfre", value); - cl_git_pass(git_attr_get(g_repo, "subdir/abc", "frotz", &value)); + cl_git_pass(git_attr_get(g_repo, "sub/abc", "frotz", &value)); cl_assert(value == NULL); } diff --git a/tests-clay/status/ignore.c b/tests-clay/status/ignore.c new file mode 100644 index 000000000..f14e10c8e --- /dev/null +++ b/tests-clay/status/ignore.c @@ -0,0 +1,49 @@ +#include "clay_libgit2.h" +#include "fileops.h" +#include "git2/attr.h" + +static git_repository *g_repo = NULL; + +void test_status_ignore__initialize(void) +{ + /* Before each test, instantiate the attr repo from the fixtures and + * rename the .gitted to .git so it is a repo with a working dir. Also + * rename gitignore to .gitignore. + */ + cl_fixture_sandbox("attr"); + cl_git_pass(p_rename("attr/.gitted", "attr/.git")); + cl_git_pass(p_rename("attr/gitignore", "attr/.gitignore")); + cl_git_pass(git_repository_open(&g_repo, "attr/.git")); +} + +void test_status_ignore__cleanup(void) +{ + git_repository_free(g_repo); + g_repo = NULL; + cl_fixture_cleanup("attr"); +} + +void test_status_ignore__0(void) +{ + struct { + const char *path; + int expected; + } test_cases[] = { + { "file", 0 }, + { "ign", 1 }, + { "sub", 1 }, + { "sub/file", 0 }, + { "sub/ign", 1 }, + { "sub/sub", 1 }, + { "sub/sub/file", 0 }, + { "sub/sub/ign", 1 }, + { "sub/sub/sub", 1 }, + { NULL, 0 } + }, *one_test; + + for (one_test = test_cases; one_test->path != NULL; one_test++) { + int ignored; + cl_git_pass(git_status_should_ignore(g_repo, one_test->path, &ignored)); + cl_assert_(ignored == one_test->expected, one_test->path); + } +} diff --git a/tests/resources/attr/.gitted/info/attributes b/tests/resources/attr/.gitted/info/attributes index 2e9643a53..5fe62a37a 100644 --- a/tests/resources/attr/.gitted/info/attributes +++ b/tests/resources/attr/.gitted/info/attributes @@ -1,2 +1,4 @@ * repoattr a* foo !bar -baz +sub/*.txt reposub +sub/sub/*.txt reposubsub diff --git a/tests/resources/attr/file b/tests/resources/attr/file new file mode 100644 index 000000000..45b983be3 --- /dev/null +++ b/tests/resources/attr/file @@ -0,0 +1 @@ +hi diff --git a/tests/resources/attr/gitignore b/tests/resources/attr/gitignore new file mode 100644 index 000000000..66f77694e --- /dev/null +++ b/tests/resources/attr/gitignore @@ -0,0 +1,2 @@ +sub +ign diff --git a/tests/resources/attr/ign b/tests/resources/attr/ign new file mode 100644 index 000000000..592fd2594 --- /dev/null +++ b/tests/resources/attr/ign @@ -0,0 +1 @@ +ignore me diff --git a/tests/resources/attr/subdir/.gitattributes b/tests/resources/attr/sub/.gitattributes index 99eae4768..329c1c5b8 100644 --- a/tests/resources/attr/subdir/.gitattributes +++ b/tests/resources/attr/sub/.gitattributes @@ -1,5 +1,7 @@ * subattr=yes -negattr -subdir/*.txt another=one +*.txt another=zero +sub/*.txt another=one ab* merge=filfre abc -foo -bar *.c frotz +deep/file deepdeep diff --git a/tests/resources/attr/subdir/abc b/tests/resources/attr/sub/abc index 3e42ffc54..3e42ffc54 100644 --- a/tests/resources/attr/subdir/abc +++ b/tests/resources/attr/sub/abc diff --git a/tests/resources/attr/sub/file b/tests/resources/attr/sub/file new file mode 100644 index 000000000..45b983be3 --- /dev/null +++ b/tests/resources/attr/sub/file @@ -0,0 +1 @@ +hi diff --git a/tests/resources/attr/sub/ign b/tests/resources/attr/sub/ign new file mode 100644 index 000000000..592fd2594 --- /dev/null +++ b/tests/resources/attr/sub/ign @@ -0,0 +1 @@ +ignore me diff --git a/tests/resources/attr/sub/sub/file b/tests/resources/attr/sub/sub/file new file mode 100644 index 000000000..45b983be3 --- /dev/null +++ b/tests/resources/attr/sub/sub/file @@ -0,0 +1 @@ +hi diff --git a/tests/resources/attr/sub/sub/subsub.txt b/tests/resources/attr/sub/sub/subsub.txt new file mode 100644 index 000000000..9e5bdc47d --- /dev/null +++ b/tests/resources/attr/sub/sub/subsub.txt @@ -0,0 +1 @@ +subsub diff --git a/tests/resources/attr/subdir/subdir_test1 b/tests/resources/attr/sub/subdir_test1 index e563cf475..e563cf475 100644 --- a/tests/resources/attr/subdir/subdir_test1 +++ b/tests/resources/attr/sub/subdir_test1 diff --git a/tests/resources/attr/subdir/subdir_test2.txt b/tests/resources/attr/sub/subdir_test2.txt index fb5067b1a..fb5067b1a 100644 --- a/tests/resources/attr/subdir/subdir_test2.txt +++ b/tests/resources/attr/sub/subdir_test2.txt diff --git a/tests/resources/attr/subdir2/subdir2_test1 b/tests/resources/attr/subdir2/subdir2_test1 deleted file mode 100644 index dccada462..000000000 --- a/tests/resources/attr/subdir2/subdir2_test1 +++ /dev/null @@ -1 +0,0 @@ -Hello from subdir2 |