{"thread":{"id":"35699","subject":"problematic git log submodule-dir/","startedAt":"2014-01-20T18:25:17Z","lastAt":"2014-01-27T22:47:57Z","messageCount":24,"participants":["Paweł Sikora","Jens Lehmann","Duy Nguyen","Nguyễn Thái Ngọc Duy","Junio C Hamano","Eric Sunshine"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"233410","messageId":"2550653.GHkhBQDSTk@localhost.localdomain","threadId":"35699","inReplyTo":null,"subject":"problematic git log submodule-dir/","fromName":"Paweł Sikora","fromEmail":"pawel.sikora@agmk.net","sentAt":"2014-01-20T18:25:17Z","receivedAt":"2014-01-20T18:25:17Z","isPatch":false,"sender":{"key":"pawel.sikora@agmk.net","avatar":null},"body":"Hi all.\n\ni've noticed that 'git log submodule-dir' and 'git log submodule-dir/'\nreturn different results (module's head changes vs. nothing). is it a bug?\nlooks like a trailing slash is a problem for git-log.\n\ntested on git-1.8.5.3-2.fc20.x86_64.\n\nBR,\nPaweł.\n\n-- \ngpg key fingerprint = 60B4 9886 AD53 EB3E 88BB 1EB5 C52E D01B 683B 9411\n"},{"id":"233541","messageId":"52E02B8C.6040309@web.de","threadId":"35699","inReplyTo":"2550653.GHkhBQDSTk@localhost.localdomain","subject":"Re: problematic git log submodule-dir/","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-01-22T20:35:24Z","receivedAt":"2014-01-22T20:35:24Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 20.01.2014 19:25, schrieb Paweł Sikora:\n> i've noticed that 'git log submodule-dir' and 'git log submodule-dir/'\n> return different results (module's head changes vs. nothing). is it a bug?\n> looks like a trailing slash is a problem for git-log.\n\nI think this is a bug, and for example \"git diff\" has similar problems.\nThis is especially nasty as shell auto-completion adds the '/' at the\nend.\n\nDuy, without having looked into the code myself yet: is this something\nthat might be easily fixed by using PATHSPEC_STRIP_SUBMODULE_SLASH*?\n"},{"id":"233570","messageId":"CACsJy8AQxwxq3x5eg0-NssDB2PQz7uaLw9oK0Otg+jW7HtG+2g@mail.gmail.com","threadId":"35699","inReplyTo":"52E02B8C.6040309@web.de","subject":"Re: problematic git log submodule-dir/","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-22T23:56:47Z","receivedAt":"2014-01-22T23:56:47Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Jan 23, 2014 at 3:35 AM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n> Am 20.01.2014 19:25, schrieb Paweł Sikora:\n>> i've noticed that 'git log submodule-dir' and 'git log submodule-dir/'\n>> return different results (module's head changes vs. nothing). is it a bug?\n>> looks like a trailing slash is a problem for git-log.\n>\n> I think this is a bug, and for example \"git diff\" has similar problems.\n> This is especially nasty as shell auto-completion adds the '/' at the\n> end.\n>\n> Duy, without having looked into the code myself yet: is this something\n> that might be easily fixed by using PATHSPEC_STRIP_SUBMODULE_SLASH*?\n\nI think so. But I dislike those preprocessing because it looks\ninefficient and the same change may be needed for other diff commands\nas well. Maybe we can handle this at diff or log-tree.c level. Will\nlook further into it tonight.\n-- \nDuy\n"},{"id":"233595","messageId":"1390483326-32258-1-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"2550653.GHkhBQDSTk@localhost.localdomain","subject":"[PATCH 1/2] tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-23T13:22:05Z","receivedAt":"2014-01-23T13:22:05Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"We do ignore trailing slash on a directory, so pathspec \"abc/\" matches\ndirectory \"abc\". A submodule is also a directory. Apply the same logic\nto it. This makes \"git log submodule-path\" and \"git log submodule-path/\"\nproduce the same output.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t4010-diff-pathspec.sh | 17 +++++++++++++++++\n tree-walk.c              |  2 +-\n 2 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\nindex af5134b..15a4912 100755\n--- a/t/t4010-diff-pathspec.sh\n+++ b/t/t4010-diff-pathspec.sh\n@@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '\n \ttest_cmp expected result\n '\n \n+test_expect_success 'setup submodules' '\n+\ttest_tick &&\n+\tgit init submod &&\n+\t( cd submod && test_commit first; ) &&\n+\tgit add submod &&\n+\tgit commit -m first &&\n+\t( cd submod && test_commit second; ) &&\n+\tgit add submod &&\n+\tgit commit -m second\n+'\n+\n+test_expect_success 'diff-tree ignores trailing slash on submodule path' '\n+\tgit diff --name-only HEAD^ HEAD submod >expect &&\n+\tgit diff --name-only HEAD^ HEAD submod/ >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\ndiff --git a/tree-walk.c b/tree-walk.c\nindex 680afda..c29b6a3 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -543,7 +543,7 @@ static int match_entry(const struct pathspec_item *item,\n \tif (matchlen > pathlen) {\n \t\tif (match[pathlen] != '/')\n \t\t\treturn 0;\n-\t\tif (!S_ISDIR(entry->mode))\n+\t\tif (!S_ISDIR(entry->mode) && !S_ISGITLINK(entry->mode))\n \t\t\treturn 0;\n \t}\n \n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233596","messageId":"1390483326-32258-2-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390483326-32258-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/2] t4010: match_pathspec_depth() and trailing slash after submodule","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-23T13:22:06Z","receivedAt":"2014-01-23T13:22:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"When you do \"git diff HEAD submodule/\", \"submodule\" from the index is\npicked out and match_pathspec_depth() in charge of matching it with\nthe pathspec \"submodule/\".\n\nUnlike tree_entry_interesting(), match_pathspec_depth() has no\nknowledge about entry mode to realize \"submodule\" is a directory and\ntreat the trailing slash specially. And it does not have too, mostly,\nbecause the index only contains files, not directories (not until\nsubmodules come)\n\nI have no solutions for it (no, stripping '/' at pathspec\npreprocessing phase seems like a workaround than a solution). So let's\nmark it. Maybe I or somebody else could revisit it later.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t4010-diff-pathspec.sh | 6 ++++++\n 1 file changed, 6 insertions(+)\n\ndiff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\nindex 15a4912..b54251a 100755\n--- a/t/t4010-diff-pathspec.sh\n+++ b/t/t4010-diff-pathspec.sh\n@@ -127,4 +127,10 @@ test_expect_success 'diff-tree ignores trailing slash on submodule path' '\n \ttest_cmp expect actual\n '\n \n+test_expect_failure 'diff-cache ignores trailing slash on submodule path' '\n+\tgit diff --name-only HEAD^ submod >expect &&\n+\tgit diff --name-only HEAD^ submod/ >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233635","messageId":"xmqqa9emtngr.fsf@gitster.dls.corp.google.com","threadId":"35699","inReplyTo":"1390483326-32258-2-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 2/2] t4010: match_pathspec_depth() and trailing slash after submodule","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-23T21:09:08Z","receivedAt":"2014-01-23T21:09:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> When you do \"git diff HEAD submodule/\", \"submodule\" from the index is\n> picked out and match_pathspec_depth() in charge of matching it with\n> the pathspec \"submodule/\".\n\nIs \"... is called\" or something missing at the end of this sentence?\n\n> Unlike tree_entry_interesting(), match_pathspec_depth() has no\n> knowledge about entry mode to realize \"submodule\" is a directory and\n> treat the trailing slash specially. And it does not have too, mostly,\n\ns/too/to/, I think.\n\n> because the index only contains files, not directories (not until\n> submodules come)\n>\n> I have no solutions for it (no, stripping '/' at pathspec\n> preprocessing phase seems like a workaround than a solution). So let's\n> mark it. Maybe I or somebody else could revisit it later.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  t/t4010-diff-pathspec.sh | 6 ++++++\n>  1 file changed, 6 insertions(+)\n>\n> diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\n> index 15a4912..b54251a 100755\n> --- a/t/t4010-diff-pathspec.sh\n> +++ b/t/t4010-diff-pathspec.sh\n> @@ -127,4 +127,10 @@ test_expect_success 'diff-tree ignores trailing slash on submodule path' '\n>  \ttest_cmp expect actual\n>  '\n>  \n> +test_expect_failure 'diff-cache ignores trailing slash on submodule path' '\n> +\tgit diff --name-only HEAD^ submod >expect &&\n> +\tgit diff --name-only HEAD^ submod/ >actual &&\n\nI actually doubt that the second line is expecting the right\nbehaviour in the first place.  As far as the top-level project is\nconcerned, \"submod\" is the name it wants, as there is nothing\nunderneath it.  Even if asked to recurse infinite levels, the caller\nshouldn't be feeding paths like \"submod/a/b/c\" to\nmatch_pathspec_depth() in the first place, no?\n\n\n\n> +\ttest_cmp expect actual\n> +'\n> +\n>  test_done\n"},{"id":"233642","messageId":"52E188D4.20904@web.de","threadId":"35699","inReplyTo":"xmqqa9emtngr.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 2/2] t4010: match_pathspec_depth() and trailing slash after submodule","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-01-23T21:25:40Z","receivedAt":"2014-01-23T21:25:40Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 23.01.2014 22:09, schrieb Junio C Hamano:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>> diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\n>> index 15a4912..b54251a 100755\n>> --- a/t/t4010-diff-pathspec.sh\n>> +++ b/t/t4010-diff-pathspec.sh\n>> @@ -127,4 +127,10 @@ test_expect_success 'diff-tree ignores trailing slash on submodule path' '\n>>  \ttest_cmp expect actual\n>>  '\n>>  \n>> +test_expect_failure 'diff-cache ignores trailing slash on submodule path' '\n>> +\tgit diff --name-only HEAD^ submod >expect &&\n>> +\tgit diff --name-only HEAD^ submod/ >actual &&\n> \n> I actually doubt that the second line is expecting the right\n> behaviour in the first place.  As far as the top-level project is\n> concerned, \"submod\" is the name it wants, as there is nothing\n> underneath it.  Even if asked to recurse infinite levels, the caller\n> shouldn't be feeding paths like \"submod/a/b/c\" to\n> match_pathspec_depth() in the first place, no?\n\nAgreed, \"submod/a/b/c\" would not make sense here. But a single\ntrailing '/' does mark \"submod\" as a directory, which I think is\nok for a submodule. And it makes life easier for the user if we\naccept that, as shell completion will add it there automatically.\n"},{"id":"233646","messageId":"xmqqwqhqs7j0.fsf@gitster.dls.corp.google.com","threadId":"35699","inReplyTo":"52E188D4.20904@web.de","subject":"Re: [PATCH 2/2] t4010: match_pathspec_depth() and trailing slash after submodule","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-23T21:38:43Z","receivedAt":"2014-01-23T21:38:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> ... But a single\n> trailing '/' does mark \"submod\" as a directory, which I think is\n> ok for a submodule. And it makes life easier for the user if we\n> accept that, as shell completion will add it there automatically.\n\nOK, that would be annoying.\n\nPerhaps the completion is what is broken here, then?  I dunno, and\nhaven't thought things through.\n"},{"id":"233679","messageId":"CACsJy8Cw3bkOuw8Xbw4hvcNGtZ0w6gqEkFCmfR2mfju3xHvNOA@mail.gmail.com","threadId":"35699","inReplyTo":"xmqqwqhqs7j0.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 2/2] t4010: match_pathspec_depth() and trailing slash after submodule","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T05:48:54Z","receivedAt":"2014-01-24T05:48:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 24, 2014 at 4:38 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jens Lehmann <Jens.Lehmann@web.de> writes:\n>\n>> ... But a single\n>> trailing '/' does mark \"submod\" as a directory, which I think is\n>> ok for a submodule. And it makes life easier for the user if we\n>> accept that, as shell completion will add it there automatically.\n>\n> OK, that would be annoying.\n>\n> Perhaps the completion is what is broken here, then?  I dunno, and\n> haven't thought things through.\n\nMy reasoning is more simple minded: if \"git diff HEAD HEAD^ submod/\"\nworks, the user would expect \"git diff HEAD submod/\" to work too. I\nthink I've got something working with a bit refactoring. Will send out\nsoon.\n-- \nDuy\n"},{"id":"233682","messageId":"1390570836-20394-1-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390483326-32258-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 0/9] About the trailing slashes","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:27Z","receivedAt":"2014-01-24T13:40:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"So this is the reroll that makes\n\n  git diff HEAD submodule\n  git diff HEAD submodule/\n\nand\n\n  git diff HEAD HEAD^ submodule\n  git diff HEAD HEAD^ submodule/\n\nbehave the same way. The main patches are 04/09 and 09/09. The rest is\njust refactoring and cleaning up.\n\nWhile looking at this, I found a funny behavior of fill_directory.\n\n  $ git init\n  $ mkdir b\n  $ >b/c\n  $ >b/d\n  $ git status b\n  Untracked files:\n          b/\n  $ git status b/\n  Untracked files:\n          b/c b/d\n\nNotice how the trailing slash produces different untracked listing.\nThis is because of common_prefix_len(). In the \"b\" case,\ncommon_prefix_len() returns empty prefix, so read_directory reads top\ndirectory, traverses through, reaches \"b\" and eventually calls\ntreat_directory() on it, which results in \"b/\" in the output.\n\nIn the \"b/\" case, common_prefix_len() found the prefix \"b\", so\nread_directory() starts at \"b\" instead of b's parent.\ntreat_directory() is never called on \"b\" itself, which results in\n\"b/c\" and \"b/d\".\n\nI'm tempted to make it consistent, favoring \"b/\" output. But that\ninvolves extra lstat, or reordering the complex read_directory() code.\nThis is probably very unusual case to pay attention to anyway.\n\nNguyễn Thái Ngọc Duy (9):\n  Convert some match_pathspec_depth() to ce_path_match()\n  Convert some match_pathspec_depth() to dir_path_match()\n  Rename match_pathspec_depth() to match_pathspec()\n  dir.c: prepare match_pathspec_item for taking more flags\n  match_pathspec: match pathspec \"foo/\" against directory \"foo\"\n  Pass directory indicator to match_pathspec_item()\n  clean: replace match_pathspec() with dir_path_match()\n  clean: use cache_name_is_other()\n  tree-walk.c: ignore trailing slash on submodule in\n    tree_entry_interesting()\n\n builtin/add.c             |  3 +--\n builtin/checkout.c        |  3 +--\n builtin/clean.c           | 24 +++---------------------\n builtin/commit.c          |  2 +-\n builtin/grep.c            |  6 ++----\n builtin/ls-files.c        |  9 ++++++---\n builtin/ls-tree.c         |  2 +-\n builtin/rm.c              |  2 +-\n builtin/update-index.c    |  3 ++-\n cache.h                   |  2 --\n diff-lib.c                |  5 +++--\n dir.c                     | 40 ++++++++++++++++++++++++++--------------\n dir.h                     | 24 +++++++++++++++++++++---\n pathspec.c                |  2 +-\n preload-index.c           |  3 ++-\n read-cache.c              |  8 +-------\n rerere.c                  |  4 ++--\n resolve-undo.c            |  2 +-\n revision.c                |  3 ++-\n t/t4010-diff-pathspec.sh  | 23 +++++++++++++++++++++++\n t/t6131-pathspec-icase.sh |  6 +++---\n tree-walk.c               |  2 +-\n wt-status.c               |  6 +++---\n 23 files changed, 107 insertions(+), 77 deletions(-)\n\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233683","messageId":"1390570836-20394-2-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 1/9] Convert some match_pathspec_depth() to ce_path_match()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:28Z","receivedAt":"2014-01-24T13:40:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This helps reduce the number of match_pathspec_depth() call sites and\nshow how match_pathspec_depth() is used.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c     | 3 +--\n builtin/commit.c       | 2 +-\n builtin/grep.c         | 2 +-\n builtin/rm.c           | 2 +-\n builtin/update-index.c | 3 ++-\n cache.h                | 2 --\n diff-lib.c             | 5 +++--\n dir.h                  | 7 +++++++\n pathspec.c             | 2 +-\n preload-index.c        | 3 ++-\n read-cache.c           | 8 +-------\n resolve-undo.c         | 2 +-\n revision.c             | 3 ++-\n wt-status.c            | 2 +-\n 14 files changed, 24 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 5df3837..ada51fa 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -297,8 +297,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\t * match_pathspec() for _all_ entries when\n \t\t * opts->source_tree != NULL.\n \t\t */\n-\t\tif (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce),\n-\t\t\t\t   0, ps_matched))\n+\t\tif (ce_path_match(ce, &opts->pathspec, ps_matched))\n \t\t\tce->ce_flags |= CE_MATCHED;\n \t}\n \ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 3767478..26b2986 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -234,7 +234,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_depth(pattern, ce->name, ce_namelen(ce), 0, m))\n+\t\tif (!ce_path_match(ce, pattern, m))\n \t\t\tcontinue;\n \t\titem = string_list_insert(list, ce->name);\n \t\tif (ce_skip_worktree(ce))\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 63f8603..3d924c2 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -379,7 +379,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int\n \t\tconst struct cache_entry *ce = active_cache[nr];\n \t\tif (!S_ISREG(ce->ce_mode))\n \t\t\tcontinue;\n-\t\tif (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))\n+\t\tif (!ce_path_match(ce, pathspec, NULL))\n \t\t\tcontinue;\n \t\t/*\n \t\t * If CE_VALID is on, we assume worktree file and its cache entry\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 3a0e0ea..0564218 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -308,7 +308,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \n \tfor (i = 0; i < active_nr; i++) {\n \t\tconst struct cache_entry *ce = active_cache[i];\n-\t\tif (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))\n+\t\tif (!ce_path_match(ce, &pathspec, 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;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex e3a10d7..aaa6f78 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -12,6 +12,7 @@\n #include \"resolve-undo.h\"\n #include \"parse-options.h\"\n #include \"pathspec.h\"\n+#include \"dir.h\"\n \n /*\n  * Default to not allowing changes to the list of files. The\n@@ -564,7 +565,7 @@ static int do_reupdate(int ac, const char **av,\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n \n-\t\tif (ce_stage(ce) || !ce_path_match(ce, &pathspec))\n+\t\tif (ce_stage(ce) || !ce_path_match(ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n \t\t\told = read_one_ent(NULL, head_sha1,\ndiff --git a/cache.h b/cache.h\nindex 83a2726..3c558f8 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -500,8 +500,6 @@ extern void *read_blob_data_from_index(struct index_state *, const char *, unsig\n extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);\n extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);\n \n-extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);\n-\n #define HASH_WRITE_OBJECT 1\n #define HASH_FORMAT_CHECK 2\n extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 346cac6..2eddc66 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -11,6 +11,7 @@\n #include \"unpack-trees.h\"\n #include \"refs.h\"\n #include \"submodule.h\"\n+#include \"dir.h\"\n \n /*\n  * diff-files\n@@ -108,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)\n \t\tif (diff_can_quit_early(&revs->diffopt))\n \t\t\tbreak;\n \n-\t\tif (!ce_path_match(ce, &revs->prune_data))\n+\t\tif (!ce_path_match(ce, &revs->prune_data, NULL))\n \t\t\tcontinue;\n \n \t\tif (ce_stage(ce)) {\n@@ -438,7 +439,7 @@ static int oneway_diff(const struct cache_entry * const *src,\n \tif (tree == o->df_conflict_entry)\n \t\ttree = NULL;\n \n-\tif (ce_path_match(idx ? idx : tree, &revs->prune_data)) {\n+\tif (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) {\n \t\tdo_oneway_diff(o, idx, tree);\n \t\tif (diff_can_quit_early(&revs->diffopt)) {\n \t\t\to->exiting_early = 1;\ndiff --git a/dir.h b/dir.h\nindex 9b7e4e7..42793e5 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -205,4 +205,11 @@ extern int git_fnmatch(const struct pathspec_item *item,\n \t\t       const char *pattern, const char *string,\n \t\t       int prefix);\n \n+static inline int ce_path_match(const struct cache_entry *ce,\n+\t\t\t\tconst struct pathspec *pathspec,\n+\t\t\t\tchar *seen)\n+{\n+\treturn match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);\n+}\n+\n #endif\ndiff --git a/pathspec.c b/pathspec.c\nindex 6cb9fd3..8043099 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -33,7 +33,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,\n \t\treturn;\n \tfor (i = 0; i < active_nr; i++) {\n \t\tconst struct cache_entry *ce = active_cache[i];\n-\t\tmatch_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);\n+\t\tce_path_match(ce, pathspec, seen);\n \t}\n }\n \ndiff --git a/preload-index.c b/preload-index.c\nindex 8c44ceb..968ee25 100644\n--- a/preload-index.c\n+++ b/preload-index.c\n@@ -3,6 +3,7 @@\n  */\n #include \"cache.h\"\n #include \"pathspec.h\"\n+#include \"dir.h\"\n \n #ifdef NO_PTHREADS\n static void preload_index(struct index_state *index,\n@@ -53,7 +54,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, &p->pathspec))\n+\t\tif (!ce_path_match(ce, &p->pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))\n \t\t\tcontinue;\ndiff --git a/read-cache.c b/read-cache.c\nindex 33dd676..23eb251 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -728,11 +728,6 @@ int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)\n \treturn ce_namelen(b) == len && !memcmp(a->name, b->name, len);\n }\n \n-int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)\n-{\n-\treturn match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL);\n-}\n-\n /*\n  * We fundamentally don't like some paths: we don't want\n  * dot or dot-dot anywhere, and for obvious reasons don't\n@@ -1149,8 +1144,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,\n \t\tif (ignore_submodules && S_ISGITLINK(ce->ce_mode))\n \t\t\tcontinue;\n \n-\t\tif (pathspec &&\n-\t\t    !match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen))\n+\t\tif (pathspec && !ce_path_match(ce, pathspec, seen))\n \t\t\tfiltered = 1;\n \n \t\tif (ce_stage(ce)) {\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex c09b006..67d1543 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -182,7 +182,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)\n \n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tconst struct cache_entry *ce = istate->cache[i];\n-\t\tif (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))\n+\t\tif (!ce_path_match(ce, pathspec, NULL))\n \t\t\tcontinue;\n \t\ti = unmerge_index_entry_at(istate, i);\n \t}\ndiff --git a/revision.c b/revision.c\nindex a68fde6..e3dff61 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -16,6 +16,7 @@\n #include \"line-log.h\"\n #include \"mailmap.h\"\n #include \"commit-slab.h\"\n+#include \"dir.h\"\n \n volatile show_early_output_fn_t show_early_output;\n \n@@ -1396,7 +1397,7 @@ static void prepare_show_merge(struct rev_info *revs)\n \t\tconst struct cache_entry *ce = active_cache[i];\n \t\tif (!ce_stage(ce))\n \t\t\tcontinue;\n-\t\tif (ce_path_match(ce, &revs->prune_data)) {\n+\t\tif (ce_path_match(ce, &revs->prune_data, NULL)) {\n \t\t\tprune_num++;\n \t\t\tprune = xrealloc(prune, sizeof(*prune) * prune_num);\n \t\t\tprune[prune_num-2] = ce->name;\ndiff --git a/wt-status.c b/wt-status.c\nindex 4e55810..295c09e 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -510,7 +510,7 @@ static void wt_status_collect_changes_initial(struct wt_status *s)\n \t\tstruct wt_status_change_data *d;\n \t\tconst struct cache_entry *ce = active_cache[i];\n \n-\t\tif (!ce_path_match(ce, &s->pathspec))\n+\t\tif (!ce_path_match(ce, &s->pathspec, NULL))\n \t\t\tcontinue;\n \t\tit = string_list_insert(&s->change, ce->name);\n \t\td = it->util;\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233684","messageId":"1390570836-20394-3-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 2/9] Convert some match_pathspec_depth() to dir_path_match()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:29Z","receivedAt":"2014-01-24T13:40:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This helps reduce the number of match_pathspec_depth() call sites and\nshow how m_p_d() is used. And it usage is:\n\n - match against an index entry (ce_path_match or match_pathspec_depth\n   in ls-files)\n\n - match against a dir_entry from read_directory (dir_path_match and\n   match_pathspec_depth in clean.c, which will be converted later)\n\n - resolve-undo (rerere.c and ls-files.c)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/add.c      | 3 +--\n builtin/grep.c     | 4 +---\n builtin/ls-files.c | 2 +-\n dir.h              | 7 +++++++\n wt-status.c        | 4 ++--\n 5 files changed, 12 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 2a2722f..672adc0 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -208,8 +208,7 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,\n \ti = dir->nr;\n \twhile (--i >= 0) {\n \t\tstruct dir_entry *entry = *src++;\n-\t\tif (match_pathspec_depth(pathspec, entry->name, entry->len,\n-\t\t\t\t\t prefix, seen))\n+\t\tif (dir_path_match(entry, pathspec, prefix, seen))\n \t\t\t*dst++ = entry;\n \t\telse if (flag & WARN_IMPLICIT_DOT)\n \t\t\t/*\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 3d924c2..69ac2d8 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -524,9 +524,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,\n \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);\n-\t\tif (!match_pathspec_depth(pathspec, name, namelen, 0, NULL))\n+\t\tif (!dir_path_match(dir.entries[i], pathspec, 0, NULL))\n \t\t\tcontinue;\n \t\thit |= grep_file(opt, dir.entries[i]->name);\n \t\tif (hit && opt->status_only)\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex e1cf6d8..e238608 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -64,7 +64,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_depth(&pathspec, ent->name, ent->len, len, ps_matched))\n+\tif (!dir_path_match(ent, &pathspec, len, ps_matched))\n \t\treturn;\n \n \tfputs(tag, stdout);\ndiff --git a/dir.h b/dir.h\nindex 42793e5..65f54b6 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -212,4 +212,11 @@ static inline int ce_path_match(const struct cache_entry *ce,\n \treturn match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);\n }\n \n+static inline int dir_path_match(const struct dir_entry *ent,\n+\t\t\t\t const struct pathspec *pathspec,\n+\t\t\t\t int prefix, char *seen)\n+{\n+\treturn match_pathspec_depth(pathspec, ent->name, ent->len, prefix, seen);\n+}\n+\n #endif\ndiff --git a/wt-status.c b/wt-status.c\nindex 295c09e..a452407 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -552,7 +552,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\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_depth(&s->pathspec, ent->name, ent->len, 0, NULL))\n+\t\t    dir_path_match(ent, &s->pathspec, 0, NULL))\n \t\t\tstring_list_insert(&s->untracked, ent->name);\n \t\tfree(ent);\n \t}\n@@ -560,7 +560,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \tfor (i = 0; i < dir.ignored_nr; i++) {\n \t\tstruct dir_entry *ent = dir.ignored[i];\n \t\tif (cache_name_is_other(ent->name, ent->len) &&\n-\t\t    match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))\n+\t\t    dir_path_match(ent, &s->pathspec, 0, NULL))\n \t\t\tstring_list_insert(&s->ignored, ent->name);\n \t\tfree(ent);\n \t}\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233686","messageId":"1390570836-20394-4-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 3/9] Rename match_pathspec_depth() to match_pathspec()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:30Z","receivedAt":"2014-01-24T13:40:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"A long time ago, for some reason I was not happy with\nmatch_pathspec(). I created a better version, match_pathspec_depth()\nthat was suppose to replace match_pathspec()\neventually. match_pathspec() has finally been gone since 6 months\nago. Use the shorter name for match_pathspec_depth().\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clean.c           |  4 ++--\n builtin/ls-files.c        |  6 ++++--\n builtin/ls-tree.c         |  2 +-\n dir.c                     | 20 ++++++++++----------\n dir.h                     | 10 +++++-----\n rerere.c                  |  4 ++--\n t/t6131-pathspec-icase.sh |  6 +++---\n 7 files changed, 27 insertions(+), 25 deletions(-)\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 2f26297..f59c753 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -961,8 +961,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\tdie_errno(\"Cannot lstat '%s'\", ent->name);\n \n \t\tif (pathspec.nr)\n-\t\t\tmatches = match_pathspec_depth(&pathspec, ent->name,\n-\t\t\t\t\t\t       len, 0, NULL);\n+\t\t\tmatches = match_pathspec(&pathspec, ent->name,\n+\t\t\t\t\t\t len, 0, NULL);\n \n \t\tif (S_ISDIR(st.st_mode)) {\n \t\t\tif (remove_directories || (matches == MATCHED_EXACTLY)) {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex e238608..02db0e1 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -139,7 +139,8 @@ static void show_ce_entry(const char *tag, const 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_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched))\n+\tif (!match_pathspec(&pathspec, ce->name, ce_namelen(ce),\n+\t\t\t    len, ps_matched))\n \t\treturn;\n \n \tif (tag && *tag && show_valid_bit &&\n@@ -195,7 +196,8 @@ 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_depth(&pathspec, path, len, max_prefix_len, ps_matched))\n+\t\tif (!match_pathspec(&pathspec, path, len,\n+\t\t\t\t    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])\ndiff --git a/builtin/ls-tree.c b/builtin/ls-tree.c\nindex 65ec931..51184df 100644\n--- a/builtin/ls-tree.c\n+++ b/builtin/ls-tree.c\n@@ -171,7 +171,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)\n \t * show_recursive() rolls its own matching code and is\n \t * generally ignorant of 'struct pathspec'. The magic mask\n \t * cannot be lifted until it is converted to use\n-\t * match_pathspec_depth() or tree_entry_interesting()\n+\t * match_pathspec() or tree_entry_interesting()\n \t */\n \tparse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE,\n \t\t       PATHSPEC_PREFER_CWD,\ndiff --git a/dir.c b/dir.c\nindex d10a63f..8960ea1 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -218,7 +218,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n \t * The normal call pattern is:\n \t * 1. prefix = common_prefix_len(ps);\n \t * 2. prune something, or fill_directory\n-\t * 3. match_pathspec_depth()\n+\t * 3. match_pathspec()\n \t *\n \t * 'prefix' at #1 may be shorter than the command's prefix and\n \t * it's ok for #2 to match extra files. Those extras will be\n@@ -282,10 +282,10 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n  * pathspec did not match any names, which could indicate that the\n  * user mistyped the nth pathspec.\n  */\n-static int match_pathspec_depth_1(const struct pathspec *ps,\n-\t\t\t\t  const char *name, int namelen,\n-\t\t\t\t  int prefix, char *seen,\n-\t\t\t\t  int exclude)\n+static int do_match_pathspec(const struct pathspec *ps,\n+\t\t\t     const char *name, int namelen,\n+\t\t\t     int prefix, char *seen,\n+\t\t\t     int exclude)\n {\n \tint i, retval = 0;\n \n@@ -350,15 +350,15 @@ static int match_pathspec_depth_1(const struct pathspec *ps,\n \treturn retval;\n }\n \n-int match_pathspec_depth(const struct pathspec *ps,\n-\t\t\t const char *name, int namelen,\n-\t\t\t int prefix, char *seen)\n+int match_pathspec(const struct pathspec *ps,\n+\t\t   const char *name, int namelen,\n+\t\t   int prefix, char *seen)\n {\n \tint positive, negative;\n-\tpositive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0);\n+\tpositive = do_match_pathspec(ps, name, namelen, prefix, seen, 0);\n \tif (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)\n \t\treturn positive;\n-\tnegative = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 1);\n+\tnegative = do_match_pathspec(ps, name, namelen, prefix, seen, 1);\n \treturn negative ? 0 : positive;\n }\n \ndiff --git a/dir.h b/dir.h\nindex 65f54b6..c31ed9a 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -132,9 +132,9 @@ struct dir_struct {\n extern int simple_length(const char *match);\n extern int no_wildcard(const char *string);\n extern char *common_prefix(const struct pathspec *pathspec);\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+extern int match_pathspec(const struct pathspec *pathspec,\n+\t\t\t  const char *name, int namelen,\n+\t\t\t  int 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 struct pathspec *pathspec);\n@@ -209,14 +209,14 @@ static inline int ce_path_match(const struct cache_entry *ce,\n \t\t\t\tconst struct pathspec *pathspec,\n \t\t\t\tchar *seen)\n {\n-\treturn match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);\n+\treturn match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);\n }\n \n static inline int dir_path_match(const struct dir_entry *ent,\n \t\t\t\t const struct pathspec *pathspec,\n \t\t\t\t int prefix, char *seen)\n {\n-\treturn match_pathspec_depth(pathspec, ent->name, ent->len, prefix, seen);\n+\treturn match_pathspec(pathspec, ent->name, ent->len, prefix, seen);\n }\n \n #endif\ndiff --git a/rerere.c b/rerere.c\nindex 1f2d21a..34a21c4 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -672,8 +672,8 @@ int rerere_forget(struct pathspec *pathspec)\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_depth(pathspec, it->string, strlen(it->string),\n-\t\t\t\t\t  0, NULL))\n+\t\tif (!match_pathspec(pathspec, it->string,\n+\t\t\t\t    strlen(it->string), 0, NULL))\n \t\t\tcontinue;\n \t\trerere_forget_one_path(it->string, &merge_rr);\n \t}\ndiff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh\nindex a7c7ff5..39fc3f6 100755\n--- a/t/t6131-pathspec-icase.sh\n+++ b/t/t6131-pathspec-icase.sh\n@@ -69,7 +69,7 @@ test_expect_success 'tree_entry_interesting matches :(icase)bar with empty prefi\n \ttest_cmp expect actual\n '\n \n-test_expect_success 'match_pathspec_depth matches :(icase)bar' '\n+test_expect_success 'match_pathspec matches :(icase)bar' '\n \tcat <<-EOF >expect &&\n \tBAR\n \tbAr\n@@ -79,7 +79,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' '\n+test_expect_success 'match_pathspec matches :(icase)bar with prefix' '\n \tcat <<-EOF >expect &&\n \tfOo/BAR\n \tfOo/bAr\n@@ -89,7 +89,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success 'match_pathspec_depth matches :(icase)bar with empty prefix' '\n+test_expect_success 'match_pathspec matches :(icase)bar with empty prefix' '\n \tcat <<-EOF >expect &&\n \tbar\n \tfOo/BAR\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233688","messageId":"1390570836-20394-5-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 4/9] dir.c: prepare match_pathspec_item for taking more flags","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:31Z","receivedAt":"2014-01-24T13:40:31Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n dir.c | 19 +++++++++++++------\n 1 file changed, 13 insertions(+), 6 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 8960ea1..35e09bd 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -195,6 +195,8 @@ int within_depth(const char *name, int namelen,\n \treturn 1;\n }\n \n+#define DO_MATCH_EXCLUDE   1\n+\n /*\n  * Does 'match' match the given name?\n  * A match is found if\n@@ -208,7 +210,7 @@ int within_depth(const char *name, int namelen,\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+\t\t\t       const char *name, int namelen, unsigned flags)\n {\n \t/* name/namelen has prefix cut off by caller */\n \tconst char *match = item->match + prefix;\n@@ -285,9 +287,9 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n static int do_match_pathspec(const struct pathspec *ps,\n \t\t\t     const char *name, int namelen,\n \t\t\t     int prefix, char *seen,\n-\t\t\t     int exclude)\n+\t\t\t     unsigned flags)\n {\n-\tint i, retval = 0;\n+\tint i, retval = 0, exclude = flags & DO_MATCH_EXCLUDE;\n \n \tGUARD_PATHSPEC(ps,\n \t\t       PATHSPEC_FROMTOP |\n@@ -327,7 +329,8 @@ static int do_match_pathspec(const struct pathspec *ps,\n \t\t */\n \t\tif (seen && ps->items[i].magic & PATHSPEC_EXCLUDE)\n \t\t\tseen[i] = MATCHED_FNMATCH;\n-\t\thow = match_pathspec_item(ps->items+i, prefix, name, namelen);\n+\t\thow = match_pathspec_item(ps->items+i, prefix, name,\n+\t\t\t\t\t  namelen, flags);\n \t\tif (ps->recursive &&\n \t\t    (ps->magic & PATHSPEC_MAXDEPTH) &&\n \t\t    ps->max_depth != -1 &&\n@@ -355,10 +358,14 @@ int match_pathspec(const struct pathspec *ps,\n \t\t   int prefix, char *seen)\n {\n \tint positive, negative;\n-\tpositive = do_match_pathspec(ps, name, namelen, prefix, seen, 0);\n+\tunsigned flags = 0;\n+\tpositive = do_match_pathspec(ps, name, namelen,\n+\t\t\t\t     prefix, seen, flags);\n \tif (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)\n \t\treturn positive;\n-\tnegative = do_match_pathspec(ps, name, namelen, prefix, seen, 1);\n+\tnegative = do_match_pathspec(ps, name, namelen,\n+\t\t\t\t     prefix, seen,\n+\t\t\t\t     flags | DO_MATCH_EXCLUDE);\n \treturn negative ? 0 : positive;\n }\n \n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233685","messageId":"1390570836-20394-6-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 5/9] match_pathspec: match pathspec \"foo/\" against directory \"foo\"","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:32Z","receivedAt":"2014-01-24T13:40:32Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Currently we do support matching pathspec \"foo/\" against directory\n\"foo\". That is because match_pathspec() has no way to tell \"foo\" is a\ndirectory and matching \"foo/\" against _file_ \"foo\" is wrong.\n\nThe callers can now tell match_pathspec if \"foo\" is a directory, we\ncould make an exception for this case. Code is not executed though\nbecause no callers pass the flag yet.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n dir.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/dir.c b/dir.c\nindex 35e09bd..7b50072 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -196,6 +196,7 @@ int within_depth(const char *name, int namelen,\n }\n \n #define DO_MATCH_EXCLUDE   1\n+#define DO_MATCH_DIRECTORY 2\n \n /*\n  * Does 'match' match the given name?\n@@ -259,7 +260,11 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n \n \t\tif (match[matchlen-1] == '/' || name[matchlen] == '/')\n \t\t\treturn MATCHED_RECURSIVELY;\n-\t}\n+\t} else if ((flags & DO_MATCH_DIRECTORY) &&\n+\t\t   match[matchlen - 1] == '/' &&\n+\t\t   namelen == matchlen - 1 &&\n+\t\t   !ps_strncmp(item, match, name, namelen))\n+\t\treturn MATCHED_EXACTLY;\n \n \tif (item->nowildcard_len < item->len &&\n \t    !git_fnmatch(item, match, name,\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233687","messageId":"1390570836-20394-7-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 6/9] Pass directory indicator to match_pathspec_item()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:33Z","receivedAt":"2014-01-24T13:40:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This patch activates the DO_MATCH_DIRECTORY code in m_p_i(), which\nmakes \"git diff HEAD submodule/\" and \"git diff HEAD submodule\" produce\nthe same output. Previously only the version without trailing slash\nreturns the difference (if any).\n\nThat's the effect of new ce_path_match(). dir_path_match() is not\nexecuted by the new tests. And it should not introduce regressions.\n\nPreviously if path \"dir/\" is passed in with pathspec \"dir/\", they\nobviously match. With new dir_path_match(), the path becomes\n_directory_ \"dir\" vs pathspec \"dir/\", which is not executed by the old\ncode path in m_p_i(). The new code path is executed and produces the\nsame result.\n\nThe other case is pathspec \"dir\" and path \"dir/\" is now turned to\n\"dir\" (with DO_MATCH_DIRECTORY). Still the same result before or after\nthe patch.\n\nSo why change? Because of the next patch about clean.c.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clean.c          |  2 +-\n builtin/ls-files.c       |  5 +++--\n dir.c                    |  4 ++--\n dir.h                    | 10 +++++++---\n rerere.c                 |  2 +-\n t/t4010-diff-pathspec.sh | 17 +++++++++++++++++\n 6 files changed, 31 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex f59c753..4c9680a 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -962,7 +962,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \n \t\tif (pathspec.nr)\n \t\t\tmatches = match_pathspec(&pathspec, ent->name,\n-\t\t\t\t\t\t len, 0, NULL);\n+\t\t\t\t\t\t len, 0, NULL, 0);\n \n \t\tif (S_ISDIR(st.st_mode)) {\n \t\t\tif (remove_directories || (matches == MATCHED_EXACTLY)) {\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 02db0e1..47c3880 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -140,7 +140,8 @@ static void show_ce_entry(const char *tag, const struct cache_entry *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),\n-\t\t\t    len, ps_matched))\n+\t\t\t    len, ps_matched,\n+\t\t\t    S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)))\n \t\treturn;\n \n \tif (tag && *tag && show_valid_bit &&\n@@ -197,7 +198,7 @@ static void show_ru_info(void)\n \t\tif (len < max_prefix_len)\n \t\t\tcontinue; /* outside of the prefix */\n \t\tif (!match_pathspec(&pathspec, path, len,\n-\t\t\t\t    max_prefix_len, ps_matched))\n+\t\t\t\t    max_prefix_len, ps_matched, 0))\n \t\t\tcontinue; /* uninterested */\n \t\tfor (i = 0; i < 3; i++) {\n \t\t\tif (!ui->mode[i])\ndiff --git a/dir.c b/dir.c\nindex 7b50072..2fd0ebd 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -360,10 +360,10 @@ static int do_match_pathspec(const struct pathspec *ps,\n \n int match_pathspec(const struct pathspec *ps,\n \t\t   const char *name, int namelen,\n-\t\t   int prefix, char *seen)\n+\t\t   int prefix, char *seen, int is_dir)\n {\n \tint positive, negative;\n-\tunsigned flags = 0;\n+\tunsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;\n \tpositive = do_match_pathspec(ps, name, namelen,\n \t\t\t\t     prefix, seen, flags);\n \tif (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)\ndiff --git a/dir.h b/dir.h\nindex c31ed9a..55e5345 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -134,7 +134,7 @@ extern int no_wildcard(const char *string);\n extern char *common_prefix(const struct pathspec *pathspec);\n extern int match_pathspec(const struct pathspec *pathspec,\n \t\t\t  const char *name, int namelen,\n-\t\t\t  int prefix, char *seen);\n+\t\t\t  int prefix, char *seen, int is_dir);\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 struct pathspec *pathspec);\n@@ -209,14 +209,18 @@ static inline int ce_path_match(const struct cache_entry *ce,\n \t\t\t\tconst struct pathspec *pathspec,\n \t\t\t\tchar *seen)\n {\n-\treturn match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);\n+\treturn match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen,\n+\t\t\t      S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));\n }\n \n static inline int dir_path_match(const struct dir_entry *ent,\n \t\t\t\t const struct pathspec *pathspec,\n \t\t\t\t int prefix, char *seen)\n {\n-\treturn match_pathspec(pathspec, ent->name, ent->len, prefix, seen);\n+\tint has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';\n+\tint len = has_trailing_dir ? ent->len - 1 : ent->len;\n+\treturn match_pathspec(pathspec, ent->name, len, prefix, seen,\n+\t\t\t      has_trailing_dir);\n }\n \n #endif\ndiff --git a/rerere.c b/rerere.c\nindex 34a21c4..d55aa8a 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -673,7 +673,7 @@ int rerere_forget(struct pathspec *pathspec)\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,\n-\t\t\t\t    strlen(it->string), 0, NULL))\n+\t\t\t\t    strlen(it->string), 0, NULL, 0))\n \t\t\tcontinue;\n \t\trerere_forget_one_path(it->string, &merge_rr);\n \t}\ndiff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\nindex af5134b..167af53 100755\n--- a/t/t4010-diff-pathspec.sh\n+++ b/t/t4010-diff-pathspec.sh\n@@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '\n \ttest_cmp expected result\n '\n \n+test_expect_success 'setup submodules' '\n+\ttest_tick &&\n+\tgit init submod &&\n+\t( cd submod && test_commit first; ) &&\n+\tgit add submod &&\n+\tgit commit -m first &&\n+\t( cd submod && test_commit second; ) &&\n+\tgit add submod &&\n+\tgit commit -m second\n+'\n+\n+test_expect_success 'diff-cache ignores trailing slash on submodule path' '\n+\tgit diff --name-only HEAD^ submod >expect &&\n+\tgit diff --name-only HEAD^ submod/ >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233689","messageId":"1390570836-20394-8-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 7/9] clean: replace match_pathspec() with dir_path_match()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:34Z","receivedAt":"2014-01-24T13:40:34Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This instance was left out when many match_pathspec() call sites that\ntake input from dir_entry were converted to dir_path_match() because\nit passed a path with the trailing slash stripped out to match_pathspec()\nwhile the others did not. Stripping for all call sites back then would\nbe a regression because match_pathspec() did not know how to match\npathspec foo/ against _directory_ foo (the stripped version of path\n\"foo/\").\n\nmatch_pathspec() knows how to do it now. And dir_path_match() strips\nthe trailing slash also. Use the new function, because the stripping\ncode is removed in the next patch.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clean.c | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 4c9680a..5adb52d 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -961,8 +961,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\tdie_errno(\"Cannot lstat '%s'\", ent->name);\n \n \t\tif (pathspec.nr)\n-\t\t\tmatches = match_pathspec(&pathspec, ent->name,\n-\t\t\t\t\t\t len, 0, NULL, 0);\n+\t\t\tmatches = dir_path_match(ent, &pathspec, 0, NULL);\n \n \t\tif (S_ISDIR(st.st_mode)) {\n \t\t\tif (remove_directories || (matches == MATCHED_EXACTLY)) {\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233690","messageId":"1390570836-20394-9-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 8/9] clean: use cache_name_is_other()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:35Z","receivedAt":"2014-01-24T13:40:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"cmd_clean() has the exact same code of index_name_is_other(). Reduce\ncode duplication.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clean.c | 21 ++-------------------\n 1 file changed, 2 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 5adb52d..cb02a53 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -933,29 +933,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n-\t\tint len, pos;\n \t\tint matches = 0;\n-\t\tconst struct cache_entry *ce;\n \t\tstruct stat st;\n \t\tconst char *rel;\n \n-\t\t/*\n-\t\t * Remove the '/' at the end that directory\n-\t\t * walking adds for directory entries.\n-\t\t */\n-\t\tlen = ent->len;\n-\t\tif (len && ent->name[len-1] == '/')\n-\t\t\tlen--;\n-\t\tpos = cache_name_pos(ent->name, len);\n-\t\tif (0 <= pos)\n-\t\t\tcontinue;\t/* exact match */\n-\t\tpos = -pos - 1;\n-\t\tif (pos < active_nr) {\n-\t\t\tce = active_cache[pos];\n-\t\t\tif (ce_namelen(ce) == len &&\n-\t\t\t    !memcmp(ce->name, ent->name, len))\n-\t\t\t\tcontinue; /* Yup, this one exists unmerged */\n-\t\t}\n+\t\tif (!cache_name_is_other(ent->name, ent->len))\n+\t\t\tcontinue;\n \n \t\tif (lstat(ent->name, &st))\n \t\t\tdie_errno(\"Cannot lstat '%s'\", ent->name);\n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233691","messageId":"1390570836-20394-10-git-send-email-pclouds@gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 9/9] tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-24T13:40:36Z","receivedAt":"2014-01-24T13:40:36Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"We do ignore trailing slash on a directory, so pathspec \"abc/\" matches\ndirectory \"abc\". A submodule is also a directory. Apply the same logic\nto it. This makes \"git log submodule-path\" and \"git log submodule-path/\"\nproduce the same output.\n\nReported-by: Paweł Sikora <pawel.sikora@agmk.net>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t4010-diff-pathspec.sh | 6 ++++++\n tree-walk.c              | 2 +-\n 2 files changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\nindex 167af53..2424af0 100755\n--- a/t/t4010-diff-pathspec.sh\n+++ b/t/t4010-diff-pathspec.sh\n@@ -127,4 +127,10 @@ test_expect_success 'diff-cache ignores trailing slash on submodule path' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'diff-tree ignores trailing slash on submodule path' '\n+\tgit diff --name-only HEAD^ HEAD submod >expect &&\n+\tgit diff --name-only HEAD^ HEAD submod/ >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\ndiff --git a/tree-walk.c b/tree-walk.c\nindex 680afda..c29b6a3 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -543,7 +543,7 @@ static int match_entry(const struct pathspec_item *item,\n \tif (matchlen > pathlen) {\n \t\tif (match[pathlen] != '/')\n \t\t\treturn 0;\n-\t\tif (!S_ISDIR(entry->mode))\n+\t\tif (!S_ISDIR(entry->mode) && !S_ISGITLINK(entry->mode))\n \t\t\treturn 0;\n \t}\n \n-- \n1.8.5.2.240.g8478abd\n"},{"id":"233704","messageId":"xmqqk3dprxr2.fsf@gitster.dls.corp.google.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 0/9] About the trailing slashes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-24T19:22:09Z","receivedAt":"2014-01-24T19:22:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> While looking at this, I found a funny behavior of fill_directory.\n>\n>   $ git init\n>   $ mkdir b\n>   $ >b/c\n>   $ >b/d\n>   $ git status b\n>   Untracked files:\n>           b/\n>   $ git status b/\n>   Untracked files:\n>           b/c b/d\n>\n> Notice how the trailing slash produces different untracked listing.\n> This is because of common_prefix_len(). In the \"b\" case,\n> common_prefix_len() returns empty prefix, so read_directory reads top\n> directory, traverses through, reaches \"b\" and eventually calls\n> treat_directory() on it, which results in \"b/\" in the output.\n>\n> In the \"b/\" case, common_prefix_len() found the prefix \"b\", so\n> read_directory() starts at \"b\" instead of b's parent.\n> treat_directory() is never called on \"b\" itself, which results in\n> \"b/c\" and \"b/d\".\n\nHmm, this feels like a borderline case.\n\nIf the user asked \"git status ?\", or even \"git status '?'\", it seems\nto me that the user wanted to get \"git status\" output but with a\nscope limited to top-level entries with a single letter.  And the\nunlimited output asks to consolidate output for directories that\nhave nothing interesting.  \"git status b\" and \"git status '[b]'\" are\nasking similar thing, but not just limiting the scope to any one\nletter but to 'b'.  So the output you showed above looks correct to\nme.  On the other hand, the other request \"git status b/\" seems to\nme that the user is very aware that 'b' is a directory and wants to\nlook inside, so again the output you showed looks correct to me.\n\nHow does \"git status '[b]/'\" behave?\n"},{"id":"233725","messageId":"CAPig+cRW5Fz62Qk22qiUo85jmqVK0Hvbb6v2GxK7V+wS+S8_qw@mail.gmail.com","threadId":"35699","inReplyTo":"1390570836-20394-7-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 6/9] Pass directory indicator to match_pathspec_item()","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-01-24T21:22:58Z","receivedAt":"2014-01-24T21:22:58Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jan 24, 2014 at 8:40 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\n> index af5134b..167af53 100755\n> --- a/t/t4010-diff-pathspec.sh\n> +++ b/t/t4010-diff-pathspec.sh\n> @@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '\n>         test_cmp expected result\n>  '\n>\n> +test_expect_success 'setup submodules' '\n> +       test_tick &&\n> +       git init submod &&\n> +       ( cd submod && test_commit first; ) &&\n\nUnnecessary semicolon might confuse the reader into thinking something\nunusual is going on here.\n\n> +       git add submod &&\n> +       git commit -m first &&\n> +       ( cd submod && test_commit second; ) &&\n\nDitto.\n\n> +       git add submod &&\n> +       git commit -m second\n> +'\n> +\n> +test_expect_success 'diff-cache ignores trailing slash on submodule path' '\n> +       git diff --name-only HEAD^ submod >expect &&\n> +       git diff --name-only HEAD^ submod/ >actual &&\n> +       test_cmp expect actual\n> +'\n> +\n>  test_done\n"},{"id":"233738","messageId":"CACsJy8BPS95+34chr4rfSTAcQNVHJccu9SYih2fiNxB_3eRy=A@mail.gmail.com","threadId":"35699","inReplyTo":"xmqqk3dprxr2.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 0/9] About the trailing slashes","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-25T01:14:42Z","receivedAt":"2014-01-25T01:14:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jan 25, 2014 at 2:22 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> How does \"git status '[b]/'\" behave?\n\nIt outputs \"b/\" (like \"git status b\"). I think that's because\ncommon_prefix_len() stops looking at the first wildcard char, '['. So\ncommon prefix is empty, just like \"b\".\n-- \nDuy\n"},{"id":"233743","messageId":"CACsJy8Aj8EnDD5Qk=VStpDXTAV-WOh_utmiY+qXGyCwoXpQHog@mail.gmail.com","threadId":"35699","inReplyTo":"CAPig+cRW5Fz62Qk22qiUo85jmqVK0Hvbb6v2GxK7V+wS+S8_qw@mail.gmail.com","subject":"Re: [PATCH v2 6/9] Pass directory indicator to match_pathspec_item()","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-01-25T04:24:11Z","receivedAt":"2014-01-25T04:24:11Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jan 25, 2014 at 4:22 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Fri, Jan 24, 2014 at 8:40 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh\n>> index af5134b..167af53 100755\n>> --- a/t/t4010-diff-pathspec.sh\n>> +++ b/t/t4010-diff-pathspec.sh\n>> @@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '\n>>         test_cmp expected result\n>>  '\n>>\n>> +test_expect_success 'setup submodules' '\n>> +       test_tick &&\n\nAlso the test_tick here. I thought I would need to match SHA-1 but I\ndid not and still forgot to take this line out.\n\n>> +       git init submod &&\n>> +       ( cd submod && test_commit first; ) &&\n>\n> Unnecessary semicolon might confuse the reader into thinking something\n> unusual is going on here.\n>\n>> +       git add submod &&\n>> +       git commit -m first &&\n>> +       ( cd submod && test_commit second; ) &&\n>\n> Ditto.\n>\n>> +       git add submod &&\n>> +       git commit -m second\n>> +'\n>> +\n>> +test_expect_success 'diff-cache ignores trailing slash on submodule path' '\n>> +       git diff --name-only HEAD^ submod >expect &&\n>> +       git diff --name-only HEAD^ submod/ >actual &&\n>> +       test_cmp expect actual\n>> +'\n>> +\n>>  test_done\n\n\n\n-- \nDuy\n"},{"id":"233844","messageId":"xmqq38k9nisi.fsf@gitster.dls.corp.google.com","threadId":"35699","inReplyTo":"1390570836-20394-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 0/9] About the trailing slashes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-01-27T22:47:57Z","receivedAt":"2014-01-27T22:47:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks; will try to rebase on top of more recent codebase and then\nreview.\n"}]}