I've read the git-config
docs and checked SO questsions here and here, but I cannot seem to find an answer.
I am writing a custom tool for Git and I would like to test it. I would like to backup my global and system Git config files and then write to new config files in my tests so I don't override what I already have in place (FYI, I am testing against multiple different portable (locally built) versions of Git both for Linux and Windows in a subdirectory of my project).
My initial thought would have simply been to use cp
:
# Backup the system config file
# NOTE: How do I test this automatically? (I have to enter root password)...
sudo cp ${PREFIX}/etc/gitconfig ${PREFIX}/etc/gitconfig.bak
# Backup the global config file
cp ~/.gitconfig ~/.gitconfig.bak
# DO MY TESTS HERE
# Restore system config file and delete backup
sudo cp ${PREFIX}/etc/gitconfig.bak ${PREFIX}/etc/gitconfig
sudo rm ${PREFIX}/etc/gitconfig.bak
# Restore global config file and delete backup
cp ~/.gitconfig.bak ~/.gitconfig
rm ~/.gitconfig.bak
However, I don't see this being done in t/t1300-config.sh
(as of the time of this writing, the current version of the master repo is v2.32). The closest thing being done that I see is this (lines 2147-2158):
test_expect_success 'write to overridden global and system config' '
cat >expect <<EOF &&
[config]
key = value
EOF
GIT_CONFIG_GLOBAL=write-to-global git config --global config.key value &&
test_cmp expect write-to-global &&
GIT_CONFIG_SYSTEM=write-to-system git config --system config.key value &&
test_cmp expect write-to-system
'
I don't understand what is going on here. The Git Docs explain GIT_CONFIG
is an environment variable that can be set to override the git config
file, but if I enter the above commands in my terminal, no file write-to-global
or write-to-system
is created (and these are not functions in the test script either).
Can someone explain how to properly use the GIT_CONFIG
environment variable and what's the right way to do this in a test script?
The environment GIT_CONFIG
variable is ancient, predating Git 1.5.3, where git config --file
was added. It still exists as a way to trick other Git commands into acting as if they were given a --file
argument to pass to git config
. It probably should be removed, but, well, Git maintains a lot of backward compatibility! It reminds me of the old joke about Intel putting the "backwards" in "backwards compatible"...
Until Git 1.8.2, git clone
relied on setting GIT_CONFIG
internally, then unsetting it. It looks (from the linked questions and their answers) like there may still be some leftovers here.
(I found the above two items in the release notes. All added snark is my own though.)
Git version 2.31.0 added new GIT_CONFIG_COUNT
and GIT_CONFIG_KEY_$i
, GIT_CONFIG_VALUE_$i
environment variables. They seem to be intended to add some degree of security, to avoid passing -c
arguments that can be read from ps
reading the command line. But since ps
can (at least on many systems) also read environment variables, I think this "security" is mostly illusory.
Can someone explain how to properly use the GIT_CONFIG environment variable and what's the right way to do this in a test script?
Unless you need to put configurations somewhere other than .git/config
, the short answer is "don't use this at all". If you want to make sure that the system configuration file does not affect you, set GIT_CONFIG_NOSYSTEM
(to any value although I'd use true
just for consistency). You can then set $HOME
and $XCD_CONFIG_HOME
to make other Git commands look for the global Git configuration file in a predictable location, and of course the local and per-work-tree configuration files' locations are predictable already.
This method is a bit clumsy.
... in
t/t1300-config.sh
This very recently (not in any release version, but in both 2.32.0 release candidates) gained the new GIT_CONFIG_SYSTEM
and GIT_CONFIG_GLOBAL
variables. They're intended to fix some of the clumsiness of the above. Unless you're building the various release candidates or other cutting-edge branches, you won't have this at all. But this does seem to me a better way to deal with all of this.