Skip to content

Commit 84ce974

Browse files
authored
Merge pull request libgit2#5824 from palmin/fix-ignore-negate
fix check for ignoring of negate rules
2 parents e5649e1 + 6d2a6f3 commit 84ce974

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/ignore.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
101101
*/
102102
static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match)
103103
{
104-
int error = 0, wildmatch_flags;
104+
int error = 0, wildmatch_flags, effective_flags;
105105
size_t i;
106106
git_attr_fnmatch *rule;
107107
char *path;
@@ -141,8 +141,17 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
141141
if (git_buf_oom(&buf))
142142
goto out;
143143

144+
/*
145+
* if rule isn't for full path we match without PATHNAME flag
146+
* as lines like *.txt should match something like dir/test.txt
147+
* requiring * to also match /
148+
*/
149+
effective_flags = wildmatch_flags;
150+
if (!(rule->flags & GIT_ATTR_FNMATCH_FULLPATH))
151+
effective_flags &= ~WM_PATHNAME;
152+
144153
/* if we found a match, we want to keep this rule */
145-
if ((wildmatch(git_buf_cstr(&buf), path, wildmatch_flags)) == WM_MATCH) {
154+
if ((wildmatch(git_buf_cstr(&buf), path, effective_flags)) == WM_MATCH) {
146155
*out = 1;
147156
error = 0;
148157
goto out;
@@ -639,4 +648,3 @@ int git_ignore__check_pathspec_for_exact_ignores(
639648

640649
return error;
641650
}
642-

tests/ignore/path.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,3 +575,11 @@ void test_ignore_path__negative_prefix_rule(void)
575575
assert_is_ignored(true, "ff");
576576
assert_is_ignored(false, "f");
577577
}
578+
579+
void test_ignore_path__negative_more_specific(void)
580+
{
581+
cl_git_rewritefile("attr/.gitignore", "*.txt\n!/dir/test.txt\n");
582+
assert_is_ignored(true, "test.txt");
583+
assert_is_ignored(false, "dir/test.txt");
584+
assert_is_ignored(true, "outer/dir/test.txt");
585+
}

0 commit comments

Comments
 (0)