提交 6330a171 编写于 作者: N Nguyễn Thái Ngọc Duy 提交者: Junio C Hamano

parse_pathspec: add special flag for max_depth feature

match_pathspec_depth() and tree_entry_interesting() check max_depth
field in order to support "git grep --max-depth". The feature
activation is tied to "recursive" field, which led to some unwanted
activation, e.g. 5c8eeb83 (diff-index: enable recursive pathspec
matching in unpack_trees - 2012-01-15).

This patch decouples the activation from "recursive" field, puts it in
"magic" field instead. This makes sure that only "git grep" can
activate this feature. And because parse_pathspec knows when the
feature is not used, it does not need to sort pathspec (required for
max_depth to work correctly). A small win for non-grep cases.

Even though a new magic flag is introduced, no magic syntax is. The
magic can be only enabled by parse_pathspec() caller. We might someday
want to support ":(maxdepth:10)src." It all depends on actual use
cases.

max_depth feature cannot be enabled via init_pathspec() anymore. But
that's ok because init_pathspec() is on its way to /dev/null.
Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 0fdc2ae5
...@@ -858,7 +858,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) ...@@ -858,7 +858,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
} }
parse_pathspec(&pathspec, 0, parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_CWD, PATHSPEC_PREFER_CWD |
(opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0),
prefix, argv + i); prefix, argv + i);
pathspec.max_depth = opt.max_depth; pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1; pathspec.recursive = 1;
......
...@@ -476,7 +476,6 @@ static int diff_cache(struct rev_info *revs, ...@@ -476,7 +476,6 @@ static int diff_cache(struct rev_info *revs,
opts.dst_index = NULL; opts.dst_index = NULL;
opts.pathspec = &revs->diffopt.pathspec; opts.pathspec = &revs->diffopt.pathspec;
opts.pathspec->recursive = 1; opts.pathspec->recursive = 1;
opts.pathspec->max_depth = -1;
init_tree_desc(&t, tree->buffer, tree->size); init_tree_desc(&t, tree->buffer, tree->size);
return unpack_trees(1, &t, &opts); return unpack_trees(1, &t, &opts);
......
...@@ -341,7 +341,9 @@ int match_pathspec_depth(const struct pathspec *ps, ...@@ -341,7 +341,9 @@ int match_pathspec_depth(const struct pathspec *ps,
int i, retval = 0; int i, retval = 0;
if (!ps->nr) { if (!ps->nr) {
if (!ps->recursive || ps->max_depth == -1) if (!ps->recursive ||
!(ps->magic & PATHSPEC_MAXDEPTH) ||
ps->max_depth == -1)
return MATCHED_RECURSIVELY; return MATCHED_RECURSIVELY;
if (within_depth(name, namelen, 0, ps->max_depth)) if (within_depth(name, namelen, 0, ps->max_depth))
...@@ -358,7 +360,9 @@ int match_pathspec_depth(const struct pathspec *ps, ...@@ -358,7 +360,9 @@ int match_pathspec_depth(const struct pathspec *ps,
if (seen && seen[i] == MATCHED_EXACTLY) if (seen && seen[i] == MATCHED_EXACTLY)
continue; continue;
how = match_pathspec_item(ps->items+i, prefix, name, namelen); how = match_pathspec_item(ps->items+i, prefix, name, namelen);
if (ps->recursive && ps->max_depth != -1 && if (ps->recursive &&
(ps->magic & PATHSPEC_MAXDEPTH) &&
ps->max_depth != -1 &&
how && how != MATCHED_FNMATCH) { how && how != MATCHED_FNMATCH) {
int len = ps->items[i].len; int len = ps->items[i].len;
if (name[len] == '/') if (name[len] == '/')
......
...@@ -267,6 +267,9 @@ void parse_pathspec(struct pathspec *pathspec, ...@@ -267,6 +267,9 @@ void parse_pathspec(struct pathspec *pathspec,
memset(pathspec, 0, sizeof(*pathspec)); memset(pathspec, 0, sizeof(*pathspec));
if (flags & PATHSPEC_MAXDEPTH_VALID)
pathspec->magic |= PATHSPEC_MAXDEPTH;
/* No arguments, no prefix -> no pathspec */ /* No arguments, no prefix -> no pathspec */
if (!entry && !prefix) if (!entry && !prefix)
return; return;
...@@ -322,8 +325,9 @@ void parse_pathspec(struct pathspec *pathspec, ...@@ -322,8 +325,9 @@ void parse_pathspec(struct pathspec *pathspec,
pathspec->magic |= item[i].magic; pathspec->magic |= item[i].magic;
} }
qsort(pathspec->items, pathspec->nr, if (pathspec->magic & PATHSPEC_MAXDEPTH)
sizeof(struct pathspec_item), pathspec_item_cmp); qsort(pathspec->items, pathspec->nr,
sizeof(struct pathspec_item), pathspec_item_cmp);
} }
/* /*
......
...@@ -3,7 +3,10 @@ ...@@ -3,7 +3,10 @@
/* Pathspec magic */ /* Pathspec magic */
#define PATHSPEC_FROMTOP (1<<0) #define PATHSPEC_FROMTOP (1<<0)
#define PATHSPEC_ALL_MAGIC PATHSPEC_FROMTOP #define PATHSPEC_MAXDEPTH (1<<1)
#define PATHSPEC_ALL_MAGIC \
(PATHSPEC_FROMTOP | \
PATHSPEC_MAXDEPTH)
#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */ #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */
...@@ -27,6 +30,7 @@ struct pathspec { ...@@ -27,6 +30,7 @@ struct pathspec {
/* parse_pathspec flags */ /* parse_pathspec flags */
#define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */ #define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
#define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */ #define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
#define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
extern int init_pathspec(struct pathspec *, const char **); extern int init_pathspec(struct pathspec *, const char **);
extern void parse_pathspec(struct pathspec *pathspec, extern void parse_pathspec(struct pathspec *pathspec,
......
...@@ -138,7 +138,6 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, ...@@ -138,7 +138,6 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
/* Enable recursion indefinitely */ /* Enable recursion indefinitely */
opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE); opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
opt->pathspec.max_depth = -1;
strbuf_init(&base, PATH_MAX); strbuf_init(&base, PATH_MAX);
strbuf_add(&base, base_str, baselen); strbuf_add(&base, base_str, baselen);
......
...@@ -637,7 +637,9 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, ...@@ -637,7 +637,9 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
entry_not_interesting : all_entries_not_interesting; entry_not_interesting : all_entries_not_interesting;
if (!ps->nr) { if (!ps->nr) {
if (!ps->recursive || ps->max_depth == -1) if (!ps->recursive ||
!(ps->magic & PATHSPEC_MAXDEPTH) ||
ps->max_depth == -1)
return all_entries_interesting; return all_entries_interesting;
return within_depth(base->buf + base_offset, baselen, return within_depth(base->buf + base_offset, baselen,
!!S_ISDIR(entry->mode), !!S_ISDIR(entry->mode),
...@@ -658,7 +660,9 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, ...@@ -658,7 +660,9 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
if (!match_dir_prefix(base_str, match, matchlen)) if (!match_dir_prefix(base_str, match, matchlen))
goto match_wildcards; goto match_wildcards;
if (!ps->recursive || ps->max_depth == -1) if (!ps->recursive ||
!(ps->magic & PATHSPEC_MAXDEPTH) ||
ps->max_depth == -1)
return all_entries_interesting; return all_entries_interesting;
return within_depth(base_str + matchlen + 1, return within_depth(base_str + matchlen + 1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册