summaryrefslogtreecommitdiff
path: root/tree-walk.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-12-15 15:02:46 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-02-03 22:08:30 (GMT)
commitd38f28093ef795bef13d2fda6621b4952afb42db (patch)
treeee06d38a5a645292a66afa665a517f184ff7a151 /tree-walk.c
parent86e4ca69e358836599d4eb0c0e217caa9c9e455b (diff)
downloadgit-d38f28093ef795bef13d2fda6621b4952afb42db.zip
git-d38f28093ef795bef13d2fda6621b4952afb42db.tar.gz
git-d38f28093ef795bef13d2fda6621b4952afb42db.tar.bz2
tree_entry_interesting(): support wildcard matching
never_interesting optimization is disabled if there is any wildcard pathspec, even if it only matches exactly on trees. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'tree-walk.c')
-rw-r--r--tree-walk.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/tree-walk.c b/tree-walk.c
index be8182c..ae7ac1a 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -553,12 +553,12 @@ static int match_dir_prefix(const char *base, int baselen,
* - negative for "no, and no subsequent entries will be either"
*/
int tree_entry_interesting(const struct name_entry *entry,
- const struct strbuf *base,
+ struct strbuf *base,
const struct pathspec *ps)
{
int i;
int pathlen, baselen = base->len;
- int never_interesting = -1;
+ int never_interesting = ps->has_wildcard ? 0 : -1;
if (!ps->nr) {
if (!ps->recursive || ps->max_depth == -1)
@@ -578,7 +578,7 @@ int tree_entry_interesting(const struct name_entry *entry,
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
if (!match_dir_prefix(base->buf, baselen, match, matchlen))
- continue;
+ goto match_wildcards;
if (!ps->recursive || ps->max_depth == -1)
return 2;
@@ -596,6 +596,30 @@ int tree_entry_interesting(const struct name_entry *entry,
&never_interesting))
return 1;
}
+
+match_wildcards:
+ if (!ps->items[i].has_wildcard)
+ continue;
+
+ /*
+ * Concatenate base and entry->path into one and do
+ * fnmatch() on it.
+ */
+
+ strbuf_add(base, entry->path, pathlen);
+
+ if (!fnmatch(match, base->buf, 0)) {
+ strbuf_setlen(base, baselen);
+ return 1;
+ }
+ strbuf_setlen(base, baselen);
+
+ /*
+ * Match all directories. We'll try to match files
+ * later on.
+ */
+ if (ps->recursive && S_ISDIR(entry->mode))
+ return 1;
}
return never_interesting; /* No matches */
}