git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 00/21] "struct pathspec" conversion
@ 2013-01-06  6:20 Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 01/21] pathspec: save the non-wildcard length part Nguyễn Thái Ngọc Duy
                   ` (21 more replies)
  0 siblings, 22 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

This is another step towards the pathspec unification. This series
introduces a get_pathspec() alternative: parse_pathspec(). The new
function intializes struct pathspec directly. Many builtin commands
(except mv) are converted to use this function. As a result, struct
pathspec is used from the start for many commands.

The next step would be dealing with pathspec manipulation code blocks
that use "raw" field, init_pathspec or get_pathspec(). add.c, dir.c,
rm.c and mv.c are hot places. And perhaps move pathspec code from
dir.c and setup.c to pathspec.c after as/check-ignore enters "master".

This series shares a patch (the first one) with nd/pathspec-wildcard. I
put the patch in the series to avoid dependency.

This series also disables wildcards in the prefix part, but it's only
effective in combination with nd/pathspec-wildcard. And of course it's
not fully effective until all "raw" use is eliminated.

Nguyễn Thái Ngọc Duy (21):
  pathspec: save the non-wildcard length part
  Add parse_pathspec() that converts cmdline args to struct pathspec
  pathspec: make sure the prefix part is wildcard-clean
  Export parse_pathspec() and convert some get_pathspec() calls
  clean: convert to use parse_pathspec
  commit: convert to use parse_pathspec
  status: convert to use parse_pathspec
  rerere: convert to use parse_pathspec
  checkout: convert to use parse_pathspec
  rm: convert to use parse_pathspec
  ls-files: convert to use parse_pathspec
  archive: convert to use parse_pathspec
  add: convert to use parse_pathspec
  Convert read_cache_preload() to take struct pathspec
  Convert unmerge_cache to take struct pathspec
  checkout: convert read_tree_some to take struct pathspec
  Convert report_path_error to take struct pathspec
  Convert refresh_index to take struct pathspec
  Convert {read,fill}_directory to take struct pathspec
  Convert add_files_to_cache to take struct pathspec
  Convert more init_pathspec() to parse_pathspec()

 archive.c              |  12 +++---
 archive.h              |   2 +-
 builtin/add.c          |  75 ++++++++++++++++++------------------
 builtin/checkout.c     |  37 ++++++++----------
 builtin/clean.c        |  20 +++++-----
 builtin/commit.c       |  35 +++++++++--------
 builtin/diff-files.c   |   2 +-
 builtin/diff-index.c   |   2 +-
 builtin/diff.c         |   4 +-
 builtin/grep.c         |   6 +--
 builtin/log.c          |   2 +-
 builtin/ls-files.c     |  64 +++++++++++--------------------
 builtin/ls-tree.c      |   4 +-
 builtin/rerere.c       |   6 +--
 builtin/rm.c           |  16 ++++----
 builtin/update-index.c |   3 +-
 cache.h                |  19 +++++++---
 diff-lib.c             |   2 +-
 dir.c                  |  38 ++++++++++++++-----
 dir.h                  |   5 ++-
 merge-recursive.c      |   2 +-
 preload-index.c        |  20 +++++-----
 read-cache.c           |   5 ++-
 rerere.c               |   6 +--
 rerere.h               |   4 +-
 resolve-undo.c         |   4 +-
 resolve-undo.h         |   2 +-
 revision.c             |   4 +-
 setup.c                | 101 +++++++++++++++++++++++++++++++++++++------------
 tree-walk.c            |   4 +-
 tree.c                 |   4 +-
 tree.h                 |   2 +-
 wt-status.c            |  17 ++++-----
 wt-status.h            |   2 +-
 34 files changed, 291 insertions(+), 240 deletions(-)

-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/21] pathspec: save the non-wildcard length part
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec Nguyễn Thái Ngọc Duy
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano

We mark pathspec with wildcards with the field use_wildcard. We
could do better by saving the length of the non-wildcard part, which
can be used for optimizations such as f9f6e2c (exclude: do strcmp as
much as possible before fnmatch - 2012-06-07).

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/ls-files.c | 2 +-
 builtin/ls-tree.c  | 2 +-
 cache.h            | 2 +-
 dir.c              | 6 +++---
 tree-walk.c        | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b5434af..4a9ee69 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -337,7 +337,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
 		matchbuf[0] = prefix;
 		matchbuf[1] = NULL;
 		init_pathspec(&pathspec, matchbuf);
-		pathspec.items[0].use_wildcard = 0;
+		pathspec.items[0].nowildcard_len = pathspec.items[0].len;
 	} else
 		init_pathspec(&pathspec, NULL);
 	if (read_tree(tree, 1, &pathspec))
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 235c17c..fb76e38 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -168,7 +168,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 
 	init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
 	for (i = 0; i < pathspec.nr; i++)
-		pathspec.items[i].use_wildcard = 0;
+		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
 	pathspec.has_wildcard = 0;
 	tree = parse_tree_indirect(sha1);
 	if (!tree)
diff --git a/cache.h b/cache.h
index 2b192d2..9304d91 100644
--- a/cache.h
+++ b/cache.h
@@ -482,7 +482,7 @@ struct pathspec {
 	struct pathspec_item {
 		const char *match;
 		int len;
-		unsigned int use_wildcard:1;
+		int nowildcard_len;
 	} *items;
 };
 
diff --git a/dir.c b/dir.c
index 5a83aa7..c391d46 100644
--- a/dir.c
+++ b/dir.c
@@ -230,7 +230,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
 			return MATCHED_RECURSIVELY;
 	}
 
-	if (item->use_wildcard && !fnmatch(match, name, 0))
+	if (item->nowildcard_len < item->len && !fnmatch(match, name, 0))
 		return MATCHED_FNMATCH;
 
 	return 0;
@@ -1429,8 +1429,8 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
 
 		item->match = path;
 		item->len = strlen(path);
-		item->use_wildcard = !no_wildcard(path);
-		if (item->use_wildcard)
+		item->nowildcard_len = simple_length(path);
+		if (item->nowildcard_len < item->len)
 			pathspec->has_wildcard = 1;
 	}
 
diff --git a/tree-walk.c b/tree-walk.c
index 3f54c02..af871c5 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -626,7 +626,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 					&never_interesting))
 				return entry_interesting;
 
-			if (item->use_wildcard) {
+			if (item->nowildcard_len < item->len) {
 				if (!fnmatch(match + baselen, entry->path, 0))
 					return entry_interesting;
 
@@ -642,7 +642,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 		}
 
 match_wildcards:
-		if (!item->use_wildcard)
+		if (item->nowildcard_len == item->len)
 			continue;
 
 		/*
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 01/21] pathspec: save the non-wildcard length part Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-10 23:26   ` Martin von Zweigbergk
  2013-01-06  6:20 ` [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean Nguyễn Thái Ngọc Duy
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

Currently to fill a struct pathspec, we do:

   const char **paths;
   paths = get_pathspec(prefix, argv);
   ...
   init_pathspec(&pathspec, paths);

"paths" can only carry bare strings, which loses information from
command line arguments such as pathspec magic or the prefix part's
length for each argument.

parse_pathspec() is introduced to combine the two calls into one. The
plan is gradually replace all get_pathspec() and init_pathspec() with
parse_pathspec(). get_pathspec() now becomes a thin wrapper of
parse_pathspec().

parse_pathspec() allows the caller to reject the pathspec magics that
it does not support. When a new pathspec magic is introduced, we can
enable it per command after making sure that all underlying code has no
problem with the new magic.

"flags" parameter is currently unused. But it would allow callers to
pass certain instructions to parse_pathspec, for example forcing
literal pathspec when no magic is used.

With the introduction of parse_pathspec, there are now two functions
that can initialize struct pathspec: init_pathspec and
parse_pathspec. Any semantic changes in struct pathspec must be
reflected in both functions. init_pathspec() will be phased out in
favor of parse_pathspec().

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 dir.c   |  2 +-
 dir.h   |  1 +
 setup.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/dir.c b/dir.c
index c391d46..31f0995 100644
--- a/dir.c
+++ b/dir.c
@@ -291,7 +291,7 @@ int match_pathspec_depth(const struct pathspec *ps,
 /*
  * Return the length of the "simple" part of a path match limiter.
  */
-static int simple_length(const char *match)
+int simple_length(const char *match)
 {
 	int len = -1;
 
diff --git a/dir.h b/dir.h
index f5c89e3..1d4888b 100644
--- a/dir.h
+++ b/dir.h
@@ -66,6 +66,7 @@ struct dir_struct {
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #define MATCHED_EXACTLY 3
+extern int simple_length(const char *match);
 extern char *common_prefix(const char **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,
diff --git a/setup.c b/setup.c
index f108c4b..4fcdae6 100644
--- a/setup.c
+++ b/setup.c
@@ -174,7 +174,7 @@ static struct pathspec_magic {
 
 /*
  * Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
+ * Append the result to the prefix. Return the magic bitmap.
  *
  * For now, we only parse the syntax and throw out anything other than
  * "top" magic.
@@ -185,7 +185,10 @@ static struct pathspec_magic {
  * the prefix part must always match literally, and a single stupid
  * string cannot express such a case.
  */
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+				const char **raw,
+				const char *prefix, int prefixlen,
+				const char *elt)
 {
 	unsigned magic = 0;
 	const char *copyfrom = elt;
@@ -241,39 +244,87 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
 	}
 
 	if (magic & PATHSPEC_FROMTOP)
-		return xstrdup(copyfrom);
+		item->match = xstrdup(copyfrom);
 	else
-		return prefix_path(prefix, prefixlen, copyfrom);
+		item->match = prefix_path(prefix, prefixlen, copyfrom);
+	*raw = item->match;
+	item->len = strlen(item->match);
+	item->nowildcard_len = simple_length(item->match);
+	return magic;
 }
 
-const char **get_pathspec(const char *prefix, const char **pathspec)
+static int pathspec_item_cmp(const void *a_, const void *b_)
 {
-	const char *entry = *pathspec;
-	const char **src, **dst;
-	int prefixlen;
+	struct pathspec_item *a, *b;
 
-	if (!prefix && !entry)
-		return NULL;
+	a = (struct pathspec_item *)a_;
+	b = (struct pathspec_item *)b_;
+	return strcmp(a->match, b->match);
+}
+
+/*
+ * Given command line arguments and a prefix, convert the input to
+ * pathspec. die() if any magic other than ones in magic_mask.
+ */
+static void parse_pathspec(struct pathspec *pathspec,
+			   unsigned magic_mask, unsigned flags,
+			   const char *prefix, const char **argv)
+{
+	struct pathspec_item *item;
+	const char *entry = *argv;
+	int i, n, prefixlen;
+
+	memset(pathspec, 0, sizeof(*pathspec));
+
+	/* No arguments, no prefix -> no pathspec */
+	if (!entry && !prefix)
+		return;
 
+	/* No arguments with prefix -> prefix pathspec */
 	if (!entry) {
-		static const char *spec[2];
-		spec[0] = prefix;
-		spec[1] = NULL;
-		return spec;
+		static const char *raw[2];
+
+		pathspec->items = item = xmalloc(sizeof(*item));
+		item->match = prefix;
+		item->nowildcard_len = item->len = strlen(prefix);
+		raw[0] = prefix;
+		raw[1] = NULL;
+		pathspec->nr = 1;
+		pathspec->raw = raw;
+		return;
 	}
 
-	/* Otherwise we have to re-write the entries.. */
-	src = pathspec;
-	dst = pathspec;
+	n = 0;
+	while (argv[n])
+		n++;
+
+	pathspec->nr = n;
+	pathspec->items = item = xmalloc(sizeof(*item) * n);
+	pathspec->raw = argv;
 	prefixlen = prefix ? strlen(prefix) : 0;
-	while (*src) {
-		*(dst++) = prefix_pathspec(prefix, prefixlen, *src);
-		src++;
+
+	for (i = 0; i < n; i++) {
+		unsigned applied_magic;
+		const char *arg = argv[i];
+
+		applied_magic = prefix_pathspec(item + i, argv + i,
+						prefix, prefixlen, arg);
+		if (applied_magic & ~magic_mask)
+			die(_("pathspec magic in '%s' is not supported"
+			      " by this command"), arg);
+		if (item[i].nowildcard_len < item[i].len)
+			pathspec->has_wildcard = 1;
 	}
-	*dst = NULL;
-	if (!*pathspec)
-		return NULL;
-	return pathspec;
+
+	qsort(pathspec->items, pathspec->nr,
+	      sizeof(struct pathspec_item), pathspec_item_cmp);
+}
+
+const char **get_pathspec(const char *prefix, const char **pathspec)
+{
+	struct pathspec ps;
+	parse_pathspec(&ps, PATHSPEC_FROMTOP, 0, prefix, pathspec);
+	return ps.raw;
 }
 
 /*
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 01/21] pathspec: save the non-wildcard length part Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-07  1:10   ` Duy Nguyen
  2013-01-06  6:20 ` [PATCH 04/21] Export parse_pathspec() and convert some get_pathspec() calls Nguyễn Thái Ngọc Duy
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

Prefix is the result of Git moving back from current directory to
worktree's top directory and it has to prepend all user provided paths
so that they become relative to the new current directory. Any
wildcards in the prefix should not be treated as such because it's not
the user intention. Make sure all wildcards in the prefix part is
disabled.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 setup.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/setup.c b/setup.c
index 4fcdae6..573ef79 100644
--- a/setup.c
+++ b/setup.c
@@ -250,6 +250,8 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 	*raw = item->match;
 	item->len = strlen(item->match);
 	item->nowildcard_len = simple_length(item->match);
+	if (item->nowildcard_len < prefixlen)
+		item->nowildcard_len = prefixlen;
 	return magic;
 }
 
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/21] Export parse_pathspec() and convert some get_pathspec() calls
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (2 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 05/21] clean: convert to use parse_pathspec Nguyễn Thái Ngọc Duy
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

These call sites follow the pattern:

   paths = get_pathspec(prefix, argv);
   init_pathspec(&pathspec, paths);

which can be converted into a single parse_pathspec() call.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/grep.c         | 4 +---
 builtin/ls-tree.c      | 2 +-
 builtin/update-index.c | 3 +--
 cache.h                | 6 ++++++
 revision.c             | 4 ++--
 setup.c                | 6 +++---
 6 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 0e1b6c8..705f9ff 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -630,7 +630,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 	const char *show_in_pager = NULL, *default_pager = "dummy";
 	struct grep_opt opt;
 	struct object_array list = OBJECT_ARRAY_INIT;
-	const char **paths = NULL;
 	struct pathspec pathspec;
 	struct string_list path_list = STRING_LIST_INIT_NODUP;
 	int i;
@@ -857,8 +856,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 			verify_filename(prefix, argv[j], j == i);
 	}
 
-	paths = get_pathspec(prefix, argv + i);
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + i);
 	pathspec.max_depth = opt.max_depth;
 	pathspec.recursive = 1;
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fb76e38..a78ba53 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -166,7 +166,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 	if (get_sha1(argv[0], sha1))
 		die("Not a valid object name %s", argv[0]);
 
-	init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
 	for (i = 0; i < pathspec.nr; i++)
 		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
 	pathspec.has_wildcard = 0;
diff --git a/builtin/update-index.c b/builtin/update-index.c
index ada1dff..6728e59 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -546,10 +546,9 @@ static int do_reupdate(int ac, const char **av,
 	 */
 	int pos;
 	int has_head = 1;
-	const char **paths = get_pathspec(prefix, av + 1);
 	struct pathspec pathspec;
 
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, av + 1);
 
 	if (read_ref("HEAD", head_sha1))
 		/* If there is no HEAD, that means it is an initial
diff --git a/cache.h b/cache.h
index 9304d91..e52365d 100644
--- a/cache.h
+++ b/cache.h
@@ -473,6 +473,9 @@ extern int index_name_is_other(const struct index_state *, const char *, int);
 extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
 extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
 
+/* Pathspec magic */
+#define PATHSPEC_FROMTOP    (1<<0)
+
 struct pathspec {
 	const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
 	int nr;
@@ -487,6 +490,9 @@ struct pathspec {
 };
 
 extern int init_pathspec(struct pathspec *, const char **);
+extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,
+			   unsigned flags, const char *prefix,
+			   const char **args);
 extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
 
diff --git a/revision.c b/revision.c
index 95d21e6..a044242 100644
--- a/revision.c
+++ b/revision.c
@@ -1851,8 +1851,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 		 */
 		ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
 		prune_data.path[prune_data.nr++] = NULL;
-		init_pathspec(&revs->prune_data,
-			      get_pathspec(revs->prefix, prune_data.path));
+		parse_pathspec(&revs->prune_data, PATHSPEC_FROMTOP, 0,
+			       revs->prefix, prune_data.path);
 	}
 
 	if (revs->def == NULL)
diff --git a/setup.c b/setup.c
index 573ef79..cd6680e 100644
--- a/setup.c
+++ b/setup.c
@@ -268,9 +268,9 @@ static int pathspec_item_cmp(const void *a_, const void *b_)
  * Given command line arguments and a prefix, convert the input to
  * pathspec. die() if any magic other than ones in magic_mask.
  */
-static void parse_pathspec(struct pathspec *pathspec,
-			   unsigned magic_mask, unsigned flags,
-			   const char *prefix, const char **argv)
+void parse_pathspec(struct pathspec *pathspec,
+		    unsigned magic_mask, unsigned flags,
+		    const char *prefix, const char **argv)
 {
 	struct pathspec_item *item;
 	const char *entry = *argv;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/21] clean: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (3 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 04/21] Export parse_pathspec() and convert some get_pathspec() calls Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 06/21] commit: " Nguyễn Thái Ngọc Duy
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/clean.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 69c1cda..788ad8c 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -42,7 +42,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
 	struct strbuf directory = STRBUF_INIT;
 	struct dir_struct dir;
-	static const char **pathspec;
+	struct pathspec pathspec;
 	struct strbuf buf = STRBUF_INIT;
 	struct string_list exclude_list = STRING_LIST_INIT_NODUP;
 	const char *qname;
@@ -101,12 +101,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 		add_exclude(exclude_list.items[i].string, "", 0,
 			    &dir.exclude_list[EXC_CMDL]);
 
-	pathspec = get_pathspec(prefix, argv);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-	fill_directory(&dir, pathspec);
+	fill_directory(&dir, pathspec.raw);
 
-	if (pathspec)
-		seen = xmalloc(argc > 0 ? argc : 1);
+	if (pathspec.nr)
+		seen = xmalloc(pathspec.nr);
 
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
@@ -141,10 +141,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 		if (lstat(ent->name, &st))
 			continue;
 
-		if (pathspec) {
-			memset(seen, 0, argc > 0 ? argc : 1);
-			matches = match_pathspec(pathspec, ent->name, len,
-						 0, seen);
+		if (pathspec.nr) {
+			memset(seen, 0, pathspec.nr);
+			matches = match_pathspec_depth(&pathspec, ent->name, len,
+						       0, seen);
 		}
 
 		if (S_ISDIR(st.st_mode)) {
@@ -169,7 +169,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 			}
 			strbuf_reset(&directory);
 		} else {
-			if (pathspec && !matches)
+			if (pathspec.nr && !matches)
 				continue;
 			qname = quote_path_relative(ent->name, -1, &buf, prefix);
 			if (show_only) {
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/21] commit: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (4 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 05/21] clean: convert to use parse_pathspec Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 07/21] status: " Nguyễn Thái Ngọc Duy
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/commit.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index d6dd3df..8410617 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -277,17 +277,18 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 {
 	int fd;
 	struct string_list partial;
-	const char **pathspec = NULL;
+	struct pathspec pathspec;
 	char *old_index_env = NULL;
 	int refresh_flags = REFRESH_QUIET;
 
 	if (is_status)
 		refresh_flags |= REFRESH_UNMERGED;
-
 	if (*argv)
-		pathspec = get_pathspec(prefix, argv);
+		parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	else
+		memset(&pathspec, 0, sizeof(pathspec));
 
-	if (read_cache_preload(pathspec) < 0)
+	if (read_cache_preload(pathspec.raw) < 0)
 		die(_("index file corrupt"));
 
 	if (interactive) {
@@ -329,9 +330,9 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 	 * (A) if all goes well, commit the real index;
 	 * (B) on failure, rollback the real index.
 	 */
-	if (all || (also && pathspec && *pathspec)) {
+	if (all || (also && pathspec.nr)) {
 		fd = hold_locked_index(&index_lock, 1);
-		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
+		add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
 		refresh_cache_or_die(refresh_flags);
 		update_main_cache_tree(WRITE_TREE_SILENT);
 		if (write_cache(fd, active_cache, active_nr) ||
@@ -350,7 +351,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 	 * and create commit from the_index.
 	 * We still need to refresh the index here.
 	 */
-	if (!only && (!pathspec || !*pathspec)) {
+	if (!only && !pathspec.nr) {
 		fd = hold_locked_index(&index_lock, 1);
 		refresh_cache_or_die(refresh_flags);
 		if (active_cache_changed) {
@@ -395,7 +396,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 
 	memset(&partial, 0, sizeof(partial));
 	partial.strdup_strings = 1;
-	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
+	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec.raw))
 		exit(1);
 
 	discard_cache();
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/21] status: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (5 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 06/21] commit: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 08/21] rerere: " Nguyễn Thái Ngọc Duy
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/commit.c |  6 +++---
 wt-status.c      | 17 +++++++----------
 wt-status.h      |  2 +-
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 8410617..b706ebb 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1207,10 +1207,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	if (show_ignored_in_status)
 		s.show_ignored_files = 1;
 	if (*argv)
-		s.pathspec = get_pathspec(prefix, argv);
+		parse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-	read_cache_preload(s.pathspec);
-	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
+	read_cache_preload(s.pathspec.raw);
+	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);
 
 	fd = hold_locked_index(&index_lock, 0);
 	if (0 <= fd)
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..13e6aba 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -434,7 +434,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
 	}
 	rev.diffopt.format_callback = wt_status_collect_changed_cb;
 	rev.diffopt.format_callback_data = s;
-	init_pathspec(&rev.prune_data, s->pathspec);
+	rev.prune_data = s->pathspec;
 	run_diff_files(&rev, 0);
 }
 
@@ -459,22 +459,20 @@ static void wt_status_collect_changes_index(struct wt_status *s)
 	rev.diffopt.detect_rename = 1;
 	rev.diffopt.rename_limit = 200;
 	rev.diffopt.break_opt = 0;
-	init_pathspec(&rev.prune_data, s->pathspec);
+	rev.prune_data = s->pathspec;
 	run_diff_index(&rev, 1);
 }
 
 static void wt_status_collect_changes_initial(struct wt_status *s)
 {
-	struct pathspec pathspec;
 	int i;
 
-	init_pathspec(&pathspec, s->pathspec);
 	for (i = 0; i < active_nr; i++) {
 		struct string_list_item *it;
 		struct wt_status_change_data *d;
 		struct cache_entry *ce = active_cache[i];
 
-		if (!ce_path_match(ce, &pathspec))
+		if (!ce_path_match(ce, &s->pathspec))
 			continue;
 		it = string_list_insert(&s->change, ce->name);
 		d = it->util;
@@ -489,7 +487,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
 		else
 			d->index_status = DIFF_STATUS_ADDED;
 	}
-	free_pathspec(&pathspec);
 }
 
 static void wt_status_collect_untracked(struct wt_status *s)
@@ -505,11 +502,11 @@ static void wt_status_collect_untracked(struct wt_status *s)
 			DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
 	setup_standard_excludes(&dir);
 
-	fill_directory(&dir, s->pathspec);
+	fill_directory(&dir, s->pathspec.raw);
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
 		if (cache_name_is_other(ent->name, ent->len) &&
-		    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+		    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
 			string_list_insert(&s->untracked, ent->name);
 		free(ent);
 	}
@@ -517,11 +514,11 @@ static void wt_status_collect_untracked(struct wt_status *s)
 	if (s->show_ignored_files) {
 		dir.nr = 0;
 		dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
-		fill_directory(&dir, s->pathspec);
+		fill_directory(&dir, s->pathspec.raw);
 		for (i = 0; i < dir.nr; i++) {
 			struct dir_entry *ent = dir.entries[i];
 			if (cache_name_is_other(ent->name, ent->len) &&
-			    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+			    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
 				string_list_insert(&s->ignored, ent->name);
 			free(ent);
 		}
diff --git a/wt-status.h b/wt-status.h
index 236b41f..dd8df41 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -44,7 +44,7 @@ struct wt_status {
 	int is_initial;
 	char *branch;
 	const char *reference;
-	const char **pathspec;
+	struct pathspec pathspec;
 	int verbose;
 	int amend;
 	enum commit_whence whence;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/21] rerere: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (6 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 07/21] status: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 09/21] checkout: " Nguyễn Thái Ngọc Duy
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/rerere.c | 6 +++---
 rerere.c         | 8 ++++----
 rerere.h         | 4 +++-
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/builtin/rerere.c b/builtin/rerere.c
index dc1708e..a573c4a 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -68,11 +68,11 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 		return rerere(flags);
 
 	if (!strcmp(argv[0], "forget")) {
-		const char **pathspec;
+		struct pathspec pathspec;
 		if (argc < 2)
 			warning("'git rerere forget' without paths is deprecated");
-		pathspec = get_pathspec(prefix, argv + 1);
-		return rerere_forget(pathspec);
+		parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
+		return rerere_forget(&pathspec);
 	}
 
 	fd = setup_rerere(&merge_rr, flags);
diff --git a/rerere.c b/rerere.c
index a6a5cd5..f8ddf85 100644
--- a/rerere.c
+++ b/rerere.c
@@ -655,7 +655,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
 	return 0;
 }
 
-int rerere_forget(const char **pathspec)
+int rerere_forget(struct pathspec *pathspec)
 {
 	int i, fd;
 	struct string_list conflict = STRING_LIST_INIT_DUP;
@@ -666,12 +666,12 @@ int rerere_forget(const char **pathspec)
 
 	fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
 
-	unmerge_cache(pathspec);
+	unmerge_cache(pathspec->raw);
 	find_conflict(&conflict);
 	for (i = 0; i < conflict.nr; i++) {
 		struct string_list_item *it = &conflict.items[i];
-		if (!match_pathspec(pathspec, it->string, strlen(it->string),
-				    0, NULL))
+		if (!match_pathspec_depth(pathspec, it->string, strlen(it->string),
+					  0, NULL))
 			continue;
 		rerere_forget_one_path(it->string, &merge_rr);
 	}
diff --git a/rerere.h b/rerere.h
index 156d2aa..4aa06c9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,6 +3,8 @@
 
 #include "string-list.h"
 
+struct pathspec;
+
 #define RERERE_AUTOUPDATE   01
 #define RERERE_NOAUTOUPDATE 02
 
@@ -16,7 +18,7 @@ extern void *RERERE_RESOLVED;
 extern int setup_rerere(struct string_list *, int);
 extern int rerere(int);
 extern const char *rerere_path(const char *hex, const char *file);
-extern int rerere_forget(const char **);
+extern int rerere_forget(struct pathspec *);
 extern int rerere_remaining(struct string_list *);
 extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/21] checkout: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (7 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 08/21] rerere: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 10/21] rm: " Nguyễn Thái Ngọc Duy
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/checkout.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index a9c1b5a..da25298 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -45,7 +45,7 @@ struct checkout_opts {
 
 	int branch_exists;
 	const char *prefix;
-	const char **pathspec;
+	struct pathspec pathspec;
 	struct tree *source_tree;
 };
 
@@ -256,39 +256,37 @@ static int checkout_paths(const struct checkout_opts *opts,
 
 	if (opts->patch_mode)
 		return run_add_interactive(revision, "--patch=checkout",
-					   opts->pathspec);
+					   opts->pathspec.raw);
 
 	lock_file = xcalloc(1, sizeof(struct lock_file));
 
 	newfd = hold_locked_index(lock_file, 1);
-	if (read_cache_preload(opts->pathspec) < 0)
+	if (read_cache_preload(opts->pathspec.raw) < 0)
 		return error(_("corrupt index file"));
 
 	if (opts->source_tree)
-		read_tree_some(opts->source_tree, opts->pathspec);
+		read_tree_some(opts->source_tree, opts->pathspec.raw);
 
-	for (pos = 0; opts->pathspec[pos]; pos++)
-		;
-	ps_matched = xcalloc(1, pos);
+	ps_matched = xcalloc(1, opts->pathspec.nr);
 
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
 		if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
 			continue;
-		match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
+		match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
 	}
 
-	if (report_path_error(ps_matched, opts->pathspec, opts->prefix))
+	if (report_path_error(ps_matched, opts->pathspec.raw, opts->prefix))
 		return 1;
 
 	/* "checkout -m path" to recreate conflicted state */
 	if (opts->merge)
-		unmerge_cache(opts->pathspec);
+		unmerge_cache(opts->pathspec.raw);
 
 	/* Any unmerged paths? */
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
-		if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+		if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
 			if (!ce_stage(ce))
 				continue;
 			if (opts->force) {
@@ -315,7 +313,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 		struct cache_entry *ce = active_cache[pos];
 		if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
 			continue;
-		if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+		if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
 			if (!ce_stage(ce)) {
 				errs |= checkout_entry(ce, &state, NULL);
 				continue;
@@ -960,7 +958,7 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts)
 static int checkout_branch(struct checkout_opts *opts,
 			   struct branch_info *new)
 {
-	if (opts->pathspec)
+	if (opts->pathspec.nr)
 		die(_("paths cannot be used with switching branches"));
 
 	if (opts->patch_mode)
@@ -1110,9 +1108,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	}
 
 	if (argc) {
-		opts.pathspec = get_pathspec(prefix, argv);
+		parse_pathspec(&opts.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-		if (!opts.pathspec)
+		if (!opts.pathspec.nr)
 			die(_("invalid path specification"));
 
 		/*
@@ -1144,7 +1142,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		strbuf_release(&buf);
 	}
 
-	if (opts.patch_mode || opts.pathspec)
+	if (opts.patch_mode || opts.pathspec.nr)
 		return checkout_paths(&opts, new.name);
 	else
 		return checkout_branch(&opts, &new);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/21] rm: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (8 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 09/21] checkout: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 11/21] ls-files: " Nguyễn Thái Ngọc Duy
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/rm.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/builtin/rm.c b/builtin/rm.c
index dabfcf6..d719d95 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -216,7 +216,7 @@ static struct option builtin_rm_options[] = {
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
 	int i, newfd;
-	const char **pathspec;
+	struct pathspec pathspec;
 	char *seen;
 
 	git_config(git_default_config, NULL);
@@ -249,27 +249,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	pathspec = get_pathspec(prefix, argv);
-	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	refresh_index(&the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
 
 	seen = NULL;
-	for (i = 0; pathspec[i] ; i++)
-		/* nothing */;
-	seen = xcalloc(i, 1);
+	seen = xcalloc(pathspec.nr, 1);
 
 	for (i = 0; i < active_nr; i++) {
 		struct cache_entry *ce = active_cache[i];
-		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+		if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
 			continue;
 		ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
 		list.entry[list.nr].name = ce->name;
 		list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);
 	}
 
-	if (pathspec) {
+	if (pathspec.nr) {
 		const char *match;
 		int seen_any = 0;
-		for (i = 0; (match = pathspec[i]) != NULL ; i++) {
+		for (i = 0; (match = pathspec.raw[i]) != NULL ; i++) {
 			if (!seen[i]) {
 				if (!ignore_unmatch) {
 					die(_("pathspec '%s' did not match any files"),
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/21] ls-files: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (9 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 10/21] rm: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:20 ` [PATCH 12/21] archive: " Nguyễn Thái Ngọc Duy
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/ls-files.c | 42 +++++++++++-------------------------------
 cache.h            |  1 +
 dir.c              | 20 ++++++++++++++++++++
 3 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 4a9ee69..9336abd 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -30,7 +30,7 @@ static int debug_mode;
 static const char *prefix;
 static int max_prefix_len;
 static int prefix_len;
