{"thread":{"id":"32593","subject":"[PATCH v2 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec","startedAt":"2013-01-11T11:20:54Z","lastAt":"2013-01-12T22:54:04Z","messageCount":27,"participants":["Nguyễn Thái Ngọc Duy","Nguyen Thai Ngoc Duy","Matt Kraai","Duy Nguyen","Martin von Zweigbergk"],"isPatch":true,"patchVersion":2,"patchTotal":21},"messages":[{"id":"206509","messageId":"1357903275-16804-1-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":null,"subject":"[PATCH v2 00/21] nd/parse-pathspec reroll","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:20:54Z","receivedAt":"2013-01-11T11:20:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Changes:\n\n- The incorrect patch 'pathspec: make sure the prefix part is\n  wildcard-clean' is removed. I want to keep this series simple.\n  Complex pathspec manipulation will have its own series later.\n\n- Fix t7400.38 failure when core.ignorecase is on. We should exercise\n  core.ignorecase codepath more in the test suite, but that should be\n  in a separate series.\n\n- parse_pathspec() learns PATHSPEC_EMPTY_MATCH_ALL flag to support\n  \"no pathspec means match everything\", which is used by some commands\n  like commit/status\n\n- rename 'raw' to '_raw' to catch new access sites\n\nI also checked if we still have similar faults to t7400.38 (modifying\npathspec directly leading to inconsistencies) and I think we're safe.\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  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  Rename field \"raw\" to \"_raw\" in struct pathspec\n\n archive.c              |  12 +++---\n archive.h              |   2 +-\n builtin/add.c          | 102 ++++++++++++++++++-------------------------------\n builtin/checkout.c     |  37 ++++++++----------\n builtin/clean.c        |  20 +++++-----\n builtin/commit.c       |  39 +++++++++----------\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      |   6 +--\n builtin/rerere.c       |   6 +--\n builtin/rm.c           |  16 ++++----\n builtin/update-index.c |   3 +-\n cache.h                |  25 +++++++++---\n diff-lib.c             |   2 +-\n dir.c                  |  72 +++++++++++++++++++++++++++++-----\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             |   8 ++--\n setup.c                | 102 +++++++++++++++++++++++++++++++++++++------------\n tree-diff.c            |   8 ++--\n tree-walk.c            |   4 +-\n tree.c                 |   4 +-\n tree.h                 |   2 +-\n wt-status.c            |  17 ++++-----\n wt-status.h            |   2 +-\n 35 files changed, 339 insertions(+), 278 deletions(-)\n\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206510","messageId":"1357903275-16804-2-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 01/21] pathspec: save the non-wildcard length part","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:20:55Z","receivedAt":"2013-01-11T11:20:55Z","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":"206508","messageId":"1357903275-16804-3-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 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-11T11:20:56Z","receivedAt":"2013-01-11T11:20:56Z","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":"206512","messageId":"1357903275-16804-4-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 03/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-11T11:20:57Z","receivedAt":"2013-01-11T11:20:57Z","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 4fcdae6..6e960b9 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -266,9 +266,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":"206511","messageId":"1357903275-16804-5-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 04/21] clean: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:20:58Z","receivedAt":"2013-01-11T11: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/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":"206513","messageId":"1357903275-16804-6-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 05/21] commit: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:20:59Z","receivedAt":"2013-01-11T11: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 builtin/commit.c | 18 +++++++++---------\n cache.h          |  3 +++\n setup.c          |  3 +++\n 3 files changed, 15 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex d6dd3df..444ae1d 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -277,17 +277,17 @@ 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+\tparse_pathspec(&pathspec, PATHSPEC_FROMTOP,\n+\t\t       PATHSPEC_EMPTY_MATCH_ALL,\n+\t\t       prefix, argv);\n \n-\tif (*argv)\n-\t\tpathspec = get_pathspec(prefix, argv);\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 +329,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 +350,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 +395,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();\ndiff --git a/cache.h b/cache.h\nindex e52365d..a3c316f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -476,6 +476,9 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct\n /* Pathspec magic */\n #define PATHSPEC_FROMTOP    (1<<0)\n \n+/* Pathspec flags */\n+#define PATHSPEC_EMPTY_MATCH_ALL (1<<0) /* No args means match everything */\n+\n struct pathspec {\n \tconst char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n \tint nr;\ndiff --git a/setup.c b/setup.c\nindex 6e960b9..a26b6c0 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -280,6 +280,9 @@ void parse_pathspec(struct pathspec *pathspec,\n \tif (!entry && !prefix)\n \t\treturn;\n \n+\tif (!*argv && (flags & PATHSPEC_EMPTY_MATCH_ALL))\n+\t\treturn;\n+\n \t/* No arguments with prefix -> prefix pathspec */\n \tif (!entry) {\n \t\tstatic const char *raw[2];\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206514","messageId":"1357903275-16804-7-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 06/21] status: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:00Z","receivedAt":"2013-01-11T11: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/commit.c |  9 +++++----\n wt-status.c      | 17 +++++++----------\n wt-status.h      |  2 +-\n 3 files changed, 13 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 444ae1d..196dfab 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1205,11 +1205,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \thandle_untracked_files_arg(&s);\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+\tparse_pathspec(&s.pathspec, PATHSPEC_FROMTOP,\n+\t\t       PATHSPEC_EMPTY_MATCH_ALL,\n+\t\t       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":"206515","messageId":"1357903275-16804-8-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 07/21] rerere: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:01Z","receivedAt":"2013-01-11T11: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/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":"206516","messageId":"1357903275-16804-9-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 08/21] checkout: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:02Z","receivedAt":"2013-01-11T11: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 | 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":"206517","messageId":"1357903275-16804-10-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 09/21] rm: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:03Z","receivedAt":"2013-01-11T11: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/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":"206518","messageId":"1357903275-16804-11-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 10/21] ls-files: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:04Z","receivedAt":"2013-01-11T11:21:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"strip_trailing_slash_from_submodules() modifies pathspec and is moved\nto dir.c, close to other pathspec code. It'll be removed later when\nparse_pathspec() learns to take over its job.\n\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 a3c316f..62eefb1 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -496,6 +496,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..4be3ca1 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\tchar *path = xstrndup(p, len - 1);\n+\t\t\tpathspec->raw[i] = path;\n+\t\t\tpathspec->items[i].match = path;\n+\t\t\tpathspec->items[i].len = len - 1;\n+\t\t\tpathspec->items[i].nowildcard_len = simple_length(path);\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":"206519","messageId":"1357903275-16804-12-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 11/21] archive: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:05Z","receivedAt":"2013-01-11T11: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 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":"206521","messageId":"1357903275-16804-13-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 12/21] add: convert to use parse_pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:06Z","receivedAt":"2013-01-11T11:21:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"treat_gitlinks() modifies pathspec and is moved to dir.c, close to\nother pathspec code. It'll be removed later when parse_pathspec()\nlearns to take over its job. Note that treat_gitlinks() and\nstrip_trailing_slash_from_submodules() do not perform exactly the same\nthing. But that does not matter for now.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c | 84 ++++++++++++++++++++---------------------------------------\n cache.h       |  1 +\n dir.c         | 32 +++++++++++++++++++++++\n 3 files changed, 61 insertions(+), 56 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex e664100..c8592fe 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -153,33 +153,6 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, int\n \treturn seen;\n }\n \n-static void treat_gitlinks(const char **pathspec)\n-{\n-\tint i;\n-\n-\tif (!pathspec || !*pathspec)\n-\t\treturn;\n-\n-\tfor (i = 0; i < active_nr; i++) {\n-\t\tstruct cache_entry *ce = active_cache[i];\n-\t\tif (S_ISGITLINK(ce->ce_mode)) {\n-\t\t\tint len = ce_namelen(ce), j;\n-\t\t\tfor (j = 0; pathspec[j]; j++) {\n-\t\t\t\tint len2 = strlen(pathspec[j]);\n-\t\t\t\tif (len2 <= len || pathspec[j][len] != '/' ||\n-\t\t\t\t    memcmp(ce->name, pathspec[j], len))\n-\t\t\t\t\tcontinue;\n-\t\t\t\tif (len2 == len + 1)\n-\t\t\t\t\t/* strip trailing slash */\n-\t\t\t\t\tpathspec[j] = xstrndup(ce->name, len);\n-\t\t\t\telse\n-\t\t\t\t\tdie (_(\"Path '%s' is in submodule '%.*s'\"),\n-\t\t\t\t\t\tpathspec[j], len, ce->name);\n-\t\t\t}\n-\t\t}\n-\t}\n-}\n-\n static void refresh(int verbose, const char **pathspec)\n {\n \tchar *seen;\n@@ -197,21 +170,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 +218,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 +338,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 +386,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);\n \n \tif (add_new_files) {\n \t\tint baselen;\n@@ -432,33 +404,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 +439,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);\ndiff --git a/cache.h b/cache.h\nindex 62eefb1..af96376 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -497,6 +497,7 @@ 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+void treat_gitlinks(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 4be3ca1..4d1f71c 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1460,6 +1460,38 @@ void strip_trailing_slash_from_submodules(struct pathspec *pathspec)\n \t}\n }\n \n+void treat_gitlinks(struct pathspec *pathspec)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < active_nr; i++) {\n+\t\tstruct cache_entry *ce = active_cache[i];\n+\t\tint len = ce_namelen(ce), j;\n+\n+\t\tif (!S_ISGITLINK(ce->ce_mode))\n+\t\t\tcontinue;\n+\n+\t\tfor (j = 0; j < pathspec->nr; j++) {\n+\t\t\tint len2 = strlen(pathspec->raw[j]);\n+\t\t\tif (len2 <= len || pathspec->raw[j][len] != '/' ||\n+\t\t\t    memcmp(ce->name, pathspec->raw[j], len))\n+\t\t\t\tcontinue;\n+\t\t\tif (len2 == len + 1) {\n+\t\t\t\t/* strip trailing slash */\n+\t\t\t\tchar *path = xstrndup(ce->name, len);\n+\t\t\t\tpathspec->raw[j] = path;\n+\t\t\t\tpathspec->items[j].match = path;\n+\t\t\t\tpathspec->items[j].len = len;\n+\t\t\t\tpathspec->items[j].nowildcard_len = simple_length(path);\n+\t\t\t} else\n+\t\t\t\tdie (_(\"Path '%s' is in submodule '%.*s'\"),\n+\t\t\t\t     pathspec->raw[j], len, ce->name);\n+\t\t}\n+\t}\n+}\n+\n+\n+\n void free_pathspec(struct pathspec *pathspec)\n {\n \tfree(pathspec->items);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206522","messageId":"1357903275-16804-14-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 13/21] Convert read_cache_preload() to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:07Z","receivedAt":"2013-01-11T11: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/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 196dfab..069d853 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -287,7 +287,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t\t       PATHSPEC_EMPTY_MATCH_ALL,\n \t\t       prefix, argv);\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 \t\t       PATHSPEC_EMPTY_MATCH_ALL,\n \t\t       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 af96376..c594ded 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":"206523","messageId":"1357903275-16804-15-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 14/21] Convert unmerge_cache to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:08Z","receivedAt":"2013-01-11T11:21:08Z","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":"206524","messageId":"1357903275-16804-16-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 15/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-11T11:21:09Z","receivedAt":"2013-01-11T11:21:09Z","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":"206525","messageId":"1357903275-16804-17-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 16/21] Convert report_path_error to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:10Z","receivedAt":"2013-01-11T11:21:10Z","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 069d853..8777c19 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@@ -395,7 +393,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 c594ded..40eaa04 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1262,7 +1262,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":"206526","messageId":"1357903275-16804-18-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 17/21] Convert refresh_index to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:11Z","receivedAt":"2013-01-11T11:21:11Z","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 c8592fe..4e2b603 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -153,19 +153,17 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, int\n \treturn seen;\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@@ -410,7 +408,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 8777c19..2fe6054 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\t       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 40eaa04..32298ba 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -515,7 +515,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":"206527","messageId":"1357903275-16804-19-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 18/21] Convert {read,fill}_directory to take struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:12Z","receivedAt":"2013-01-11T11:21:12Z","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 4e2b603..0295cef 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -402,7 +402,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 4d1f71c..eb52913 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":"206528","messageId":"1357903275-16804-20-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 19/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-11T11:21:13Z","receivedAt":"2013-01-11T11:21:13Z","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 0295cef..5d262eb 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@@ -437,7 +439,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 2fe6054..d79613d 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -329,7 +329,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 32298ba..3e09a61 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1228,7 +1228,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":"206529","messageId":"1357903275-16804-21-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 20/21] Convert more init_pathspec() to parse_pathspec()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:14Z","receivedAt":"2013-01-11T11:21:14Z","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":"206530","messageId":"1357903275-16804-22-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 21/21] Rename field \"raw\" to \"_raw\" in struct pathspec","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T11:21:15Z","receivedAt":"2013-01-11T11:21:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This patch is essentially no-op. It helps catching new use of this\nfield though. This field is introduced as an intermediate step for the\npathspec conversion and will be removed eventually. At this stage no\nmore access sites should be introduced.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c          |  2 +-\n builtin/add.c      | 20 ++++++++++----------\n builtin/checkout.c |  2 +-\n builtin/commit.c   |  2 +-\n builtin/ls-files.c |  8 ++++----\n builtin/ls-tree.c  |  2 +-\n builtin/rm.c       |  2 +-\n cache.h            |  2 +-\n dir.c              | 22 +++++++++++-----------\n revision.c         |  4 ++--\n setup.c            |  6 +++---\n tree-diff.c        |  8 ++++----\n 12 files changed, 40 insertions(+), 40 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 3caa31f..c52e525 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -229,7 +229,7 @@ static void parse_pathspec_arg(const char **pathspec,\n {\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\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/builtin/add.c b/builtin/add.c\nindex 5d262eb..6b6a72e 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -165,7 +165,7 @@ static void refresh(int verbose, const struct pathspec *pathspec)\n \t\t      pathspec, seen, _(\"Unstaged changes after refreshing the index:\"));\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->raw[i]);\n+\t\t\tdie(_(\"pathspec '%s' did not match any files\"), pathspec->_raw[i]);\n \t}\n         free(seen);\n }\n@@ -387,7 +387,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \t}\n \tparse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);\n-\tvalidate_pathspec(pathspec.raw, prefix);\n+\tvalidate_pathspec(pathspec._raw, prefix);\n \n \tif (read_cache() < 0)\n \t\tdie(_(\"index file corrupt\"));\n@@ -406,7 +406,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t/* This picks up the paths that are not tracked */\n \t\tbaselen = fill_directory(&dir, &pathspec);\n \t\tif (pathspec.nr)\n-\t\t\tseen = prune_directory(&dir, pathspec.raw, baselen);\n+\t\t\tseen = prune_directory(&dir, pathspec._raw, baselen);\n \t}\n \n \tif (refresh_only) {\n@@ -420,17 +420,17 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \t\tpath_exclude_check_init(&check, &dir);\n \t\tif (!seen)\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\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.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\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.raw[i]);\n+\t\t\t\t\t    pathspec._raw[i]);\n \t\t\t}\n \t\t}\n \t\tfree(seen);\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 648768e..716a949 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -253,7 +253,7 @@ 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.raw);\n+\t\t\t\t\t   opts->pathspec._raw);\n \n \tlock_file = xcalloc(1, sizeof(struct lock_file));\n \ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex d79613d..876916c 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -192,7 +192,7 @@ static int list_paths(struct string_list *list, const char *with_tree,\n \tm = xcalloc(1, pattern->nr);\n \n \tif (with_tree) {\n-\t\tchar *max_prefix = common_prefix(pattern->raw);\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}\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 79949de..e9caa42 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -367,11 +367,11 @@ int report_path_error(const char *ps_matched,\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->raw[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->raw[other], pathspec->raw[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 +380,7 @@ int report_path_error(const char *ps_matched,\n \t\tif (found_dup)\n \t\t\tcontinue;\n \n-\t\tname = quote_path_relative(pathspec->raw[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@@ -540,7 +540,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \tstrip_trailing_slash_from_submodules(&pathspec);\n \n \t/* Find common prefix for all pathspec's */\n-\tmax_prefix = common_prefix(pathspec.raw);\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 */\ndiff --git a/builtin/ls-tree.c b/builtin/ls-tree.c\nindex a78ba53..ebb587b 100644\n--- a/builtin/ls-tree.c\n+++ b/builtin/ls-tree.c\n@@ -35,7 +35,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)\n \tif (ls_options & LS_RECURSIVE)\n \t\treturn 1;\n \n-\ts = pathspec.raw;\n+\ts = pathspec._raw;\n \tif (!s)\n \t\treturn 0;\n \ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex b5edde8..d12311c 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -267,7 +267,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (pathspec.nr) {\n \t\tconst char *match;\n \t\tint seen_any = 0;\n-\t\tfor (i = 0; (match = pathspec.raw[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\"),\ndiff --git a/cache.h b/cache.h\nindex 3e09a61..c5a408f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -482,7 +482,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct\n #define PATHSPEC_EMPTY_MATCH_ALL (1<<0) /* No args means match everything */\n \n struct pathspec {\n-\tconst char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n+\tconst char **_raw; /* get_pathspec() result, not freed by free_pathspec() */\n \tint nr;\n \tunsigned int has_wildcard:1;\n \tunsigned int recursive:1;\ndiff --git a/dir.c b/dir.c\nindex eb52913..aad180b 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -80,10 +80,10 @@ int fill_directory(struct dir_struct *dir, const struct pathspec *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->raw);\n+\tlen = common_prefix_len(pathspec->_raw);\n \n \t/* Read the directory and prune it */\n-\tread_directory(dir, pathspec->nr ? pathspec->raw[0] : \"\", len, pathspec);\n+\tread_directory(dir, pathspec->nr ? pathspec->_raw[0] : \"\", len, pathspec);\n \treturn len;\n }\n \n@@ -1218,7 +1218,7 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru\n \tif (has_symlink_leading_path(path, len))\n \t\treturn dir->nr;\n \n-\tsimplify = create_simplify(pathspec ? pathspec->raw : NULL);\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);\n@@ -1417,7 +1417,7 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)\n \t\treturn 0;\n \twhile (*p)\n \t\tp++;\n-\tpathspec->raw = paths;\n+\tpathspec->_raw = paths;\n \tpathspec->nr = p - paths;\n \tif (!pathspec->nr)\n \t\treturn 0;\n@@ -1444,7 +1444,7 @@ 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\tconst char *p = pathspec->_raw[i];\n \t\tint len = strlen(p), pos;\n \n \t\tif (len < 1 || p[len - 1] != '/')\n@@ -1452,7 +1452,7 @@ void strip_trailing_slash_from_submodules(struct pathspec *pathspec)\n \t\tpos = cache_name_pos(p, len - 1);\n \t\tif (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode)) {\n \t\t\tchar *path = xstrndup(p, len - 1);\n-\t\t\tpathspec->raw[i] = path;\n+\t\t\tpathspec->_raw[i] = path;\n \t\t\tpathspec->items[i].match = path;\n \t\t\tpathspec->items[i].len = len - 1;\n \t\t\tpathspec->items[i].nowildcard_len = simple_length(path);\n@@ -1472,20 +1472,20 @@ void treat_gitlinks(struct pathspec *pathspec)\n \t\t\tcontinue;\n \n \t\tfor (j = 0; j < pathspec->nr; j++) {\n-\t\t\tint len2 = strlen(pathspec->raw[j]);\n-\t\t\tif (len2 <= len || pathspec->raw[j][len] != '/' ||\n-\t\t\t    memcmp(ce->name, pathspec->raw[j], len))\n+\t\t\tint len2 = strlen(pathspec->_raw[j]);\n+\t\t\tif (len2 <= len || pathspec->_raw[j][len] != '/' ||\n+\t\t\t    memcmp(ce->name, pathspec->_raw[j], len))\n \t\t\t\tcontinue;\n \t\t\tif (len2 == len + 1) {\n \t\t\t\t/* strip trailing slash */\n \t\t\t\tchar *path = xstrndup(ce->name, len);\n-\t\t\t\tpathspec->raw[j] = path;\n+\t\t\t\tpathspec->_raw[j] = path;\n \t\t\t\tpathspec->items[j].match = path;\n \t\t\t\tpathspec->items[j].len = len;\n \t\t\t\tpathspec->items[j].nowildcard_len = simple_length(path);\n \t\t\t} else\n \t\t\t\tdie (_(\"Path '%s' is in submodule '%.*s'\"),\n-\t\t\t\t     pathspec->raw[j], len, ce->name);\n+\t\t\t\t     pathspec->_raw[j], len, ce->name);\n \t\t}\n \t}\n }\ndiff --git a/revision.c b/revision.c\nindex a044242..d89bb22 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1885,12 +1885,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\trevs->limited = 1;\n \n \tif (revs->prune_data.nr) {\n-\t\tdiff_tree_setup_paths(revs->prune_data.raw, &revs->pruning);\n+\t\tdiff_tree_setup_paths(revs->prune_data._raw, &revs->pruning);\n \t\t/* Can't prune commits with rename following: the paths change.. */\n \t\tif (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))\n \t\t\trevs->prune = 1;\n \t\tif (!revs->full_diff)\n-\t\t\tdiff_tree_setup_paths(revs->prune_data.raw, &revs->diffopt);\n+\t\t\tdiff_tree_setup_paths(revs->prune_data._raw, &revs->diffopt);\n \t}\n \tif (revs->combine_merges)\n \t\trevs->ignore_merges = 0;\ndiff --git a/setup.c b/setup.c\nindex a26b6c0..1182a0a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -293,7 +293,7 @@ void parse_pathspec(struct pathspec *pathspec,\n \t\traw[0] = prefix;\n \t\traw[1] = NULL;\n \t\tpathspec->nr = 1;\n-\t\tpathspec->raw = raw;\n+\t\tpathspec->_raw = raw;\n \t\treturn;\n \t}\n \n@@ -303,7 +303,7 @@ void parse_pathspec(struct pathspec *pathspec,\n \n \tpathspec->nr = n;\n \tpathspec->items = item = xmalloc(sizeof(*item) * n);\n-\tpathspec->raw = argv;\n+\tpathspec->_raw = argv;\n \tprefixlen = prefix ? strlen(prefix) : 0;\n \n \tfor (i = 0; i < n; i++) {\n@@ -327,7 +327,7 @@ 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+\treturn ps._raw;\n }\n \n /*\ndiff --git a/tree-diff.c b/tree-diff.c\nindex ba01563..09bddd1 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -207,7 +207,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co\n \tDIFF_OPT_SET(&diff_opts, RECURSIVE);\n \tDIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);\n \tdiff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;\n-\tdiff_opts.single_follow = opt->pathspec.raw[0];\n+\tdiff_opts.single_follow = opt->pathspec._raw[0];\n \tdiff_opts.break_opt = opt->break_opt;\n \tdiff_opts.rename_score = opt->rename_score;\n \tpaths[0] = NULL;\n@@ -228,15 +228,15 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co\n \t\t * the future!\n \t\t */\n \t\tif ((p->status == 'R' || p->status == 'C') &&\n-\t\t    !strcmp(p->two->path, opt->pathspec.raw[0])) {\n+\t\t    !strcmp(p->two->path, opt->pathspec._raw[0])) {\n \t\t\t/* Switch the file-pairs around */\n \t\t\tq->queue[i] = choice;\n \t\t\tchoice = p;\n \n \t\t\t/* Update the path we use from now on.. */\n \t\t\tdiff_tree_release_paths(opt);\n-\t\t\topt->pathspec.raw[0] = xstrdup(p->one->path);\n-\t\t\tdiff_tree_setup_paths(opt->pathspec.raw, opt);\n+\t\t\topt->pathspec._raw[0] = xstrdup(p->one->path);\n+\t\t\tdiff_tree_setup_paths(opt->pathspec._raw, opt);\n \n \t\t\t/*\n \t\t\t * The caller expects us to return a set of vanilla\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206533","messageId":"20130111141939.GA28448@lanh","threadId":"32593","inReplyTo":"1357903275-16804-18-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 17/21] Convert refresh_index to take struct pathspec","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T14:19:39Z","receivedAt":"2013-01-11T14:19:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 11, 2013 at 06:21:11PM +0700, Nguyễn Thái Ngọc Duy wrote:\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\nThis needs the following fixup on top. I don't want to send another\nreroll just a couple hours after I flooded git@vger. I did not plan to\nwork on the series this soon but somehow another problem got me back\nhere.\n\n-- 8< --\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 1235eb9..e1bcdb9 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -159,7 +159,8 @@ static void refresh(int verbose, const struct pathspec *pathspec)\n \t\t      pathspec, seen, _(\"Unstaged changes after refreshing the index:\"));\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->raw[i]);\n+\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n+\t\t\t    pathspec->items[i].match);\n \t}\n         free(seen);\n }\n-- 8< --\n\nand the baaad reason: pathspec->items[] are sorted because of 86e4ca6\n(tree_entry_interesting(): fix depth limit with overlapping pathspecs\n- 2010-12-15). But raw[] are _not_. So raw[i] does not correspond to\nitem[i].\n\nNow seen[] array returned from match_pathspec() has the order\ncorresponding to raw[]. On the other hand match_pathspec_depth()\nreturns seen[] corresponds to items[]. This patch converts\nmatch_pathspec() to match_pathspec_depth() so we need to use the\ncorrect pathspec array.\n\nI'll put these explanation in the next reroll. And don't worry about\nthis subtle difference. My next email kills match_pathspec() for good.\n"},{"id":"206534","messageId":"1357914391-28734-1-git-send-email-pclouds@gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-22-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 22/21] Convert the last use of match_pathspec() and remove it","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-11T14:26:31Z","receivedAt":"2013-01-11T14:26:31Z","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 I was digging the t7400.38 failure and found that add.c is the last\n place that uses match_pathspec(). This is the first yay moment for me\n since 'struct pathspec' was introduced. I wanted to remove this\n function for so long!\n\n Good luck resolving conflicts by the way ;-)\n\n builtin/add.c | 47 ++++++++++++-----------------\n dir.c         | 97 -----------------------------------------------------------\n dir.h         |  1 -\n 3 files changed, 20 insertions(+), 125 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 6b6a72e..1235eb9 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -99,7 +99,7 @@ int add_files_to_cache(const char *prefix,\n \treturn !!data.add_errors;\n }\n \n-static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)\n+static void fill_pathspec_matches(struct pathspec *pathspec, char *seen)\n {\n \tint num_unmatched = 0, i;\n \n@@ -109,49 +109,43 @@ static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)\n \t * mistakenly think that the user gave a pathspec that did not match\n \t * anything.\n \t */\n-\tfor (i = 0; i < specs; i++)\n+\tfor (i = 0; i < pathspec->nr; i++)\n \t\tif (!seen[i])\n \t\t\tnum_unmatched++;\n \tif (!num_unmatched)\n \t\treturn;\n \tfor (i = 0; i < active_nr; i++) {\n \t\tstruct cache_entry *ce = active_cache[i];\n-\t\tmatch_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);\n+\t\tmatch_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);\n \t}\n }\n \n-static char *find_used_pathspec(const char **pathspec)\n+static char *find_used_pathspec(struct pathspec *pathspec)\n {\n \tchar *seen;\n-\tint i;\n-\n-\tfor (i = 0; pathspec[i];  i++)\n-\t\t; /* just counting */\n-\tseen = xcalloc(i, 1);\n-\tfill_pathspec_matches(pathspec, seen, i);\n+\tseen = xcalloc(pathspec->nr, 1);\n+\tfill_pathspec_matches(pathspec, seen);\n \treturn seen;\n }\n \n-static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)\n+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)\n {\n \tchar *seen;\n-\tint i, specs;\n+\tint i;\n \tstruct dir_entry **src, **dst;\n \n-\tfor (specs = 0; pathspec[specs];  specs++)\n-\t\t/* nothing */;\n-\tseen = xcalloc(specs, 1);\n+\tseen = xcalloc(pathspec->nr, 1);\n \n \tsrc = dst = dir->entries;\n \ti = dir->nr;\n \twhile (--i >= 0) {\n \t\tstruct dir_entry *entry = *src++;\n-\t\tif (match_pathspec(pathspec, entry->name, entry->len,\n-\t\t\t\t   prefix, seen))\n+\t\tif (match_pathspec_depth(pathspec, entry->name, entry->len,\n+\t\t\t\t\t prefix, seen))\n \t\t\t*dst++ = entry;\n \t}\n \tdir->nr = dst - dir->entries;\n-\tfill_pathspec_matches(pathspec, seen, specs);\n+\tfill_pathspec_matches(pathspec, seen);\n \treturn seen;\n }\n \n@@ -406,7 +400,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t/* This picks up the paths that are not tracked */\n \t\tbaselen = fill_directory(&dir, &pathspec);\n \t\tif (pathspec.nr)\n-\t\t\tseen = prune_directory(&dir, pathspec._raw, baselen);\n+\t\t\tseen = prune_directory(&dir, &pathspec, baselen);\n \t}\n \n \tif (refresh_only) {\n@@ -420,17 +414,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \t\tpath_exclude_check_init(&check, &dir);\n \t\tif (!seen)\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\tseen = find_used_pathspec(&pathspec);\n+\t\tfor (i = 0; i < pathspec.nr; i++) {\n+\t\t\tconst char *path = pathspec.items[i].match;\n+\t\t\tif (!seen[i] && !file_exists(path)) {\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._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\tif (path_excluded(&check, path, -1, &dtype))\n+\t\t\t\t\t\tdir_add_ignored(&dir, path, pathspec.items[i].len);\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._raw[i]);\n+\t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"), path);\n \t\t\t}\n \t\t}\n \t\tfree(seen);\ndiff --git a/dir.c b/dir.c\nindex aad180b..44ff9bb 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -114,103 +114,6 @@ int within_depth(const char *name, int namelen,\n  *\n  * It returns 0 when there is no match.\n  */\n-static int match_one(const char *match, const char *name, int namelen)\n-{\n-\tint matchlen;\n-\n-\t/* If the match was just the prefix, we matched */\n-\tif (!*match)\n-\t\treturn MATCHED_RECURSIVELY;\n-\n-\tif (ignore_case) {\n-\t\tfor (;;) {\n-\t\t\tunsigned char c1 = tolower(*match);\n-\t\t\tunsigned char c2 = tolower(*name);\n-\t\t\tif (c1 == '\\0' || is_glob_special(c1))\n-\t\t\t\tbreak;\n-\t\t\tif (c1 != c2)\n-\t\t\t\treturn 0;\n-\t\t\tmatch++;\n-\t\t\tname++;\n-\t\t\tnamelen--;\n-\t\t}\n-\t} else {\n-\t\tfor (;;) {\n-\t\t\tunsigned char c1 = *match;\n-\t\t\tunsigned char c2 = *name;\n-\t\t\tif (c1 == '\\0' || is_glob_special(c1))\n-\t\t\t\tbreak;\n-\t\t\tif (c1 != c2)\n-\t\t\t\treturn 0;\n-\t\t\tmatch++;\n-\t\t\tname++;\n-\t\t\tnamelen--;\n-\t\t}\n-\t}\n-\n-\n-\t/*\n-\t * If we don't match the matchstring exactly,\n-\t * we need to match by fnmatch\n-\t */\n-\tmatchlen = strlen(match);\n-\tif (strncmp_icase(match, name, matchlen))\n-\t\treturn !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;\n-\n-\tif (namelen == matchlen)\n-\t\treturn MATCHED_EXACTLY;\n-\tif (match[matchlen-1] == '/' || name[matchlen] == '/')\n-\t\treturn MATCHED_RECURSIVELY;\n-\treturn 0;\n-}\n-\n-/*\n- * Given a name and a list of pathspecs, see if the name matches\n- * any of the pathspecs.  The caller is also interested in seeing\n- * all pathspec matches some names it calls this function with\n- * (otherwise the user could have mistyped the unmatched pathspec),\n- * and a mark is left in seen[] array for pathspec element that\n- * actually matched anything.\n- */\n-int match_pathspec(const char **pathspec, const char *name, int namelen,\n-\t\tint prefix, char *seen)\n-{\n-\tint i, retval = 0;\n-\n-\tif (!pathspec)\n-\t\treturn 1;\n-\n-\tname += prefix;\n-\tnamelen -= prefix;\n-\n-\tfor (i = 0; pathspec[i] != NULL; i++) {\n-\t\tint how;\n-\t\tconst char *match = pathspec[i] + prefix;\n-\t\tif (seen && seen[i] == MATCHED_EXACTLY)\n-\t\t\tcontinue;\n-\t\thow = match_one(match, name, namelen);\n-\t\tif (how) {\n-\t\t\tif (retval < how)\n-\t\t\t\tretval = how;\n-\t\t\tif (seen && seen[i] < how)\n-\t\t\t\tseen[i] = how;\n-\t\t}\n-\t}\n-\treturn retval;\n-}\n-\n-/*\n- * Does 'match' match the given name?\n- * A match is found if\n- *\n- * (1) the 'match' string is leading directory of 'name', or\n- * (2) the 'match' string is a wildcard and matches 'name', or\n- * (3) the 'match' string is exactly the same as 'name'.\n- *\n- * and the return value tells which case it was.\n- *\n- * It returns 0 when there is no match.\n- */\n static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n \t\t\t       const char *name, int namelen)\n {\ndiff --git a/dir.h b/dir.h\nindex b51d2e9..44e24eb 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -68,7 +68,6 @@ struct dir_struct {\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,\n \t\t\t\tconst char *name, int namelen,\n \t\t\t\tint prefix, char *seen);\n-- \n1.8.0.rc2.23.g1fb49df\n"},{"id":"206545","messageId":"20130111175644.GA12359@ftbfs.org","threadId":"32593","inReplyTo":"1357903275-16804-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 03/21] Export parse_pathspec() and convert some get_pathspec() calls","fromName":"Matt Kraai","fromEmail":"kraai@ftbfs.org","sentAt":"2013-01-11T17:56:44Z","receivedAt":"2013-01-11T17:56:44Z","isPatch":true,"sender":{"key":"kraai@ftbfs.org","avatar":null},"body":"On Fri, Jan 11, 2013 at 06:20:57PM +0700, Nguyễn Thái Ngọc Duy wrote:\n> +#define PATHSPEC_FROMTOP    (1<<0)\n\nThe previous commit introduces a use of this macro in get_pathspec.\nShould this be defined by that commit instead?\n\n> @@ -266,9 +266,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\nThe prototype for this function uses just \"magic\" instead of\n\"magic_mask\".  Should they be consistent?\n\n-- \nMatt\n"},{"id":"206580","messageId":"CACsJy8Drszo=wvd-b0WXWiYkJysrbQabAP0c3NVcbrJuO2S4tA@mail.gmail.com","threadId":"32593","inReplyTo":"20130111175644.GA12359@ftbfs.org","subject":"Re: [PATCH v2 03/21] Export parse_pathspec() and convert some get_pathspec() calls","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-01-12T06:00:30Z","receivedAt":"2013-01-12T06:00:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jan 12, 2013 at 12:56 AM, Matt Kraai <kraai@ftbfs.org> wrote:\n> On Fri, Jan 11, 2013 at 06:20:57PM +0700, Nguyễn Thái Ngọc Duy wrote:\n>> +#define PATHSPEC_FROMTOP    (1<<0)\n>\n> The previous commit introduces a use of this macro in get_pathspec.\n> Should this be defined by that commit instead?\n\nThis macro is already defined in setup.c when parse_pathspec is\nintroduced. I wanted to move it from setup.c to cache.h but forgot to\nremove the original definition. Will fix.\n\n\n>> @@ -266,9 +266,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>> -                        unsigned magic_mask, unsigned flags,\n>> -                        const char *prefix, const char **argv)\n>> +void parse_pathspec(struct pathspec *pathspec,\n>> +                 unsigned magic_mask, unsigned flags,\n>\n> The prototype for this function uses just \"magic\" instead of\n> \"magic_mask\".  Should they be consistent?\n\nDefinitely. Will fix.\n-- \nDuy\n"},{"id":"206626","messageId":"CANiSa6hSgYcGAYCfWu5wkQyaKF9R2SME2LmJ-Qt+uvpBQU2qBw@mail.gmail.com","threadId":"32593","inReplyTo":"1357903275-16804-6-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 05/21] commit: convert to use parse_pathspec","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2013-01-12T22:54:04Z","receivedAt":"2013-01-12T22:54:04Z","isPatch":true,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Fri, Jan 11, 2013 at 3:20 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>\n> diff --git a/cache.h b/cache.h\n> index e52365d..a3c316f 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -476,6 +476,9 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct\n>  /* Pathspec magic */\n>  #define PATHSPEC_FROMTOP    (1<<0)\n>\n> +/* Pathspec flags */\n> +#define PATHSPEC_EMPTY_MATCH_ALL (1<<0) /* No args means match everything */\n> +\n>  struct pathspec {\n>         const char **raw; /* get_pathspec() result, not freed by free_pathspec() */\n>         int nr;\n> diff --git a/setup.c b/setup.c\n> index 6e960b9..a26b6c0 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -280,6 +280,9 @@ void parse_pathspec(struct pathspec *pathspec,\n>         if (!entry && !prefix)\n>                 return;\n>\n> +       if (!*argv && (flags & PATHSPEC_EMPTY_MATCH_ALL))\n> +               return;\n> +\n>         /* No arguments with prefix -> prefix pathspec */\n>         if (!entry) {\n>                 static const char *raw[2];\n\nI was surprised not to find these two hunks in 02/21. If they were\nthere, you wouldn't have to explain in the log message of that patch\nthat \"flags\" is for future-proofing. Also, \"*argv\" is written \"entry\"\nin the surrounding conditions.\n"}]}