On Wed, Nov 30, 2016 at 06:46:36PM -0500, Jeff King wrote: > > For now the work around could be to just pass "-C <dir>" to the child > > process instead of relying on run-command to chdir. > > Yeah, that would push it after the exec. I just don't understand why > that would be necessary. Hmm. It still seems to fail, even with the workaround (the patch in run-command is there to make sure there's not some other call that we're not catching): diff --git a/builtin/grep.c b/builtin/grep.c index 2c727ef49..3323a3e7f 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -553,6 +553,7 @@ static int grep_submodule_launch(struct grep_opt *opt, argv_array_pushf(&cp.args, "--super-prefix=%s%s/", super_prefix ? super_prefix : "", name); + argv_array_pushl(&cp.args, "-C", gs->path, NULL); argv_array_push(&cp.args, "grep"); /* @@ -586,7 +587,6 @@ static int grep_submodule_launch(struct grep_opt *opt, } cp.git_cmd = 1; - cp.dir = gs->path; /* * Capture output to output buffer and check the return code from the diff --git a/run-command.c b/run-command.c index 5a4dbb66d..d040f4f77 100644 --- a/run-command.c +++ b/run-command.c @@ -393,6 +393,8 @@ int start_command(struct child_process *cmd) close(cmd->out); } + if (cmd->dir && git_env_bool("GIT_NO_CHDIR", 0)) + die("temporarily disallowing chdir"); if (cmd->dir && chdir(cmd->dir)) die_errno("exec '%s': cd to '%s' failed", cmd->argv[0], cmd->dir); diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh index 050777186..591ff74ed 100755 --- a/t/t7814-grep-recurse-submodules.sh +++ b/t/t7814-grep-recurse-submodules.sh @@ -175,7 +175,7 @@ test_expect_success 'grep recurse submodule colon in name' ' fi:le:foobar su:b/fi:le:foobar EOF - git -C parent grep -e "foobar" --recurse-submodules >actual && + GIT_NO_CHDIR=1 strace -o foo.out -f git -C parent grep -e "foobar" --recurse-submodules >actual && test_cmp expect actual && cat >expect <<-\EOF && So I think there is some other chdir(). I'm not sure if there is an easy way to get a backtrace on every call to chdir() in every thread. I'm sure somebody more clever than me could figure out how to make gdb do it automatically, but it might be workable manually. I think the chdir was in the main thread. -Peff