Running git-grep with --recurse-submodules results in a cached grep for
the submodules even when --cached is not used. This makes all
modifications in submodules' tracked files be always ignored when
grepping. Solve that making git-grep respect the cached option when
invoking grep_cache() inside grep_submodule(). Also, add tests to
ensure that the desired behavior is performed.

Reported-by: Daniel Zaoui <jackdani...@eyomi.org>
Signed-off-by: Matheus Tavares <matheus.bernard...@usp.br>
---
Changes in v2:
- repositioned the '/* ignored */' comment to avoid ambiguity
- joined `git clean` and `git reset` invokations in a single `git
  submodule foreach`. 

travis build: https://travis-ci.org/matheustavares/git/builds/565749070

builtin/grep.c                     | 10 ++++++----
 t/t7814-grep-recurse-submodules.sh | 20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 560051784e..d9866dd936 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -403,7 +403,7 @@ static int grep_tree(struct grep_opt *opt, const struct 
pathspec *pathspec,
 static int grep_submodule(struct grep_opt *opt,
                          const struct pathspec *pathspec,
                          const struct object_id *oid,
-                         const char *filename, const char *path)
+                         const char *filename, const char *path, int cached)
 {
        struct repository subrepo;
        struct repository *superproject = opt->repo;
@@ -475,7 +475,7 @@ static int grep_submodule(struct grep_opt *opt,
                strbuf_release(&base);
                free(data);
        } else {
-               hit = grep_cache(&subopt, pathspec, 1);
+               hit = grep_cache(&subopt, pathspec, cached);
        }
 
        repo_clear(&subrepo);
@@ -523,7 +523,8 @@ static int grep_cache(struct grep_opt *opt,
                        }
                } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
                           submodule_path_match(repo->index, pathspec, 
name.buf, NULL)) {
-                       hit |= grep_submodule(opt, pathspec, NULL, ce->name, 
ce->name);
+                       hit |= grep_submodule(opt, pathspec, NULL, ce->name,
+                                             ce->name, cached);
                } else {
                        continue;
                }
@@ -598,7 +599,8 @@ static int grep_tree(struct grep_opt *opt, const struct 
pathspec *pathspec,
                        free(data);
                } else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
                        hit |= grep_submodule(opt, pathspec, &entry.oid,
-                                             base->buf, base->buf + tn_len);
+                                             base->buf, base->buf + tn_len,
+                                             1 /* ignored */);
                }
 
                strbuf_setlen(base, old_baselen);
diff --git a/t/t7814-grep-recurse-submodules.sh 
b/t/t7814-grep-recurse-submodules.sh
index a11366b4ce..edb64690e6 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -408,4 +408,24 @@ test_expect_success 'grep --recurse-submodules with 
submodules without .gitmodul
        test_cmp expect actual
 '
 
+reset_and_clean () {
+       git reset --hard &&
+       git clean -fd &&
+       git submodule foreach --recursive 'git reset --hard && git clean -fd'
+}
+
+test_expect_success 'grep --recurse-submodules without --cached considers 
worktree modifications' '
+       reset_and_clean &&
+       echo "A modified line in submodule" >>submodule/a &&
+       echo "submodule/a:A modified line in submodule" >expect &&
+       git grep --recurse-submodules "A modified line in submodule" >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'grep --recurse-submodules with --cached ignores worktree 
modifications' '
+       reset_and_clean &&
+       echo "A modified line in submodule" >>submodule/a &&
+       test_must_fail git grep --recurse-submodules --cached "A modified line 
in submodule" >actual 2>&1 &&
+       test_must_be_empty actual
+'
 test_done
-- 
2.22.0

Reply via email to