-static const char **pathspec;
+static struct pathspec pathspec;
 static int error_unmatch;
 static char *ps_matched;
 static const char *with_tree;
@@ -58,7 +58,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 	if (len >= ent->len)
 		die("git ls-files: internal error - directory entry not superset of prefix");
 
-	if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
+	if (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched))
 		return;
 
 	fputs(tag, stdout);
@@ -133,7 +133,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
 	if (len >= ce_namelen(ce))
 		die("git ls-files: internal error - cache entry not superset of prefix");
 
-	if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))
+	if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched))
 		return;
 
 	if (tag && *tag && show_valid_bit &&
@@ -187,7 +187,7 @@ static void show_ru_info(void)
 		len = strlen(path);
 		if (len < max_prefix_len)
 			continue; /* outside of the prefix */
-		if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched))
+		if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched))
 			continue; /* uninterested */
 		for (i = 0; i < 3; i++) {
 			if (!ui->mode[i])
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
 
 	/* For cached/deleted files we don't need to even do the readdir */
 	if (show_others || show_killed) {
-		fill_directory(dir, pathspec);
+		fill_directory(dir, pathspec.raw);
 		if (show_others)
 			show_other_files(dir);
 		if (show_killed)
@@ -287,21 +287,6 @@ static void prune_cache(const char *prefix)
 	active_nr = last;
 }
 
-static void strip_trailing_slash_from_submodules(void)
-{
-	const char **p;
-
-	for (p = pathspec; *p != NULL; p++) {
-		int len = strlen(*p), pos;
-
-		if (len < 1 || (*p)[len - 1] != '/')
-			continue;
-		pos = cache_name_pos(*p, len - 1);
-		if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))
-			*p = xstrndup(*p, len - 1);
-	}
-}
-
 /*
  * Read the tree specified with --with-tree option
  * (typically, HEAD) into stage #1 and then
@@ -549,23 +534,18 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	if (require_work_tree && !is_inside_work_tree())
 		setup_work_tree();
 
-	pathspec = get_pathspec(prefix, argv);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
 	/* be nice with submodule paths ending in a slash */
