remove match_pathspec() in favor of match_pathspec_depth()
match_pathspec_depth was created to replace match_pathspec (see
61cf282 (pathspec: add match_pathspec_depth() - 2010-12-15). It took
more than two years, but the replacement finally happens :-)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
			
			
				maint
			
			
		
							parent
							
								
									9a08727443
								
							
						
					
					
						commit
						84b8b5d1fa
					
				|  | @ -195,23 +195,21 @@ int add_files_to_cache(const char *prefix, | |||
| } | ||||
|  | ||||
| #define WARN_IMPLICIT_DOT (1u << 0) | ||||
| static char *prune_directory(struct dir_struct *dir, const char **pathspec, | ||||
| static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, | ||||
| 			     int prefix, unsigned flag) | ||||
| { | ||||
| 	char *seen; | ||||
| 	int i, specs; | ||||
| 	int i; | ||||
| 	struct dir_entry **src, **dst; | ||||
|  | ||||
| 	for (specs = 0; pathspec[specs];  specs++) | ||||
| 		/* nothing */; | ||||
| 	seen = xcalloc(specs, 1); | ||||
| 	seen = xcalloc(pathspec->nr, 1); | ||||
|  | ||||
| 	src = dst = dir->entries; | ||||
| 	i = dir->nr; | ||||
| 	while (--i >= 0) { | ||||
| 		struct dir_entry *entry = *src++; | ||||
| 		if (match_pathspec(pathspec, entry->name, entry->len, | ||||
| 				   prefix, seen)) | ||||
| 		if (match_pathspec_depth(pathspec, entry->name, entry->len, | ||||
| 					 prefix, seen)) | ||||
| 			*dst++ = entry; | ||||
| 		else if (flag & WARN_IMPLICIT_DOT) | ||||
| 			/* | ||||
|  | @ -225,7 +223,7 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, | |||
| 			warn_pathless_add(); | ||||
| 	} | ||||
| 	dir->nr = dst - dir->entries; | ||||
| 	add_pathspec_matches_against_index(pathspec, seen, specs); | ||||
| 	add_pathspec_matches_against_index(pathspec, seen); | ||||
| 	return seen; | ||||
| } | ||||
|  | ||||
|  | @ -523,7 +521,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| 		/* This picks up the paths that are not tracked */ | ||||
| 		baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec); | ||||
| 		if (pathspec.nr) | ||||
| 			seen = prune_directory(&dir, pathspec.raw, baselen, | ||||
| 			seen = prune_directory(&dir, &pathspec, baselen, | ||||
| 					implicit_dot ? WARN_IMPLICIT_DOT : 0); | ||||
| 	} | ||||
|  | ||||
|  | @ -538,23 +536,23 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| 		int i; | ||||
|  | ||||
| 		if (!seen) | ||||
| 			seen = find_pathspecs_matching_against_index(pathspec.raw); | ||||
| 			seen = find_pathspecs_matching_against_index(&pathspec); | ||||
|  | ||||
| 		/* | ||||
| 		 * file_exists() assumes exact match | ||||
| 		 */ | ||||
| 		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP); | ||||
|  | ||||
| 		for (i = 0; pathspec.raw[i]; i++) { | ||||
| 			if (!seen[i] && pathspec.raw[i][0] | ||||
| 			    && !file_exists(pathspec.raw[i])) { | ||||
| 		for (i = 0; i < pathspec.nr; i++) { | ||||
| 			const char *path = pathspec.items[i].match; | ||||
| 			if (!seen[i] && !file_exists(path)) { | ||||
| 				if (ignore_missing) { | ||||
| 					int dtype = DT_UNKNOWN; | ||||
| 					if (is_excluded(&dir, pathspec.raw[i], &dtype)) | ||||
| 						dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i])); | ||||
| 					if (is_excluded(&dir, path, &dtype)) | ||||
| 						dir_add_ignored(&dir, path, pathspec.items[i].len); | ||||
| 				} else | ||||
| 					die(_("pathspec '%s' did not match any files"), | ||||
| 					    pathspec.raw[i]); | ||||
| 					    pathspec.items[i].original); | ||||
| 			} | ||||
| 		} | ||||
| 		free(seen); | ||||
|  |  | |||
|  | @ -94,9 +94,9 @@ static int check_ignore(struct dir_struct *dir, | |||
| 	 * should not be ignored, in order to be consistent with | ||||
| 	 * 'git status', 'git add' etc. | ||||
| 	 */ | ||||
| 	seen = find_pathspecs_matching_against_index(pathspec.raw); | ||||
| 	seen = find_pathspecs_matching_against_index(&pathspec); | ||||
| 	for (i = 0; i < pathspec.nr; i++) { | ||||
| 		full_path = pathspec.raw[i]; | ||||
| 		full_path = pathspec.items[i].match; | ||||
| 		exclude = NULL; | ||||
| 		if (!seen[i]) { | ||||
| 			exclude = last_exclude_matching(dir, full_path, &dtype); | ||||
|  |  | |||
							
								
								
									
										107
									
								
								dir.c
								
								
								
								
							
							
						
						
									
										107
									
								
								dir.c
								
								
								
								
							|  | @ -171,113 +171,6 @@ int within_depth(const char *name, int namelen, | |||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Does 'match' match the given name? | ||||
|  * A match is found if | ||||
|  * | ||||
|  * (1) the 'match' string is leading directory of 'name', or | ||||
|  * (2) the 'match' string is a wildcard and matches 'name', or | ||||
|  * (3) the 'match' string is exactly the same as 'name'. | ||||
|  * | ||||
|  * and the return value tells which case it was. | ||||
|  * | ||||
|  * It returns 0 when there is no match. | ||||
|  */ | ||||
| static int match_one(const char *match, const char *name, int namelen) | ||||
| { | ||||
| 	int matchlen; | ||||
| 	int literal = limit_pathspec_to_literal(); | ||||
|  | ||||
| 	/* If the match was just the prefix, we matched */ | ||||
| 	if (!*match) | ||||
| 		return MATCHED_RECURSIVELY; | ||||
|  | ||||
| 	if (ignore_case) { | ||||
| 		for (;;) { | ||||
| 			unsigned char c1 = tolower(*match); | ||||
| 			unsigned char c2 = tolower(*name); | ||||
| 			if (c1 == '\0' || (!literal && is_glob_special(c1))) | ||||
| 				break; | ||||
| 			if (c1 != c2) | ||||
| 				return 0; | ||||
| 			match++; | ||||
| 			name++; | ||||
| 			namelen--; | ||||
| 		} | ||||
| 	} else { | ||||
| 		for (;;) { | ||||
| 			unsigned char c1 = *match; | ||||
| 			unsigned char c2 = *name; | ||||
| 			if (c1 == '\0' || (!literal && is_glob_special(c1))) | ||||
| 				break; | ||||
| 			if (c1 != c2) | ||||
| 				return 0; | ||||
| 			match++; | ||||
| 			name++; | ||||
| 			namelen--; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * If we don't match the matchstring exactly, | ||||
| 	 * we need to match by fnmatch | ||||
| 	 */ | ||||
| 	matchlen = strlen(match); | ||||
| 	if (strncmp_icase(match, name, matchlen)) { | ||||
| 		if (literal) | ||||
| 			return 0; | ||||
| 		return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0; | ||||
| 	} | ||||
|  | ||||
| 	if (namelen == matchlen) | ||||
| 		return MATCHED_EXACTLY; | ||||
| 	if (match[matchlen-1] == '/' || name[matchlen] == '/') | ||||
| 		return MATCHED_RECURSIVELY; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Given a name and a list of pathspecs, returns the nature of the | ||||
|  * closest (i.e. most specific) match of the name to any of the | ||||
|  * pathspecs. | ||||
|  * | ||||
|  * The caller typically calls this multiple times with the same | ||||
|  * pathspec and seen[] array but with different name/namelen | ||||
|  * (e.g. entries from the index) and is interested in seeing if and | ||||
|  * how each pathspec matches all the names it calls this function | ||||
|  * with.  A mark is left in the seen[] array for each pathspec element | ||||
|  * indicating the closest type of match that element achieved, so if | ||||
|  * seen[n] remains zero after multiple invocations, that means the nth | ||||
|  * pathspec did not match any names, which could indicate that the | ||||
|  * user mistyped the nth pathspec. | ||||
|  */ | ||||
| int match_pathspec(const char **pathspec, const char *name, int namelen, | ||||
| 		int prefix, char *seen) | ||||
| { | ||||
| 	int i, retval = 0; | ||||
|  | ||||
| 	if (!pathspec) | ||||
| 		return 1; | ||||
|  | ||||
| 	name += prefix; | ||||
| 	namelen -= prefix; | ||||
|  | ||||
| 	for (i = 0; pathspec[i] != NULL; i++) { | ||||
| 		int how; | ||||
| 		const char *match = pathspec[i] + prefix; | ||||
| 		if (seen && seen[i] == MATCHED_EXACTLY) | ||||
| 			continue; | ||||
| 		how = match_one(match, name, namelen); | ||||
| 		if (how) { | ||||
| 			if (retval < how) | ||||
| 				retval = how; | ||||
| 			if (seen && seen[i] < how) | ||||
| 				seen[i] = how; | ||||
| 		} | ||||
| 	} | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Does 'match' match the given name? | ||||
|  * A match is found if | ||||
|  |  | |||
							
								
								
									
										1
									
								
								dir.h
								
								
								
								
							
							
						
						
									
										1
									
								
								dir.h
								
								
								
								
							|  | @ -131,7 +131,6 @@ struct dir_struct { | |||
| extern int simple_length(const char *match); | ||||
| extern int no_wildcard(const char *string); | ||||
| extern char *common_prefix(const struct pathspec *pathspec); | ||||
| extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen); | ||||
| extern int match_pathspec_depth(const struct pathspec *pathspec, | ||||
| 				const char *name, int namelen, | ||||
| 				int prefix, char *seen); | ||||
|  |  | |||
							
								
								
									
										19
									
								
								pathspec.c
								
								
								
								
							
							
						
						
									
										19
									
								
								pathspec.c
								
								
								
								
							|  | @ -15,8 +15,8 @@ | |||
|  * If seen[] has not already been written to, it may make sense | ||||
|  * to use find_pathspecs_matching_against_index() instead. | ||||
|  */ | ||||
| void add_pathspec_matches_against_index(const char **pathspec, | ||||
| 					char *seen, int specs) | ||||
| void add_pathspec_matches_against_index(const struct pathspec *pathspec, | ||||
| 					char *seen) | ||||
| { | ||||
| 	int num_unmatched = 0, i; | ||||
|  | ||||
|  | @ -26,14 +26,14 @@ void add_pathspec_matches_against_index(const char **pathspec, | |||
| 	 * mistakenly think that the user gave a pathspec that did not match | ||||
| 	 * anything. | ||||
| 	 */ | ||||
| 	for (i = 0; i < specs; i++) | ||||
| 	for (i = 0; i < pathspec->nr; i++) | ||||
| 		if (!seen[i]) | ||||
| 			num_unmatched++; | ||||
| 	if (!num_unmatched) | ||||
| 		return; | ||||
| 	for (i = 0; i < active_nr; i++) { | ||||
| 		struct cache_entry *ce = active_cache[i]; | ||||
| 		match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen); | ||||
| 		match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | @ -45,15 +45,10 @@ void add_pathspec_matches_against_index(const char **pathspec, | |||
|  * nature of the "closest" (i.e. most specific) matches which each of the | ||||
|  * given pathspecs achieves against all items in the index. | ||||
|  */ | ||||
| char *find_pathspecs_matching_against_index(const char **pathspec) | ||||
| char *find_pathspecs_matching_against_index(const struct pathspec *pathspec) | ||||
| { | ||||
| 	char *seen; | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; pathspec[i];  i++) | ||||
| 		; /* just counting */ | ||||
| 	seen = xcalloc(i, 1); | ||||
| 	add_pathspec_matches_against_index(pathspec, seen, i); | ||||
| 	char *seen = xcalloc(pathspec->nr, 1); | ||||
| 	add_pathspec_matches_against_index(pathspec, seen); | ||||
| 	return seen; | ||||
| } | ||||
|  | ||||
|  |  | |||
|  | @ -63,8 +63,8 @@ extern void free_pathspec(struct pathspec *); | |||
|  | ||||
| extern int limit_pathspec_to_literal(void); | ||||
|  | ||||
| extern char *find_pathspecs_matching_against_index(const char **pathspec); | ||||
| extern void add_pathspec_matches_against_index(const char **pathspec, char *seen, int specs); | ||||
| extern char *find_pathspecs_matching_against_index(const struct pathspec *pathspec); | ||||
| extern void add_pathspec_matches_against_index(const struct pathspec *pathspec, char *seen); | ||||
| extern const char *check_path_for_gitlink(const char *path); | ||||
| extern void die_if_path_beyond_symlink(const char *path, const char *prefix); | ||||
|  | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy