public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Eric Sunshine <sunshine@sunshineco.com>
Cc: Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>,
	git@vger.kernel.org, gitster@pobox.com, fastcat@gmail.com,
	Derrick Stolee <stolee@gmail.com>
Subject: Re: [PATCH 2/2] for-each-repo: work correctly in a worktree
Date: Tue, 24 Feb 2026 04:18:06 -0500	[thread overview]
Message-ID: <20260224091806.GC986367@coredump.intra.peff.net> (raw)
In-Reply-To: <CAPig+cQcpJu_Z6VXbn5cee2AHmPHQaOLG39HFRG1SGnnY1cWFA@mail.gmail.com>

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).

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.

-Peff

  reply	other threads:[~2026-02-24  9:18 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 [this message]
2026-02-24 12:11       ` Derrick Stolee
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=20260224091806.GC986367@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=fastcat@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=gitster@pobox.com \
    --cc=stolee@gmail.com \
    --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