-	if (pathspec)
-		strip_trailing_slash_from_submodules();
+	strip_trailing_slash_from_submodules(&pathspec);
 
 	/* Find common prefix for all pathspec's */
-	max_prefix = common_prefix(pathspec);
+	max_prefix = common_prefix(pathspec.raw);
 	max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
 
 	/* Treat unmatching pathspec elements as errors */
-	if (pathspec && error_unmatch) {
-		int num;
-		for (num = 0; pathspec[num]; num++)
-			;
-		ps_matched = xcalloc(1, num);
-	}
+	if (pathspec.nr && error_unmatch)
+		ps_matched = xcalloc(1, pathspec.nr);
 
 	if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
 		die("ls-files --ignored needs some exclude pattern");
@@ -592,7 +572,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 
 	if (ps_matched) {
 		int bad;
-		bad = report_path_error(ps_matched, pathspec, prefix);
+		bad = report_path_error(ps_matched, pathspec.raw, prefix);
 		if (bad)
 			fprintf(stderr, "Did you forget to 'git add'?\n");
 
diff --git a/cache.h b/cache.h
index e52365d..890d89b 100644
--- a/cache.h
+++ b/cache.h
@@ -493,6 +493,7 @@ extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,
 			   unsigned flags, const char *prefix,
 			   const char **args);
