diff options
author | Steve King Jr <stevek@axosoft.com> | 2019-03-14 15:51:15 -0700 |
---|---|---|
committer | Steven King Jr <stevek@axosoft.com> | 2019-03-14 16:00:13 -0700 |
commit | e3d7bccbec2a19f9bcda15679f28a33ad98ded93 (patch) | |
tree | 80512daa94dba905625cb2e8cf5c53fb57bf52f4 | |
parent | bc74c53a3776c69bc01208e43af1613e0401f94a (diff) | |
download | libgit2-e3d7bccbec2a19f9bcda15679f28a33ad98ded93.tar.gz |
ignore: Do not match on prefix of negated patterns
Matching on the prefix of a negated pattern was triggering false
negatives on siblings of that pattern. e.g.
Given the .gitignore:
dir/*
!dir/sub1/sub2/**
The path `dir/a.text` would not be ignored.
-rw-r--r-- | src/attr_file.c | 12 | ||||
-rw-r--r-- | tests/status/ignore.c | 26 |
2 files changed, 23 insertions, 15 deletions
diff --git a/src/attr_file.c b/src/attr_file.c index 40c72ea04..8619647a3 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -429,18 +429,6 @@ bool git_attr_fnmatch__match( return (p_fnmatch(match->pattern, relpath, flags) != FNM_NOMATCH); } - /* if path is a directory prefix of a negated pattern, then match */ - if ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) && path->is_dir) { - size_t pathlen = strlen(relpath); - bool prefixed = (pathlen <= match->length) && - ((match->flags & GIT_ATTR_FNMATCH_ICASE) ? - !strncasecmp(match->pattern, relpath, pathlen) : - !strncmp(match->pattern, relpath, pathlen)); - - if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen])) - return true; - } - return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH); } diff --git a/tests/status/ignore.c b/tests/status/ignore.c index f6c72c243..7256fb72c 100644 --- a/tests/status/ignore.c +++ b/tests/status/ignore.c @@ -1218,16 +1218,36 @@ void test_status_ignore__ignored_subdirfiles_with_subdir_rule(void) { static const char *test_files[] = { "empty_standard_repo/dir/a.test", - "empty_standard_repo/dir/sub1/b.test", + "empty_standard_repo/dir/sub1/sub2/b.test", NULL }; make_test_data("empty_standard_repo", test_files); cl_git_mkfile( "empty_standard_repo/.gitignore", - "/dir/*\n" - "!/dir/sub1/sub2/**/*\n"); + "dir/*\n" + "!dir/sub1/sub2/**\n"); assert_is_ignored("dir/a.test"); assert_is_ignored("dir/sub1/a.test"); } + +void test_status_ignore__ignored_subdirfiles_with_negations(void) +{ + static const char *test_files[] = { + "empty_standard_repo/dir/a.test", + "empty_standard_repo/dir/b.test", + "empty_standard_repo/dir/sub1/c.test", + NULL + }; + + make_test_data("empty_standard_repo", test_files); + cl_git_mkfile( + "empty_standard_repo/.gitignore", + "dir/*\n" + "!dir/a.test\n"); + + refute_is_ignored("dir/a.test"); + assert_is_ignored("dir/b.test"); + assert_is_ignored("dir/sub1/c.test"); +} |