{"thread":{"id":"32540","subject":"[PATCH 00/21] \"struct pathspec\" conversion","startedAt":"2013-01-06T06:20:47Z","lastAt":"2013-01-11T02:33:48Z","messageCount":26,"participants":["Nguyễn Thái Ngọc Duy","Junio C Hamano","Duy Nguyen","Martin von Zweigbergk"],"isPatch":true,"patchVersion":1,"patchTotal":21},"messages":[{"id":"206087","messageId":"1357453268-12543-1-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":null,"subject":"[PATCH 00/21] \"struct pathspec\" conversion","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:47Z","receivedAt":"2013-01-06T06:20:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is another step towards the pathspec unification. This series\nintroduces a get_pathspec() alternative: parse_pathspec(). The new\nfunction intializes struct pathspec directly. Many builtin commands\n(except mv) are converted to use this function. As a result, struct\npathspec is used from the start for many commands.\n\nThe next step would be dealing with pathspec manipulation code blocks\nthat use \"raw\" field, init_pathspec or get_pathspec(). add.c, dir.c,\nrm.c and mv.c are hot places. And perhaps move pathspec code from\ndir.c and setup.c to pathspec.c after as/check-ignore enters \"master\".\n\nThis series shares a patch (the first one) with nd/pathspec-wildcard. I\nput the patch in the series to avoid dependency.\n\nThis series also disables wildcards in the prefix part, but it's only\neffective in combination with nd/pathspec-wildcard. And of course it's\nnot fully effective until all \"raw\" use is eliminated.\n\nNguyễn Thái Ngọc Duy (21):\n  pathspec: save the non-wildcard length part\n  Add parse_pathspec() that converts cmdline args to struct pathspec\n  pathspec: make sure the prefix part is wildcard-clean\n  Export parse_pathspec() and convert some get_pathspec() calls\n  clean: convert to use parse_pathspec\n  commit: convert to use parse_pathspec\n  status: convert to use parse_pathspec\n  rerere: convert to use parse_pathspec\n  checkout: convert to use parse_pathspec\n  rm: convert to use parse_pathspec\n  ls-files: convert to use parse_pathspec\n  archive: convert to use parse_pathspec\n  add: convert to use parse_pathspec\n  Convert read_cache_preload() to take struct pathspec\n  Convert unmerge_cache to take struct pathspec\n  checkout: convert read_tree_some to take struct pathspec\n  Convert report_path_error to take struct pathspec\n  Convert refresh_index to take struct pathspec\n  Convert {read,fill}_directory to take struct pathspec\n  Convert add_files_to_cache to take struct pathspec\n  Convert more init_pathspec() to parse_pathspec()\n\n archive.c              |  12 +++---\n archive.h              |   2 +-\n builtin/add.c          |  75 ++++++++++++++++++------------------\n builtin/checkout.c     |  37 ++++++++----------\n builtin/clean.c        |  20 +++++-----\n builtin/commit.c       |  35 +++++++++--------\n builtin/diff-files.c   |   2 +-\n builtin/diff-index.c   |   2 +-\n builtin/diff.c         |   4 +-\n builtin/grep.c         |   6 +--\n builtin/log.c          |   2 +-\n builtin/ls-files.c     |  64 +++++++++++--------------------\n builtin/ls-tree.c      |   4 +-\n builtin/rerere.c       |   6 +--\n builtin/rm.c           |  16 ++++----\n builtin/update-index.c |   3 +-\n cache.h                |  19 +++++++---\n diff-lib.c             |   2 +-\n dir.c                  |  38 ++++++++++++++-----\n dir.h                  |   5 ++-\n merge-recursive.c      |   2 +-\n preload-index.c        |  20 +++++-----\n read-cache.c           |   5 ++-\n rerere.c               |   6 +--\n rerere.h               |   4 +-\n resolve-undo.c         |   4 +-\n resolve-undo.h         |   2 +-\n revision.c             |   4 +-\n setup.c                | 101 +++++++++++++++++++++++++++++++++++++------------\n tree-walk.c            |   4 +-\n tree.c                 |   4 +-\n tree.h                 |   2 +-\n wt-status.c            |  17 ++++-----\n wt-status.h            |   2 +-\n 34 files changed, 291 insertions(+), 240 deletions(-)\n\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206088","messageId":"1357453268-12543-2-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 01/21] pathspec: save the non-wildcard length part","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:48Z","receivedAt":"2013-01-06T06:20:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"We mark pathspec with wildcards with the field use_wildcard. We\ncould do better by saving the length of the non-wildcard part, which\ncan be used for optimizations such as f9f6e2c (exclude: do strcmp as\nmuch as possible before fnmatch - 2012-06-07).\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/ls-files.c | 2 +-\n builtin/ls-tree.c  | 2 +-\n cache.h            | 2 +-\n dir.c              | 6 +++---\n tree-walk.c        | 4 ++--\n 5 files changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex b5434af..4a9ee69 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -337,7 +337,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)\n \t\tmatchbuf[0] = prefix;\n \t\tmatchbuf[1] = NULL;\n \t\tinit_pathspec(&pathspec, matchbuf);\n-\t\tpathspec.items[0].use_wildcard = 0;\n+\t\tpathspec.items[0].nowildcard_len = pathspec.items[0].len;\n \t} else\n \t\tinit_pathspec(&pathspec, NULL);\n \tif (read_tree(tree, 1, &pathspec))\ndiff --git a/builtin/ls-tree.c b/builtin/ls-tree.c\nindex 235c17c..fb76e38 100644\n--- a/builtin/ls-tree.c\n+++ b/builtin/ls-tree.c\n@@ -168,7 +168,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)\n \n \tinit_pathspec(&pathspec, get_pathspec(prefix, argv + 1));\n \tfor (i = 0; i < pathspec.nr; i++)\n-\t\tpathspec.items[i].use_wildcard = 0;\n+\t\tpathspec.items[i].nowildcard_len = pathspec.items[i].len;\n \tpathspec.has_wildcard = 0;\n \ttree = parse_tree_indirect(sha1);\n \tif (!tree)\ndiff --git a/cache.h b/cache.h\nindex 2b192d2..9304d91 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -482,7 +482,7 @@ struct pathspec {\n \tstruct pathspec_item {\n \t\tconst char *match;\n \t\tint len;\n-\t\tunsigned int use_wildcard:1;\n+\t\tint nowildcard_len;\n \t} *items;\n };\n \ndiff --git a/dir.c b/dir.c\nindex 5a83aa7..c391d46 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -230,7 +230,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n \t\t\treturn MATCHED_RECURSIVELY;\n \t}\n \n-\tif (item->use_wildcard && !fnmatch(match, name, 0))\n+\tif (item->nowildcard_len < item->len && !fnmatch(match, name, 0))\n \t\treturn MATCHED_FNMATCH;\n \n \treturn 0;\n@@ -1429,8 +1429,8 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)\n \n \t\titem->match = path;\n \t\titem->len = strlen(path);\n-\t\titem->use_wildcard = !no_wildcard(path);\n-\t\tif (item->use_wildcard)\n+\t\titem->nowildcard_len = simple_length(path);\n+\t\tif (item->nowildcard_len < item->len)\n \t\t\tpathspec->has_wildcard = 1;\n \t}\n \ndiff --git a/tree-walk.c b/tree-walk.c\nindex 3f54c02..af871c5 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -626,7 +626,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,\n \t\t\t\t\t&never_interesting))\n \t\t\t\treturn entry_interesting;\n \n-\t\t\tif (item->use_wildcard) {\n+\t\t\tif (item->nowildcard_len < item->len) {\n \t\t\t\tif (!fnmatch(match + baselen, entry->path, 0))\n \t\t\t\t\treturn entry_interesting;\n \n@@ -642,7 +642,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,\n \t\t}\n \n match_wildcards:\n-\t\tif (!item->use_wildcard)\n+\t\tif (item->nowildcard_len == item->len)\n \t\t\tcontinue;\n \n \t\t/*\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206089","messageId":"1357453268-12543-3-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:49Z","receivedAt":"2013-01-06T06:20:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Currently to fill a struct pathspec, we do:\n\n   const char **paths;\n   paths = get_pathspec(prefix, argv);\n   ...\n   init_pathspec(&pathspec, paths);\n\n\"paths\" can only carry bare strings, which loses information from\ncommand line arguments such as pathspec magic or the prefix part's\nlength for each argument.\n\nparse_pathspec() is introduced to combine the two calls into one. The\nplan is gradually replace all get_pathspec() and init_pathspec() with\nparse_pathspec(). get_pathspec() now becomes a thin wrapper of\nparse_pathspec().\n\nparse_pathspec() allows the caller to reject the pathspec magics that\nit does not support. When a new pathspec magic is introduced, we can\nenable it per command after making sure that all underlying code has no\nproblem with the new magic.\n\n\"flags\" parameter is currently unused. But it would allow callers to\npass certain instructions to parse_pathspec, for example forcing\nliteral pathspec when no magic is used.\n\nWith the introduction of parse_pathspec, there are now two functions\nthat can initialize struct pathspec: init_pathspec and\nparse_pathspec. Any semantic changes in struct pathspec must be\nreflected in both functions. init_pathspec() will be phased out in\nfavor of parse_pathspec().\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n dir.c   |  2 +-\n dir.h   |  1 +\n setup.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++----------------\n 3 files changed, 77 insertions(+), 25 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex c391d46..31f0995 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -291,7 +291,7 @@ int match_pathspec_depth(const struct pathspec *ps,\n /*\n  * Return the length of the \"simple\" part of a path match limiter.\n  */\n-static int simple_length(const char *match)\n+int simple_length(const char *match)\n {\n \tint len = -1;\n \ndiff --git a/dir.h b/dir.h\nindex f5c89e3..1d4888b 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -66,6 +66,7 @@ struct dir_struct {\n #define MATCHED_RECURSIVELY 1\n #define MATCHED_FNMATCH 2\n #define MATCHED_EXACTLY 3\n+extern int simple_length(const char *match);\n extern char *common_prefix(const char **pathspec);\n extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);\n extern int match_pathspec_depth(const struct pathspec *pathspec,\ndiff --git a/setup.c b/setup.c\nindex f108c4b..4fcdae6 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -174,7 +174,7 @@ static struct pathspec_magic {\n \n /*\n  * Take an element of a pathspec and check for magic signatures.\n- * Append the result to the prefix.\n+ * Append the result to the prefix. Return the magic bitmap.\n  *\n  * For now, we only parse the syntax and throw out anything other than\n  * \"top\" magic.\n@@ -185,7 +185,10 @@ static struct pathspec_magic {\n  * the prefix part must always match literally, and a single stupid\n  * string cannot express such a case.\n  */\n-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)\n+static unsigned prefix_pathspec(struct pathspec_item *item,\n+\t\t\t\tconst char **raw,\n+\t\t\t\tconst char *prefix, int prefixlen,\n+\t\t\t\tconst char *elt)\n {\n \tunsigned magic = 0;\n \tconst char *copyfrom = elt;\n@@ -241,39 +244,87 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char\n \t}\n \n \tif (magic & PATHSPEC_FROMTOP)\n-\t\treturn xstrdup(copyfrom);\n+\t\titem->match = xstrdup(copyfrom);\n \telse\n-\t\treturn prefix_path(prefix, prefixlen, copyfrom);\n+\t\titem->match = prefix_path(prefix, prefixlen, copyfrom);\n+\t*raw = item->match;\n+\titem->len = strlen(item->match);\n+\titem->nowildcard_len = simple_length(item->match);\n+\treturn magic;\n }\n \n-const char **get_pathspec(const char *prefix, const char **pathspec)\n+static int pathspec_item_cmp(const void *a_, const void *b_)\n {\n-\tconst char *entry = *pathspec;\n-\tconst char **src, **dst;\n-\tint prefixlen;\n+\tstruct pathspec_item *a, *b;\n \n-\tif (!prefix && !entry)\n-\t\treturn NULL;\n+\ta = (struct pathspec_item *)a_;\n+\tb = (struct pathspec_item *)b_;\n+\treturn strcmp(a->match, b->match);\n+}\n+\n+/*\n+ * Given command line arguments and a prefix, convert the input to\n+ * pathspec. die() if any magic other than ones in magic_mask.\n+ */\n+static void parse_pathspec(struct pathspec *pathspec,\n+\t\t\t   unsigned magic_mask, unsigned flags,\n+\t\t\t   const char *prefix, const char **argv)\n+{\n+\tstruct pathspec_item *item;\n+\tconst char *entry = *argv;\n+\tint i, n, prefixlen;\n+\n+\tmemset(pathspec, 0, sizeof(*pathspec));\n+\n+\t/* No arguments, no prefix -> no pathspec */\n+\tif (!entry && !prefix)\n+\t\treturn;\n \n+\t/* No arguments with prefix -> prefix pathspec */\n \tif (!entry) {\n-\t\tstatic const char *spec[2];\n-\t\tspec[0] = prefix;\n-\t\tspec[1] = NULL;\n-\t\treturn spec;\n+\t\tstatic const char *raw[2];\n+\n+\t\tpathspec->items = item = xmalloc(sizeof(*item));\n+\t\titem->match = prefix;\n+\t\titem->nowildcard_len = item->len = strlen(prefix);\n+\t\traw[0] = prefix;\n+\t\traw[1] = NULL;\n+\t\tpathspec->nr = 1;\n+\t\tpathspec->raw = raw;\n+\t\treturn;\n \t}\n \n-\t/* Otherwise we have to re-write the entries.. */\n-\tsrc = pathspec;\n-\tdst = pathspec;\n+\tn = 0;\n+\twhile (argv[n])\n+\t\tn++;\n+\n+\tpathspec->nr = n;\n+\tpathspec->items = item = xmalloc(sizeof(*item) * n);\n+\tpathspec->raw = argv;\n \tprefixlen = prefix ? strlen(prefix) : 0;\n-\twhile (*src) {\n-\t\t*(dst++) = prefix_pathspec(prefix, prefixlen, *src);\n-\t\tsrc++;\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tunsigned applied_magic;\n+\t\tconst char *arg = argv[i];\n+\n+\t\tapplied_magic = prefix_pathspec(item + i, argv + i,\n+\t\t\t\t\t\tprefix, prefixlen, arg);\n+\t\tif (applied_magic & ~magic_mask)\n+\t\t\tdie(_(\"pathspec magic in '%s' is not supported\"\n+\t\t\t      \" by this command\"), arg);\n+\t\tif (item[i].nowildcard_len < item[i].len)\n+\t\t\tpathspec->has_wildcard = 1;\n \t}\n-\t*dst = NULL;\n-\tif (!*pathspec)\n-\t\treturn NULL;\n-\treturn pathspec;\n+\n+\tqsort(pathspec->items, pathspec->nr,\n+\t      sizeof(struct pathspec_item), pathspec_item_cmp);\n+}\n+\n+const char **get_pathspec(const char *prefix, const char **pathspec)\n+{\n+\tstruct pathspec ps;\n+\tparse_pathspec(&ps, PATHSPEC_FROMTOP, 0, prefix, pathspec);\n+\treturn ps.raw;\n }\n \n /*\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206090","messageId":"1357453268-12543-4-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:50Z","receivedAt":"2013-01-06T06:20:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Prefix is the result of Git moving back from current directory to\nworktree's top directory and it has to prepend all user provided paths\nso that they become relative to the new current directory. Any\nwildcards in the prefix should not be treated as such because it's not\nthe user intention. Make sure all wildcards in the prefix part is\ndisabled.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n setup.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/setup.c b/setup.c\nindex 4fcdae6..573ef79 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -250,6 +250,8 @@ static unsigned prefix_pathspec(struct pathspec_item *item,\n \t*raw = item->match;\n \titem->len = strlen(item->match);\n \titem->nowildcard_len = simple_length(item->match);\n+\tif (item->nowildcard_len < prefixlen)\n+\t\titem->nowildcard_len = prefixlen;\n \treturn magic;\n }\n \n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206091","messageId":"1357453268-12543-5-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 04/21] Export parse_pathspec() and convert some get_pathspec() calls","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:51Z","receivedAt":"2013-01-06T06:20:51Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"These call sites follow the pattern:\n\n   paths = get_pathspec(prefix, argv);\n   init_pathspec(&pathspec, paths);\n\nwhich can be converted into a single parse_pathspec() call.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/grep.c         | 4 +---\n builtin/ls-tree.c      | 2 +-\n builtin/update-index.c | 3 +--\n cache.h                | 6 ++++++\n revision.c             | 4 ++--\n setup.c                | 6 +++---\n 6 files changed, 14 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 0e1b6c8..705f9ff 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -630,7 +630,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \tconst char *show_in_pager = NULL, *default_pager = \"dummy\";\n \tstruct grep_opt opt;\n \tstruct object_array list = OBJECT_ARRAY_INIT;\n-\tconst char **paths = NULL;\n \tstruct pathspec pathspec;\n \tstruct string_list path_list = STRING_LIST_INIT_NODUP;\n \tint i;\n@@ -857,8 +856,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t\tverify_filename(prefix, argv[j], j == i);\n \t}\n \n-\tpaths = get_pathspec(prefix, argv + i);\n-\tinit_pathspec(&pathspec, paths);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + i);\n \tpathspec.max_depth = opt.max_depth;\n \tpathspec.recursive = 1;\n \ndiff --git a/builtin/ls-tree.c b/builtin/ls-tree.c\nindex fb76e38..a78ba53 100644\n--- a/builtin/ls-tree.c\n+++ b/builtin/ls-tree.c\n@@ -166,7 +166,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)\n \tif (get_sha1(argv[0], sha1))\n \t\tdie(\"Not a valid object name %s\", argv[0]);\n \n-\tinit_pathspec(&pathspec, get_pathspec(prefix, argv + 1));\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);\n \tfor (i = 0; i < pathspec.nr; i++)\n \t\tpathspec.items[i].nowildcard_len = pathspec.items[i].len;\n \tpathspec.has_wildcard = 0;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex ada1dff..6728e59 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -546,10 +546,9 @@ static int do_reupdate(int ac, const char **av,\n \t */\n \tint pos;\n \tint has_head = 1;\n-\tconst char **paths = get_pathspec(prefix, av + 1);\n \tstruct pathspec pathspec;\n \n-\tinit_pathspec(&pathspec, paths);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, av + 1);\n \n \tif (read_ref(\"HEAD\", head_sha1))\n \t\t/* If there is no HEAD, that means it is an initial\ndiff --git a/cache.h b/cache.h\nindex 9304d91..e52365d 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -473,6 +473,9 @@ extern int index_name_is_other(const struct index_state *, const char *, int);\n extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);\n extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);\n \n+/* Pathspec magic */\n+#define PATHSPEC_FROMTOP    (1<<0)\n+\n struct pathspec {\n \tconst char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n \tint nr;\n@@ -487,6 +490,9 @@ struct pathspec {\n };\n \n extern int init_pathspec(struct pathspec *, const char **);\n+extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,\n+\t\t\t   unsigned flags, const char *prefix,\n+\t\t\t   const char **args);\n extern void free_pathspec(struct pathspec *);\n extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);\n \ndiff --git a/revision.c b/revision.c\nindex 95d21e6..a044242 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1851,8 +1851,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\t */\n \t\tALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);\n \t\tprune_data.path[prune_data.nr++] = NULL;\n-\t\tinit_pathspec(&revs->prune_data,\n-\t\t\t      get_pathspec(revs->prefix, prune_data.path));\n+\t\tparse_pathspec(&revs->prune_data, PATHSPEC_FROMTOP, 0,\n+\t\t\t       revs->prefix, prune_data.path);\n \t}\n \n \tif (revs->def == NULL)\ndiff --git a/setup.c b/setup.c\nindex 573ef79..cd6680e 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -268,9 +268,9 @@ static int pathspec_item_cmp(const void *a_, const void *b_)\n  * Given command line arguments and a prefix, convert the input to\n  * pathspec. die() if any magic other than ones in magic_mask.\n  */\n-static void parse_pathspec(struct pathspec *pathspec,\n-\t\t\t   unsigned magic_mask, unsigned flags,\n-\t\t\t   const char *prefix, const char **argv)\n+void parse_pathspec(struct pathspec *pathspec,\n+\t\t    unsigned magic_mask, unsigned flags,\n+\t\t    const char *prefix, const char **argv)\n {\n \tstruct pathspec_item *item;\n \tconst char *entry = *argv;\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206092","messageId":"1357453268-12543-6-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 05/21] clean: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:52Z","receivedAt":"2013-01-06T06:20:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clean.c | 20 ++++++++++----------\n 1 file changed, 10 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 69c1cda..788ad8c 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -42,7 +42,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tint rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;\n \tstruct strbuf directory = STRBUF_INIT;\n \tstruct dir_struct dir;\n-\tstatic const char **pathspec;\n+\tstruct pathspec pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct string_list exclude_list = STRING_LIST_INIT_NODUP;\n \tconst char *qname;\n@@ -101,12 +101,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tadd_exclude(exclude_list.items[i].string, \"\", 0,\n \t\t\t    &dir.exclude_list[EXC_CMDL]);\n \n-\tpathspec = get_pathspec(prefix, argv);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n-\tfill_directory(&dir, pathspec);\n+\tfill_directory(&dir, pathspec.raw);\n \n-\tif (pathspec)\n-\t\tseen = xmalloc(argc > 0 ? argc : 1);\n+\tif (pathspec.nr)\n+\t\tseen = xmalloc(pathspec.nr);\n \n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n@@ -141,10 +141,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tif (lstat(ent->name, &st))\n \t\t\tcontinue;\n \n-\t\tif (pathspec) {\n-\t\t\tmemset(seen, 0, argc > 0 ? argc : 1);\n-\t\t\tmatches = match_pathspec(pathspec, ent->name, len,\n-\t\t\t\t\t\t 0, seen);\n+\t\tif (pathspec.nr) {\n+\t\t\tmemset(seen, 0, pathspec.nr);\n+\t\t\tmatches = match_pathspec_depth(&pathspec, ent->name, len,\n+\t\t\t\t\t\t       0, seen);\n \t\t}\n \n \t\tif (S_ISDIR(st.st_mode)) {\n@@ -169,7 +169,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\t}\n \t\t\tstrbuf_reset(&directory);\n \t\t} else {\n-\t\t\tif (pathspec && !matches)\n+\t\t\tif (pathspec.nr && !matches)\n \t\t\t\tcontinue;\n \t\t\tqname = quote_path_relative(ent->name, -1, &buf, prefix);\n \t\t\tif (show_only) {\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206093","messageId":"1357453268-12543-7-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 06/21] commit: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:53Z","receivedAt":"2013-01-06T06:20:53Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/commit.c | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex d6dd3df..8410617 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -277,17 +277,18 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n {\n \tint fd;\n \tstruct string_list partial;\n-\tconst char **pathspec = NULL;\n+\tstruct pathspec pathspec;\n \tchar *old_index_env = NULL;\n \tint refresh_flags = REFRESH_QUIET;\n \n \tif (is_status)\n \t\trefresh_flags |= REFRESH_UNMERGED;\n-\n \tif (*argv)\n-\t\tpathspec = get_pathspec(prefix, argv);\n+\t\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n+\telse\n+\t\tmemset(&pathspec, 0, sizeof(pathspec));\n \n-\tif (read_cache_preload(pathspec) < 0)\n+\tif (read_cache_preload(pathspec.raw) < 0)\n \t\tdie(_(\"index file corrupt\"));\n \n \tif (interactive) {\n@@ -329,9 +330,9 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t * (A) if all goes well, commit the real index;\n \t * (B) on failure, rollback the real index.\n \t */\n-\tif (all || (also && pathspec && *pathspec)) {\n+\tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -350,7 +351,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t * and create commit from the_index.\n \t * We still need to refresh the index here.\n \t */\n-\tif (!only && (!pathspec || !*pathspec)) {\n+\tif (!only && !pathspec.nr) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tif (active_cache_changed) {\n@@ -395,7 +396,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \n \tmemset(&partial, 0, sizeof(partial));\n \tpartial.strdup_strings = 1;\n-\tif (list_paths(&partial, !current_head ? NULL : \"HEAD\", prefix, pathspec))\n+\tif (list_paths(&partial, !current_head ? NULL : \"HEAD\", prefix, pathspec.raw))\n \t\texit(1);\n \n \tdiscard_cache();\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206094","messageId":"1357453268-12543-8-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 07/21] status: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:54Z","receivedAt":"2013-01-06T06:20:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/commit.c |  6 +++---\n wt-status.c      | 17 +++++++----------\n wt-status.h      |  2 +-\n 3 files changed, 11 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 8410617..b706ebb 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1207,10 +1207,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \tif (show_ignored_in_status)\n \t\ts.show_ignored_files = 1;\n \tif (*argv)\n-\t\ts.pathspec = get_pathspec(prefix, argv);\n+\t\tparse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n-\tread_cache_preload(s.pathspec);\n-\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);\n+\tread_cache_preload(s.pathspec.raw);\n+\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);\n \n \tfd = hold_locked_index(&index_lock, 0);\n \tif (0 <= fd)\ndiff --git a/wt-status.c b/wt-status.c\nindex 2a9658b..13e6aba 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -434,7 +434,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)\n \t}\n \trev.diffopt.format_callback = wt_status_collect_changed_cb;\n \trev.diffopt.format_callback_data = s;\n-\tinit_pathspec(&rev.prune_data, s->pathspec);\n+\trev.prune_data = s->pathspec;\n \trun_diff_files(&rev, 0);\n }\n \n@@ -459,22 +459,20 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \trev.diffopt.detect_rename = 1;\n \trev.diffopt.rename_limit = 200;\n \trev.diffopt.break_opt = 0;\n-\tinit_pathspec(&rev.prune_data, s->pathspec);\n+\trev.prune_data = s->pathspec;\n \trun_diff_index(&rev, 1);\n }\n \n static void wt_status_collect_changes_initial(struct wt_status *s)\n {\n-\tstruct pathspec pathspec;\n \tint i;\n \n-\tinit_pathspec(&pathspec, s->pathspec);\n \tfor (i = 0; i < active_nr; i++) {\n \t\tstruct string_list_item *it;\n \t\tstruct wt_status_change_data *d;\n \t\tstruct cache_entry *ce = active_cache[i];\n \n-\t\tif (!ce_path_match(ce, &pathspec))\n+\t\tif (!ce_path_match(ce, &s->pathspec))\n \t\t\tcontinue;\n \t\tit = string_list_insert(&s->change, ce->name);\n \t\td = it->util;\n@@ -489,7 +487,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s)\n \t\telse\n \t\t\td->index_status = DIFF_STATUS_ADDED;\n \t}\n-\tfree_pathspec(&pathspec);\n }\n \n static void wt_status_collect_untracked(struct wt_status *s)\n@@ -505,11 +502,11 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \t\t\tDIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n \tsetup_standard_excludes(&dir);\n \n-\tfill_directory(&dir, s->pathspec);\n+\tfill_directory(&dir, s->pathspec.raw);\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n \t\tif (cache_name_is_other(ent->name, ent->len) &&\n-\t\t    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))\n+\t\t    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))\n \t\t\tstring_list_insert(&s->untracked, ent->name);\n \t\tfree(ent);\n \t}\n@@ -517,11 +514,11 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \tif (s->show_ignored_files) {\n \t\tdir.nr = 0;\n \t\tdir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;\n-\t\tfill_directory(&dir, s->pathspec);\n+\t\tfill_directory(&dir, s->pathspec.raw);\n \t\tfor (i = 0; i < dir.nr; i++) {\n \t\t\tstruct dir_entry *ent = dir.entries[i];\n \t\t\tif (cache_name_is_other(ent->name, ent->len) &&\n-\t\t\t    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))\n+\t\t\t    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))\n \t\t\t\tstring_list_insert(&s->ignored, ent->name);\n \t\t\tfree(ent);\n \t\t}\ndiff --git a/wt-status.h b/wt-status.h\nindex 236b41f..dd8df41 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -44,7 +44,7 @@ struct wt_status {\n \tint is_initial;\n \tchar *branch;\n \tconst char *reference;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tint verbose;\n \tint amend;\n \tenum commit_whence whence;\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206095","messageId":"1357453268-12543-9-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 08/21] rerere: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:55Z","receivedAt":"2013-01-06T06:20:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/rerere.c | 6 +++---\n rerere.c         | 8 ++++----\n rerere.h         | 4 +++-\n 3 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/rerere.c b/builtin/rerere.c\nindex dc1708e..a573c4a 100644\n--- a/builtin/rerere.c\n+++ b/builtin/rerere.c\n@@ -68,11 +68,11 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)\n \t\treturn rerere(flags);\n \n \tif (!strcmp(argv[0], \"forget\")) {\n-\t\tconst char **pathspec;\n+\t\tstruct pathspec pathspec;\n \t\tif (argc < 2)\n \t\t\twarning(\"'git rerere forget' without paths is deprecated\");\n-\t\tpathspec = get_pathspec(prefix, argv + 1);\n-\t\treturn rerere_forget(pathspec);\n+\t\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);\n+\t\treturn rerere_forget(&pathspec);\n \t}\n \n \tfd = setup_rerere(&merge_rr, flags);\ndiff --git a/rerere.c b/rerere.c\nindex a6a5cd5..f8ddf85 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -655,7 +655,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)\n \treturn 0;\n }\n \n-int rerere_forget(const char **pathspec)\n+int rerere_forget(struct pathspec *pathspec)\n {\n \tint i, fd;\n \tstruct string_list conflict = STRING_LIST_INIT_DUP;\n@@ -666,12 +666,12 @@ int rerere_forget(const char **pathspec)\n \n \tfd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);\n \n-\tunmerge_cache(pathspec);\n+\tunmerge_cache(pathspec->raw);\n \tfind_conflict(&conflict);\n \tfor (i = 0; i < conflict.nr; i++) {\n \t\tstruct string_list_item *it = &conflict.items[i];\n-\t\tif (!match_pathspec(pathspec, it->string, strlen(it->string),\n-\t\t\t\t    0, NULL))\n+\t\tif (!match_pathspec_depth(pathspec, it->string, strlen(it->string),\n+\t\t\t\t\t  0, NULL))\n \t\t\tcontinue;\n \t\trerere_forget_one_path(it->string, &merge_rr);\n \t}\ndiff --git a/rerere.h b/rerere.h\nindex 156d2aa..4aa06c9 100644\n--- a/rerere.h\n+++ b/rerere.h\n@@ -3,6 +3,8 @@\n \n #include \"string-list.h\"\n \n+struct pathspec;\n+\n #define RERERE_AUTOUPDATE   01\n #define RERERE_NOAUTOUPDATE 02\n \n@@ -16,7 +18,7 @@ extern void *RERERE_RESOLVED;\n extern int setup_rerere(struct string_list *, int);\n extern int rerere(int);\n extern const char *rerere_path(const char *hex, const char *file);\n-extern int rerere_forget(const char **);\n+extern int rerere_forget(struct pathspec *);\n extern int rerere_remaining(struct string_list *);\n extern void rerere_clear(struct string_list *);\n extern void rerere_gc(struct string_list *);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206096","messageId":"1357453268-12543-10-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 09/21] checkout: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:56Z","receivedAt":"2013-01-06T06:20:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c | 30 ++++++++++++++----------------\n 1 file changed, 14 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex a9c1b5a..da25298 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -45,7 +45,7 @@ struct checkout_opts {\n \n \tint branch_exists;\n \tconst char *prefix;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tstruct tree *source_tree;\n };\n \n@@ -256,39 +256,37 @@ static int checkout_paths(const struct checkout_opts *opts,\n \n \tif (opts->patch_mode)\n \t\treturn run_add_interactive(revision, \"--patch=checkout\",\n-\t\t\t\t\t   opts->pathspec);\n+\t\t\t\t\t   opts->pathspec.raw);\n \n \tlock_file = xcalloc(1, sizeof(struct lock_file));\n \n \tnewfd = hold_locked_index(lock_file, 1);\n-\tif (read_cache_preload(opts->pathspec) < 0)\n+\tif (read_cache_preload(opts->pathspec.raw) < 0)\n \t\treturn error(_(\"corrupt index file\"));\n \n \tif (opts->source_tree)\n-\t\tread_tree_some(opts->source_tree, opts->pathspec);\n+\t\tread_tree_some(opts->source_tree, opts->pathspec.raw);\n \n-\tfor (pos = 0; opts->pathspec[pos]; pos++)\n-\t\t;\n-\tps_matched = xcalloc(1, pos);\n+\tps_matched = xcalloc(1, opts->pathspec.nr);\n \n \tfor (pos = 0; pos < active_nr; pos++) {\n \t\tstruct cache_entry *ce = active_cache[pos];\n \t\tif (opts->source_tree && !(ce->ce_flags & CE_UPDATE))\n \t\t\tcontinue;\n-\t\tmatch_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);\n+\t\tmatch_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);\n \t}\n \n-\tif (report_path_error(ps_matched, opts->pathspec, opts->prefix))\n+\tif (report_path_error(ps_matched, opts->pathspec.raw, opts->prefix))\n \t\treturn 1;\n \n \t/* \"checkout -m path\" to recreate conflicted state */\n \tif (opts->merge)\n-\t\tunmerge_cache(opts->pathspec);\n+\t\tunmerge_cache(opts->pathspec.raw);\n \n \t/* Any unmerged paths? */\n \tfor (pos = 0; pos < active_nr; pos++) {\n \t\tstruct cache_entry *ce = active_cache[pos];\n-\t\tif (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {\n+\t\tif (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {\n \t\t\tif (!ce_stage(ce))\n \t\t\t\tcontinue;\n \t\t\tif (opts->force) {\n@@ -315,7 +313,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\tstruct cache_entry *ce = active_cache[pos];\n \t\tif (opts->source_tree && !(ce->ce_flags & CE_UPDATE))\n \t\t\tcontinue;\n-\t\tif (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {\n+\t\tif (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {\n \t\t\tif (!ce_stage(ce)) {\n \t\t\t\terrs |= checkout_entry(ce, &state, NULL);\n \t\t\t\tcontinue;\n@@ -960,7 +958,7 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts)\n static int checkout_branch(struct checkout_opts *opts,\n \t\t\t   struct branch_info *new)\n {\n-\tif (opts->pathspec)\n+\tif (opts->pathspec.nr)\n \t\tdie(_(\"paths cannot be used with switching branches\"));\n \n \tif (opts->patch_mode)\n@@ -1110,9 +1108,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (argc) {\n-\t\topts.pathspec = get_pathspec(prefix, argv);\n+\t\tparse_pathspec(&opts.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n-\t\tif (!opts.pathspec)\n+\t\tif (!opts.pathspec.nr)\n \t\t\tdie(_(\"invalid path specification\"));\n \n \t\t/*\n@@ -1144,7 +1142,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_release(&buf);\n \t}\n \n-\tif (opts.patch_mode || opts.pathspec)\n+\tif (opts.patch_mode || opts.pathspec.nr)\n \t\treturn checkout_paths(&opts, new.name);\n \telse\n \t\treturn checkout_branch(&opts, &new);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206097","messageId":"1357453268-12543-11-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 10/21] rm: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:57Z","receivedAt":"2013-01-06T06:20:57Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/rm.c | 16 +++++++---------\n 1 file changed, 7 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex dabfcf6..d719d95 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -216,7 +216,7 @@ static struct option builtin_rm_options[] = {\n int cmd_rm(int argc, const char **argv, const char *prefix)\n {\n \tint i, newfd;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tchar *seen;\n \n \tgit_config(git_default_config, NULL);\n@@ -249,27 +249,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\t}\n \t}\n \n-\tpathspec = get_pathspec(prefix, argv);\n-\trefresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n+\trefresh_index(&the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);\n \n \tseen = NULL;\n-\tfor (i = 0; pathspec[i] ; i++)\n-\t\t/* nothing */;\n-\tseen = xcalloc(i, 1);\n+\tseen = xcalloc(pathspec.nr, 1);\n \n \tfor (i = 0; i < active_nr; i++) {\n \t\tstruct cache_entry *ce = active_cache[i];\n-\t\tif (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))\n+\t\tif (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))\n \t\t\tcontinue;\n \t\tALLOC_GROW(list.entry, list.nr + 1, list.alloc);\n \t\tlist.entry[list.nr].name = ce->name;\n \t\tlist.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);\n \t}\n \n-\tif (pathspec) {\n+\tif (pathspec.nr) {\n \t\tconst char *match;\n \t\tint seen_any = 0;\n-\t\tfor (i = 0; (match = pathspec[i]) != NULL ; i++) {\n+\t\tfor (i = 0; (match = pathspec.raw[i]) != NULL ; i++) {\n \t\t\tif (!seen[i]) {\n \t\t\t\tif (!ignore_unmatch) {\n \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206098","messageId":"1357453268-12543-12-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 11/21] ls-files: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:58Z","receivedAt":"2013-01-06T06:20:58Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/ls-files.c | 42 +++++++++++-------------------------------\n cache.h            |  1 +\n dir.c              | 20 ++++++++++++++++++++\n 3 files changed, 32 insertions(+), 31 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 4a9ee69..9336abd 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -30,7 +30,7 @@ static int debug_mode;\n static const char *prefix;\n static int max_prefix_len;\n static int prefix_len;\n-static const char **pathspec;\n+static struct pathspec pathspec;\n static int error_unmatch;\n static char *ps_matched;\n static const char *with_tree;\n@@ -58,7 +58,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)\n \tif (len >= ent->len)\n \t\tdie(\"git ls-files: internal error - directory entry not superset of prefix\");\n \n-\tif (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))\n+\tif (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched))\n \t\treturn;\n \n \tfputs(tag, stdout);\n@@ -133,7 +133,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)\n \tif (len >= ce_namelen(ce))\n \t\tdie(\"git ls-files: internal error - cache entry not superset of prefix\");\n \n-\tif (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))\n+\tif (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched))\n \t\treturn;\n \n \tif (tag && *tag && show_valid_bit &&\n@@ -187,7 +187,7 @@ static void show_ru_info(void)\n \t\tlen = strlen(path);\n \t\tif (len < max_prefix_len)\n \t\t\tcontinue; /* outside of the prefix */\n-\t\tif (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched))\n+\t\tif (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched))\n \t\t\tcontinue; /* uninterested */\n \t\tfor (i = 0; i < 3; i++) {\n \t\t\tif (!ui->mode[i])\n@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)\n \n \t/* For cached/deleted files we don't need to even do the readdir */\n \tif (show_others || show_killed) {\n-\t\tfill_directory(dir, pathspec);\n+\t\tfill_directory(dir, pathspec.raw);\n \t\tif (show_others)\n \t\t\tshow_other_files(dir);\n \t\tif (show_killed)\n@@ -287,21 +287,6 @@ static void prune_cache(const char *prefix)\n \tactive_nr = last;\n }\n \n-static void strip_trailing_slash_from_submodules(void)\n-{\n-\tconst char **p;\n-\n-\tfor (p = pathspec; *p != NULL; p++) {\n-\t\tint len = strlen(*p), pos;\n-\n-\t\tif (len < 1 || (*p)[len - 1] != '/')\n-\t\t\tcontinue;\n-\t\tpos = cache_name_pos(*p, len - 1);\n-\t\tif (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))\n-\t\t\t*p = xstrndup(*p, len - 1);\n-\t}\n-}\n-\n /*\n  * Read the tree specified with --with-tree option\n  * (typically, HEAD) into stage #1 and then\n@@ -549,23 +534,18 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \tif (require_work_tree && !is_inside_work_tree())\n \t\tsetup_work_tree();\n \n-\tpathspec = get_pathspec(prefix, argv);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n \t/* be nice with submodule paths ending in a slash */\n-\tif (pathspec)\n-\t\tstrip_trailing_slash_from_submodules();\n+\tstrip_trailing_slash_from_submodules(&pathspec);\n \n \t/* Find common prefix for all pathspec's */\n-\tmax_prefix = common_prefix(pathspec);\n+\tmax_prefix = common_prefix(pathspec.raw);\n \tmax_prefix_len = max_prefix ? strlen(max_prefix) : 0;\n \n \t/* Treat unmatching pathspec elements as errors */\n-\tif (pathspec && error_unmatch) {\n-\t\tint num;\n-\t\tfor (num = 0; pathspec[num]; num++)\n-\t\t\t;\n-\t\tps_matched = xcalloc(1, num);\n-\t}\n+\tif (pathspec.nr && error_unmatch)\n+\t\tps_matched = xcalloc(1, pathspec.nr);\n \n \tif ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)\n \t\tdie(\"ls-files --ignored needs some exclude pattern\");\n@@ -592,7 +572,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \n \tif (ps_matched) {\n \t\tint bad;\n-\t\tbad = report_path_error(ps_matched, pathspec, prefix);\n+\t\tbad = report_path_error(ps_matched, pathspec.raw, prefix);\n \t\tif (bad)\n \t\t\tfprintf(stderr, \"Did you forget to 'git add'?\\n\");\n \ndiff --git a/cache.h b/cache.h\nindex e52365d..890d89b 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -493,6 +493,7 @@ extern int init_pathspec(struct pathspec *, const char **);\n extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,\n \t\t\t   unsigned flags, const char *prefix,\n \t\t\t   const char **args);\n+void strip_trailing_slash_from_submodules(struct pathspec *pathspec);\n extern void free_pathspec(struct pathspec *);\n extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);\n \ndiff --git a/dir.c b/dir.c\nindex 31f0995..11e8c1d 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1440,6 +1440,26 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)\n \treturn 0;\n }\n \n+void strip_trailing_slash_from_submodules(struct pathspec *pathspec)\n+{\n+\tint i;\n+\tfor (i = 0; i < pathspec->nr; i++) {\n+\t\tconst char *p = pathspec->raw[i];\n+\t\tint len = strlen(p), pos;\n+\n+\t\tif (len < 1 || p[len - 1] != '/')\n+\t\t\tcontinue;\n+\t\tpos = cache_name_pos(p, len - 1);\n+\t\tif (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode)) {\n+\t\t\tpathspec->raw[i] = xstrndup(p, len - 1);\n+\t\t\tpathspec->items[i].len--;\n+\t\t\tpathspec->items[i].match =\n+\t\t\t\txstrndup(pathspec->items[i].match,\n+\t\t\t\t\t pathspec->items[i].len);\n+\t\t}\n+\t}\n+}\n+\n void free_pathspec(struct pathspec *pathspec)\n {\n \tfree(pathspec->items);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206099","messageId":"1357453268-12543-13-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 12/21] archive: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:20:59Z","receivedAt":"2013-01-06T06:20:59Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c | 10 ++++------\n archive.h |  2 +-\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 4666404..530badb 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -150,7 +150,6 @@ int write_archive_entries(struct archiver_args *args,\n \tstruct archiver_context context;\n \tstruct unpack_trees_options opts;\n \tstruct tree_desc t;\n-\tstruct pathspec pathspec;\n \tint err;\n \n \tif (args->baselen > 0 && args->base[args->baselen - 1] == '/') {\n@@ -185,10 +184,8 @@ int write_archive_entries(struct archiver_args *args,\n \t\tgit_attr_set_direction(GIT_ATTR_INDEX, &the_index);\n \t}\n \n-\tinit_pathspec(&pathspec, args->pathspec);\n-\terr = read_tree_recursive(args->tree, \"\", 0, 0, &pathspec,\n+\terr = read_tree_recursive(args->tree, \"\", 0, 0, &args->pathspec,\n \t\t\t\t  write_archive_entry, &context);\n-\tfree_pathspec(&pathspec);\n \tif (err == READ_TREE_RECURSIVE)\n \t\terr = 0;\n \treturn err;\n@@ -230,8 +227,9 @@ static int path_exists(struct tree *tree, const char *path)\n static void parse_pathspec_arg(const char **pathspec,\n \t\tstruct archiver_args *ar_args)\n {\n-\tar_args->pathspec = pathspec = get_pathspec(\"\", pathspec);\n-\tif (pathspec) {\n+\tparse_pathspec(&ar_args->pathspec, PATHSPEC_FROMTOP, 0, \"\", pathspec);\n+\tif (ar_args->pathspec.nr) {\n+\t\tpathspec = ar_args->pathspec.raw;\n \t\twhile (*pathspec) {\n \t\t\tif (!path_exists(ar_args->tree, *pathspec))\n \t\t\t\tdie(\"path not found: %s\", *pathspec);\ndiff --git a/archive.h b/archive.h\nindex 895afcd..a98c49e 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -8,7 +8,7 @@ struct archiver_args {\n \tconst unsigned char *commit_sha1;\n \tconst struct commit *commit;\n \ttime_t time;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tunsigned int verbose : 1;\n \tunsigned int worktree_attributes : 1;\n \tunsigned int convert : 1;\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206100","messageId":"1357453268-12543-14-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 13/21] add: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:00Z","receivedAt":"2013-01-06T06:21:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c | 57 ++++++++++++++++++++++++++++-----------------------------\n 1 file changed, 28 insertions(+), 29 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex e664100..af36bc4 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -197,21 +197,18 @@ static void refresh(int verbose, const char **pathspec)\n         free(seen);\n }\n \n-static const char **validate_pathspec(int argc, const char **argv, const char *prefix)\n+static void validate_pathspec(const char **pathspec, const char *prefix)\n {\n-\tconst char **pathspec = get_pathspec(prefix, argv);\n-\n-\tif (pathspec) {\n-\t\tconst char **p;\n-\t\tfor (p = pathspec; *p; p++) {\n-\t\t\tif (has_symlink_leading_path(*p, strlen(*p))) {\n-\t\t\t\tint len = prefix ? strlen(prefix) : 0;\n-\t\t\t\tdie(_(\"'%s' is beyond a symbolic link\"), *p + len);\n-\t\t\t}\n+\tconst char **p;\n+\tif (!pathspec)\n+\t\treturn;\n+\n+\tfor (p = pathspec; *p; p++) {\n+\t\tif (has_symlink_leading_path(*p, strlen(*p))) {\n+\t\t\tint len = prefix ? strlen(prefix) : 0;\n+\t\t\tdie(_(\"'%s' is beyond a symbolic link\"), *p + len);\n \t\t}\n \t}\n-\n-\treturn pathspec;\n }\n \n int run_add_interactive(const char *revision, const char *patch_mode,\n@@ -248,7 +245,8 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)\n \tconst char **pathspec = NULL;\n \n \tif (argc) {\n-\t\tpathspec = validate_pathspec(argc, argv, prefix);\n+\t\tpathspec = get_pathspec(prefix, argv);\n+\t\tvalidate_pathspec(pathspec, prefix);\n \t\tif (!pathspec)\n \t\t\treturn -1;\n \t}\n@@ -367,7 +365,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n {\n \tint exit_status = 0;\n \tint newfd;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tstruct dir_struct dir;\n \tint flags;\n \tint add_new_files;\n@@ -415,11 +413,12 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tfprintf(stderr, _(\"Maybe you wanted to say 'git add .'?\\n\"));\n \t\treturn 0;\n \t}\n-\tpathspec = validate_pathspec(argc, argv, prefix);\n+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n+\tvalidate_pathspec(pathspec.raw, prefix);\n \n \tif (read_cache() < 0)\n \t\tdie(_(\"index file corrupt\"));\n-\ttreat_gitlinks(pathspec);\n+\ttreat_gitlinks(pathspec.raw);\n \n \tif (add_new_files) {\n \t\tint baselen;\n@@ -432,33 +431,33 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t}\n \n \t\t/* This picks up the paths that are not tracked */\n-\t\tbaselen = fill_directory(&dir, pathspec);\n-\t\tif (pathspec)\n-\t\t\tseen = prune_directory(&dir, pathspec, baselen);\n+\t\tbaselen = fill_directory(&dir, pathspec.raw);\n+\t\tif (pathspec.nr)\n+\t\t\tseen = prune_directory(&dir, pathspec.raw, baselen);\n \t}\n \n \tif (refresh_only) {\n-\t\trefresh(verbose, pathspec);\n+\t\trefresh(verbose, pathspec.raw);\n \t\tgoto finish;\n \t}\n \n-\tif (pathspec) {\n+\tif (pathspec.nr) {\n \t\tint i;\n \t\tstruct path_exclude_check check;\n \n \t\tpath_exclude_check_init(&check, &dir);\n \t\tif (!seen)\n-\t\t\tseen = find_used_pathspec(pathspec);\n-\t\tfor (i = 0; pathspec[i]; i++) {\n-\t\t\tif (!seen[i] && pathspec[i][0]\n-\t\t\t    && !file_exists(pathspec[i])) {\n+\t\t\tseen = find_used_pathspec(pathspec.raw);\n+\t\tfor (i = 0; pathspec.raw[i]; i++) {\n+\t\t\tif (!seen[i] && pathspec.raw[i][0]\n+\t\t\t    && !file_exists(pathspec.raw[i])) {\n \t\t\t\tif (ignore_missing) {\n \t\t\t\t\tint dtype = DT_UNKNOWN;\n-\t\t\t\t\tif (path_excluded(&check, pathspec[i], -1, &dtype))\n-\t\t\t\t\t\tdir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));\n+\t\t\t\t\tif (path_excluded(&check, pathspec.raw[i], -1, &dtype))\n+\t\t\t\t\t\tdir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));\n \t\t\t\t} else\n \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n-\t\t\t\t\t    pathspec[i]);\n+\t\t\t\t\t    pathspec.raw[i]);\n \t\t\t}\n \t\t}\n \t\tfree(seen);\n@@ -467,7 +466,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tplug_bulk_checkin();\n \n-\texit_status |= add_files_to_cache(prefix, pathspec, flags);\n+\texit_status |= add_files_to_cache(prefix, pathspec.raw, flags);\n \n \tif (add_new_files)\n \t\texit_status |= add_files(&dir, flags);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206101","messageId":"1357453268-12543-15-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 14/21] Convert read_cache_preload() to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:01Z","receivedAt":"2013-01-06T06:21:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c   |  2 +-\n builtin/commit.c     |  4 ++--\n builtin/diff-files.c |  2 +-\n builtin/diff-index.c |  2 +-\n builtin/diff.c       |  4 ++--\n cache.h              |  4 +++-\n preload-index.c      | 20 +++++++++++---------\n 7 files changed, 21 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex da25298..00910dc 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -261,7 +261,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \tlock_file = xcalloc(1, sizeof(struct lock_file));\n \n \tnewfd = hold_locked_index(lock_file, 1);\n-\tif (read_cache_preload(opts->pathspec.raw) < 0)\n+\tif (read_cache_preload(&opts->pathspec) < 0)\n \t\treturn error(_(\"corrupt index file\"));\n \n \tif (opts->source_tree)\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex b706ebb..7b5f123 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -288,7 +288,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \telse\n \t\tmemset(&pathspec, 0, sizeof(pathspec));\n \n-\tif (read_cache_preload(pathspec.raw) < 0)\n+\tif (read_cache_preload(&pathspec) < 0)\n \t\tdie(_(\"index file corrupt\"));\n \n \tif (interactive) {\n@@ -1209,7 +1209,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \tif (*argv)\n \t\tparse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n-\tread_cache_preload(s.pathspec.raw);\n+\tread_cache_preload(&s.pathspec);\n \trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);\n \n \tfd = hold_locked_index(&index_lock, 0);\ndiff --git a/builtin/diff-files.c b/builtin/diff-files.c\nindex 46085f8..9200069 100644\n--- a/builtin/diff-files.c\n+++ b/builtin/diff-files.c\n@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)\n \t    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))\n \t\trev.combine_merges = rev.dense_combined_merges = 1;\n \n-\tif (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {\n+\tif (read_cache_preload(&rev.diffopt.pathspec) < 0) {\n \t\tperror(\"read_cache_preload\");\n \t\treturn -1;\n \t}\ndiff --git a/builtin/diff-index.c b/builtin/diff-index.c\nindex 1c737f7..ce15b23 100644\n--- a/builtin/diff-index.c\n+++ b/builtin/diff-index.c\n@@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)\n \t\tusage(diff_cache_usage);\n \tif (!cached) {\n \t\tsetup_work_tree();\n-\t\tif (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {\n+\t\tif (read_cache_preload(&rev.diffopt.pathspec) < 0) {\n \t\t\tperror(\"read_cache_preload\");\n \t\t\treturn -1;\n \t\t}\ndiff --git a/builtin/diff.c b/builtin/diff.c\nindex 8c2af6c..62bdc4d 100644\n--- a/builtin/diff.c\n+++ b/builtin/diff.c\n@@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs,\n \t\tusage(builtin_diff_usage);\n \tif (!cached) {\n \t\tsetup_work_tree();\n-\t\tif (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {\n+\t\tif (read_cache_preload(&revs->diffopt.pathspec) < 0) {\n \t\t\tperror(\"read_cache_preload\");\n \t\t\treturn -1;\n \t\t}\n@@ -240,7 +240,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv\n \t\trevs->combine_merges = revs->dense_combined_merges = 1;\n \n \tsetup_work_tree();\n-\tif (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {\n+\tif (read_cache_preload(&revs->diffopt.pathspec) < 0) {\n \t\tperror(\"read_cache_preload\");\n \t\treturn -1;\n \t}\ndiff --git a/cache.h b/cache.h\nindex 890d89b..7871cd1 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -182,6 +182,8 @@ struct cache_entry {\n #error \"CE_EXTENDED_FLAGS out of range\"\n #endif\n \n+struct pathspec;\n+\n /*\n  * Copy the sha1 and stat state of a cache entry from one to\n  * another. But we never change the name, or the hash state!\n@@ -433,7 +435,7 @@ extern int init_db(const char *template_dir, unsigned int flags);\n \n /* Initialize and use the cache information */\n extern int read_index(struct index_state *);\n-extern int read_index_preload(struct index_state *, const char **pathspec);\n+extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);\n extern int read_index_from(struct index_state *, const char *path);\n extern int is_index_unborn(struct index_state *);\n extern int read_index_unmerged(struct index_state *);\ndiff --git a/preload-index.c b/preload-index.c\nindex 49cb08d..91f27f7 100644\n--- a/preload-index.c\n+++ b/preload-index.c\n@@ -4,7 +4,8 @@\n #include \"cache.h\"\n \n #ifdef NO_PTHREADS\n-static void preload_index(struct index_state *index, const char **pathspec)\n+static void preload_index(struct index_state *index,\n+\t\t\t  const struct pathspec *pathspec)\n {\n \t; /* nothing */\n }\n@@ -24,7 +25,7 @@ static void preload_index(struct index_state *index, const char **pathspec)\n struct thread_data {\n \tpthread_t pthread;\n \tstruct index_state *index;\n-\tconst char **pathspec;\n+\tstruct pathspec pathspec;\n \tint offset, nr;\n };\n \n@@ -35,9 +36,7 @@ static void *preload_thread(void *_data)\n \tstruct index_state *index = p->index;\n \tstruct cache_entry **cep = index->cache + p->offset;\n \tstruct cache_def cache;\n-\tstruct pathspec pathspec;\n \n-\tinit_pathspec(&pathspec, p->pathspec);\n \tmemset(&cache, 0, sizeof(cache));\n \tnr = p->nr;\n \tif (nr + p->offset > index->cache_nr)\n@@ -53,7 +52,7 @@ static void *preload_thread(void *_data)\n \t\t\tcontinue;\n \t\tif (ce_uptodate(ce))\n \t\t\tcontinue;\n-\t\tif (!ce_path_match(ce, &pathspec))\n+\t\tif (!ce_path_match(ce, &p->pathspec))\n \t\t\tcontinue;\n \t\tif (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))\n \t\t\tcontinue;\n@@ -63,11 +62,11 @@ static void *preload_thread(void *_data)\n \t\t\tcontinue;\n \t\tce_mark_uptodate(ce);\n \t} while (--nr > 0);\n-\tfree_pathspec(&pathspec);\n \treturn NULL;\n }\n \n-static void preload_index(struct index_state *index, const char **pathspec)\n+static void preload_index(struct index_state *index,\n+\t\t\t  const struct pathspec *pathspec)\n {\n \tint threads, i, work, offset;\n \tstruct thread_data data[MAX_PARALLEL];\n@@ -82,10 +81,12 @@ static void preload_index(struct index_state *index, const char **pathspec)\n \t\tthreads = MAX_PARALLEL;\n \toffset = 0;\n \twork = DIV_ROUND_UP(index->cache_nr, threads);\n+\tmemset(&data, 0, sizeof(data));\n \tfor (i = 0; i < threads; i++) {\n \t\tstruct thread_data *p = data+i;\n \t\tp->index = index;\n-\t\tp->pathspec = pathspec;\n+\t\tif (pathspec)\n+\t\t\tp->pathspec = *pathspec;\n \t\tp->offset = offset;\n \t\tp->nr = work;\n \t\toffset += work;\n@@ -100,7 +101,8 @@ static void preload_index(struct index_state *index, const char **pathspec)\n }\n #endif\n \n-int read_index_preload(struct index_state *index, const char **pathspec)\n+int read_index_preload(struct index_state *index,\n+\t\t       const struct pathspec *pathspec)\n {\n \tint retval = read_index(index);\n \n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206102","messageId":"1357453268-12543-16-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 15/21] Convert unmerge_cache to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:02Z","receivedAt":"2013-01-06T06:21:02Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c | 2 +-\n rerere.c           | 2 +-\n resolve-undo.c     | 4 ++--\n resolve-undo.h     | 2 +-\n 4 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 00910dc..aa399d6 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -281,7 +281,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \n \t/* \"checkout -m path\" to recreate conflicted state */\n \tif (opts->merge)\n-\t\tunmerge_cache(opts->pathspec.raw);\n+\t\tunmerge_cache(&opts->pathspec);\n \n \t/* Any unmerged paths? */\n \tfor (pos = 0; pos < active_nr; pos++) {\ndiff --git a/rerere.c b/rerere.c\nindex f8ddf85..9d149fa 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -666,7 +666,7 @@ int rerere_forget(struct pathspec *pathspec)\n \n \tfd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);\n \n-\tunmerge_cache(pathspec->raw);\n+\tunmerge_cache(pathspec);\n \tfind_conflict(&conflict);\n \tfor (i = 0; i < conflict.nr; i++) {\n \t\tstruct string_list_item *it = &conflict.items[i];\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex 72b4612..1bfece2 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -156,7 +156,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)\n \treturn unmerge_index_entry_at(istate, pos);\n }\n \n-void unmerge_index(struct index_state *istate, const char **pathspec)\n+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)\n {\n \tint i;\n \n@@ -165,7 +165,7 @@ void unmerge_index(struct index_state *istate, const char **pathspec)\n \n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tstruct cache_entry *ce = istate->cache[i];\n-\t\tif (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))\n+\t\tif (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))\n \t\t\tcontinue;\n \t\ti = unmerge_index_entry_at(istate, i);\n \t}\ndiff --git a/resolve-undo.h b/resolve-undo.h\nindex 8458769..81e8803 100644\n--- a/resolve-undo.h\n+++ b/resolve-undo.h\n@@ -11,6 +11,6 @@ extern void resolve_undo_write(struct strbuf *, struct string_list *);\n extern struct string_list *resolve_undo_read(const char *, unsigned long);\n extern void resolve_undo_clear_index(struct index_state *);\n extern int unmerge_index_entry_at(struct index_state *, int);\n-extern void unmerge_index(struct index_state *, const char **);\n+extern void unmerge_index(struct index_state *, const struct pathspec *);\n \n #endif\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206103","messageId":"1357453268-12543-17-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 16/21] checkout: convert read_tree_some to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:03Z","receivedAt":"2013-01-06T06:21:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c | 9 +++------\n tree.c             | 4 ++--\n tree.h             | 2 +-\n 3 files changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex aa399d6..a7ddb35 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -82,12 +82,9 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,\n \treturn 0;\n }\n \n-static int read_tree_some(struct tree *tree, const char **pathspec)\n+static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)\n {\n-\tstruct pathspec ps;\n-\tinit_pathspec(&ps, pathspec);\n-\tread_tree_recursive(tree, \"\", 0, 0, &ps, update_some, NULL);\n-\tfree_pathspec(&ps);\n+\tread_tree_recursive(tree, \"\", 0, 0, pathspec, update_some, NULL);\n \n \t/* update the index with the given tree's info\n \t * for all args, expanding wildcards, and exit\n@@ -265,7 +262,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\treturn error(_(\"corrupt index file\"));\n \n \tif (opts->source_tree)\n-\t\tread_tree_some(opts->source_tree, opts->pathspec.raw);\n+\t\tread_tree_some(opts->source_tree, &opts->pathspec);\n \n \tps_matched = xcalloc(1, opts->pathspec.nr);\n \ndiff --git a/tree.c b/tree.c\nindex 62fed63..ff72f67 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -47,7 +47,7 @@ static int read_one_entry_quick(const unsigned char *sha1, const char *base, int\n }\n \n static int read_tree_1(struct tree *tree, struct strbuf *base,\n-\t\t       int stage, struct pathspec *pathspec,\n+\t\t       int stage, const struct pathspec *pathspec,\n \t\t       read_tree_fn_t fn, void *context)\n {\n \tstruct tree_desc desc;\n@@ -116,7 +116,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,\n \n int read_tree_recursive(struct tree *tree,\n \t\t\tconst char *base, int baselen,\n-\t\t\tint stage, struct pathspec *pathspec,\n+\t\t\tint stage, const struct pathspec *pathspec,\n \t\t\tread_tree_fn_t fn, void *context)\n {\n \tstruct strbuf sb = STRBUF_INIT;\ndiff --git a/tree.h b/tree.h\nindex 69bcb5e..9dc90ba 100644\n--- a/tree.h\n+++ b/tree.h\n@@ -25,7 +25,7 @@ typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const ch\n \n extern int read_tree_recursive(struct tree *tree,\n \t\t\t       const char *base, int baselen,\n-\t\t\t       int stage, struct pathspec *pathspec,\n+\t\t\t       int stage, const struct pathspec *pathspec,\n \t\t\t       read_tree_fn_t fn, void *context);\n \n extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206104","messageId":"1357453268-12543-18-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 17/21] Convert report_path_error to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:04Z","receivedAt":"2013-01-06T06:21:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c |  2 +-\n builtin/commit.c   | 14 ++++++--------\n builtin/ls-files.c | 14 ++++++++------\n cache.h            |  2 +-\n 4 files changed, 16 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex a7ddb35..648768e 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -273,7 +273,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\tmatch_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);\n \t}\n \n-\tif (report_path_error(ps_matched, opts->pathspec.raw, opts->prefix))\n+\tif (report_path_error(ps_matched, &opts->pathspec, opts->prefix))\n \t\treturn 1;\n \n \t/* \"checkout -m path\" to recreate conflicted state */\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 7b5f123..71c5afb 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -181,20 +181,18 @@ static int commit_index_files(void)\n  * and return the paths that match the given pattern in list.\n  */\n static int list_paths(struct string_list *list, const char *with_tree,\n-\t\t      const char *prefix, const char **pattern)\n+\t\t      const char *prefix, const struct pathspec *pattern)\n {\n \tint i;\n \tchar *m;\n \n-\tif (!pattern)\n+\tif (!pattern->nr)\n \t\treturn 0;\n \n-\tfor (i = 0; pattern[i]; i++)\n-\t\t;\n-\tm = xcalloc(1, i);\n+\tm = xcalloc(1, pattern->nr);\n \n \tif (with_tree) {\n-\t\tchar *max_prefix = common_prefix(pattern);\n+\t\tchar *max_prefix = common_prefix(pattern->raw);\n \t\toverlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);\n \t\tfree(max_prefix);\n \t}\n@@ -205,7 +203,7 @@ static int list_paths(struct string_list *list, const char *with_tree,\n \n \t\tif (ce->ce_flags & CE_UPDATE)\n \t\t\tcontinue;\n-\t\tif (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))\n+\t\tif (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m))\n \t\t\tcontinue;\n \t\titem = string_list_insert(list, ce->name);\n \t\tif (ce_skip_worktree(ce))\n@@ -396,7 +394,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \n \tmemset(&partial, 0, sizeof(partial));\n \tpartial.strdup_strings = 1;\n-\tif (list_paths(&partial, !current_head ? NULL : \"HEAD\", prefix, pathspec.raw))\n+\tif (list_paths(&partial, !current_head ? NULL : \"HEAD\", prefix, &pathspec))\n \t\texit(1);\n \n \tdiscard_cache();\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 9336abd..be6e05d 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -349,7 +349,9 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)\n \t}\n }\n \n-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix)\n+int report_path_error(const char *ps_matched,\n+\t\t      const struct pathspec *pathspec,\n+\t\t      const char *prefix)\n {\n \t/*\n \t * Make sure all pathspec matched; otherwise it is an error.\n@@ -357,7 +359,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char\n \tstruct strbuf sb = STRBUF_INIT;\n \tconst char *name;\n \tint num, errors = 0;\n-\tfor (num = 0; pathspec[num]; num++) {\n+\tfor (num = 0; num < pathspec->nr; num++) {\n \t\tint other, found_dup;\n \n \t\tif (ps_matched[num])\n@@ -367,11 +369,11 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char\n \t\t * twice.  Do not barf on such a mistake.\n \t\t */\n \t\tfor (found_dup = other = 0;\n-\t\t     !found_dup && pathspec[other];\n+\t\t     !found_dup && pathspec->raw[other];\n \t\t     other++) {\n \t\t\tif (other == num || !ps_matched[other])\n \t\t\t\tcontinue;\n-\t\t\tif (!strcmp(pathspec[other], pathspec[num]))\n+\t\t\tif (!strcmp(pathspec->raw[other], pathspec->raw[num]))\n \t\t\t\t/*\n \t\t\t\t * Ok, we have a match already.\n \t\t\t\t */\n@@ -380,7 +382,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char\n \t\tif (found_dup)\n \t\t\tcontinue;\n \n-\t\tname = quote_path_relative(pathspec[num], -1, &sb, prefix);\n+\t\tname = quote_path_relative(pathspec->raw[num], -1, &sb, prefix);\n \t\terror(\"pathspec '%s' did not match any file(s) known to git.\",\n \t\t      name);\n \t\terrors++;\n@@ -572,7 +574,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \n \tif (ps_matched) {\n \t\tint bad;\n-\t\tbad = report_path_error(ps_matched, pathspec.raw, prefix);\n+\t\tbad = report_path_error(ps_matched, &pathspec, prefix);\n \t\tif (bad)\n \t\t\tfprintf(stderr, \"Did you forget to 'git add'?\\n\");\n \ndiff --git a/cache.h b/cache.h\nindex 7871cd1..3c34ef5 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1258,7 +1258,7 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);\n #define ws_tab_width(rule)     ((rule) & WS_TAB_WIDTH_MASK)\n \n /* ls-files */\n-int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix);\n+int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);\n void overlay_tree_on_cache(const char *tree_name, const char *prefix);\n \n char *alias_lookup(const char *alias);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206105","messageId":"1357453268-12543-19-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 18/21] Convert refresh_index to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:05Z","receivedAt":"2013-01-06T06:21:05Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c    | 14 ++++++--------\n builtin/commit.c |  2 +-\n builtin/rm.c     |  2 +-\n cache.h          |  2 +-\n read-cache.c     |  5 +++--\n 5 files changed, 12 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex af36bc4..623f167 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -180,19 +180,17 @@ static void treat_gitlinks(const char **pathspec)\n \t}\n }\n \n-static void refresh(int verbose, const char **pathspec)\n+static void refresh(int verbose, const struct pathspec *pathspec)\n {\n \tchar *seen;\n-\tint i, specs;\n+\tint i;\n \n-\tfor (specs = 0; pathspec[specs];  specs++)\n-\t\t/* nothing */;\n-\tseen = xcalloc(specs, 1);\n+\tseen = xcalloc(pathspec->nr, 1);\n \trefresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,\n \t\t      pathspec, seen, _(\"Unstaged changes after refreshing the index:\"));\n-\tfor (i = 0; i < specs; i++) {\n+\tfor (i = 0; i < pathspec->nr; i++) {\n \t\tif (!seen[i])\n-\t\t\tdie(_(\"pathspec '%s' did not match any files\"), pathspec[i]);\n+\t\t\tdie(_(\"pathspec '%s' did not match any files\"), pathspec->raw[i]);\n \t}\n         free(seen);\n }\n@@ -437,7 +435,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (refresh_only) {\n-\t\trefresh(verbose, pathspec.raw);\n+\t\trefresh(verbose, &pathspec);\n \t\tgoto finish;\n \t}\n \ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 71c5afb..193a37e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1208,7 +1208,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \t\tparse_pathspec(&s.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n \tread_cache_preload(&s.pathspec);\n-\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);\n+\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL);\n \n \tfd = hold_locked_index(&index_lock, 0);\n \tif (0 <= fd)\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex d719d95..b5edde8 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -250,7 +250,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t}\n \n \tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n-\trefresh_index(&the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);\n+\trefresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);\n \n \tseen = NULL;\n \tseen = xcalloc(pathspec.nr, 1);\ndiff --git a/cache.h b/cache.h\nindex 3c34ef5..41e1421 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -511,7 +511,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);\n #define REFRESH_IGNORE_MISSING\t0x0008\t/* ignore non-existent */\n #define REFRESH_IGNORE_SUBMODULES\t0x0010\t/* ignore submodules */\n #define REFRESH_IN_PORCELAIN\t0x0020\t/* user friendly output, not \"needs update\" */\n-extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg);\n+extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);\n \n struct lock_file {\n \tstruct lock_file *next;\ndiff --git a/read-cache.c b/read-cache.c\nindex fda78bc..dec2ba6 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1093,7 +1093,8 @@ static void show_file(const char * fmt, const char * name, int in_porcelain,\n \tprintf(fmt, name);\n }\n \n-int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,\n+int refresh_index(struct index_state *istate, unsigned int flags,\n+\t\t  const struct pathspec *pathspec,\n \t\t  char *seen, const char *header_msg)\n {\n \tint i;\n@@ -1128,7 +1129,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p\n \t\t\tcontinue;\n \n \t\tif (pathspec &&\n-\t\t    !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))\n+\t\t    !match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen))\n \t\t\tfiltered = 1;\n \n \t\tif (ce_stage(ce)) {\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206107","messageId":"1357453268-12543-20-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 19/21] Convert {read,fill}_directory to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:06Z","receivedAt":"2013-01-06T06:21:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c      |  2 +-\n builtin/clean.c    |  2 +-\n builtin/grep.c     |  2 +-\n builtin/ls-files.c |  2 +-\n dir.c              | 10 +++++-----\n dir.h              |  4 ++--\n wt-status.c        |  4 ++--\n 7 files changed, 13 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 623f167..f5ceb5c 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -429,7 +429,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t}\n \n \t\t/* This picks up the paths that are not tracked */\n-\t\tbaselen = fill_directory(&dir, pathspec.raw);\n+\t\tbaselen = fill_directory(&dir, &pathspec);\n \t\tif (pathspec.nr)\n \t\t\tseen = prune_directory(&dir, pathspec.raw, baselen);\n \t}\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 788ad8c..41c8cad 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -103,7 +103,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \n \tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n \n-\tfill_directory(&dir, pathspec.raw);\n+\tfill_directory(&dir, &pathspec);\n \n \tif (pathspec.nr)\n \t\tseen = xmalloc(pathspec.nr);\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 705f9ff..f370bad 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -522,7 +522,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,\n \tif (exc_std)\n \t\tsetup_standard_excludes(&dir);\n \n-\tfill_directory(&dir, pathspec->raw);\n+\tfill_directory(&dir, pathspec);\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tconst char *name = dir.entries[i]->name;\n \t\tint namelen = strlen(name);\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex be6e05d..7bb637b 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)\n \n \t/* For cached/deleted files we don't need to even do the readdir */\n \tif (show_others || show_killed) {\n-\t\tfill_directory(dir, pathspec.raw);\n+\t\tfill_directory(dir, &pathspec);\n \t\tif (show_others)\n \t\t\tshow_other_files(dir);\n \t\tif (show_killed)\ndiff --git a/dir.c b/dir.c\nindex 11e8c1d..cfd9dac 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -72,7 +72,7 @@ char *common_prefix(const char **pathspec)\n \treturn len ? xmemdupz(*pathspec, len) : NULL;\n }\n \n-int fill_directory(struct dir_struct *dir, const char **pathspec)\n+int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)\n {\n \tsize_t len;\n \n@@ -80,10 +80,10 @@ int fill_directory(struct dir_struct *dir, const char **pathspec)\n \t * Calculate common prefix for the pathspec, and\n \t * use that to optimize the directory walk\n \t */\n-\tlen = common_prefix_len(pathspec);\n+\tlen = common_prefix_len(pathspec->raw);\n \n \t/* Read the directory and prune it */\n-\tread_directory(dir, pathspec ? *pathspec : \"\", len, pathspec);\n+\tread_directory(dir, pathspec->nr ? pathspec->raw[0] : \"\", len, pathspec);\n \treturn len;\n }\n \n@@ -1211,14 +1211,14 @@ static int treat_leading_path(struct dir_struct *dir,\n \treturn rc;\n }\n \n-int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)\n+int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec)\n {\n \tstruct path_simplify *simplify;\n \n \tif (has_symlink_leading_path(path, len))\n \t\treturn dir->nr;\n \n-\tsimplify = create_simplify(pathspec);\n+\tsimplify = create_simplify(pathspec ? pathspec->raw : NULL);\n \tif (!len || treat_leading_path(dir, path, len, simplify))\n \t\tread_directory_recursive(dir, path, len, 0, simplify);\n \tfree_simplify(simplify);\ndiff --git a/dir.h b/dir.h\nindex 1d4888b..b51d2e9 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -74,8 +74,8 @@ extern int match_pathspec_depth(const struct pathspec *pathspec,\n \t\t\t\tint prefix, char *seen);\n extern int within_depth(const char *name, int namelen, int depth, int max_depth);\n \n-extern int fill_directory(struct dir_struct *dir, const char **pathspec);\n-extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);\n+extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);\n+extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec);\n \n extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,\n \t\t\t      int *dtype, struct exclude_list *el);\ndiff --git a/wt-status.c b/wt-status.c\nindex 13e6aba..2e1a62b 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -502,7 +502,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \t\t\tDIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n \tsetup_standard_excludes(&dir);\n \n-\tfill_directory(&dir, s->pathspec.raw);\n+\tfill_directory(&dir, &s->pathspec);\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n \t\tif (cache_name_is_other(ent->name, ent->len) &&\n@@ -514,7 +514,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \tif (s->show_ignored_files) {\n \t\tdir.nr = 0;\n \t\tdir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;\n-\t\tfill_directory(&dir, s->pathspec.raw);\n+\t\tfill_directory(&dir, &s->pathspec);\n \t\tfor (i = 0; i < dir.nr; i++) {\n \t\t\tstruct dir_entry *ent = dir.entries[i];\n \t\t\tif (cache_name_is_other(ent->name, ent->len) &&\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206106","messageId":"1357453268-12543-21-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 20/21] Convert add_files_to_cache to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:07Z","receivedAt":"2013-01-06T06:21:07Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c    | 8 +++++---\n builtin/commit.c | 2 +-\n cache.h          | 2 +-\n 3 files changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex f5ceb5c..641037f 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -80,13 +80,15 @@ static void update_callback(struct diff_queue_struct *q,\n \t}\n }\n \n-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)\n+int add_files_to_cache(const char *prefix,\n+\t\t       const struct pathspec *pathspec, int flags)\n {\n \tstruct update_callback_data data;\n \tstruct rev_info rev;\n \tinit_revisions(&rev, prefix);\n \tsetup_revisions(0, NULL, &rev, NULL);\n-\tinit_pathspec(&rev.prune_data, pathspec);\n+\tif (pathspec)\n+\t\trev.prune_data = *pathspec;\n \trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n \trev.diffopt.format_callback = update_callback;\n \tdata.flags = flags;\n@@ -464,7 +466,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tplug_bulk_checkin();\n \n-\texit_status |= add_files_to_cache(prefix, pathspec.raw, flags);\n+\texit_status |= add_files_to_cache(prefix, &pathspec, flags);\n \n \tif (add_new_files)\n \t\texit_status |= add_files(&dir, flags);\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 193a37e..a3a22b8 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -330,7 +330,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\ndiff --git a/cache.h b/cache.h\nindex 41e1421..10cba21 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1224,7 +1224,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const char **pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206108","messageId":"1357453268-12543-22-git-send-email-pclouds@gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 21/21] Convert more init_pathspec() to parse_pathspec()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-06T06:21:08Z","receivedAt":"2013-01-06T06:21:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"init_pathspec() was introduced to work with the result from\nget_pathspec(). init_pathspec() will be removed eventually after\nparse_pathspec() takes over, so that there is only place that\ninitializes struct pathspec.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c          |  2 +-\n builtin/log.c      |  2 +-\n builtin/ls-files.c | 10 ++++------\n diff-lib.c         |  2 +-\n merge-recursive.c  |  2 +-\n 5 files changed, 8 insertions(+), 10 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 530badb..3caa31f 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -218,7 +218,7 @@ static int path_exists(struct tree *tree, const char *path)\n \tstruct pathspec pathspec;\n \tint ret;\n \n-\tinit_pathspec(&pathspec, paths);\n+\tparse_pathspec(&pathspec, 0, 0, \"\", paths);\n \tret = read_tree_recursive(tree, \"\", 0, 0, &pathspec, reject_entry, NULL);\n \tfree_pathspec(&pathspec);\n \treturn ret != 0;\ndiff --git a/builtin/log.c b/builtin/log.c\nindex e7b7db1..495ae77 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -455,7 +455,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)\n \tinit_grep_defaults();\n \tgit_config(git_log_config, NULL);\n \n-\tinit_pathspec(&match_all, NULL);\n+\tmemset(&match_all, 0, sizeof(match_all));\n \tinit_revisions(&rev, prefix);\n \trev.diff = 1;\n \trev.always_show_header = 1;\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 7bb637b..79949de 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -318,13 +318,11 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)\n \t}\n \n \tif (prefix) {\n-\t\tstatic const char *(matchbuf[2]);\n-\t\tmatchbuf[0] = prefix;\n-\t\tmatchbuf[1] = NULL;\n-\t\tinit_pathspec(&pathspec, matchbuf);\n-\t\tpathspec.items[0].nowildcard_len = pathspec.items[0].len;\n+\t\tstatic const char *(matchbuf[1]);\n+\t\tmatchbuf[0] = NULL;\n+\t\tparse_pathspec(&pathspec, 0, 0, prefix, matchbuf);\n \t} else\n-\t\tinit_pathspec(&pathspec, NULL);\n+\t\tmemset(&pathspec, 0, sizeof(pathspec));\n \tif (read_tree(tree, 1, &pathspec))\n \t\tdie(\"unable to read tree entries %s\", tree_name);\n \ndiff --git a/diff-lib.c b/diff-lib.c\nindex f35de0f..9c07f6a 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -500,7 +500,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n \tstruct rev_info revs;\n \n \tinit_revisions(&revs, NULL);\n-\tinit_pathspec(&revs.prune_data, opt->pathspec.raw);\n+\trevs.prune_data = opt->pathspec;\n \trevs.diffopt = *opt;\n \n \tif (diff_cache(&revs, tree_sha1, NULL, 1))\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex d882060..cd95bdb 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -297,7 +297,7 @@ static int get_files_dirs(struct merge_options *o, struct tree *tree)\n {\n \tint n;\n \tstruct pathspec match_all;\n-\tinit_pathspec(&match_all, NULL);\n+\tmemset(&match_all, 0, sizeof(match_all));\n \tif (read_tree_recursive(tree, \"\", 0, 0, &match_all, save_files_dirs, o))\n \t\treturn 0;\n \tn = o->current_file_set.nr + o->current_directory_set.nr;\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206178","messageId":"7vpq1im1el.fsf@alter.siamese.dyndns.org","threadId":"32540","inReplyTo":"1357453268-12543-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 00/21] \"struct pathspec\" conversion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-06T21:45:06Z","receivedAt":"2013-01-06T21:45:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> This is another step towards the pathspec unification. This series\n> introduces a get_pathspec() alternative: parse_pathspec(). The new\n> function intializes struct pathspec directly. Many builtin commands\n> (except mv) are converted to use this function. As a result, struct\n> pathspec is used from the start for many commands.\n>\n> The next step would be dealing with pathspec manipulation code blocks\n> that use \"raw\" field, init_pathspec or get_pathspec(). add.c, dir.c,\n> rm.c and mv.c are hot places. And perhaps move pathspec code from\n> dir.c and setup.c to pathspec.c after as/check-ignore enters \"master\".\n>\n> This series shares a patch (the first one) with nd/pathspec-wildcard. I\n> put the patch in the series to avoid dependency.\n>\n> This series also disables wildcards in the prefix part, but it's only\n> effective in combination with nd/pathspec-wildcard. And of course it's\n> not fully effective until all \"raw\" use is eliminated.\n\nYay!\n\nThanks, looking forward to reading it through.\n"},{"id":"206194","messageId":"CACsJy8AHZhrXMziaERxXRg_s9aXa0SX=JzHbpvOA_BhG0-c59w@mail.gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 03/21] pathspec: make sure the prefix part is wildcard-clean","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-07T01:10:27Z","receivedAt":"2013-01-07T01:10:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Jan 6, 2013 at 1:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -250,6 +250,8 @@ static unsigned prefix_pathspec(struct pathspec_item *item,\n>         *raw = item->match;\n>         item->len = strlen(item->match);\n>         item->nowildcard_len = simple_length(item->match);\n> +       if (item->nowildcard_len < prefixlen)\n> +               item->nowildcard_len = prefixlen;\n>         return magic;\n>  }\n\nThis is wrong (so much for the last-minute patch). Prefix length\ndepends on actual pathspec (e.g. abc, ../abc and ../../abc use\ndifferent prefix length). This patch should be discarded (it does not\nhave any real impacts anyway).\n-- \nDuy\n"},{"id":"206478","messageId":"CANiSa6iUqZ7E9NWgMfR3bUxZoyhjO2Jz+Z=yjs9vkfmbit7SOg@mail.gmail.com","threadId":"32540","inReplyTo":"1357453268-12543-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2013-01-10T23:26:25Z","receivedAt":"2013-01-10T23:26:25Z","isPatch":true,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Sat, Jan 5, 2013 at 10:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> +\n> +       /* No arguments, no prefix -> no pathspec */\n> +       if (!entry && !prefix)\n> +               return;\n>\n> +       /* No arguments with prefix -> prefix pathspec */\n\nWhen working with the old get_pathspec(), I remember wondering if a\nflag switching between \"no argument -> prefix pathspec\" and \"no\nargument -> no pathspec\" would be worthwhile. I think e.g. 'add' and\n'clean' would use the former , while 'reset' and 'commit' would use\nthe latter. Since you're now changing all the callers of\nget_pathspec(), it seems like the perfect time to ask this question.\nWhat do you think?\n"},{"id":"206481","messageId":"CACsJy8DOPZD_zd1cTtrCcvVUU6d7LA7_UNJse4xTcDp4ttP9jQ@mail.gmail.com","threadId":"32540","inReplyTo":"CANiSa6iUqZ7E9NWgMfR3bUxZoyhjO2Jz+Z=yjs9vkfmbit7SOg@mail.gmail.com","subject":"Re: [PATCH 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T02:33:48Z","receivedAt":"2013-01-11T02:33:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 11, 2013 at 6:26 AM, Martin von Zweigbergk\n<martinvonz@gmail.com> wrote:\n> On Sat, Jan 5, 2013 at 10:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> +\n>> +       /* No arguments, no prefix -> no pathspec */\n>> +       if (!entry && !prefix)\n>> +               return;\n>>\n>> +       /* No arguments with prefix -> prefix pathspec */\n>\n> When working with the old get_pathspec(), I remember wondering if a\n> flag switching between \"no argument -> prefix pathspec\" and \"no\n> argument -> no pathspec\" would be worthwhile. I think e.g. 'add' and\n> 'clean' would use the former , while 'reset' and 'commit' would use\n> the latter. Since you're now changing all the callers of\n> get_pathspec(), it seems like the perfect time to ask this question.\n> What do you think?\n\nYes that'll simplify the call sites. Will do.\n-- \nDuy\n"}]}