public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
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>,
	Derrick Stolee <stolee@gmail.com>
Subject: [PATCH v2 2/2] for-each-repo: work correctly in a worktree
Date: Tue, 24 Feb 2026 21:35:24 +0000	[thread overview]
Message-ID: <4e3f4aa6cd36f779c6c1d6b4f30bb68ed807b9da.1771968924.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2056.v2.git.1771968924.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).

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  | 33 ++++++++++++++++++++++++++++++---
 t/t0068-for-each-repo.sh | 14 ++++++++++++--
 2 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index 325a7925f1..3f3e71979c 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -2,6 +2,7 @@
 
 #include "builtin.h"
 #include "config.h"
+#include "environment.h"
 #include "gettext.h"
 #include "parse-options.h"
 #include "path.h"
@@ -15,19 +16,45 @@ 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]);
 
 	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]);
+		}
+	}
+
+	free(envvars);
+	return res;
 }
 
 int cmd_for_each_repo(int argc,
diff --git a/t/t0068-for-each-repo.sh b/t/t0068-for-each-repo.sh
index 512af34c82..d55557a934 100755
--- a/t/t0068-for-each-repo.sh
+++ b/t/t0068-for-each-repo.sh
@@ -10,7 +10,7 @@ TEST_NO_CREATE_REPO=1
 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 --global run.key "$TRASH_DIRECTORY/one" &&
@@ -35,7 +35,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

  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 ` [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   ` Derrick Stolee via GitGitGadget [this message]
2026-02-24 21:47     ` [PATCH v2 2/2] for-each-repo: work correctly in a worktree 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=4e3f4aa6cd36f779c6c1d6b4f30bb68ed807b9da.1771968924.git.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox