From 4179b4897f2de28858acaebd6382c06c91532e98 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 19 Apr 2021 14:31:16 +0200 Subject: config: allow overriding of global and system configuration In order to have git run in a fully controlled environment without any misconfiguration, it may be desirable for users or scripts to override global- and system-level configuration files. We already have a way of doing this, which is to unset both HOME and XDG_CONFIG_HOME environment variables and to set `GIT_CONFIG_NOGLOBAL=true`. This is quite kludgy, and unsetting the first two variables likely has an impact on other executables spawned by such a script. The obvious way to fix this would be to introduce `GIT_CONFIG_NOGLOBAL` as an equivalent to `GIT_CONFIG_NOSYSTEM`. But in the past, it has turned out that this design is inflexible: we cannot test system-level parsing of the git configuration in our test harness because there is no way to change its location, so all tests run with `GIT_CONFIG_NOSYSTEM` set. Instead of doing the same mistake with `GIT_CONFIG_NOGLOBAL`, introduce two new variables `GIT_CONFIG_GLOBAL` and `GIT_CONFIG_SYSTEM`: - If unset, git continues to use the usual locations. - If set to a specific path, we skip reading the normal configuration files and instead take the path. By setting the path to `/dev/null`, no configuration will be loaded for the respective level. This implements the usecase where we want to execute code in a sanitized environment without any potential misconfigurations via `/dev/null`, but is more flexible and allows for more usecases than simply adding `GIT_CONFIG_NOGLOBAL`. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- t/t1300-config.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 't/t1300-config.sh') diff --git a/t/t1300-config.sh b/t/t1300-config.sh index e0dd5d65ce..0f92dfe6fb 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -2059,6 +2059,92 @@ test_expect_success '--show-scope with --show-origin' ' test_cmp expect output ' +test_expect_success 'override global and system config' ' + test_when_finished rm -f "$HOME"/.config/git && + + cat >"$HOME"/.gitconfig <<-EOF && + [home] + config = true + EOF + mkdir -p "$HOME"/.config/git && + cat >"$HOME"/.config/git/config <<-EOF && + [xdg] + config = true + EOF + cat >.git/config <<-EOF && + [local] + config = true + EOF + cat >custom-global-config <<-EOF && + [global] + config = true + EOF + cat >custom-system-config <<-EOF && + [system] + config = true + EOF + + cat >expect <<-EOF && + global xdg.config=true + global home.config=true + local local.config=true + EOF + git config --show-scope --list >output && + test_cmp expect output && + + sane_unset GIT_CONFIG_NOSYSTEM && + + cat >expect <<-EOF && + system system.config=true + global global.config=true + local local.config=true + EOF + GIT_CONFIG_SYSTEM=custom-system-config GIT_CONFIG_GLOBAL=custom-global-config \ + git config --show-scope --list >output && + test_cmp expect output && + + cat >expect <<-EOF && + local local.config=true + EOF + GIT_CONFIG_SYSTEM=/dev/null GIT_CONFIG_GLOBAL=/dev/null git config --show-scope --list >output && + test_cmp expect output +' + +test_expect_success 'override global and system config with missing file' ' + test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config --global --list && + test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config --system --list && + GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=does-not-exist git version +' + +test_expect_success 'system override has no effect with GIT_CONFIG_NOSYSTEM' ' + # `git config --system` has different semantics compared to other + # commands as it ignores GIT_CONFIG_NOSYSTEM. We thus test whether the + # variable has an effect via a different proxy. + cat >alias-config <<-EOF && + [alias] + hello-world = !echo "hello world" + EOF + test_must_fail env GIT_CONFIG_NOSYSTEM=true GIT_CONFIG_SYSTEM=alias-config \ + git hello-world && + GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=alias-config \ + git hello-world >actual && + echo "hello world" >expect && + test_cmp expect actual +' + +test_expect_success 'write to overridden global and system config' ' + cat >expect < Date: Fri, 23 Apr 2021 07:47:15 +0200 Subject: t1300: fix unset of GIT_CONFIG_NOSYSTEM leaking into subsequent tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to test whether the new GIT_CONFIG_SYSTEM environment variable behaves as expected, we unset GIT_CONFIG_NOSYSTEM in one of our tests in t1300. But because tests are not executed in a subshell, this unset leaks into all subsequent tests and may thus cause them to fail in some environments. These failures are easily reproducable with `make prefix=/root test`. Fix the issue by not using `sane_unset GIT_CONFIG_NOSYSTEM`, but instead just manually add it to the environment of the two command invocations which need it. Reported-by: SZEDER Gábor Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- t/t1300-config.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 't/t1300-config.sh') diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 0f92dfe6fb..ec599baeba 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -2092,21 +2092,20 @@ test_expect_success 'override global and system config' ' git config --show-scope --list >output && test_cmp expect output && - sane_unset GIT_CONFIG_NOSYSTEM && - cat >expect <<-EOF && system system.config=true global global.config=true local local.config=true EOF - GIT_CONFIG_SYSTEM=custom-system-config GIT_CONFIG_GLOBAL=custom-global-config \ + GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=custom-system-config GIT_CONFIG_GLOBAL=custom-global-config \ git config --show-scope --list >output && test_cmp expect output && cat >expect <<-EOF && local local.config=true EOF - GIT_CONFIG_SYSTEM=/dev/null GIT_CONFIG_GLOBAL=/dev/null git config --show-scope --list >output && + GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=/dev/null GIT_CONFIG_GLOBAL=/dev/null \ + git config --show-scope --list >output && test_cmp expect output ' -- cgit v1.2.3