A pathspec with wildcard usually requires full path to do matching. When full path is found, match_pathspec() can do the job pretty well (actually it can utilize pathspec_item.has_wildcard, but that's another matter). So if tree_entry_interesting() finds that there is wildcard in any pathspec, it just skips all of its optimizations, tries to make full path and pass to match_pathspec(). The implementation is pretty naive. Maybe with some pattern analysis, we can do some early tree cutting. Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- t/t4010-diff-pathspec.sh | 14 ++++++++++++++ tree-walk.c | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 94df7ae..4b120f8 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -70,4 +70,18 @@ test_expect_success 'diff-tree pathspec' ' test_cmp expected current ' +EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + +test_expect_success 'diff-tree with wildcard shows dir also matches' ' + git diff-tree --name-only $EMPTY_TREE $tree -- "f*" >result && + echo file0 >expected && + test_cmp expected result +' + +test_expect_success 'diff-tree -r with wildcard' ' + git diff-tree -r --name-only $EMPTY_TREE $tree -- "*file1" >result && + echo path1/file1 >expected && + test_cmp expected result +' + test_done diff --git a/tree-walk.c b/tree-walk.c index 01168ea..bc8c9bd 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -2,6 +2,7 @@ #include "tree-walk.h" #include "unpack-trees.h" #include "tree.h" +#include "dir.h" static const char *get_mode(const char *str, unsigned int *modep) { @@ -478,6 +479,23 @@ int tree_entry_interesting(const struct name_entry *entry, pathlen = tree_entry_len(entry->path, entry->sha1); + if (ps->has_wildcard) { + static char full_path[PATH_MAX]; + + /* + * If it's recursive diff, directories are + * intermediate step before ending up to a file. + * Let it pass and we can match the files within + * later. + */ + if (ps->tree_recursive_diff && S_ISDIR(entry->mode)) + return 1; + + memcpy(full_path, base, baselen); + memcpy(full_path+baselen, entry->path, pathlen+1); + return match_pathspec(ps->raw, full_path, baselen+pathlen, 0, NULL) > 0; + } + for (i = 0; i < ps->nr; i++) { const char *match = ps->raw[i]; int matchlen = ps->items[i].len; -- 1.7.1.rc1.70.g788ca -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html