+void strip_trailing_slash_from_submodules(struct pathspec *pathspec);
 extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
 
diff --git a/dir.c b/dir.c
index 31f0995..11e8c1d 100644
--- a/dir.c
+++ b/dir.c
@@ -1440,6 +1440,26 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
 	return 0;
 }
 
+void strip_trailing_slash_from_submodules(struct pathspec *pathspec)
+{
+	int i;
+	for (i = 0; i < pathspec->nr; i++) {
+		const char *p = pathspec->raw[i];
+		int len = strlen(p), pos;
+
+		if (len < 1 || p[len - 1] != '/')
+			continue;
+		pos = cache_name_pos(p, len - 1);
+		if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode)) {
+			pathspec->raw[i] = xstrndup(p, len - 1);
+			pathspec->items[i].len--;
+			pathspec->items[i].match =
+				xstrndup(pathspec->items[i].match,
+					 pathspec->items[i].len);
+		}
+	}
+}
+
 void free_pathspec(struct pathspec *pathspec)
 {
 	free(pathspec->items);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/21] archive: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (10 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 11/21] ls-files: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:20 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 13/21] add: " Nguyễn Thái Ngọc Duy
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:20 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 archive.c | 10 ++++------
 archive.h |  2 +-
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/archive.c b/archive.c
index 4666404..530badb 100644
--- a/archive.c
+++ b/archive.c
@@ -150,7 +150,6 @@ int write_archive_entries(struct archiver_args *args,
 	struct archiver_context context;
 	struct unpack_trees_options opts;
 	struct tree_desc t;
-	struct pathspec pathspec;
 	int err;
 
 	if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -185,10 +184,8 @@ int write_archive_entries(struct archiver_args *args,
 		git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
 	}
 
-	init_pathspec(&pathspec, args->pathspec);
-	err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
+	err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
 				  write_archive_entry, &context);
-	free_pathspec(&pathspec);
 	if (err == READ_TREE_RECURSIVE)
 		err = 0;
 	return err;
