[PATCH 2/2] for-each-repo: work correctly in a worktree
- From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Feb 24, 2026, 03:32 UTC
- Message-ID
- <a47f9e9386badd83f0f5820f33f5eed68ca5fd82.1771903950.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2056.git.1771903950.gitgitgadget@gmail.com>
From: Derrick Stolee <stolee@gmail.com>
When run in a worktree, the GIT_DIR directory is set in a different way than in a typical repository. Show this by updating t0068 to include a worktree and add a test that runs from that worktree. This requires moving the repo.key config into a global config instead of the base test 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.
Reported-by: Matthew Gabeler-Lee <fastcat@gmail.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> --- builtin/for-each-repo.c | 4 ++++ t/t0068-for-each-repo.sh | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c index 478ccf1287..f39b085d7d 100644 --- a/builtin/for-each-repo.c +++ b/builtin/for-each-repo.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "path.h" @@ -60,6 +61,9 @@ int cmd_for_each_repo(int argc, else if (err) return 0; + /* Be sure to not pass GIT_DIR to children. */ + unsetenv(GIT_DIR_ENVIRONMENT); + for (size_t i = 0; i < values->nr; i++) { int ret = run_command_on_repo(values->items[i].string, argc, argv); if (ret) { diff --git a/t/t0068-for-each-repo.sh b/t/t0068-for-each-repo.sh index f2f3e50031..00b72dcac1 100755 --- a/t/t0068-for-each-repo.sh +++ b/t/t0068-for-each-repo.sh @@ -7,12 +7,13 @@ test_description='git for-each-repo builtin' test_expect_success 'run based on configured value' ' git init one && git init two && - git init three && + 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 && @@ -22,6 +23,7 @@ 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 && @@ -30,7 +32,17 @@ test_expect_success 'run based on configured value' ' git -C three log -1 --pretty=format:%s >message && grep again message && git -C ~/four log -1 --pretty=format:%s >message && - grep again message + grep again message && + + git -C three for-each-repo --config=run.key -- commit --allow-empty -m "ran from worktree" && + git -C one log -1 --pretty=format:%s >message && + grep worktree message && + git -C two log -1 --pretty=format:%s >message && + ! grep worktree message && + git -C three log -1 --pretty=format:%s >message && + grep worktree message && + git -C ~/four log -1 --pretty=format:%s >message && + grep worktree message ' test_expect_success 'do nothing on empty config' '
-- gitgitgadget