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

Reply via email to