2020-09-11 17:49:16 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='git for-each-repo builtin'
|
|
|
|
|
2022-11-08 18:17:39 +00:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2020-09-11 17:49:16 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'run based on configured value' '
|
|
|
|
git init one &&
|
|
|
|
git init two &&
|
|
|
|
git init three &&
|
2022-11-09 19:07:07 +00:00
|
|
|
git init ~/four &&
|
2020-09-11 17:49:16 +00:00
|
|
|
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" &&
|
2022-11-09 19:07:07 +00:00
|
|
|
git config --add run.key "~/four" &&
|
2020-09-11 17:49:16 +00:00
|
|
|
git for-each-repo --config=run.key commit --allow-empty -m "ran" &&
|
|
|
|
git -C one log -1 --pretty=format:%s >message &&
|
|
|
|
grep ran message &&
|
|
|
|
git -C two log -1 --pretty=format:%s >message &&
|
|
|
|
! grep ran message &&
|
|
|
|
git -C three log -1 --pretty=format:%s >message &&
|
|
|
|
grep ran message &&
|
2022-11-09 19:07:07 +00:00
|
|
|
git -C ~/four log -1 --pretty=format:%s >message &&
|
|
|
|
grep ran message &&
|
2020-09-11 17:49:16 +00:00
|
|
|
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 -C two log -1 --pretty=format:%s >message &&
|
|
|
|
! grep again message &&
|
|
|
|
git -C three log -1 --pretty=format:%s >message &&
|
2022-11-09 19:07:07 +00:00
|
|
|
grep again message &&
|
|
|
|
git -C ~/four log -1 --pretty=format:%s >message &&
|
2020-09-11 17:49:16 +00:00
|
|
|
grep again message
|
|
|
|
'
|
|
|
|
|
2021-01-08 02:30:46 +00:00
|
|
|
test_expect_success 'do nothing on empty config' '
|
|
|
|
# the whole thing would fail if for-each-ref iterated even
|
|
|
|
# once, because "git help --no-such-option" would fail
|
|
|
|
git for-each-repo --config=bogus.config -- help --no-such-option
|
|
|
|
'
|
|
|
|
|
2023-03-28 14:04:25 +00:00
|
|
|
test_expect_success 'error on bad config keys' '
|
|
|
|
test_expect_code 129 git for-each-repo --config=a &&
|
|
|
|
test_expect_code 129 git for-each-repo --config=a.b. &&
|
|
|
|
test_expect_code 129 git for-each-repo --config="'\''.b"
|
|
|
|
'
|
|
|
|
|
for-each-repo: with bad config, don't conflate <path> and <cmd>
Fix a logic error in 4950b2a2b5c (for-each-repo: run subcommands on
configured repos, 2020-09-11). Due to assuming that elements returned
from the repo_config_get_value_multi() call wouldn't be "NULL" we'd
conflate the <path> and <command> part of the argument list when
running commands.
As noted in the preceding commit the fix is to move to a safer
"*_string_multi()" version of the *_multi() API. This change is
separated from the rest because those all segfaulted. In this change
we ended up with different behavior.
When using the "--config=<config>" form we take each element of the
list as a path to a repository. E.g. with a configuration like:
[repo] list = /some/repo
We would, with this command:
git for-each-repo --config=repo.list status builtin
Run a "git status" in /some/repo, as:
git -C /some/repo status builtin
I.e. ask "status" to report on the "builtin" directory. But since a
configuration such as this would result in a "struct string_list *"
with one element, whose "string" member is "NULL":
[repo] list
We would, when constructing our command-line in
"builtin/for-each-repo.c"...
strvec_pushl(&child.args, "-C", path, NULL);
for (i = 0; i < argc; i++)
strvec_push(&child.args, argv[i]);
...have that "path" be "NULL", and as strvec_pushl() stops when it
sees NULL we'd end with the first "argv" element as the argument to
the "-C" option, e.g.:
git -C status builtin
I.e. we'd run the command "builtin" in the "status" directory.
In another context this might be an interesting security
vulnerability, but I think that this amounts to a nothingburger on
that front.
A hypothetical attacker would need to be able to write config for the
victim to run, if they're able to do that there's more interesting
attack vectors. See the "safe.directory" facility added in
8d1a7448206 (setup.c: create `safe.bareRepository`, 2022-07-14).
An even more unlikely possibility would be an attacker able to
generate the config used for "for-each-repo --config=<key>", but
nothing else (e.g. an automated system producing that list).
Even in that case the attack vector is limited to the user running
commands whose name matches a directory that's interesting to the
attacker (e.g. a "log" directory in a repository). The second
argument (if any) of the command is likely to make git die without
doing anything interesting (e.g. "-p" to "log", there being no "-p"
built-in command to run).
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-28 14:04:28 +00:00
|
|
|
test_expect_success 'error on NULL value for config keys' '
|
|
|
|
cat >>.git/config <<-\EOF &&
|
|
|
|
[empty]
|
|
|
|
key
|
|
|
|
EOF
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
error: missing value for '\''empty.key'\''
|
|
|
|
EOF
|
|
|
|
test_expect_code 129 git for-each-repo --config=empty.key 2>actual.raw &&
|
|
|
|
grep ^error actual.raw >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-09-11 17:49:16 +00:00
|
|
|
test_done
|