git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v1 37/45] Remove match_pathspec() in favor of match_pathspec_depth()

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 15, 2013, 06:06 UTC
Message-ID
<1363327620-29017-38-git-send-email-pclouds@gmail.com>
In-Reply-To
<1363327620-29017-1-git-send-email-pclouds@gmail.com>

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>
---
 builtin/add.c          |  30 +++++++-------
 builtin/check-ignore.c |   4 +-
 dir.c                  | 107 -------------------------------------------------
 dir.h                  |   1 -
 pathspec.c             |  19 ++++-----
 pathspec.h             |   4 +-
 6 files changed, 25 insertions(+), 140 deletions(-)
diff --git a/builtin/add.c b/builtin/add.c
index 70bfc05..aa0709e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -100,26 +100,24 @@ int add_files_to_cache(const char *prefix,
 	return !!data.add_errors;
 }
 
-static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
 {
 	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;
 	}
 	dir->nr = dst - dir->entries;
-	add_pathspec_matches_against_index(pathspec, seen, specs);
+	add_pathspec_matches_against_index(pathspec, seen);
 	return seen;
 }
 
@@ -409,7 +407,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, &pathspec);
 		if (pathspec.nr)
-			seen = prune_directory(&dir, pathspec.raw, baselen);
+			seen = prune_directory(&dir, &pathspec, baselen);
 	}
 
 	if (refresh_only) {
@@ -423,23 +421,23 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 		path_exclude_check_init(&check, &dir);
 		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_path_excluded(&check, pathspec.raw[i], -1, &dtype))
-						dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));
+					if (is_path_excluded(&check, path, -1, &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);
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 6e55f06..80e6bf7 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -93,9 +93,9 @@ static int check_ignore(int argc, const char **argv, const char *prefix)
 	 * 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++) {
-		const char *full_path = pathspec.raw[i];
+		const char *full_path = pathspec.items[i].match;
 		if (!seen[i]) {
 			exclude = last_exclude_matching_path(&check, full_path,
 							     -1, &dtype);
diff --git a/dir.c b/dir.c
index e354abb..9627d7e 100644
--- a/dir.c
+++ b/dir.c
@@ -140,113 +140,6 @@ int within_depth(const char *name, int namelen,
  *
  * 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) 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_pathspec_item(const struct pathspec_item *item, int prefix,
 			       const char *name, int namelen)
 {
diff --git a/dir.h b/dir.h
index d3f76df..13da62c 100644
--- a/dir.h
+++ b/dir.h
@@ -128,7 +128,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);
diff --git a/pathspec.c b/pathspec.c
index 767ce65..1ea1c4c 100644
--- a/pathspec.c
+++ b/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;
 }
 
diff --git a/pathspec.h b/pathspec.h
index 9e9e442..30aea46 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -54,8 +54,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);
 
