Skip to content

Commit 0316174

Browse files
committed
Merge branch 'ds/for-each-repo-w-worktree'
"git for-each-repo" started from a secondary worktree did not work as expected, which has been corrected. * ds/for-each-repo-w-worktree: for-each-repo: simplify passing of parameters for-each-repo: work correctly in a worktree run-command: extract sanitize_repo_env helper for-each-repo: test outside of repo context
2 parents 67006b9 + e87493b commit 0316174

4 files changed

Lines changed: 77 additions & 24 deletions

File tree

builtin/for-each-repo.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "builtin.h"
44
#include "config.h"
5+
#include "environment.h"
56
#include "gettext.h"
67
#include "parse-options.h"
78
#include "path.h"
@@ -13,17 +14,16 @@ static const char * const for_each_repo_usage[] = {
1314
NULL
1415
};
1516

16-
static int run_command_on_repo(const char *path, int argc, const char ** argv)
17+
static int run_command_on_repo(const char *path, const char **argv)
1718
{
18-
int i;
1919
struct child_process child = CHILD_PROCESS_INIT;
2020
char *abspath = interpolate_path(path, 0);
2121

22+
sanitize_repo_env(&child.env);
23+
2224
child.git_cmd = 1;
2325
strvec_pushl(&child.args, "-C", abspath, NULL);
24-
25-
for (i = 0; i < argc; i++)
26-
strvec_push(&child.args, argv[i]);
26+
strvec_pushv(&child.args, argv);
2727

2828
free(abspath);
2929

@@ -63,7 +63,7 @@ int cmd_for_each_repo(int argc,
6363
return 0;
6464

6565
for (size_t i = 0; i < values->nr; i++) {
66-
int ret = run_command_on_repo(values->items[i].string, argc, argv);
66+
int ret = run_command_on_repo(values->items[i].string, argv);
6767
if (ret) {
6868
if (!keep_going)
6969
return ret;

run-command.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,7 @@ int run_auto_maintenance(int quiet)
19711971
return run_command(&maint);
19721972
}
19731973

1974-
void prepare_other_repo_env(struct strvec *env, const char *new_git_dir)
1974+
void sanitize_repo_env(struct strvec *env)
19751975
{
19761976
const char * const *var;
19771977

@@ -1980,6 +1980,11 @@ void prepare_other_repo_env(struct strvec *env, const char *new_git_dir)
19801980
strcmp(*var, CONFIG_COUNT_ENVIRONMENT))
19811981
strvec_push(env, *var);
19821982
}
1983+
}
1984+
1985+
void prepare_other_repo_env(struct strvec *env, const char *new_git_dir)
1986+
{
1987+
sanitize_repo_env(env);
19831988
strvec_pushf(env, "%s=%s", GIT_DIR_ENVIRONMENT, new_git_dir);
19841989
}
19851990

run-command.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -530,13 +530,18 @@ struct run_process_parallel_opts
530530
*/
531531
void run_processes_parallel(const struct run_process_parallel_opts *opts);
532532

533+
/**
534+
* Unset all local-repo GIT_* variables in env; see local_repo_env in
535+
* environment.h. GIT_CONFIG_PARAMETERS and GIT_CONFIG_COUNT are preserved
536+
* to pass -c and --config-env options from the parent process.
537+
*/
538+
void sanitize_repo_env(struct strvec *env);
539+
533540
/**
534541
* Convenience function which prepares env for a command to be run in a
535-
* new repo. This adds all GIT_* environment variables to env with the
536-
* exception of GIT_CONFIG_PARAMETERS and GIT_CONFIG_COUNT (which cause the
537-
* corresponding environment variables to be unset in the subprocess) and adds
538-
* an environment variable pointing to new_git_dir. See local_repo_env in
539-
* environment.h for more information.
542+
* new repo. This removes variables pointing to the local repository (using
543+
* sanitize_repo_env() above), and adds an environment variable pointing to
544+
* new_git_dir.
540545
*/
541546
void prepare_other_repo_env(struct strvec *env, const char *new_git_dir);
542547

t/t0068-for-each-repo.sh

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22

33
test_description='git for-each-repo builtin'
44

5+
# We need to test running 'git for-each-repo' outside of a repo context.
6+
TEST_NO_CREATE_REPO=1
7+
58
. ./test-lib.sh
69

710
test_expect_success 'run based on configured value' '
8-
git init one &&
9-
git init two &&
10-
git init three &&
11-
git init ~/four &&
11+
git init --initial-branch=one one &&
12+
git init --initial-branch=two two &&
13+
git -C two worktree add --orphan ../three &&
14+
git -C three checkout -b three &&
15+
git init --initial-branch=four ~/four &&
16+
1217
git -C two commit --allow-empty -m "DID NOT RUN" &&
13-
git config run.key "$TRASH_DIRECTORY/one" &&
14-
git config --add run.key "$TRASH_DIRECTORY/three" &&
15-
git config --add run.key "~/four" &&
18+
git config --global run.key "$TRASH_DIRECTORY/one" &&
19+
git config --global --add run.key "$TRASH_DIRECTORY/three" &&
20+
git config --global --add run.key "~/four" &&
21+
1622
git for-each-repo --config=run.key commit --allow-empty -m "ran" &&
1723
git -C one log -1 --pretty=format:%s >message &&
1824
grep ran message &&
@@ -22,6 +28,7 @@ test_expect_success 'run based on configured value' '
2228
grep ran message &&
2329
git -C ~/four log -1 --pretty=format:%s >message &&
2430
grep ran message &&
31+
2532
git for-each-repo --config=run.key -- commit --allow-empty -m "ran again" &&
2633
git -C one log -1 --pretty=format:%s >message &&
2734
grep again message &&
@@ -30,7 +37,43 @@ test_expect_success 'run based on configured value' '
3037
git -C three log -1 --pretty=format:%s >message &&
3138
grep again message &&
3239
git -C ~/four log -1 --pretty=format:%s >message &&
33-
grep again message
40+
grep again message &&
41+
42+
git -C three for-each-repo --config=run.key -- \
43+
commit --allow-empty -m "ran from worktree" &&
44+
git -C one log -1 --pretty=format:%s >message &&
45+
test_grep "ran from worktree" message &&
46+
git -C two log -1 --pretty=format:%s >message &&
47+
test_grep ! "ran from worktree" message &&
48+
git -C three log -1 --pretty=format:%s >message &&
49+
test_grep "ran from worktree" message &&
50+
git -C ~/four log -1 --pretty=format:%s >message &&
51+
test_grep "ran from worktree" message &&
52+
53+
# Test running with config values set by environment
54+
cat >expect <<-EOF &&
55+
ran from worktree (HEAD -> refs/heads/one)
56+
ran from worktree (HEAD -> refs/heads/three)
57+
ran from worktree (HEAD -> refs/heads/four)
58+
EOF
59+
60+
GIT_CONFIG_PARAMETERS="${SQ}log.decorate=full${SQ}" \
61+
git -C three for-each-repo --config=run.key -- log --format="%s%d" -1 >out &&
62+
test_cmp expect out &&
63+
64+
cat >test-config <<-EOF &&
65+
[run]
66+
key = $(pwd)/one
67+
key = $(pwd)/three
68+
key = $(pwd)/four
69+
70+
[log]
71+
decorate = full
72+
EOF
73+
74+
GIT_CONFIG_GLOBAL="$(pwd)/test-config" \
75+
git -C three for-each-repo --config=run.key -- log --format="%s%d" -1 >out &&
76+
test_cmp expect out
3477
'
3578

3679
test_expect_success 'do nothing on empty config' '
@@ -46,7 +89,7 @@ test_expect_success 'error on bad config keys' '
4689
'
4790

4891
test_expect_success 'error on NULL value for config keys' '
49-
cat >>.git/config <<-\EOF &&
92+
cat >>.gitconfig <<-\EOF &&
5093
[empty]
5194
key
5295
EOF
@@ -59,8 +102,8 @@ test_expect_success 'error on NULL value for config keys' '
59102
'
60103

61104
test_expect_success '--keep-going' '
62-
git config keep.going non-existing &&
63-
git config --add keep.going . &&
105+
git config --global keep.going non-existing &&
106+
git config --global --add keep.going one &&
64107
65108
test_must_fail git for-each-repo --config=keep.going \
66109
-- branch >out 2>err &&
@@ -70,7 +113,7 @@ test_expect_success '--keep-going' '
70113
test_must_fail git for-each-repo --config=keep.going --keep-going \
71114
-- branch >out 2>err &&
72115
test_grep "cannot change to .*non-existing" err &&
73-
git branch >expect &&
116+
git -C one branch >expect &&
74117
test_cmp expect out
75118
'
76119

0 commit comments

Comments
 (0)