summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2014-08-26 17:48:20 +0200
committerVicent Marti <vicent@github.com>2014-08-26 17:48:20 +0200
commit00e9ae5ab4787601a9f3e6ce1ef50ca9c8e60dc9 (patch)
treee08aa5d99440c41cf1c7384cc636d0649df1bd11 /src
parentcd0c4fa73ac22eb03462a791f0494cf3c000b103 (diff)
parentbbe13802b7f85343d3db1aeb799662ee11461e6b (diff)
downloadlibgit2-00e9ae5ab4787601a9f3e6ce1ef50ca9c8e60dc9.tar.gz
Merge pull request #2508 from libgit2/rb/fix-ignore-slash-star
Fix bugs with negative ignores inside an ignored parent directory
Diffstat (limited to 'src')
-rw-r--r--src/attr_file.c15
-rw-r--r--src/path.h8
2 files changed, 22 insertions, 1 deletions
diff --git a/src/attr_file.c b/src/attr_file.c
index 3e95a2134..07ffacbaf 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -378,6 +378,18 @@ bool git_attr_fnmatch__match(
return (matchval != 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(path->path);
+ bool prefixed = (pathlen <= match->length) &&
+ ((match->flags & GIT_ATTR_FNMATCH_ICASE) ?
+ !strncasecmp(match->pattern, path->path, pathlen) :
+ !strncmp(match->pattern, path->path, pathlen));
+
+ if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen]))
+ return true;
+ }
+
return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH);
}
@@ -522,7 +534,8 @@ int git_attr_fnmatch__parse(
}
if (*pattern == '!' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWNEG) != 0) {
- spec->flags = spec->flags | GIT_ATTR_FNMATCH_NEGATIVE;
+ spec->flags = spec->flags |
+ GIT_ATTR_FNMATCH_NEGATIVE | GIT_ATTR_FNMATCH_LEADINGDIR;
pattern++;
}
diff --git a/src/path.h b/src/path.h
index 2e86241e1..46d6efe93 100644
--- a/src/path.h
+++ b/src/path.h
@@ -128,6 +128,14 @@ GIT_INLINE(int) git_path_is_relative(const char *p)
return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/')));
}
+/**
+ * Check if string is at end of path segment (i.e. looking at '/' or '\0')
+ */
+GIT_INLINE(int) git_path_at_end_of_segment(const char *p)
+{
+ return !*p || *p == '/';
+}
+
extern int git__percent_decode(git_buf *decoded_out, const char *input);
/**