pathspec: do exact comparison on the leading non-wildcard part
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Nov 24, 2012 at 11:33 UTC
5d74762d87859d08fdf4c87ec9387e31e097acba
3 files changed
+29
-3
dir.c
+17
-1
@@ -34,6 +34,21 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
34
return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
35
}
36
37
+inline int git_fnmatch(const char *pattern, const char *string,
38
+ int flags, int prefix)
39
+{
40
+ int fnm_flags = 0;
41
+ if (flags & GFNM_PATHNAME)
42
+ fnm_flags |= FNM_PATHNAME;
43
+ if (prefix > 0) {
44
+ if (strncmp(pattern, string, prefix))
45
+ return FNM_NOMATCH;
46
+ pattern += prefix;
47
+ string += prefix;
48
+ }
49
+ return fnmatch(pattern, string, fnm_flags);
50
+}
51
+
52
static size_t common_prefix_len(const char **pathspec)
53
{
54
const char *n, *first;
@@ -230,7 +245,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
245
return MATCHED_RECURSIVELY;
246
}
247
233
- if (item->nowildcard_len < item->len && !fnmatch(match, name, 0))
248
+ if (item->nowildcard_len < item->len &&
249
+ !git_fnmatch(match, name, 0, item->nowildcard_len - prefix))
250
return MATCHED_FNMATCH;
251
252
return 0;
dir.h
+8
@@ -139,4 +139,12 @@ extern int strcmp_icase(const char *a, const char *b);
139
extern int strncmp_icase(const char *a, const char *b, size_t count);
140
extern int fnmatch_icase(const char *pattern, const char *string, int flags);
141
142
+/*
143
+ * The prefix part of pattern must not contains wildcards.
144
+ */
145
+#define GFNM_PATHNAME 1 /* similar to FNM_PATHNAME */
146
+
147
+extern int git_fnmatch(const char *pattern, const char *string,
148
+ int flags, int prefix);
149
+
150
#endif
tree-walk.c
+4
-2
@@ -627,7 +627,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
627
return entry_interesting;
628
629
if (item->nowildcard_len < item->len) {
630
- if (!fnmatch(match + baselen, entry->path, 0))
630
+ if (!git_fnmatch(match + baselen, entry->path,
631
+ 0, item->nowildcard_len - baselen))
632
return entry_interesting;
633
634
/*
@@ -652,7 +653,8 @@ match_wildcards:
653
654
strbuf_add(base, entry->path, pathlen);
655
655
- if (!fnmatch(match, base->buf + base_offset, 0)) {
656
+ if (!git_fnmatch(match, base->buf + base_offset,
657
+ 0, item->nowildcard_len)) {
658
strbuf_setlen(base, base_offset + baselen);
659
return entry_interesting;
660
}