summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/grep.c39
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh75
2 files changed, 99 insertions, 15 deletions
diff --git a/builtin/grep.c b/builtin/grep.c
index 4b7b2da104..4a279ca4bf 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -310,10 +310,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
{
struct strbuf pathbuf = STRBUF_INIT;
- if (opt->relative && opt->prefix_length) {
- quote_path_relative(filename + tree_name_len, opt->prefix, &pathbuf);
- strbuf_insert(&pathbuf, 0, filename, tree_name_len);
- } else if (super_prefix) {
+ if (super_prefix) {
strbuf_add(&pathbuf, filename, tree_name_len);
strbuf_addstr(&pathbuf, super_prefix);
strbuf_addstr(&pathbuf, filename + tree_name_len);
@@ -321,6 +318,13 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
strbuf_addstr(&pathbuf, filename);
}
+ if (opt->relative && opt->prefix_length) {
+ char *name = strbuf_detach(&pathbuf, NULL);
+ quote_path_relative(name + tree_name_len, opt->prefix, &pathbuf);
+ strbuf_insert(&pathbuf, 0, name, tree_name_len);
+ free(name);
+ }
+
#ifndef NO_PTHREADS
if (num_threads) {
add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
@@ -345,12 +349,14 @@ static int grep_file(struct grep_opt *opt, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
+ if (super_prefix)
+ strbuf_addstr(&buf, super_prefix);
+ strbuf_addstr(&buf, filename);
+
if (opt->relative && opt->prefix_length) {
- quote_path_relative(filename, opt->prefix, &buf);
- } else {
- if (super_prefix)
- strbuf_addstr(&buf, super_prefix);
- strbuf_addstr(&buf, filename);
+ char *name = strbuf_detach(&buf, NULL);
+ quote_path_relative(name, opt->prefix, &buf);
+ free(name);
}
#ifndef NO_PTHREADS
@@ -399,13 +405,12 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
}
static void compile_submodule_options(const struct grep_opt *opt,
- const struct pathspec *pathspec,
+ const char **argv,
int cached, int untracked,
int opt_exclude, int use_index,
int pattern_type_arg)
{
struct grep_pat *pattern;
- int i;
if (recurse_submodules)
argv_array_push(&submodule_options, "--recurse-submodules");
@@ -523,9 +528,8 @@ static void compile_submodule_options(const struct grep_opt *opt,
/* Add Pathspecs */
argv_array_push(&submodule_options, "--");
- for (i = 0; i < pathspec->nr; i++)
- argv_array_push(&submodule_options,
- pathspec->items[i].original);
+ for (; *argv; argv++)
+ argv_array_push(&submodule_options, *argv);
}
/*
@@ -549,6 +553,11 @@ static int grep_submodule_launch(struct grep_opt *opt,
prepare_submodule_repo_env(&cp.env_array);
argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
+ if (opt->relative && opt->prefix_length)
+ argv_array_pushf(&cp.env_array, "%s=%s",
+ GIT_TOPLEVEL_PREFIX_ENVIRONMENT,
+ opt->prefix);
+
/* Add super prefix */
argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
super_prefix ? super_prefix : "",
@@ -1206,7 +1215,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (recurse_submodules) {
gitmodules_config();
- compile_submodule_options(&opt, &pathspec, cached, untracked,
+ compile_submodule_options(&opt, argv + i, cached, untracked,
opt_exclude, use_index,
pattern_type_arg);
}
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index 67247a01d6..5b6eb3a65e 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -227,6 +227,81 @@ test_expect_success 'grep history with moved submoules' '
test_cmp expect actual
'
+test_expect_success 'grep using relative path' '
+ test_when_finished "rm -rf parent sub" &&
+ git init sub &&
+ echo "foobar" >sub/file &&
+ git -C sub add file &&
+ git -C sub commit -m "add file" &&
+
+ git init parent &&
+ echo "foobar" >parent/file &&
+ git -C parent add file &&
+ mkdir parent/src &&
+ echo "foobar" >parent/src/file2 &&
+ git -C parent add src/file2 &&
+ git -C parent submodule add ../sub &&
+ git -C parent commit -m "add files and submodule" &&
+
+ # From top works
+ cat >expect <<-\EOF &&
+ file:foobar
+ src/file2:foobar
+ sub/file:foobar
+ EOF
+ git -C parent grep --recurse-submodules -e "foobar" >actual &&
+ test_cmp expect actual &&
+
+ # Relative path to top
+ cat >expect <<-\EOF &&
+ ../file:foobar
+ file2:foobar
+ ../sub/file:foobar
+ EOF
+ git -C parent/src grep --recurse-submodules -e "foobar" -- .. >actual &&
+ test_cmp expect actual &&
+
+ # Relative path to submodule
+ cat >expect <<-\EOF &&
+ ../sub/file:foobar
+ EOF
+ git -C parent/src grep --recurse-submodules -e "foobar" -- ../sub >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep from a subdir' '
+ test_when_finished "rm -rf parent sub" &&
+ git init sub &&
+ echo "foobar" >sub/file &&
+ git -C sub add file &&
+ git -C sub commit -m "add file" &&
+
+ git init parent &&
+ mkdir parent/src &&
+ echo "foobar" >parent/src/file &&
+ git -C parent add src/file &&
+ git -C parent submodule add ../sub src/sub &&
+ git -C parent submodule add ../sub sub &&
+ git -C parent commit -m "add files and submodules" &&
+
+ # Verify grep from root works
+ cat >expect <<-\EOF &&
+ src/file:foobar
+ src/sub/file:foobar
+ sub/file:foobar
+ EOF
+ git -C parent grep --recurse-submodules -e "foobar" >actual &&
+ test_cmp expect actual &&
+
+ # Verify grep from a subdir works
+ cat >expect <<-\EOF &&
+ file:foobar
+ sub/file:foobar
+ EOF
+ git -C parent/src grep --recurse-submodules -e "foobar" >actual &&
+ test_cmp expect actual
+'
+
test_incompatible_with_recurse_submodules ()
{
test_expect_success "--recurse-submodules and $1 are incompatible" "