Skip to content

Commit e10cb0f

Browse files
pcloudsgitster
authored andcommitted
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>
1 parent 9d7d10e commit e10cb0f

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,13 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
496496
struct pathspec {
497497
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
498498
int nr;
499+
int has_wildcard:1;
499500
int recursive:1;
500501
int max_depth;
501502
struct pathspec_item {
502503
const char *match;
503504
int len;
505+
int has_wildcard:1;
504506
} *items;
505507
};
506508

dir.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,9 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
11171117

11181118
item->match = path;
11191119
item->len = strlen(path);
1120+
item->has_wildcard = !no_wildcard(path);
1121+
if (item->has_wildcard)
1122+
pathspec->has_wildcard = 1;
11201123
}
11211124

11221125
qsort(pathspec->items, pathspec->nr,

t/t4010-diff-pathspec.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,18 @@ test_expect_success 'diff-tree pathspec' '
7070
test_cmp expected current
7171
'
7272

73+
EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
74+
75+
test_expect_success 'diff-tree with wildcard shows dir also matches' '
76+
git diff-tree --name-only $EMPTY_TREE $tree -- "f*" >result &&
77+
echo file0 >expected &&
78+
test_cmp expected result
79+
'
80+
81+
test_expect_success 'diff-tree -r with wildcard' '
82+
git diff-tree -r --name-only $EMPTY_TREE $tree -- "*file1" >result &&
83+
echo path1/file1 >expected &&
84+
test_cmp expected result
85+
'
86+
7387
test_done

tree-walk.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,12 +551,12 @@ static int match_dir_prefix(const char *base, int baselen,
551551
* - negative for "no, and no subsequent entries will be either"
552552
*/
553553
int tree_entry_interesting(const struct name_entry *entry,
554-
const struct strbuf *base,
554+
struct strbuf *base,
555555
const struct pathspec *ps)
556556
{
557557
int i;
558558
int pathlen, baselen = base->len;
559-
int never_interesting = -1;
559+
int never_interesting = ps->has_wildcard ? 0 : -1;
560560

561561
if (!ps->nr) {
562562
if (!ps->recursive || ps->max_depth == -1)
@@ -576,7 +576,7 @@ int tree_entry_interesting(const struct name_entry *entry,
576576
if (baselen >= matchlen) {
577577
/* If it doesn't match, move along... */
578578
if (!match_dir_prefix(base->buf, baselen, match, matchlen))
579-
continue;
579+
goto match_wildcards;
580580

581581
if (!ps->recursive || ps->max_depth == -1)
582582
return 2;
@@ -594,6 +594,30 @@ int tree_entry_interesting(const struct name_entry *entry,
594594
&never_interesting))
595595
return 1;
596596
}
597+
598+
match_wildcards:
599+
if (!ps->items[i].has_wildcard)
600+
continue;
601+
602+
/*
603+
* Concatenate base and entry->path into one and do
604+
* fnmatch() on it.
605+
*/
606+
607+
strbuf_add(base, entry->path, pathlen);
608+
609+
if (!fnmatch(match, base->buf, 0)) {
610+
strbuf_setlen(base, baselen);
611+
return 1;
612+
}
613+
strbuf_setlen(base, baselen);
614+
615+
/*
616+
* Match all directories. We'll try to match files
617+
* later on.
618+
*/
619+
if (ps->recursive && S_ISDIR(entry->mode))
620+
return 1;
597621
}
598622
return never_interesting; /* No matches */
599623
}

tree-walk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru
6060
return info->pathlen + tree_entry_len(n->path, n->sha1);
6161
}
6262

63-
extern int tree_entry_interesting(const struct name_entry *, const struct strbuf *, const struct pathspec *ps);
63+
extern int tree_entry_interesting(const struct name_entry *, struct strbuf *, const struct pathspec *ps);
6464

6565
#endif

0 commit comments

Comments
 (0)