diff options
| author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-12-15 22:02:44 +0700 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2011-02-03 14:08:30 -0800 | 
| commit | bc96cc87dbb229cbdabfd93391e24ef168713a74 (patch) | |
| tree | 9ff90a888efab369476fe4003fe1e36fa0fbd9ba | |
| parent | 58c4d66619eb21fa23a1305401e0ec4988c1c17e (diff) | |
| download | git-bc96cc87dbb229cbdabfd93391e24ef168713a74.tar.gz | |
tree_entry_interesting(): support depth limit
This is needed to replace pathspec_matches() in builtin/grep.c.
max_depth == -1 means infinite depth. Depth limit is only effective
when pathspec.recursive == 1. When pathspec.recursive == 0, the
behavior depends on match functions: non-recursive for
tree_entry_interesting() and recursive for match_pathspec{,_depth}
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
| -rw-r--r-- | cache.h | 2 | ||||
| -rw-r--r-- | dir.c | 15 | ||||
| -rw-r--r-- | dir.h | 1 | ||||
| -rw-r--r-- | tree-diff.c | 4 | ||||
| -rw-r--r-- | tree-walk.c | 19 | 
5 files changed, 38 insertions, 3 deletions
@@ -503,6 +503,8 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct  struct pathspec {  	const char **raw; /* get_pathspec() result, not freed by free_pathspec() */  	int nr; +	int recursive:1; +	int max_depth;  	struct pathspec_item {  		const char *match;  		int len; @@ -87,6 +87,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 @@ -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 45a3845c0a..03dc5c8e70 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -146,6 +146,10 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,  	int all_t1_interesting = 0;  	int all_t2_interesting = 0; +	/* Enable recursion indefinitely */ +	opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE); +	opt->pathspec.max_depth = -1; +  	strbuf_init(&base, PATH_MAX);  	strbuf_add(&base, base_str, baselen); diff --git a/tree-walk.c b/tree-walk.c index 83bede9527..33feafa964 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) @@ -559,8 +560,13 @@ int tree_entry_interesting(const struct name_entry *entry,  	int pathlen, baselen = base->len;  	int never_interesting = -1; -	if (!ps || !ps->nr) -		return 2; +	if (!ps->nr) { +		if (!ps->recursive || ps->max_depth == -1) +			return 2; +		return !!within_depth(base->buf, baselen, +				      !!S_ISDIR(entry->mode), +				      ps->max_depth); +	}  	pathlen = tree_entry_len(entry->path, entry->sha1); @@ -573,7 +579,14 @@ int tree_entry_interesting(const struct name_entry *entry,  			/* If it doesn't match, move along... */  			if (!match_dir_prefix(base->buf, baselen, match, matchlen))  				continue; -			return 2; + +			if (!ps->recursive || ps->max_depth == -1) +				return 2; + +			return !!within_depth(base->buf + matchlen + 1, +					      baselen - matchlen - 1, +					      !!S_ISDIR(entry->mode), +					      ps->max_depth);  		}  		/* Does the base match? */  | 
