Skip to content

Commit e6fac7f

Browse files
bmwillgitster
authored andcommitted
grep: search history of moved submodules
If a submodule was renamed at any point since it's inception then if you were to try and grep on a commit prior to the submodule being moved, you wouldn't be able to find a working directory for the submodule since the path in the past is different from the current path. This patch teaches grep to find the .git directory for a submodule in the parents .git/modules/ directory in the event the path to the submodule in the commit that is being searched differs from the state of the currently checked out commit. If found, the child process that is spawned to grep the submodule will chdir into its gitdir instead of a working directory. In order to override the explicit setting of submodule child process's gitdir environment variable (which was introduced in '10f5c526') `GIT_DIR_ENVIORMENT` needs to be pushed onto child process's env_array. This allows the searching of history from a submodule's gitdir, rather than from a working directory. Signed-off-by: Brandon Williams <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 74ed437 commit e6fac7f

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

builtin/grep.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ static int grep_submodule_launch(struct grep_opt *opt,
547547
name = gs->name;
548548

549549
prepare_submodule_repo_env(&cp.env_array);
550+
argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
550551

551552
/* Add super prefix */
552553
argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
@@ -615,8 +616,23 @@ static int grep_submodule(struct grep_opt *opt, const unsigned char *sha1,
615616
{
616617
if (!is_submodule_initialized(path))
617618
return 0;
618-
if (!is_submodule_populated(path))
619-
return 0;
619+
if (!is_submodule_populated(path)) {
620+
/*
621+
* If searching history, check for the presense of the
622+
* submodule's gitdir before skipping the submodule.
623+
*/
624+
if (sha1) {
625+
const struct submodule *sub =
626+
submodule_from_path(null_sha1, path);
627+
if (sub)
628+
path = git_path("modules/%s", sub->name);
629+
630+
if (!(is_directory(path) && is_git_directory(path)))
631+
return 0;
632+
} else {
633+
return 0;
634+
}
635+
}
620636

621637
#ifndef NO_PTHREADS
622638
if (num_threads) {

t/t7814-grep-recurse-submodules.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,47 @@ test_expect_success !MINGW 'grep recurse submodule colon in name' '
186186
test_cmp expect actual
187187
'
188188

189+
test_expect_success 'grep history with moved submoules' '
190+
git init parent &&
191+
test_when_finished "rm -rf parent" &&
192+
echo "foobar" >parent/file &&
193+
git -C parent add file &&
194+
git -C parent commit -m "add file" &&
195+
196+
git init sub &&
197+
test_when_finished "rm -rf sub" &&
198+
echo "foobar" >sub/file &&
199+
git -C sub add file &&
200+
git -C sub commit -m "add file" &&
201+
202+
git -C parent submodule add ../sub dir/sub &&
203+
git -C parent commit -m "add submodule" &&
204+
205+
cat >expect <<-\EOF &&
206+
dir/sub/file:foobar
207+
file:foobar
208+
EOF
209+
git -C parent grep -e "foobar" --recurse-submodules >actual &&
210+
test_cmp expect actual &&
211+
212+
git -C parent mv dir/sub sub-moved &&
213+
git -C parent commit -m "moved submodule" &&
214+
215+
cat >expect <<-\EOF &&
216+
file:foobar
217+
sub-moved/file:foobar
218+
EOF
219+
git -C parent grep -e "foobar" --recurse-submodules >actual &&
220+
test_cmp expect actual &&
221+
222+
cat >expect <<-\EOF &&
223+
HEAD^:dir/sub/file:foobar
224+
HEAD^:file:foobar
225+
EOF
226+
git -C parent grep -e "foobar" --recurse-submodules HEAD^ >actual &&
227+
test_cmp expect actual
228+
'
229+
189230
test_incompatible_with_recurse_submodules ()
190231
{
191232
test_expect_success "--recurse-submodules and $1 are incompatible" "

0 commit comments

Comments
 (0)