From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, fastcat@gmail.com,
Eric Sunshine <sunshine@sunshineco.com>,
Jeff King <peff@peff.net>, Patrick Steinhardt <ps@pks.im>,
Derrick Stolee <stolee@gmail.com>
Subject: [PATCH v2 0/2] for-each-repo: work correctly in a worktree
Date: Tue, 24 Feb 2026 21:35:22 +0000 [thread overview]
Message-ID: <pull.2056.v2.git.1771968924.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2056.git.1771903950.gitgitgadget@gmail.com>
This was reported by Matthew [1] and is a quick fix.
[1]
https://lore.kernel.org/git/CABpCjbY=wpStuhxqRJ5TSNV3A-CmN-g-xZGJOQGSSv3GYhs2fQ@mail.gmail.com/
I also took the liberty of removing the_repository as I wanted to make sure
that wasn't involved here.
Thanks, -Stolee
Derrick Stolee (2):
for-each-repo: test outside of repo context
for-each-repo: work correctly in a worktree
builtin/for-each-repo.c | 33 ++++++++++++++++++++++++++++++---
t/t0068-for-each-repo.sh | 33 ++++++++++++++++++++++++---------
2 files changed, 54 insertions(+), 12 deletions(-)
base-commit: 67ad42147a7acc2af6074753ebd03d904476118f
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2056%2Fderrickstolee%2Ffor-each-repo-in-gitdir-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2056/derrickstolee/for-each-repo-in-gitdir-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2056
Range-diff vs v1:
1: 86cd83f65b < -: ---------- for-each-repo: stop using the_repository
-: ---------- > 1: 6e9d4f3029 for-each-repo: test outside of repo context
2: a47f9e9386 ! 2: 4e3f4aa6cd for-each-repo: work correctly in a worktree
@@ Commit message
repository's local config (demonstrating that it worked with
non-worktree Git repositories).
- The fix is simple: unset the environment variable before looping over
- the repos.
+ We need to be careful to unset the local Git environment variables and
+ let the child process rediscover them, while also reinstating those
+ variables in the parent process afterwards. Update run_command_on_repo()
+ to store, unset, then reset the non-NULL variables.
Reported-by: Matthew Gabeler-Lee <fastcat@gmail.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
## builtin/for-each-repo.c ##
@@
+
#include "builtin.h"
#include "config.h"
+#include "environment.h"
#include "gettext.h"
#include "parse-options.h"
#include "path.h"
-@@ builtin/for-each-repo.c: int cmd_for_each_repo(int argc,
- else if (err)
- return 0;
+@@ builtin/for-each-repo.c: static const char * const for_each_repo_usage[] = {
+
+ static int run_command_on_repo(const char *path, int argc, const char ** argv)
+ {
+- int i;
++ int res;
+ struct child_process child = CHILD_PROCESS_INIT;
++ char **envvars;
++ size_t envvar_nr = 0;
+ char *abspath = interpolate_path(path, 0);
+
++ while (local_repo_env[envvar_nr])
++ envvar_nr++;
++
++ CALLOC_ARRAY(envvars, envvar_nr);
++
++ for (size_t i = 0; i < envvar_nr; i++) {
++ envvars[i] = getenv(local_repo_env[i]);
++
++ if (envvars[i]) {
++ unsetenv(local_repo_env[i]);
++ envvars[i] = xstrdup(envvars[i]);
++ }
++ }
++
+ child.git_cmd = 1;
+ strvec_pushl(&child.args, "-C", abspath, NULL);
+
+- for (i = 0; i < argc; i++)
++ for (int i = 0; i < argc; i++)
+ strvec_push(&child.args, argv[i]);
-+ /* Be sure to not pass GIT_DIR to children. */
-+ unsetenv(GIT_DIR_ENVIRONMENT);
+ free(abspath);
+
+- return run_command(&child);
++ res = run_command(&child);
++
++ for (size_t i = 0; i < envvar_nr; i++) {
++ if (envvars[i]) {
++ setenv(local_repo_env[i], envvars[i], 1);
++ free(envvars[i]);
++ }
++ }
+
- for (size_t i = 0; i < values->nr; i++) {
- int ret = run_command_on_repo(values->items[i].string, argc, argv);
- if (ret) {
++ free(envvars);
++ return res;
+ }
+
+ int cmd_for_each_repo(int argc,
## t/t0068-for-each-repo.sh ##
-@@ t/t0068-for-each-repo.sh: test_description='git for-each-repo builtin'
+@@ t/t0068-for-each-repo.sh: TEST_NO_CREATE_REPO=1
test_expect_success 'run based on configured value' '
git init one &&
git init two &&
@@ t/t0068-for-each-repo.sh: test_description='git for-each-repo builtin'
+ git -C two worktree add --orphan ../three &&
git init ~/four &&
git -C two commit --allow-empty -m "DID NOT RUN" &&
-- git config run.key "$TRASH_DIRECTORY/one" &&
-- git config --add run.key "$TRASH_DIRECTORY/three" &&
-- git config --add run.key "~/four" &&
-+ git config --global run.key "$TRASH_DIRECTORY/one" &&
-+ git config --global --add run.key "$TRASH_DIRECTORY/three" &&
-+ git config --global --add run.key "~/four" &&
-+
- git for-each-repo --config=run.key commit --allow-empty -m "ran" &&
- git -C one log -1 --pretty=format:%s >message &&
- grep ran message &&
-@@ t/t0068-for-each-repo.sh: test_expect_success 'run based on configured value' '
- grep ran message &&
- git -C ~/four log -1 --pretty=format:%s >message &&
- grep ran message &&
-+
- git for-each-repo --config=run.key -- commit --allow-empty -m "ran again" &&
- git -C one log -1 --pretty=format:%s >message &&
- grep again message &&
+ git config --global run.key "$TRASH_DIRECTORY/one" &&
@@ t/t0068-for-each-repo.sh: test_expect_success 'run based on configured value' '
git -C three log -1 --pretty=format:%s >message &&
grep again message &&
--
gitgitgadget
next prev parent reply other threads:[~2026-02-24 21:35 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
2026-02-25 13:23 ` Jeff King
2026-02-24 9:18 ` Patrick Steinhardt
2026-02-24 21:35 ` Derrick Stolee via GitGitGadget [this message]
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=pull.2056.v2.git.1771968924.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=fastcat@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
--cc=ps@pks.im \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.