In addition of git config -l --show-origin
, that I presented here, with git 2.8 (March 2016), you now have, with Git 2.26 (Q1 2020)
git config -l --show-scope
# you can combine both options:
git config -l --show-origin --show-scope
git config
learned to show in which "scope
", in addition to in which file, each config setting comes from.
See commit 145d59f, commit 9a83d08, commit e37efa4, commit 5c105a8, commit 6766e41, commit 6dc905d, commit a5cb420 (10 Feb 2020), and commit 417be08, commit 3de7ee3, commit 329e6ec (24 Jan 2020) by Matthew Rogers (ROGERSM94
).
(Merged by Junio C Hamano -- gitster
-- in commit 5d55554, 17 Feb 2020)
config
: add '--show-scope' to print the scope of a config value
Signed-off-by: Matthew Rogers
When a user queries config values with --show-origin
, often it's difficult to determine what the actual "scope
" (local
, global
, etc.) of a given value is based on just the origin file.
Teach 'git config' the '--show-scope
' option to print the scope of all displayed config values.
Note that we should never see anything of "submodule" scope as that is only ever used by submodule-config.c
when parsing the '.gitmodules' file.
Example:
git config -l --show-scope
global user.global=true
global user.override=global
global include.path=$INCLUDE_DIR/absolute.include
global user.absolute=include
local user.local=true
local user.override=local
local include.path=../include/relative.include
local user.relative=include
That allows you to quickly distinguish between:
- Protected configuration: '
system
', 'global
', and 'command
' scopes.
- standard configuration:
local
to the repository.
This is introduced with Git 2.38 (Q3 2022):
See commit 8d1a744, commit 6061601, commit 5b3c650, commit 779ea93, commit 5f5af37 (14 Jul 2022) by Glen Choo (chooglen
).
(Merged by Junio C Hamano -- gitster
-- in commit 18bbc79, 22 Jul 2022)
Documentation
: define protected configuration
Signed-off-by: Glen Choo
For security reasons, there are config variables that are only trusted when they are specified in certain configuration scopes, which are sometimes referred to on-list as 'protected configuration' (as in this thread).
A future commit will introduce another such variable (safe.bareRepository
), so let's define our terms so that we can have consistent documentation and implementation.
In our documentation, define 'protected configuration' as the system
, global
and command
config scopes.
As a shorthand, I will refer to variables that are only respected in protected configuration as 'protected configuration only', but this term is not used in the documentation.
This definition of protected configuration is based on whether or not Git can reasonably protect the user by ignoring the configuration scope:
- System, global and command line config are considered protected because an attacker who has control over any of those can do plenty of harm without Git, so we gain very little by ignoring those scopes.
- On the other hand, local (and similarly, worktree) config are not considered protected because it is relatively easy for an attacker to control local config, e.g.:
- On some shared user environments, a non-admin attacker can create a repository high up the directory hierarchy (e.g.
C:\.git
on Windows), and a user may accidentally use it when their PS1 automatically invokes "git" commands.
safe.directory
prevents attacks of this form by making sure that the user intended to use the shared repository.
It obviously shouldn't be read from the repository, because that would end up trusting the repository that Git was supposed to reject.
- "
git upload-pack
"(man) is expected to run in repositories that may not be controlled by the user.
We cannot ignore all config in that repository (because "git upload-pack
" would fail), but we can limit the risks by ignoring uploadpack.packObjectsHook
.
Only uploadpack.packObjectsHook
is 'protected configuration only'.
The following variables are intentionally excluded:
safe.directory
should be 'protected configuration only', but it does not technically fit the definition because it is not respected in the "command" scope.
A future commit will fix this.
trace2.*
happens to read the same scopes as safe.directory
because they share an implementation.
However, this is not for security reasons; it is because we want to start tracing so early that repository-level config and "-c
" are not available.
This requirement is unique to trace2.*
, so it does not makes sense for protected configuration to be subject to the same constraints.
git config
now includes in its man page:
Protected configuration
Protected configuration refers to the 'system
', 'global
', and 'command
' scopes.
For security reasons, certain options are only respected when they are specified in protected configuration, and ignored otherwise.
Git treats these scopes as if they are controlled by the user or a trusted administrator. This is because an attacker who controls these scopes can do substantial harm without using Git, so it is assumed that the user's environment protects these scopes against attackers.
With Git 2.39 (Q4 2022), allow configuration files in "protected" scopes to include other configuration files.
See commit ecec57b (13 Oct 2022) by Glen Choo (chooglen
).
(Merged by Junio C Hamano -- gitster
-- in commit 777f548, 25 Oct 2022)
config
: respect includes
in protected config
Signed-off-by: Glen Choo
Protected config is implemented by reading a fixed set of paths, which ignores config [include]
-s.
Replace this implementation with a call to config_with_options()
, which handles [include]
-s and saves us from duplicating the logic of 1) identifying which paths to read and 2) reading command line config.
As a result, git_configset_add_parameters()
is unused, so remove it.
It was introduced alongside protected config in 5b3c650 ("config
: learn git_protected_config()
", 2022-07-14, Git v2.38.0-rc0 -- merge listed in batch #6) as a way to handle command line config.
git config --list --show-origin
, you won't have to guess which git config is where. See my answer below – Jahnke