This is needed to replace pathspec_matches() in builtin/grep.c. Depth limit is only effective when pathspec.recursive == 1 max_depth == -1 means unlimited depth. Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- pathspec.recursive is also needed for wildcard matching later on. cache.h | 2 ++ dir.c | 15 +++++++++++++++ dir.h | 1 + tree-diff.c | 2 ++ tree-walk.c | 19 +++++++++++++++++-- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/cache.h b/cache.h index 3a1acf1..56da281 100644 --- a/cache.h +++ b/cache.h @@ -497,6 +497,8 @@ struct pathspec { const char **raw; /* get_pathspec() result, not freed by free_pathspec() */ int nr; int has_wildcard:1; + int recursive:1; + int max_depth; struct pathspec_item { int len, prefix_len; int has_wildcard:1; diff --git a/dir.c b/dir.c index 0987d0c..bb5076c 100644 --- a/dir.c +++ b/dir.c @@ -71,6 +71,21 @@ int fill_directory(struct dir_struct *dir, const char **pathspec) return len; } +int within_depth(const char *name, int namelen, + int depth, int max_depth) +{ + const char *cp = name, *cpe = name + namelen; + + while (cp < cpe) { + if (*cp++ != '/') + continue; + depth++; + if (depth > max_depth) + return 0; + } + return 1; +} + /* * Does 'match' match the given name? * A match is found if diff --git a/dir.h b/dir.h index 278d84c..c71de08 100644 --- a/dir.h +++ b/dir.h @@ -65,6 +65,7 @@ struct dir_struct { #define MATCHED_FNMATCH 2 #define MATCHED_EXACTLY 3 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen); +extern int within_depth(const char *name, int namelen, int depth, int max_depth); extern int fill_directory(struct dir_struct *dir, const char **pathspec); extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec); diff --git a/tree-diff.c b/tree-diff.c index a870f6c..7c3b770 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -165,6 +165,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, int baselen = strlen(base_); memcpy(base, base_, baselen+1); + opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE); + opt->pathspec.max_depth = -1; for (;;) { if (DIFF_OPT_TST(opt, QUICK) && DIFF_OPT_TST(opt, HAS_CHANGES)) diff --git a/tree-walk.c b/tree-walk.c index 40a4657..d28de30 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -1,6 +1,7 @@ #include "cache.h" #include "tree-walk.h" #include "unpack-trees.h" +#include "dir.h" #include "tree.h" static const char *get_mode(const char *str, unsigned int *modep) @@ -558,9 +559,17 @@ int tree_entry_interesting(const struct name_entry *entry, int pathlen; int never_interesting = -1; - if (!ps || !ps->nr) + if (!ps) return 1; + if (!ps->nr) { + if (!ps->recursive || ps->max_depth == -1) + return 1; + return !!within_depth(base, baselen, + !!S_ISDIR(entry->mode), + ps->max_depth); + } + pathlen = tree_entry_len(entry->path, entry->sha1); for (i = 0; i < ps->nr; i++) { @@ -571,7 +580,13 @@ int tree_entry_interesting(const struct name_entry *entry, if (!match_dir_prefix(base, baselen, match, matchlen)) /* Just a random prefix match */ continue; - return 2; + + if (!ps->recursive || ps->max_depth == -1) + return 2; + + return !!within_depth(base+matchlen+1, baselen-matchlen-1, + !!S_ISDIR(entry->mode), + ps->max_depth); } /* Does the base match? */ -- 1.7.3.3.476.g10a82 -- 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