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 <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									86e4ca69e3
								
							
						
					
					
						commit
						d38f28093e
					
				
							
								
								
									
										2
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										2
									
								
								cache.h
								
								
								
								
							|  | @ -503,11 +503,13 @@ 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 has_wildcard:1; | ||||
| 	int recursive:1; | ||||
| 	int max_depth; | ||||
| 	struct pathspec_item { | ||||
| 		const char *match; | ||||
| 		int len; | ||||
| 		int has_wildcard:1; | ||||
| 	} *items; | ||||
| }; | ||||
|  | ||||
|  |  | |||
							
								
								
									
										3
									
								
								dir.c
								
								
								
								
							
							
						
						
									
										3
									
								
								dir.c
								
								
								
								
							|  | @ -1197,6 +1197,9 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) | |||
|  | ||||
| 		item->match = path; | ||||
| 		item->len = strlen(path); | ||||
| 		item->has_wildcard = !no_wildcard(path); | ||||
| 		if (item->has_wildcard) | ||||
| 			pathspec->has_wildcard = 1; | ||||
| 	} | ||||
|  | ||||
| 	qsort(pathspec->items, pathspec->nr, | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										30
									
								
								tree-walk.c
								
								
								
								
							
							
						
						
									
										30
									
								
								tree-walk.c
								
								
								
								
							|  | @ -553,12 +553,12 @@ static int match_dir_prefix(const char *base, int baselen, | |||
|  *  - negative for "no, and no subsequent entries will be either" | ||||
|  */ | ||||
| int tree_entry_interesting(const struct name_entry *entry, | ||||
| 			   const struct strbuf *base, | ||||
| 			   struct strbuf *base, | ||||
| 			   const struct pathspec *ps) | ||||
| { | ||||
| 	int i; | ||||
| 	int pathlen, baselen = base->len; | ||||
| 	int never_interesting = -1; | ||||
| 	int never_interesting = ps->has_wildcard ? 0 : -1; | ||||
|  | ||||
| 	if (!ps->nr) { | ||||
| 		if (!ps->recursive || ps->max_depth == -1) | ||||
|  | @ -578,7 +578,7 @@ int tree_entry_interesting(const struct name_entry *entry, | |||
| 		if (baselen >= matchlen) { | ||||
| 			/* If it doesn't match, move along... */ | ||||
| 			if (!match_dir_prefix(base->buf, baselen, match, matchlen)) | ||||
| 				continue; | ||||
| 				goto match_wildcards; | ||||
|  | ||||
| 			if (!ps->recursive || ps->max_depth == -1) | ||||
| 				return 2; | ||||
|  | @ -596,6 +596,30 @@ int tree_entry_interesting(const struct name_entry *entry, | |||
| 					&never_interesting)) | ||||
| 				return 1; | ||||
| 		} | ||||
|  | ||||
| match_wildcards: | ||||
| 		if (!ps->items[i].has_wildcard) | ||||
| 			continue; | ||||
|  | ||||
| 		/* | ||||
| 		 * Concatenate base and entry->path into one and do | ||||
| 		 * fnmatch() on it. | ||||
| 		 */ | ||||
|  | ||||
| 		strbuf_add(base, entry->path, pathlen); | ||||
|  | ||||
| 		if (!fnmatch(match, base->buf, 0)) { | ||||
| 			strbuf_setlen(base, baselen); | ||||
| 			return 1; | ||||
| 		} | ||||
| 		strbuf_setlen(base, baselen); | ||||
|  | ||||
| 		/* | ||||
| 		 * Match all directories. We'll try to match files | ||||
| 		 * later on. | ||||
| 		 */ | ||||
| 		if (ps->recursive && S_ISDIR(entry->mode)) | ||||
| 			return 1; | ||||
| 	} | ||||
| 	return never_interesting; /* No matches */ | ||||
| } | ||||
|  |  | |||
|  | @ -60,6 +60,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru | |||
| 	return info->pathlen + tree_entry_len(n->path, n->sha1); | ||||
| } | ||||
|  | ||||
| extern int tree_entry_interesting(const struct name_entry *, const struct strbuf *, const struct pathspec *ps); | ||||
| extern int tree_entry_interesting(const struct name_entry *, struct strbuf *, const struct pathspec *ps); | ||||
|  | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy