diff options
-rw-r--r-- | dir.c | 18 | ||||
-rw-r--r-- | dir.h | 8 | ||||
-rw-r--r-- | tree-walk.c | 6 |
3 files changed, 29 insertions, 3 deletions
@@ -34,6 +34,21 @@ int fnmatch_icase(const char *pattern, const char *string, int flags) return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0)); } +inline int git_fnmatch(const char *pattern, const char *string, + int flags, int prefix) +{ + int fnm_flags = 0; + if (flags & GFNM_PATHNAME) + fnm_flags |= FNM_PATHNAME; + if (prefix > 0) { + if (strncmp(pattern, string, prefix)) + return FNM_NOMATCH; + pattern += prefix; + string += prefix; + } + return fnmatch(pattern, string, fnm_flags); +} + static size_t common_prefix_len(const char **pathspec) { const char *n, *first; @@ -230,7 +245,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, return MATCHED_RECURSIVELY; } - if (item->nowildcard_len < item->len && !fnmatch(match, name, 0)) + if (item->nowildcard_len < item->len && + !git_fnmatch(match, name, 0, item->nowildcard_len - prefix)) return MATCHED_FNMATCH; return 0; @@ -139,4 +139,12 @@ extern int strcmp_icase(const char *a, const char *b); extern int strncmp_icase(const char *a, const char *b, size_t count); extern int fnmatch_icase(const char *pattern, const char *string, int flags); +/* + * The prefix part of pattern must not contains wildcards. + */ +#define GFNM_PATHNAME 1 /* similar to FNM_PATHNAME */ + +extern int git_fnmatch(const char *pattern, const char *string, + int flags, int prefix); + #endif diff --git a/tree-walk.c b/tree-walk.c index af871c50d1..2fcf3c02da 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -627,7 +627,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, return entry_interesting; if (item->nowildcard_len < item->len) { - if (!fnmatch(match + baselen, entry->path, 0)) + if (!git_fnmatch(match + baselen, entry->path, + 0, item->nowildcard_len - baselen)) return entry_interesting; /* @@ -652,7 +653,8 @@ match_wildcards: strbuf_add(base, entry->path, pathlen); - if (!fnmatch(match, base->buf + base_offset, 0)) { + if (!git_fnmatch(match, base->buf + base_offset, + 0, item->nowildcard_len)) { strbuf_setlen(base, base_offset + baselen); return entry_interesting; } |