-- 
1.8.0.rc0.19.g7bbb31d
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 55 of 88 in “nd/parse-pathspec and :(glob) pathspec magic”
  1. 00/45 nd/parse-pathspec and :(glob) pathspec magicNguyễn Thái Ngọc Duy, Mar 15, 2013
  2. 01/45 setup.c: check that the pathspec magic ends with ")"Nguyễn Thái Ngọc Duy, Mar 15, 2013
  3. 02/45 clean: remove unused variable "seen"Nguyễn Thái Ngọc Duy, Mar 15, 2013
  4. 03/45 Move struct pathspec and related functions to pathspec.[ch]Nguyễn Thái Ngọc Duy, Mar 15, 2013
  5. 04/45 pathspec: i18n-ize error strings in pathspec parsing codeNguyễn Thái Ngọc Duy, Mar 15, 2013
  6. 05/45 pathspec: add copy_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  7. 06/45 Add parse_pathspec() that converts cmdline args to struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  8. 07/45 parse_pathspec: save original pathspec for reportingNguyễn Thái Ngọc Duy, Mar 15, 2013
  9. 08/45 parse_pathspec: add PATHSPEC_PREFER_{CWD,FULL}Nguyễn Thái Ngọc Duy, Mar 15, 2013
  10. 09/45 Convert some get_pathspec() calls to parse_pathspec()Nguyễn Thái Ngọc Duy, Mar 15, 2013
  11. 10/45 parse_pathspec: a special flag for max_depth featureNguyễn Thái Ngọc Duy, Mar 15, 2013
  12. Eric SunshineMar 15, 2013
  13. 11/45 parse_pathspec: support stripping submodule trailing slashesNguyễn Thái Ngọc Duy, Mar 15, 2013
  14. Junio C HamanoMar 17, 2013
  15. Duy NguyenMar 18, 2013
  16. 12/45 parse_pathspec: support stripping/checking submodule pathsNguyễn Thái Ngọc Duy, Mar 15, 2013
  17. 13/45 parse_pathspec: support prefixing original patternsNguyễn Thái Ngọc Duy, Mar 15, 2013
  18. 14/45 Guard against new pathspec magic in pathspec matching codeNguyễn Thái Ngọc Duy, Mar 15, 2013
  19. Junio C HamanoMar 17, 2013
  20. 15/45 clean: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  21. 16/45 commit: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  22. 17/45 status: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  23. 18/45 rerere: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  24. 19/45 checkout: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  25. 20/45 rm: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  26. 21/45 ls-files: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  27. 22/45 archive: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  28. Junio C HamanoMar 15, 2013
  29. Duy NguyenMar 16, 2013
  30. Junio C HamanoMar 17, 2013
  31. Duy NguyenMar 17, 2013
  32. Junio C HamanoMar 17, 2013
  33. 23/45 check-ignore: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  34. Adam SpiersApr 12, 2013
  35. Duy NguyenApr 12, 2013
  36. Adam SpiersApr 14, 2013
  37. Duy NguyenApr 14, 2013
  38. Adam SpiersApr 15, 2013
  39. 24/45 add: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  40. 25/45 reset: convert to use parse_pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  41. 26/45 Convert read_cache_preload() to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  42. 27/45 Convert run_add_interactive to use struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  43. John KeepingMar 18, 2013
  44. Duy NguyenMar 19, 2013
  45. John KeepingMar 19, 2013
  46. 28/45 Convert unmerge_cache to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  47. 29/45 checkout: convert read_tree_some to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  48. 30/45 Convert report_path_error to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  49. 31/45 Convert refresh_index to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  50. 32/45 Convert {read,fill}_directory to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  51. 33/45 Convert add_files_to_cache to take struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  52. 34/45 Convert common_prefix() to use struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  53. 35/45 Remove diff_tree_{setup,release}_pathsNguyễn Thái Ngọc Duy, Mar 15, 2013
  54. 36/45 Remove init_pathspec() in favor of parse_pathspec()Nguyễn Thái Ngọc Duy, Mar 15, 2013
  55. 37/45 Remove match_pathspec() in favor of match_pathspec_depth()Nguyễn Thái Ngọc Duy, Mar 15, 2013
  56. 38/45 tree-diff: remove the use of pathspec's raw[] in follow-rename codepathNguyễn Thái Ngọc Duy, Mar 15, 2013
  57. 39/45 parse_pathspec: make sure the prefix part is wildcard-freeNguyễn Thái Ngọc Duy, Mar 15, 2013
  58. Junio C HamanoMar 19, 2013
  59. Duy NguyenMar 20, 2013
  60. Duy NguyenMar 20, 2013
  61. 40/45 parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGINNguyễn Thái Ngọc Duy, Mar 15, 2013
  62. Eric SunshineMar 15, 2013
  63. 41/45 Kill limit_pathspec_to_literal() as it's only used by parse_pathspec()Nguyễn Thái Ngọc Duy, Mar 15, 2013
  64. 42/45 pathspec: support :(literal) syntax for noglob pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  65. 43/45 pathspec: make --literal-pathspecs disable pathspec magicNguyễn Thái Ngọc Duy, Mar 15, 2013
  66. 44/45 pathspec: support :(glob) syntaxNguyễn Thái Ngọc Duy, Mar 15, 2013
  67. Eric SunshineMar 15, 2013
  68. 45/45 Rename field "raw" to "_raw" in struct pathspecNguyễn Thái Ngọc Duy, Mar 15, 2013
  69. Junio C HamanoMar 15, 2013
  70. 00/45 parse_pathspec and :(glob) magicNguyễn Thái Ngọc Duy, Mar 20, 2013
  71. 06/45 Add parse_pathspec() that converts cmdline args to struct pathspecNguyễn Thái Ngọc Duy, Mar 20, 2013
  72. Eric SunshineMar 20, 2013
  73. Junio C HamanoMar 22, 2013
  74. 11/45 parse_pathspec: support stripping submodule trailing slashesNguyễn Thái Ngọc Duy, Mar 20, 2013
  75. 12/45 parse_pathspec: support stripping/checking submodule pathsNguyễn Thái Ngọc Duy, Mar 20, 2013
  76. 14/45 Guard against new pathspec magic in pathspec matching codeNguyễn Thái Ngọc Duy, Mar 20, 2013
  77. Eric SunshineMar 20, 2013
  78. 27/45 Convert run_add_interactive to use struct pathspecNguyễn Thái Ngọc Duy, Mar 20, 2013
  79. 39/45 parse_pathspec: make sure the prefix part is wildcard-freeNguyễn Thái Ngọc Duy, Mar 20, 2013
  80. Junio C HamanoMar 20, 2013
  81. Duy NguyenMar 21, 2013
  82. Duy NguyenMar 21, 2013
  83. Junio C HamanoMar 21, 2013
  84. Junio C HamanoMar 21, 2013
  85. Duy NguyenMar 23, 2013
  86. Duy NguyenMar 23, 2013
  87. Junio C HamanoMar 27, 2013
  88. Eric SunshineMar 24, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.