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;
object = parse_object_or_die(oid, oid_to_hex(oid));
grep_read_lock();
- data = read_object_with_reference(&object->oid, tree_type,
+ data = read_object_with_reference(&subrepo,
+ &object->oid, tree_type,
&size, NULL);
grep_read_unlock();
strbuf_release(&base);
free(data);
} else {
- hit = grep_cache(&subopt, pathspec, 1);
+ hit = grep_cache(&subopt, pathspec, cached);
}
repo_clear(&subrepo);
}
} 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;
}
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);
int hit, len;
grep_read_lock();
- data = read_object_with_reference(&obj->oid, tree_type,
+ data = read_object_with_reference(opt->repo,
+ &obj->oid, tree_type,
&size, NULL);
grep_read_unlock();
echo "(3|4)" >b/b &&
git add a b &&
git commit -m "add a and b" &&
+ test_tick &&
git init submodule &&
echo "(1|2)d(3|4)" >submodule/a &&
git -C submodule add a &&
git -C submodule commit -m "add a" &&
git submodule add ./submodule &&
- git commit -m "added submodule"
+ git commit -m "added submodule" &&
+ test_tick
'
test_expect_success 'grep correctly finds patterns in a submodule' '
echo "(1|2)d(3|4)" >submodule/sub/a &&
git -C submodule/sub add a &&
git -C submodule/sub commit -m "add a" &&
+ test_tick &&
git -C submodule submodule add ./sub &&
git -C submodule add sub &&
git -C submodule commit -m "added sub" &&
+ test_tick &&
git add submodule &&
git commit -m "updated submodule" &&
+ test_tick &&
cat >expect <<-\EOF &&
a:(1|2)d(3|4)
echo "(1|2)d(3|4)" >"parent/fi:le" &&
git -C parent add "fi:le" &&
git -C parent commit -m "add fi:le" &&
+ test_tick &&
git init "su:b" &&
test_when_finished "rm -rf su:b" &&
echo "(1|2)d(3|4)" >"su:b/fi:le" &&
git -C "su:b" add "fi:le" &&
git -C "su:b" commit -m "add fi:le" &&
+ test_tick &&
git -C parent submodule add "../su:b" "su:b" &&
git -C parent commit -m "add submodule" &&
+ test_tick &&
cat >expect <<-\EOF &&
fi:le:(1|2)d(3|4)
echo "(1|2)d(3|4)" >parent/file &&
git -C parent add file &&
git -C parent commit -m "add file" &&
+ test_tick &&
git init sub &&
test_when_finished "rm -rf sub" &&
echo "(1|2)d(3|4)" >sub/file &&
git -C sub add file &&
git -C sub commit -m "add file" &&
+ test_tick &&
git -C parent submodule add ../sub dir/sub &&
git -C parent commit -m "add submodule" &&
+ test_tick &&
cat >expect <<-\EOF &&
dir/sub/file:(1|2)d(3|4)
git -C parent mv dir/sub sub-moved &&
git -C parent commit -m "moved submodule" &&
+ test_tick &&
cat >expect <<-\EOF &&
file:(1|2)d(3|4)
echo "(1|2)d(3|4)" >sub/file &&
git -C sub add file &&
git -C sub commit -m "add file" &&
+ test_tick &&
git init parent &&
echo "(1|2)d(3|4)" >parent/file &&
git -C parent add src/file2 &&
git -C parent submodule add ../sub &&
git -C parent commit -m "add files and submodule" &&
+ test_tick &&
# From top works
cat >expect <<-\EOF &&
echo "(1|2)d(3|4)" >sub/file &&
git -C sub add file &&
git -C sub commit -m "add file" &&
+ test_tick &&
git init parent &&
mkdir parent/src &&
git -C parent submodule add ../sub src/sub &&
git -C parent submodule add ../sub sub &&
git -C parent commit -m "add files and submodules" &&
+ test_tick &&
# Verify grep from root works
cat >expect <<-\EOF &&
test_cmp expect actual
'
+ reset_and_clean () {
+ git reset --hard &&
+ git clean -fd &&
+ git submodule foreach --recursive 'git reset --hard' &&
+ git submodule foreach --recursive '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