Major change in v5 is to use tree_is_interesting api instead of the vanilla pathspec code for submodules. This is to fix the issue in the last seires where I mix the two types. More tests were also added to ensure that the changes to the pathspec code functioned properly. Brandon Williams (6): submodules: add helper functions to determine presence of submodules submodules: load gitmodules file from commit sha1 grep: add submodules as a grep source type grep: optionally recurse into submodules grep: enable recurse-submodules to work on <tree> objects grep: search history of moved submodules Documentation/git-grep.txt | 14 ++ builtin/grep.c | 386 ++++++++++++++++++++++++++++++++++--- cache.h | 2 + config.c | 8 +- git.c | 2 +- grep.c | 16 +- grep.h | 1 + submodule-config.c | 6 +- submodule-config.h | 3 + submodule.c | 50 +++++ submodule.h | 3 + t/t7814-grep-recurse-submodules.sh | 241 +++++++++++++++++++++++ tree-walk.c | 28 +++ 13 files changed, 729 insertions(+), 31 deletions(-) create mode 100755 t/t7814-grep-recurse-submodules.sh -- interdiff based on 'bw/grep-recurse-submodules' diff --git a/builtin/grep.c b/builtin/grep.c index 052f605..2c727ef 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -698,6 +698,8 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && submodule_path_match(pathspec, name.buf, NULL)) { hit |= grep_submodule(opt, NULL, ce->name, ce->name); + } else { + continue; } if (ce_stage(ce)) { @@ -734,17 +736,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, int te_len = tree_entry_len(&entry); if (match != all_entries_interesting) { - strbuf_setlen(&name, name_base_len); strbuf_addstr(&name, base->buf + tn_len); - - if (recurse_submodules && S_ISGITLINK(entry.mode)) { - strbuf_addstr(&name, entry.path); - match = submodule_path_match(pathspec, name.buf, - NULL); - } else { - match = tree_entry_interesting(&entry, &name, - 0, pathspec); - } + match = tree_entry_interesting(&entry, &name, + 0, pathspec); + strbuf_setlen(&name, name_base_len); if (match == all_entries_not_interesting) break; diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh index 7d66716..0507771 100755 --- a/t/t7814-grep-recurse-submodules.sh +++ b/t/t7814-grep-recurse-submodules.sh @@ -127,6 +127,34 @@ test_expect_success 'grep tree and pathspecs' ' test_cmp expect actual ' +test_expect_success 'grep tree and pathspecs' ' + cat >expect <<-\EOF && + HEAD:submodule/a:foobar + HEAD:submodule/sub/a:foobar + EOF + + git grep -e "bar" --recurse-submodules HEAD -- "submodule*a" >actual && + test_cmp expect actual +' + +test_expect_success 'grep tree and more pathspecs' ' + cat >expect <<-\EOF && + HEAD:submodule/a:foobar + EOF + + git grep -e "bar" --recurse-submodules HEAD -- "submodul?/a" >actual && + test_cmp expect actual +' + +test_expect_success 'grep tree and more pathspecs' ' + cat >expect <<-\EOF && + HEAD:submodule/sub/a:foobar + EOF + + git grep -e "bar" --recurse-submodules HEAD -- "submodul*/sub/a" >actual && + test_cmp expect actual +' + test_expect_success 'grep recurse submodule colon in name' ' git init parent && test_when_finished "rm -rf parent" && diff --git a/tree-walk.c b/tree-walk.c index 828f435..ff77605 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -1004,6 +1004,19 @@ static enum interesting do_match(const struct name_entry *entry, */ if (ps->recursive && S_ISDIR(entry->mode)) return entry_interesting; + + /* + * When matching against submodules with + * wildcard characters, ensure that the entry + * at least matches up to the first wild + * character. More accurate matching can then + * be performed in the submodule itself. + */ + if (ps->recursive && S_ISGITLINK(entry->mode) && + !ps_strncmp(item, match + baselen, + entry->path, + item->nowildcard_len - baselen)) + return entry_interesting; } continue; @@ -1040,6 +1053,21 @@ static enum interesting do_match(const struct name_entry *entry, strbuf_setlen(base, base_offset + baselen); return entry_interesting; } + + /* + * When matching against submodules with + * wildcard characters, ensure that the entry + * at least matches up to the first wild + * character. More accurate matching can then + * be performed in the submodule itself. + */ + if (ps->recursive && S_ISGITLINK(entry->mode) && + !ps_strncmp(item, match, base->buf + base_offset, + item->nowildcard_len)) { + strbuf_setlen(base, base_offset + baselen); + return entry_interesting; + } + strbuf_setlen(base, base_offset + baselen); /* -- 2.8.0.rc3.226.g39d4020