@@ -230,8 +227,9 @@ static int path_exists(struct tree *tree, const char *path)
 static void parse_pathspec_arg(const char **pathspec,
 		struct archiver_args *ar_args)
 {
-	ar_args->pathspec = pathspec = get_pathspec("", pathspec);
-	if (pathspec) {
+	parse_pathspec(&ar_args->pathspec, PATHSPEC_FROMTOP, 0, "", pathspec);
+	if (ar_args->pathspec.nr) {
+		pathspec = ar_args->pathspec.raw;
 		while (*pathspec) {
 			if (!path_exists(ar_args->tree, *pathspec))
 				die("path not found: %s", *pathspec);
diff --git a/archive.h b/archive.h
index 895afcd..a98c49e 100644
--- a/archive.h
+++ b/archive.h
@@ -8,7 +8,7 @@ struct archiver_args {
 	const unsigned char *commit_sha1;
 	const struct commit *commit;
 	time_t time;
-	const char **pathspec;
+	struct pathspec pathspec;
 	unsigned int verbose : 1;
 	unsigned int worktree_attributes : 1;
 	unsigned int convert : 1;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/21] add: convert to use parse_pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (11 preceding siblings ...)
  2013-01-06  6:20 ` [PATCH 12/21] archive: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 14/21] Convert read_cache_preload() to take struct pathspec Nguyễn Thái Ngọc Duy
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c | 57 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 29 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index e664100..af36bc4 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -197,21 +197,18 @@ static void refresh(int verbose, const char **pathspec)
         free(seen);
 }
 
-static const char **validate_pathspec(int argc, const char **argv, const char *prefix)
+static void validate_pathspec(const char **pathspec, const char *prefix)
 {
-	const char **pathspec = get_pathspec(prefix, argv);
-
-	if (pathspec) {
-		const char **p;
-		for (p = pathspec; *p; p++) {
-			if (has_symlink_leading_path(*p, strlen(*p))) {
-				int len = prefix ? strlen(prefix) : 0;
-				die(_("'%s' is beyond a symbolic link"), *p + len);
-			}
+	const char **p;
+	if (!pathspec)
+		return;
+
+	for (p = pathspec; *p; p++) {
+		if (has_symlink_leading_path(*p, strlen(*p))) {
+			int len = prefix ? strlen(prefix) : 0;
+			die(_("'%s' is beyond a symbolic link"), *p + len);
 		}
 	}
-
-	return pathspec;
 }
 
 int run_add_interactive(const char *revision, const char *patch_mode,
@@ -248,7 +245,8 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 	const char **pathspec = NULL;
 
 	if (argc) {
-		pathspec = validate_pathspec(argc, argv, prefix);
+		pathspec = get_pathspec(prefix, argv);
+		validate_pathspec(pathspec, prefix);
 		if (!pathspec)
 			return -1;
 	}
@@ -367,7 +365,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 {
 	int exit_status = 0;
 	int newfd;
-	const char **pathspec;
+	struct pathspec pathspec;
 	struct dir_struct dir;
 	int flags;
 	int add_new_files;
@@ -415,11 +413,12 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 		return 0;
 	}
-	pathspec = validate_pathspec(argc, argv, prefix);
+	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	validate_pathspec(pathspec.raw, prefix);
 
 	if (read_cache() < 0)
 		die(_("index file corrupt"));
-	treat_gitlinks(pathspec);
+	treat_gitlinks(pathspec.raw);
 
 	if (add_new_files) {
 		int baselen;
@@ -432,33 +431,33 @@ 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)
-			seen = prune_directory(&dir, pathspec, baselen);
+		baselen = fill_directory(&dir, pathspec.raw);
+		if (pathspec.nr)
+			seen = prune_directory(&dir, pathspec.raw, baselen);
 	}
 
 	if (refresh_only) {
-		refresh(verbose, pathspec);
+		refresh(verbose, pathspec.raw);
 		goto finish;
 	}
 
-	if (pathspec) {
+	if (pathspec.nr) {
 		int i;
 		struct path_exclude_check check;
 
 		path_exclude_check_init(&check, &dir);
 		if (!seen)
-			seen = find_used_pathspec(pathspec);
-		for (i = 0; pathspec[i]; i++) {
-			if (!seen[i] && pathspec[i][0]
-			    && !file_exists(pathspec[i])) {
+			seen = find_used_pathspec(pathspec.raw);
+		for (i = 0; pathspec.raw[i]; i++) {
+			if (!seen[i] && pathspec.raw[i][0]
+			    && !file_exists(pathspec.raw[i])) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
-					if (path_excluded(&check, pathspec[i], -1, &dtype))
-						dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
+					if (path_excluded(&check, pathspec.raw[i], -1, &dtype))
+						dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));
 				} else
 					die(_("pathspec '%s' did not match any files"),
-					    pathspec[i]);
+					    pathspec.raw[i]);
 			}
 		}
 		free(seen);
@@ -467,7 +466,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 	plug_bulk_checkin();
 
-	exit_status |= add_files_to_cache(prefix, pathspec, flags);
+	exit_status |= add_files_to_cache(prefix, pathspec.raw, flags);
 
 	if (add_new_files)
 		exit_status |= add_files(&dir, flags);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/21] Convert read_cache_preload() to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (12 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 13/21] add: " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 15/21] Convert unmerge_cache " Nguyễn Thái Ngọc Duy
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/checkout.c   |  2 +-
 builtin/commit.c     |  4 ++--
 builtin/diff-files.c |  2 +-
 builtin/diff-index.c |  2 +-
 builtin/diff.c       |  4 ++--
 cache.h              |  4 +++-
 preload-index.c      | 20 +++++++++++---------
 7 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index da25298..00910dc 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -261,7 +261,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 	lock_file = xcalloc(1, sizeof(struct lock_file));
 
 	newfd = hold_locked_index(lock_file, 1);
-	if (read_cache_preload(opts->pathspec.raw) < 0)
+	if (read_cache_preload(&opts->pathspec) < 0)
 		return error(_("corrupt index file"));
 
 	if (opts->source_tree)
diff --git a/builtin/commit.c b/builtin/commit.c
index b706ebb..7b5f123 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -288,7 +288,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 	else
 		memset(&pathspec, 0, sizeof(pathspec));
 
-	if (read_cache_preload(pathspec.raw) < 0)
+	if (read_cache_preload(&pathspec) < 0)
 		die(_("index file corrupt"));
 
 	if (interactive) {
@@ -1209,7 +1209,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	if (*argv)
 		parse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-	read_cache_preload(s.pathspec.raw);
+	read_cache_preload(&s.pathspec);
 	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);
 
 	fd = hold_locked_index(&index_lock, 0);
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 46085f8..9200069 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
 	    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))
 		rev.combine_merges = rev.dense_combined_merges = 1;
 
-	if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+	if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
 		perror("read_cache_preload");
 		return -1;
 	}
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 1c737f7..ce15b23 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
 		usage(diff_cache_usage);
 	if (!cached) {
 		setup_work_tree();
-		if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
 			perror("read_cache_preload");
 			return -1;
 		}
diff --git a/builtin/diff.c b/builtin/diff.c
index 8c2af6c..62bdc4d 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs,
 		usage(builtin_diff_usage);
 	if (!cached) {
 		setup_work_tree();
-		if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+		if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
 			perror("read_cache_preload");
 			return -1;
 		}
@@ -240,7 +240,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
 		revs->combine_merges = revs->dense_combined_merges = 1;
 
 	setup_work_tree();
-	if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+	if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
 		perror("read_cache_preload");
 		return -1;
 	}
diff --git a/cache.h b/cache.h
index 890d89b..7871cd1 100644
--- a/cache.h
+++ b/cache.h
@@ -182,6 +182,8 @@ struct cache_entry {
 #error "CE_EXTENDED_FLAGS out of range"
 #endif
 
+struct pathspec;
+
 /*
  * Copy the sha1 and stat state of a cache entry from one to
  * another. But we never change the name, or the hash state!
@@ -433,7 +435,7 @@ extern int init_db(const char *template_dir, unsigned int flags);
 
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
-extern int read_index_preload(struct index_state *, const char **pathspec);
+extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);
 extern int read_index_from(struct index_state *, const char *path);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
diff --git a/preload-index.c b/preload-index.c
index 49cb08d..91f27f7 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -4,7 +4,8 @@
 #include "cache.h"
 
 #ifdef NO_PTHREADS
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+			  const struct pathspec *pathspec)
 {
 	; /* nothing */
 }
@@ -24,7 +25,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
 struct thread_data {
 	pthread_t pthread;
 	struct index_state *index;
-	const char **pathspec;
+	struct pathspec pathspec;
 	int offset, nr;
 };
 
@@ -35,9 +36,7 @@ static void *preload_thread(void *_data)
 	struct index_state *index = p->index;
 	struct cache_entry **cep = index->cache + p->offset;
 	struct cache_def cache;
-	struct pathspec pathspec;
 
-	init_pathspec(&pathspec, p->pathspec);
 	memset(&cache, 0, sizeof(cache));
 	nr = p->nr;
 	if (nr + p->offset > index->cache_nr)
@@ -53,7 +52,7 @@ static void *preload_thread(void *_data)
 			continue;
 		if (ce_uptodate(ce))
 			continue;
-		if (!ce_path_match(ce, &pathspec))
+		if (!ce_path_match(ce, &p->pathspec))
 			continue;
 		if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
 			continue;
@@ -63,11 +62,11 @@ static void *preload_thread(void *_data)
 			continue;
 		ce_mark_uptodate(ce);
 	} while (--nr > 0);
-	free_pathspec(&pathspec);
 	return NULL;
 }
 
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+			  const struct pathspec *pathspec)
 {
 	int threads, i, work, offset;
 	struct thread_data data[MAX_PARALLEL];
@@ -82,10 +81,12 @@ static void preload_index(struct index_state *index, const char **pathspec)
 		threads = MAX_PARALLEL;
 	offset = 0;
 	work = DIV_ROUND_UP(index->cache_nr, threads);
+	memset(&data, 0, sizeof(data));
 	for (i = 0; i < threads; i++) {
 		struct thread_data *p = data+i;
 		p->index = index;
-		p->pathspec = pathspec;
+		if (pathspec)
+			p->pathspec = *pathspec;
 		p->offset = offset;
 		p->nr = work;
 		offset += work;
@@ -100,7 +101,8 @@ static void preload_index(struct index_state *index, const char **pathspec)
 }
 #endif
 
-int read_index_preload(struct index_state *index, const char **pathspec)
+int read_index_preload(struct index_state *index,
+		       const struct pathspec *pathspec)
 {
 	int retval = read_index(index);
 
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 15/21] Convert unmerge_cache to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (13 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 14/21] Convert read_cache_preload() to take struct pathspec Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 16/21] checkout: convert read_tree_some " Nguyễn Thái Ngọc Duy
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/checkout.c | 2 +-
 rerere.c           | 2 +-
 resolve-undo.c     | 4 ++--
 resolve-undo.h     | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 00910dc..aa399d6 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -281,7 +281,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 
 	/* "checkout -m path" to recreate conflicted state */
 	if (opts->merge)
-		unmerge_cache(opts->pathspec.raw);
+		unmerge_cache(&opts->pathspec);
 
 	/* Any unmerged paths? */
 	for (pos = 0; pos < active_nr; pos++) {
diff --git a/rerere.c b/rerere.c
index f8ddf85..9d149fa 100644
--- a/rerere.c
+++ b/rerere.c
@@ -666,7 +666,7 @@ int rerere_forget(struct pathspec *pathspec)
 
 	fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
 
-	unmerge_cache(pathspec->raw);
+	unmerge_cache(pathspec);
 	find_conflict(&conflict);
 	for (i = 0; i < conflict.nr; i++) {
 		struct string_list_item *it = &conflict.items[i];
diff --git a/resolve-undo.c b/resolve-undo.c
index 72b4612..1bfece2 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -156,7 +156,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
 	return unmerge_index_entry_at(istate, pos);
 }
 
-void unmerge_index(struct index_state *istate, const char **pathspec)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
 {
 	int i;
 
@@ -165,7 +165,7 @@ void unmerge_index(struct index_state *istate, const char **pathspec)
 
 	for (i = 0; i < istate->cache_nr; i++) {
 		struct cache_entry *ce = istate->cache[i];
-		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+		if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
 			continue;
 		i = unmerge_index_entry_at(istate, i);
 	}
diff --git a/resolve-undo.h b/resolve-undo.h
index 8458769..81e8803 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -11,6 +11,6 @@ extern void resolve_undo_write(struct strbuf *, struct string_list *);
 extern struct string_list *resolve_undo_read(const char *, unsigned long);
 extern void resolve_undo_clear_index(struct index_state *);
 extern int unmerge_index_entry_at(struct index_state *, int);
-extern void unmerge_index(struct index_state *, const char **);
+extern void unmerge_index(struct index_state *, const struct pathspec *);
 
 #endif
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 16/21] checkout: convert read_tree_some to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (14 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 15/21] Convert unmerge_cache " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 17/21] Convert report_path_error " Nguyễn Thái Ngọc Duy
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/checkout.c | 9 +++------
 tree.c             | 4 ++--
 tree.h             | 2 +-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index aa399d6..a7ddb35 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -82,12 +82,9 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
 	return 0;
 }
 
-static int read_tree_some(struct tree *tree, const char **pathspec)
+static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
 {
-	struct pathspec ps;
-	init_pathspec(&ps, pathspec);
-	read_tree_recursive(tree, "", 0, 0, &ps, update_some, NULL);
-	free_pathspec(&ps);
+	read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
 
 	/* update the index with the given tree's info
 	 * for all args, expanding wildcards, and exit
@@ -265,7 +262,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 		return error(_("corrupt index file"));
 
 	if (opts->source_tree)
-		read_tree_some(opts->source_tree, opts->pathspec.raw);
+		read_tree_some(opts->source_tree, &opts->pathspec);
 
 	ps_matched = xcalloc(1, opts->pathspec.nr);
 
diff --git a/tree.c b/tree.c
index 62fed63..ff72f67 100644
--- a/tree.c
+++ b/tree.c
@@ -47,7 +47,7 @@ static int read_one_entry_quick(const unsigned char *sha1, const char *base, int
 }
 
 static int read_tree_1(struct tree *tree, struct strbuf *base,
-		       int stage, struct pathspec *pathspec,
+		       int stage, const struct pathspec *pathspec,
 		       read_tree_fn_t fn, void *context)
 {
 	struct tree_desc desc;
@@ -116,7 +116,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
 
 int read_tree_recursive(struct tree *tree,
 			const char *base, int baselen,
-			int stage, struct pathspec *pathspec,
+			int stage, const struct pathspec *pathspec,
 			read_tree_fn_t fn, void *context)
 {
 	struct strbuf sb = STRBUF_INIT;
diff --git a/tree.h b/tree.h
index 69bcb5e..9dc90ba 100644
--- a/tree.h
+++ b/tree.h
@@ -25,7 +25,7 @@ typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const ch
 
 extern int read_tree_recursive(struct tree *tree,
 			       const char *base, int baselen,
-			       int stage, struct pathspec *pathspec,
+			       int stage, const struct pathspec *pathspec,
 			       read_tree_fn_t fn, void *context);
 
 extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 17/21] Convert report_path_error to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (15 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 16/21] checkout: convert read_tree_some " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 18/21] Convert refresh_index " Nguyễn Thái Ngọc Duy
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/checkout.c |  2 +-
 builtin/commit.c   | 14 ++++++--------
 builtin/ls-files.c | 14 ++++++++------
 cache.h            |  2 +-
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index a7ddb35..648768e 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -273,7 +273,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 		match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
 	}
 
-	if (report_path_error(ps_matched, opts->pathspec.raw, opts->prefix))
+	if (report_path_error(ps_matched, &opts->pathspec, opts->prefix))
 		return 1;
 
 	/* "checkout -m path" to recreate conflicted state */
diff --git a/builtin/commit.c b/builtin/commit.c
index 7b5f123..71c5afb 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -181,20 +181,18 @@ static int commit_index_files(void)
  * and return the paths that match the given pattern in list.
  */
 static int list_paths(struct string_list *list, const char *with_tree,
-		      const char *prefix, const char **pattern)
+		      const char *prefix, const struct pathspec *pattern)
 {
 	int i;
 	char *m;
 
-	if (!pattern)
+	if (!pattern->nr)
 		return 0;
 
-	for (i = 0; pattern[i]; i++)
-		;
-	m = xcalloc(1, i);
+	m = xcalloc(1, pattern->nr);
 
 	if (with_tree) {
-		char *max_prefix = common_prefix(pattern);
+		char *max_prefix = common_prefix(pattern->raw);
 		overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
 		free(max_prefix);
 	}
@@ -205,7 +203,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
 		if (ce->ce_flags & CE_UPDATE)
 			continue;
-		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
+		if (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m))
 			continue;
 		item = string_list_insert(list, ce->name);
 		if (ce_skip_worktree(ce))
@@ -396,7 +394,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 
 	memset(&partial, 0, sizeof(partial));
 	partial.strdup_strings = 1;
-	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec.raw))
+	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, &pathspec))
 		exit(1);
 
 	discard_cache();
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 9336abd..be6e05d 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -349,7 +349,9 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
 	}
 }
 
-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix)
+int report_path_error(const char *ps_matched,
+		      const struct pathspec *pathspec,
+		      const char *prefix)
 {
 	/*
 	 * Make sure all pathspec matched; otherwise it is an error.
@@ -357,7 +359,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char
 	struct strbuf sb = STRBUF_INIT;
 	const char *name;
 	int num, errors = 0;
-	for (num = 0; pathspec[num]; num++) {
+	for (num = 0; num < pathspec->nr; num++) {
 		int other, found_dup;
 
 		if (ps_matched[num])
@@ -367,11 +369,11 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char
 		 * twice.  Do not barf on such a mistake.
 		 */
 		for (found_dup = other = 0;
-		     !found_dup && pathspec[other];
+		     !found_dup && pathspec->raw[other];
 		     other++) {
 			if (other == num || !ps_matched[other])
 				continue;
-			if (!strcmp(pathspec[other], pathspec[num]))
+			if (!strcmp(pathspec->raw[other], pathspec->raw[num]))
 				/*
 				 * Ok, we have a match already.
 				 */
@@ -380,7 +382,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char
 		if (found_dup)
 			continue;
 
-		name = quote_path_relative(pathspec[num], -1, &sb, prefix);
+		name = quote_path_relative(pathspec->raw[num], -1, &sb, prefix);
 		error("pathspec '%s' did not match any file(s) known to git.",
 		      name);
 		errors++;
@@ -572,7 +574,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 
 	if (ps_matched) {
 		int bad;
-		bad = report_path_error(ps_matched, pathspec.raw, prefix);
+		bad = report_path_error(ps_matched, &pathspec, prefix);
 		if (bad)
 			fprintf(stderr, "Did you forget to 'git add'?\n");
 
diff --git a/cache.h b/cache.h
index 7871cd1..3c34ef5 100644
--- a/cache.h
+++ b/cache.h
@@ -1258,7 +1258,7 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);
 #define ws_tab_width(rule)     ((rule) & WS_TAB_WIDTH_MASK)
 
 /* ls-files */
-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix);
+int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);
 void overlay_tree_on_cache(const char *tree_name, const char *prefix);
 
 char *alias_lookup(const char *alias);
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 18/21] Convert refresh_index to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (16 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 17/21] Convert report_path_error " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 19/21] Convert {read,fill}_directory " Nguyễn Thái Ngọc Duy
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c    | 14 ++++++--------
 builtin/commit.c |  2 +-
 builtin/rm.c     |  2 +-
 cache.h          |  2 +-
 read-cache.c     |  5 +++--
 5 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index af36bc4..623f167 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -180,19 +180,17 @@ static void treat_gitlinks(const char **pathspec)
 	}
 }
 
-static void refresh(int verbose, const char **pathspec)
+static void refresh(int verbose, const struct pathspec *pathspec)
 {
 	char *seen;
-	int i, specs;
+	int i;
 
-	for (specs = 0; pathspec[specs];  specs++)
-		/* nothing */;
-	seen = xcalloc(specs, 1);
+	seen = xcalloc(pathspec->nr, 1);
 	refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
 		      pathspec, seen, _("Unstaged changes after refreshing the index:"));
-	for (i = 0; i < specs; i++) {
+	for (i = 0; i < pathspec->nr; i++) {
 		if (!seen[i])
-			die(_("pathspec '%s' did not match any files"), pathspec[i]);
+			die(_("pathspec '%s' did not match any files"), pathspec->raw[i]);
 	}
         free(seen);
 }
@@ -437,7 +435,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	}
 
 	if (refresh_only) {
-		refresh(verbose, pathspec.raw);
+		refresh(verbose, &pathspec);
 		goto finish;
 	}
 
diff --git a/builtin/commit.c b/builtin/commit.c
index 71c5afb..193a37e 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1208,7 +1208,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 		parse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
 	read_cache_preload(&s.pathspec);
-	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);
+	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL);
 
 	fd = hold_locked_index(&index_lock, 0);
 	if (0 <= fd)
diff --git a/builtin/rm.c b/builtin/rm.c
index d719d95..b5edde8 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -250,7 +250,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	}
 
 	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
-	refresh_index(&the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
+	refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
 
 	seen = NULL;
 	seen = xcalloc(pathspec.nr, 1);
diff --git a/cache.h b/cache.h
index 3c34ef5..41e1421 100644
--- a/cache.h
+++ b/cache.h
@@ -511,7 +511,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 #define REFRESH_IGNORE_MISSING	0x0008	/* ignore non-existent */
 #define REFRESH_IGNORE_SUBMODULES	0x0010	/* ignore submodules */
 #define REFRESH_IN_PORCELAIN	0x0020	/* user friendly output, not "needs update" */
-extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg);
+extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
 
 struct lock_file {
 	struct lock_file *next;
diff --git a/read-cache.c b/read-cache.c
index fda78bc..dec2ba6 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1093,7 +1093,8 @@ static void show_file(const char * fmt, const char * name, int in_porcelain,
 	printf(fmt, name);
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
+int refresh_index(struct index_state *istate, unsigned int flags,
+		  const struct pathspec *pathspec,
 		  char *seen, const char *header_msg)
 {
 	int i;
@@ -1128,7 +1129,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
 			continue;
 
 		if (pathspec &&
-		    !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+		    !match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen))
 			filtered = 1;
 
 		if (ce_stage(ce)) {
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 19/21] Convert {read,fill}_directory to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (17 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 18/21] Convert refresh_index " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 20/21] Convert add_files_to_cache " Nguyễn Thái Ngọc Duy
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c      |  2 +-
 builtin/clean.c    |  2 +-
 builtin/grep.c     |  2 +-
 builtin/ls-files.c |  2 +-
 dir.c              | 10 +++++-----
 dir.h              |  4 ++--
 wt-status.c        |  4 ++--
 7 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 623f167..f5ceb5c 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -429,7 +429,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.raw);
+		baselen = fill_directory(&dir, &pathspec);
 		if (pathspec.nr)
 			seen = prune_directory(&dir, pathspec.raw, baselen);
 	}
diff --git a/builtin/clean.c b/builtin/clean.c
index 788ad8c..41c8cad 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -103,7 +103,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-	fill_directory(&dir, pathspec.raw);
+	fill_directory(&dir, &pathspec);
 
 	if (pathspec.nr)
 		seen = xmalloc(pathspec.nr);
diff --git a/builtin/grep.c b/builtin/grep.c
index 705f9ff..f370bad 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -522,7 +522,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 	if (exc_std)
 		setup_standard_excludes(&dir);
 
-	fill_directory(&dir, pathspec->raw);
+	fill_directory(&dir, pathspec);
 	for (i = 0; i < dir.nr; i++) {
 		const char *name = dir.entries[i]->name;
 		int namelen = strlen(name);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index be6e05d..7bb637b 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
 
 	/* For cached/deleted files we don't need to even do the readdir */
 	if (show_others || show_killed) {
-		fill_directory(dir, pathspec.raw);
+		fill_directory(dir, &pathspec);
 		if (show_others)
 			show_other_files(dir);
 		if (show_killed)
diff --git a/dir.c b/dir.c
index 11e8c1d..cfd9dac 100644
--- a/dir.c
+++ b/dir.c
@@ -72,7 +72,7 @@ char *common_prefix(const char **pathspec)
 	return len ? xmemdupz(*pathspec, len) : NULL;
 }
 
-int fill_directory(struct dir_struct *dir, const char **pathspec)
+int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
 {
 	size_t len;
 
@@ -80,10 +80,10 @@ int fill_directory(struct dir_struct *dir, const char **pathspec)
 	 * Calculate common prefix for the pathspec, and
 	 * use that to optimize the directory walk
 	 */
-	len = common_prefix_len(pathspec);
+	len = common_prefix_len(pathspec->raw);
 
 	/* Read the directory and prune it */
-	read_directory(dir, pathspec ? *pathspec : "", len, pathspec);
+	read_directory(dir, pathspec->nr ? pathspec->raw[0] : "", len, pathspec);
 	return len;
 }
 
@@ -1211,14 +1211,14 @@ static int treat_leading_path(struct dir_struct *dir,
 	return rc;
 }
 
-int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)
+int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec)
 {
 	struct path_simplify *simplify;
 
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
 
-	simplify = create_simplify(pathspec);
+	simplify = create_simplify(pathspec ? pathspec->raw : NULL);
 	if (!len || treat_leading_path(dir, path, len, simplify))
 		read_directory_recursive(dir, path, len, 0, simplify);
 	free_simplify(simplify);
diff --git a/dir.h b/dir.h
index 1d4888b..b51d2e9 100644
--- a/dir.h
+++ b/dir.h
@@ -74,8 +74,8 @@ extern int match_pathspec_depth(const struct pathspec *pathspec,
 				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);
+extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);
+extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec);
 
 extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
 			      int *dtype, struct exclude_list *el);
diff --git a/wt-status.c b/wt-status.c
index 13e6aba..2e1a62b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -502,7 +502,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
 			DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
 	setup_standard_excludes(&dir);
 
-	fill_directory(&dir, s->pathspec.raw);
+	fill_directory(&dir, &s->pathspec);
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
 		if (cache_name_is_other(ent->name, ent->len) &&
@@ -514,7 +514,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
 	if (s->show_ignored_files) {
 		dir.nr = 0;
 		dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
-		fill_directory(&dir, s->pathspec.raw);
+		fill_directory(&dir, &s->pathspec);
 		for (i = 0; i < dir.nr; i++) {
 			struct dir_entry *ent = dir.entries[i];
 			if (cache_name_is_other(ent->name, ent->len) &&
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 20/21] Convert add_files_to_cache to take struct pathspec
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (18 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 19/21] Convert {read,fill}_directory " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06  6:21 ` [PATCH 21/21] Convert more init_pathspec() to parse_pathspec() Nguyễn Thái Ngọc Duy
  2013-01-06 21:45 ` [PATCH 00/21] "struct pathspec" conversion Junio C Hamano
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c    | 8 +++++---
 builtin/commit.c | 2 +-
 cache.h          | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index f5ceb5c..641037f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -80,13 +80,15 @@ static void update_callback(struct diff_queue_struct *q,
 	}
 }
 
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
+int add_files_to_cache(const char *prefix,
+		       const struct pathspec *pathspec, int flags)
 {
 	struct update_callback_data data;
 	struct rev_info rev;
 	init_revisions(&rev, prefix);
 	setup_revisions(0, NULL, &rev, NULL);
-	init_pathspec(&rev.prune_data, pathspec);
+	if (pathspec)
+		rev.prune_data = *pathspec;
 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = update_callback;
 	data.flags = flags;
@@ -464,7 +466,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 	plug_bulk_checkin();
 
-	exit_status |= add_files_to_cache(prefix, pathspec.raw, flags);
+	exit_status |= add_files_to_cache(prefix, &pathspec, flags);
 
 	if (add_new_files)
 		exit_status |= add_files(&dir, flags);
diff --git a/builtin/commit.c b/builtin/commit.c
index 193a37e..a3a22b8 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -330,7 +330,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 	 */
 	if (all || (also && pathspec.nr)) {
 		fd = hold_locked_index(&index_lock, 1);
-		add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
+		add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
 		refresh_cache_or_die(refresh_flags);
 		update_main_cache_tree(WRITE_TREE_SILENT);
 		if (write_cache(fd, active_cache, active_nr) ||
diff --git a/cache.h b/cache.h
index 41e1421..10cba21 100644
--- a/cache.h
+++ b/cache.h
@@ -1224,7 +1224,7 @@ void packet_trace_identity(const char *prog);
  * return 0 if success, 1 - if addition of a file failed and
  * ADD_FILES_IGNORE_ERRORS was specified in flags
  */
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags);
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);
 
 /* diff.c */
 extern int diff_auto_refresh_index;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 21/21] Convert more init_pathspec() to parse_pathspec()
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (19 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 20/21] Convert add_files_to_cache " Nguyễn Thái Ngọc Duy
@ 2013-01-06  6:21 ` Nguyễn Thái Ngọc Duy
  2013-01-06 21:45 ` [PATCH 00/21] "struct pathspec" conversion Junio C Hamano
  21 siblings, 0 replies; 26+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-06  6:21 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

init_pathspec() was introduced to work with the result from
get_pathspec(). init_pathspec() will be removed eventually after
parse_pathspec() takes over, so that there is only place that
initializes struct pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 archive.c          |  2 +-
 builtin/log.c      |  2 +-
 builtin/ls-files.c | 10 ++++------
 diff-lib.c         |  2 +-
 merge-recursive.c  |  2 +-
 5 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/archive.c b/archive.c
index 530badb..3caa31f 100644
--- a/archive.c
+++ b/archive.c
@@ -218,7 +218,7 @@ static int path_exists(struct tree *tree, const char *path)
 	struct pathspec pathspec;
 	int ret;
 
-	init_pathspec(&pathspec, paths);
+	parse_pathspec(&pathspec, 0, 0, "", paths);
 	ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
 	free_pathspec(&pathspec);
 	return ret != 0;
diff --git a/builtin/log.c b/builtin/log.c
index e7b7db1..495ae77 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -455,7 +455,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
-	init_pathspec(&match_all, NULL);
+	memset(&match_all, 0, sizeof(match_all));
 	init_revisions(&rev, prefix);
 	rev.diff = 1;
 	rev.always_show_header = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 7bb637b..79949de 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -318,13 +318,11 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
 	}
 
 	if (prefix) {
-		static const char *(matchbuf[2]);
-		matchbuf[0] = prefix;
-		matchbuf[1] = NULL;
-		init_pathspec(&pathspec, matchbuf);
-		pathspec.items[0].nowildcard_len = pathspec.items[0].len;
+		static const char *(matchbuf[1]);
+		matchbuf[0] = NULL;
+		parse_pathspec(&pathspec, 0, 0, prefix, matchbuf);
 	} else
-		init_pathspec(&pathspec, NULL);
+		memset(&pathspec, 0, sizeof(pathspec));
 	if (read_tree(tree, 1, &pathspec))
 		die("unable to read tree entries %s", tree_name);
 
diff --git a/diff-lib.c b/diff-lib.c
index f35de0f..9c07f6a 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -500,7 +500,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
 	struct rev_info revs;
 
 	init_revisions(&revs, NULL);
-	init_pathspec(&revs.prune_data, opt->pathspec.raw);
+	revs.prune_data = opt->pathspec;
 	revs.diffopt = *opt;
 
 	if (diff_cache(&revs, tree_sha1, NULL, 1))
diff --git a/merge-recursive.c b/merge-recursive.c
index d882060..cd95bdb 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -297,7 +297,7 @@ static int get_files_dirs(struct merge_options *o, struct tree *tree)
 {
 	int n;
 	struct pathspec match_all;
-	init_pathspec(&match_all, NULL);
+	memset(&match_all, 0, sizeof(match_all));
 	if (read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o))
 		return 0;
 	n = o->current_file_set.nr + o->current_directory_set.nr;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/21] "struct pathspec" conversion
  2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
                   ` (20 preceding siblings ...)
  2013-01-06  6:21 ` [PATCH 21/21] Convert more init_pathspec() to parse_pathspec() Nguyễn Thái Ngọc Duy
@ 2013-01-06 21:45 ` Junio C Hamano
  21 siblings, 0 replies; 26+ messages in thread
From: Junio C Hamano @ 2013-01-06 21:45 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git

Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> This is another step towards the pathspec unification. This series
> introduces a get_pathspec() alternative: parse_pathspec(). The new
> function intializes struct pathspec directly. Many builtin commands
> (except mv) are converted to use this function. As a result, struct
> pathspec is used from the start for many commands.
>
> The next step would be dealing with pathspec manipulation code blocks
> that use "raw" field, init_pathspec or get_pathspec(). add.c, dir.c,
> rm.c and mv.c are hot places. And perhaps move pathspec code from
> dir.c and setup.c to pathspec.c after as/check-ignore enters "master".
>
> This series shares a patch (the first one) with nd/pathspec-wildcard. I
> put the patch in the series to avoid dependency.
>
> This series also disables wildcards in the prefix part, but it's only
> effective in combination with nd/pathspec-wildcard. And of course it's
> not fully effective until all "raw" use is eliminated.

Yay!

Thanks, looking forward to reading it through.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean
  2013-01-06  6:20 ` [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean Nguyễn Thái Ngọc Duy
@ 2013-01-07  1:10   ` Duy Nguyen
  0 siblings, 0 replies; 26+ messages in thread
From: Duy Nguyen @ 2013-01-07  1:10 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

On Sun, Jan 6, 2013 at 1:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> --- a/setup.c
> +++ b/setup.c
> @@ -250,6 +250,8 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
>         *raw = item->match;
>         item->len = strlen(item->match);
>         item->nowildcard_len = simple_length(item->match);
> +       if (item->nowildcard_len < prefixlen)
> +               item->nowildcard_len = prefixlen;
>         return magic;
>  }

This is wrong (so much for the last-minute patch). Prefix length
depends on actual pathspec (e.g. abc, ../abc and ../../abc use
different prefix length). This patch should be discarded (it does not
have any real impacts anyway).
-- 
Duy

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec
  2013-01-06  6:20 ` [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec Nguyễn Thái Ngọc Duy
@ 2013-01-10 23:26   ` Martin von Zweigbergk
  2013-01-11  2:33     ` Duy Nguyen
  0 siblings, 1 reply; 26+ messages in thread
From: Martin von Zweigbergk @ 2013-01-10 23:26 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git

On Sat, Jan 5, 2013 at 10:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> +
> +       /* No arguments, no prefix -> no pathspec */
> +       if (!entry && !prefix)
> +               return;
>
> +       /* No arguments with prefix -> prefix pathspec */

When working with the old get_pathspec(), I remember wondering if a
flag switching between "no argument -> prefix pathspec" and "no
argument -> no pathspec" would be worthwhile. I think e.g. 'add' and
'clean' would use the former , while 'reset' and 'commit' would use
the latter. Since you're now changing all the callers of
get_pathspec(), it seems like the perfect time to ask this question.
What do you think?

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec
  2013-01-10 23:26   ` Martin von Zweigbergk
@ 2013-01-11  2:33     ` Duy Nguyen
  0 siblings, 0 replies; 26+ messages in thread
From: Duy Nguyen @ 2013-01-11  2:33 UTC (permalink / raw)
  To: Martin von Zweigbergk; +Cc: git

On Fri, Jan 11, 2013 at 6:26 AM, Martin von Zweigbergk
<martinvonz@gmail.com> wrote:
> On Sat, Jan 5, 2013 at 10:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>> +
>> +       /* No arguments, no prefix -> no pathspec */
>> +       if (!entry && !prefix)
>> +               return;
>>
>> +       /* No arguments with prefix -> prefix pathspec */
>
> When working with the old get_pathspec(), I remember wondering if a
> flag switching between "no argument -> prefix pathspec" and "no
> argument -> no pathspec" would be worthwhile. I think e.g. 'add' and
> 'clean' would use the former , while 'reset' and 'commit' would use
> the latter. Since you're now changing all the callers of
> get_pathspec(), it seems like the perfect time to ask this question.
> What do you think?

Yes that'll simplify the call sites. Will do.
-- 
Duy

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2013-01-11  2:34 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-06  6:20 [PATCH 00/21] "struct pathspec" conversion Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 01/21] pathspec: save the non-wildcard length part Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec Nguyễn Thái Ngọc Duy
2013-01-10 23:26   ` Martin von Zweigbergk
2013-01-11  2:33     ` Duy Nguyen
2013-01-06  6:20 ` [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean Nguyễn Thái Ngọc Duy
2013-01-07  1:10   ` Duy Nguyen
2013-01-06  6:20 ` [PATCH 04/21] Export parse_pathspec() and convert some get_pathspec() calls Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 05/21] clean: convert to use parse_pathspec Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 06/21] commit: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 07/21] status: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 08/21] rerere: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 09/21] checkout: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 10/21] rm: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 11/21] ls-files: " Nguyễn Thái Ngọc Duy
2013-01-06  6:20 ` [PATCH 12/21] archive: " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 13/21] add: " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 14/21] Convert read_cache_preload() to take struct pathspec Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 15/21] Convert unmerge_cache " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 16/21] checkout: convert read_tree_some " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 17/21] Convert report_path_error " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 18/21] Convert refresh_index " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 19/21] Convert {read,fill}_directory " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 20/21] Convert add_files_to_cache " Nguyễn Thái Ngọc Duy
2013-01-06  6:21 ` [PATCH 21/21] Convert more init_pathspec() to parse_pathspec() Nguyễn Thái Ngọc Duy
2013-01-06 21:45 ` [PATCH 00/21] "struct pathspec" conversion Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).