@@ -400,10 +400,14 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len,
int check_attr);
+/*
+ * The cached bit is only meaningful when a NULL oid is given (i.e. when not
+ * grepping inside a tree object).
+ */
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 +479,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 +527,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 +603,7 @@ 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);
}
strbuf_setlen(base, old_baselen);
@@ -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
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 <jackdanielz@eyomi.org> Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> --- Changes in v3: - Replaced the "\* ignored *\" comment by a more meaningful note at the top of grep_submodule() builtin/grep.c | 13 +++++++++---- t/t7814-grep-recurse-submodules.sh | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-)