Skip to content

Commit d38f280

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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 86e4ca6 commit d38f280

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
@@ -503,11 +503,13 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
503503
struct pathspec {
504504
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
505505
int nr;
506+
int has_wildcard:1;
506507
int recursive:1;
507508
int max_depth;
508509
struct pathspec_item {
509510
const char *match;
510511
int len;
512+
int has_wildcard:1;
511513
} *items;
512514
};
513515

dir.c

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

11981198
item->match = path;
11991199
item->len = strlen(path);
1200+
item->has_wildcard = !no_wildcard(path);
1201+
if (item->has_wildcard)
1202+
pathspec->has_wildcard = 1;
12001203
}
12011204

12021205
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
@@ -553,12 +553,12 @@ static int match_dir_prefix(const char *base, int baselen,
553553
* - negative for "no, and no subsequent entries will be either"
554554
*/
555555
int tree_entry_interesting(const struct name_entry *entry,
556-
const struct strbuf *base,
556+
struct strbuf *base,
557557
const struct pathspec *ps)
558558
{
559559
int i;
560560
int pathlen, baselen = base->len;
561-
int never_interesting = -1;
561+
int never_interesting = ps->has_wildcard ? 0 : -1;
562562

563563
if (!ps->nr) {
564564
if (!ps->recursive || ps->max_depth == -1)
@@ -578,7 +578,7 @@ int tree_entry_interesting(const struct name_entry *entry,
578578
if (baselen >= matchlen) {
579579
/* If it doesn't match, move along... */
580580
if (!match_dir_prefix(base->buf, baselen, match, matchlen))
581-
continue;
581+
goto match_wildcards;
582582

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

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)