From: Derrick Stolee <stolee@gmail.com>
To: Jeff King <peff@peff.net>, Eric Sunshine <sunshine@sunshineco.com>
Cc: Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>,
git@vger.kernel.org, gitster@pobox.com, fastcat@gmail.com
Subject: Re: [PATCH 2/2] for-each-repo: work correctly in a worktree
Date: Tue, 24 Feb 2026 07:11:13 -0500 [thread overview]
Message-ID: <fce7662f-d741-41e1-93dd-f82e65e04f41@gmail.com> (raw)
In-Reply-To: <20260224091806.GC986367@coredump.intra.peff.net>
On 2/24/26 4:18 AM, Jeff King wrote:
> On Mon, Feb 23, 2026 at 10:34:30PM -0500, Eric Sunshine wrote:
>
>>> diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
>>> @@ -60,6 +61,9 @@ int cmd_for_each_repo(int argc,
>>> + /* Be sure to not pass GIT_DIR to children. */
>>> + unsetenv(GIT_DIR_ENVIRONMENT);
>>
>> This only unsets GIT_DIR. Is that sufficient in the general case?
>> Elsewhere, we recommend[*] unsetting all of Git's local environment
>> variables.
>>
>> [*]: From the "githooks" man page: "Environment variables, such as
>> GIT_DIR, GIT_WORK_TREE, etc., are exported so that Git commands run by
>> the hook can correctly locate the repository. If your hook needs to
>> invoke Git commands in a foreign repository or in a different working
>> tree of the same repository, then it should clear these environment
>> variables so they do not interfere with Git operations at the foreign
>> location. For example: `unset $(git rev-parse --local-env-vars)`"
>
> Yeah, agreed. There's another subtle issue, which is that this is
> unsetting GIT_DIR in the parent process. So any other code we call that
> is meant to run in the original repo might get confused. I can well
> believe there isn't any such code for a command like for-each-repo, but
> as a general principle, the change should be made in the sub-process.
>
> You can stick the elements of local_repo_env into the "env" list of the
> child_process struct. If you grep around, you can find some instances of
> this.
>
> There's an open question there of how to handle config in the
> environment, though. Depending on the sub-process, you may or may not
> want such config to pass down to it. For for-each-repo, I'd guess that
> you'd want:
>
> git -c foo.bar=baz for-each-repo ...
>
> to pass that foo.bar value. We do have a helper to handle that in
> run-command.h:
>
> /**
> * Convenience function which prepares env for a command to be run in a
> * new repo. This adds all GIT_* environment variables to env with the
> * exception of GIT_CONFIG_PARAMETERS and GIT_CONFIG_COUNT (which cause the
> * corresponding environment variables to be unset in the subprocess) and adds
> * an environment variable pointing to new_git_dir. See local_repo_env in
> * environment.h for more information.
> */
> void prepare_other_repo_env(struct strvec *env, const char *new_git_dir);
>
> Do be careful using it here, though. It expects to set GIT_DIR itself to
> point to the new repo (which is passed in). But I'm not sure that's 100%
> compatible with how for-each-repo works, which is using "git -C $repo"
> under the hood, and letting the usual discovery happen.
>
> So for a bare repo, you'd want to pass the repo directory. But for a
> non-bare one, you'd want $repo/.git. And there are even more weird
> corner cases, like the fact that using "/my/repo/but/inside/a/subdir"
> with for-each-repo will find "/my/repo".
>
> So you might need to refactor prepare_other_repo_env() to split out the
> "everything but the config" logic versus the "set GIT_DIR" logic. Or
> just inline the former in run_command_on_repo(), though it probably is
> better to keep the logic in one place (it's not many lines, but it has
> to know about all of the env variables that affect config).
Thanks for the recommendations. I'll come back with a more sophisticated
v2 that handles these issues.
> Alternatively, for-each-repo could do repo discovery itself on the paths
> it is passed, before calling sub-programs. That's a bigger change, but
> possibly it could or should be flagging an error for some cases? I
> dunno.
I'm surprised that passing '-C <repo>' doesn't already overwrite these
variables but I suppose environment variables override arguments in this
case. (This is the root of the bug.)
Thanks,
-Stolee
next prev parent reply other threads:[~2026-02-24 12:11 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 3:32 [PATCH 0/2] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-02-24 3:32 ` [PATCH 1/2] for-each-repo: stop using the_repository Derrick Stolee via GitGitGadget
2026-02-24 9:18 ` Patrick Steinhardt
2026-02-24 12:07 ` Derrick Stolee
2026-02-24 3:32 ` [PATCH 2/2] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-02-24 3:34 ` Eric Sunshine
2026-02-24 9:18 ` Jeff King
2026-02-24 12:11 ` Derrick Stolee [this message]
2026-02-25 13:23 ` Jeff King
2026-02-24 9:18 ` Patrick Steinhardt
2026-02-24 21:35 ` [PATCH v2 0/2] " Derrick Stolee via GitGitGadget
2026-02-24 21:35 ` [PATCH v2 1/2] for-each-repo: test outside of repo context Derrick Stolee via GitGitGadget
2026-02-24 21:35 ` [PATCH v2 2/2] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-02-24 21:47 ` Junio C Hamano
2026-02-25 11:44 ` Derrick Stolee
2026-02-25 13:13 ` Jeff King
2026-02-26 15:29 ` Derrick Stolee
2026-02-26 16:21 ` Junio C Hamano
2026-02-26 18:14 ` Phillip Wood
2026-02-27 19:41 ` Junio C Hamano
2026-02-27 22:28 ` Derrick Stolee
2026-02-27 22:45 ` Jeff King
2026-02-27 22:42 ` Jeff King
2026-03-02 15:31 ` Derrick Stolee
2026-03-02 18:09 ` Jeff King
2026-03-02 15:36 ` [PATCH v3 0/4] " Derrick Stolee via GitGitGadget
2026-03-02 15:36 ` [PATCH v3 1/4] for-each-repo: test outside of repo context Derrick Stolee via GitGitGadget
2026-03-02 17:56 ` Jeff King
2026-03-02 18:31 ` Junio C Hamano
2026-03-02 18:36 ` Derrick Stolee
2026-03-02 15:36 ` [PATCH v3 2/4] run-command: extract clear_local_repo_env helper Derrick Stolee via GitGitGadget
2026-03-02 18:03 ` Jeff King
2026-03-02 18:35 ` Junio C Hamano
2026-03-02 18:37 ` Derrick Stolee
2026-03-02 15:36 ` [PATCH v3 3/4] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-03-02 18:06 ` Jeff King
2026-03-02 18:39 ` Derrick Stolee
2026-03-02 21:32 ` Junio C Hamano
2026-03-02 15:36 ` [PATCH v3 4/4] for-each-repo: simplify passing of parameters Derrick Stolee via GitGitGadget
2026-03-02 18:06 ` Jeff King
2026-03-03 17:31 ` [PATCH v4 0/4] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-03-03 17:31 ` [PATCH v4 1/4] for-each-repo: test outside of repo context Derrick Stolee via GitGitGadget
2026-03-03 17:31 ` [PATCH v4 2/4] run-command: extract sanitize_repo_env helper Derrick Stolee via GitGitGadget
2026-03-03 17:31 ` [PATCH v4 3/4] for-each-repo: work correctly in a worktree Derrick Stolee via GitGitGadget
2026-03-03 17:31 ` [PATCH v4 4/4] for-each-repo: simplify passing of parameters Derrick Stolee via GitGitGadget
2026-03-05 1:20 ` [PATCH v4 0/4] for-each-repo: work correctly in a worktree Jeff King
2026-03-05 6:14 ` Patrick Steinhardt
2026-03-05 17:23 ` Derrick Stolee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fce7662f-d741-41e1-93dd-f82e65e04f41@gmail.com \
--to=stolee@gmail.com \
--cc=fastcat@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox