我的Git配置文件中的设置是从哪里来的?

105

我注意到当我运行git config -l时,core.autocrlf有两个列表。

$ git config -l
core.symlinks=false
core.autocrlf=false
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.name=name
user.email=email@example.com
core.autocrlf=true

从“user.name”开始往下数的最后三个是我在C:\users\username\.gitconfig文件中唯一存在的。其他的都从哪里来的?为什么core.autocrlf会列两次?

这是使用MSysGit 1.8.3版本,在Windows 7上也安装了Sourcetree。在Sourcetree中,我取消了“允许Sourcetree修改您的全局Git配置文件”的勾选。


22
注意:使用 Git 2.8(2016 年 3 月)和 git config --list --show-origin,您将不必猜测哪个 git 配置在哪里。请参见下面的我的答案 - VonC
10个回答

110

Git会检查四个位置的配置文件:

  1. 您机器上的系统 .gitconfig 文件。
  2. 您用户的 .gitconfig 文件位于 ~/.gitconfig
  3. 第二个用户特定的配置文件位于 $XDG_CONFIG_HOME/git/config 或者 $HOME/.config/git/config
  4. 本地仓库的配置文件 .git/config

这些设置按照以下顺序级联,每个文件都会添加或覆盖在其上面定义的设置。

  1. 系统配置。
  2. 用户配置。
  3. 仓库特定的配置。

您可以使用以下命令查看每个文件定义了什么:

# System, applies to entire machine and all users
$ git config --system --list
$ git config --system --edit

# User defined
$ git config --global --list
$ git config --global --edit

你可以通过打开该仓库的文件.git/config来查看仅特定于存储库的文件定义。

如果你在Windows上使用MSysGit,则可能会发现你的用户~/.gitconfig文件位于%homepath%指向的任何位置,如果你从Windows命令提示符使用echo %homepath%

根据git config的文档显示:

如果没有使用--file显式设置,那么git config将在四个文件中搜索配置选项:
  • $(prefix)/etc/gitconfig

    系统范围的配置文件。

  • $XDG_CONFIG_HOME/git/config

第二个用户特定的配置文件。如果$XDG_CONFIG_HOME未设置或为空,则将使用$HOME/.config/git/config。此文件中设置的任何单值变量都将被~/.gitconfig中的内容覆盖。如果您有时使用较旧版本的Git,则最好不要创建此文件,因为对此文件的支持是最近添加的。

  • ~/.gitconfig

用户特定的配置文件。也称为“全局”配置文件。

  • $GIT_DIR/config

    存储库特定的配置文件。

如果没有给出更多选项,则所有读取选项都将读取所有可用的文件。如果全局或系统范围的配置文件不可用,则它们将被忽略。如果存储库配置文件不可用或不可读,则git config将以非零错误代码退出。但是,在任何情况下都不会发出错误消息。

文件按照上述给定的顺序读取,后找到的最后一个值优先于早期读取的值。当取多个值时,则将使用所有文件中键的所有值。

所有写入选项默认情况下都将写入存储库特定的配置文件。请注意,这也会影响--replace-all--unset等选项。 git config 一次只会更改一个文件。

您可以通过命令行选项或环境变量覆盖这些规则。 --global--system选项将分别限制用于全局或系统范围文件的文件。 GIT_CONFIG环境变量具有类似的效果,但您可以指定任何文件名。


3
在使用msysgit的Windows系统中,“机器的系统.gitconfig文件”在哪里? - DanielSank
3
尝试使用C:\Program Files (x86)\Git\etc\gitconfig路径。不确定是否正确,请先尝试。 - user456814
@Cupcake:是的,就是那个文件。但出于某种原因,我无法修改它。有些进程一直在占用它……我也不知道是哪一个。不过没关系,因为我可以在用户级别配置中覆盖它。谢谢。 - DanielSank
对我来说,“HOME”环境变量没有设置(或者被设置为“/”),导致git在奇怪的地方寻找我的全局配置。使用$>setx HOME“%USERPROFILE%”解决了这个问题(因为USERPROFILE是一个现有的环境变量,指向正确的位置)。 - Paul Suart
2
当前的 Git 读取 C:\Program Files\Git\mingw64\etc\gitconfig - Kevin Smyth
1
@KevinSmyth,最近这个路径已经更改为C:\Program Files\Git\etc\gitconfig - Enrice

78

从2016年3月开始,使用Git 2.8后,您不再需要猜测哪个配置被设置在哪里了!

请参阅 提交 70bd879, 提交 473166b, 提交 7454ee3, 提交 7454ee3 (2016年2月19日), 提交 473166b, 提交 7454ee3 (2016年2月19日), 提交 7454ee3 (2016年2月19日) 和 提交 a0578e0 (2016年2月17日),作者为Lars Schneider (larsxschneider)
(由Junio C Hamano -- gitster --合并于提交dd0f567,2016年2月26日)

config: 添加 '--show-origin' 选项以打印配置值的来源

如果使用 'git config' 查询配置值(例如通过 --get--get-all--get-regexp--list 标志), 则有时很难找到定义这些值的配置文件。

通过添加 '--show-origin' 选项,教会 'git config' 打印每个打印值的源配置文件。

git config man page 现在将指出:

--show-origin:

增强所有查询的配置选项输出,包括原始类型(文件、标准输入、blob、命令行)和实际来源(如果适用,则为配置文件路径、ref 或 blob id)。

例如:

git config --list --show-origin

那将返回:

    file:$HOME/.gitconfig   user.global=true
    file:$HOME/.gitconfig   user.override=global
    file:$HOME/.gitconfig   include.path=$INCLUDE_DIR/absolute.include
    file:$INCLUDE_DIR/absolute.include  user.absolute=include
    file:.git/config    user.local=true
    file:.git/config    user.override=local
    file:.git/config    include.path=../include/relative.include
    file:.git/../include/relative.include   user.relative=include
    command line:   user.cmdline=true

对于一个设置,正如wisbucky所评论的:

git config --show-origin --get-all core.autocrlf

    file:"D:\\prgs\\git\\latest\\mingw64/etc/gitconfig"     true
    file:C:/Users/vonc/.gitconfig   false

在Git 2.26(2020年第一季度)中,您可以添加--show-scope选项

git config -l --show-origin --show-scope

1
谢天谢地。网上有很多不同的文章猜测git配置文件可能存储在哪里。所有文章都错过了一个可能存在于我的机器上的位置:c:\programdata\git\config。我不知道它为什么在那里,但我怀疑是Visual Studio的TFS集成。我花了太多时间寻找其他奇怪的位置:C:\program files\mingw64\etc.gitconfig和H:.gitconfig。感谢这个新命令。天啊。基督。 - RMuesi
我想知道为什么需要 user.cmdline=true 才能让 --show-origin 生效?此外,我注意到 --show-origin 需要紧接在 config 后面才能与 --get--get-all 一起使用。因此应该是 ... config --show-origin --get-all core.autocrlf - wisbucky
@wisbucky 同意:我会移除 -c 'user.cmdline=true' 这一部分,因为它似乎是指测试范围:https://github.com/git/git/blob/e629a7d28a405e48fae6b064a781a10e885159fc/t/helper/test-config.c#L39-L68 - VonC
@wisbucky,我已经包含了你的一个设置示例。 - VonC
@VonC,啊,看起来在Git 2.13中需要user.cmdline=true,但在Git 2.15中不再需要了。 - wisbucky
@RMuesi ProgramData配置文件是新的,目前还没有被广泛讨论。我只在https://dev59.com/YVwY5IYBdhLWcg3wPVtS上遇到过它。 - ojchase

10

在之前安装了Git for Windows并卸载后,我发现有一个配置文件安装在C:\Users\All Users\Git\config,这是一个系统级别的配置文件,会持续生效并影响任何未来的MinGW32 Git包(在我的情况下,我正在运行由公司提供的便携式MinGW32 Git包)。当我运行时:

git config --system --edit

它会显示位于 mingw32/etc/gitconfig 的系统配置文件,但仍会从第一个位置加载值。这会在尝试使用 Git LFS 时出现配置值冲突的警告。
WARNING: These git config values clash:
  git config "http.sslcainfo" = "C:/Users/foo/AppData/Local/Programs/Git/mingw64/ssl/certs/ca-bundle.crt"
  git config "http.sslcainfo" = "/ssl/certs/ca-bundle.crt"

(注:这也可能是LFS警告过于自信的情况, #861

这非常有用。我永远不会在所有用户中找到那个文件。你对它做了什么? - T3rm1
1
我从C:\Users\All Users\(一个别名为C:\ProgramData\)和C:\Users\foo\AppData\Local\Programs\中删除了'Git'文件夹,这样就删除了所有剩余的配置文件。 - jinxcat2008

6
除了我之前介绍的这里git config -l --show-origin,现在你还可以在Git 2.26(2020年第一季度)中使用。请注意,本文不提供解释,并保留HTML标签。
git config -l --show-scope

# you can combine both options:
git config -l --show-origin --show-scope

git config 已经学会显示每个配置设置来自哪个"scope",除了显示来自哪个文件。

请查看提交 145d59f, 提交 9a83d08, 提交 e37efa4, 提交 5c105a8, 提交 6766e41, 提交 6dc905d, 提交 a5cb420 (2020年2月10日),以及提交 417be08, 提交 3de7ee3, 提交 329e6ec (2020年1月24日) 由Matthew Rogers (ROGERSM94)完成。
(由Junio C Hamano -- gitster --提交 5d55554中合并,2020年2月17日)

config: 添加 '--show-scope' 选项以打印配置值的作用域

签署者:Matthew Rogers

当用户使用 --show-origin 查询配置值时,通常很难确定给定值的实际 "作用域"(localglobal 等)仅基于原始文件。

教 'git config' 使用 '--show-scope' 选项以打印所有显示的配置值的作用域。

请注意,我们永远不应该看到 "submodule" 作用域的任何内容,因为这只有在解析 '.gitmodules' 文件时由 submodule-config.c 使用。

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

这使您能够快速区分以下内容:

  • 受保护的配置:systemglobalcommand作用域。
  • 标准配置:local到存储库。

这是在Git 2.38(2022年第三季度)引入的:

请参阅由Glen Choo (chooglen)于2022年7月14日提交的提交8d1a744, 提交6061601, 提交5b3c650, 提交779ea93, 提交5f5af37
(由Junio C Hamano -- gitster --在2022年7月22日合并至提交18bbc79

文档: 定义受保护的配置

签名作者: Glen Choo

出于安全原因,有些配置变量只有在特定的配置范围内才被信任,有时在邮件列表上称之为“受保护的配置”(如此线程中所述)。将来的提交将引入另一个这样的变量(safe.bareRepository),因此让我们定义术语,以便我们可以有一致的文档和实现。
在我们的文档中,将“受保护的配置”定义为systemglobalcommand配置范围。简写为“仅受保护配置”,但不在文档中使用此术语。
受保护配置的定义基于Git是否可以通过忽略配置范围来合理地保护用户:
- 系统、全局和命令行配置被认为是受保护的,因为控制其中任何一个的攻击者都可以在没有Git的情况下造成很大的伤害,因此忽略这些范围几乎没有任何好处。 - 另一方面,本地(以及类似的工作树)配置不被认为是受保护的,因为攻击者相对容易控制本地配置,例如: - 在某些共享用户环境中,非管理员攻击者可以在目录层次结构中高处创建一个存储库(例如Windows上的C:\.git),当用户的PS1自动调用“git”命令时,用户可能会意外使用它。safe.directory通过确保用户打算使用共享存储库来防止此类攻击。显然不应从存储库中读取它,因为这将信任Git应该拒绝的存储库。 - “git upload-pack(man)预计在用户无法控制的存储库中运行。我们不能忽略该存储库中的所有配置(因为“git upload-pack”将失败),但是我们可以通过忽略uploadpack.packObjectsHook来限制风险。
只有uploadpack.packObjectsHook是“仅受保护配置”。
以下变量被有意排除:
- safe.directory应该是“仅受保护配置”,但从技术上讲,它不符合定义,因为它在“command”范围内不受尊重。将来的提交将解决此问题。 - trace2.*恰好读取与safe.directory相同的范围,因为它们共享实现。但是,这不是出于安全原因;而是因为我们希望尽早开始跟踪,以便存储库级别的配置和"-c"不可用。这个要求对trace2.*是独特的,因此受保护的配置不受相同约束的影响。

git config现在包含在其手册页面中:

受保护的配置

受保护的配置是指“系统”,“全局”和“命令”范围。
出于安全原因,只有在受保护的配置中指定某些选项时才会被尊重,否则将被忽略。

Git将这些范围视为由用户或可信管理员控制。这是因为控制这些范围的攻击者可以在不使用Git的情况下造成重大损害,因此假定用户的环境会保护这些范围免受攻击。


从 Git 2.39(2022年Q4)开始,允许在“受保护”的范围内的配置文件包含其他配置文件。

请参见提交记录ecec57b(由Glen Choo(chooglen于2022年10月13日提交)。
(由Junio C Hamano -- gitster --合并于提交记录777f548,2022年10月25日)

config: 在受保护的配置中尊重 includes

签名作者: Glen Choo

保护配置是通过读取一组固定路径来实现的,这忽略了配置中的 [include]。将此实现替换为调用 config_with_options(),它处理 [include] 并避免我们重复逻辑:1)识别要读取的路径和2)读取命令行配置。
结果是,git_configset_add_parameters() 没有使用,因此删除它。它与受保护的配置同时引入 5b3c650(“config:学习 git_protected_config()”,2022-07-14,Git v2.38.0-rc0 -- merge 列在 batch #6 中),作为处理命令行配置的一种方式。

4

git config -l 显示了从系统、全局和本地继承的所有值。

因此,您还有另一个配置文件被加载,与您定义的.gitconfig文件一起。


谢谢,你的回答让我明白了system和global之间的区别。@Cupcake的回答使用--system标志帮助我找到了文件。 - RyanW

4
您可以使用--show-origin来查找配置文件的来源。
Git for Windows中的配置文件优先级:

...

$PROGRAMDATA/Git/config::
(仅限Windows)系统范围的配置文件,与其他Git实现共享。通常情况下,$PROGRAMDATA指向C:\ProgramData

$(prefix)/etc/gitconfig::
系统范围的配置文件。 (仅限Windows)此文件仅包含特定于此Git for Windows安装的设置,不应与其他Git实现(如JGit、libgit2)共享。--system将选择此文件。

$XDG_CONFIG_HOME/git/config::
第二个用户特定的配置 文件。如果未设置$XDG_CONFIG_HOME或为空,则将使用$HOME/.config/git/config。在此文件中设置的任何单值变量都将被覆盖为 ~/.gitconfig中的任何内容。如果您有时使用较旧的Git版本,则最好不要创建此文件,因为对此文件的支持是最近添加的。

~/.gitconfig::
用户特定的配置文件。也称为“全局” 配置文件。

$GIT_DIR/config::
存储库特定的配置文件。

...

按照上述顺序读取这些文件,最后找到的值优先于之前读取的值。

...

源:https://github.com/git-for-windows/git/blob/master@%7B2018-01-07%7D/Documentation/git-config.txt#L231

$PROGRAMDATA是一个环境变量。您可以像这样获取这些变量的值:

在Git Bash中,您需要使用echo "$ProgramData"。 在CMD中,您需要使用echo %PROGRAMDATA%。 请注意,Git Bash似乎假装环境变量区分大小写。

什么是$(prefix)

前缀是安装内容的顶级目录。在Git for Windows中,这是<some-path>/mingw64<some-path>/mingw32


2
Windows下的完整答案(即接受答案的Windows版本):
与Linux一样,Windows有四个级别的配置文件/设置,其中三个是直接对应的。需要注意的重要事情是另外一个 - “所有应用程序/用户” - 特别是因为这是安装程序设置值的地方,例如“core.autocrlf = true”,但它无法从命令行访问,所以会引起困惑。
所有应用程序和用户:这就像共享版本的“系统”设置,以防您安装了多个Git应用程序。没有“git config”命令来访问它们,但它们仍然影响设置的最终结果。
配置文件位置:
C:\ProgramData\Git\config
(请注意,在旧版本的Windows上,“ProgramData”是“All Users”)
系统:配置文件位置: C:/Program Files/Git/mingw64/etc/gitconfig
$ git config --system --list

用户

配置文件位置: %USERPROFILE%.gitconfig (这解析为'C:/Users/ ')

最初的回答
$ git config --global --list

代码仓库

配置文件位置: [当前仓库目录]/.git/config

$ git config --local --list

1
在Windows 7(或许Windows 10也相同或类似),对于Visual Studio和Git命令行,你的全局配置位于:
%USERPROFILE%\.gitconfig

(文件名前面有点号)

但是这在Sourcetree中并没有得到尊重,至少在Git嵌入式模式下,并且配置在以下位置:

%USERPROFILE%\AppData\Local\Atlassian\SourceTree\git_local\mingw32\etc\gitconfig

(文件名前面没有点号)

还有一个有趣的部分。为了修改我的全局Git命令和Sourcetree设置,我需要更新这两个文件。

Git挂钩配置在 AppData\Local\...位置工作良好,但是经过更多的Process Monitor研究,我注意到某种方式下Sourcetree也会从公司映射的驱动器中加载全局配置。

这几乎没有任何意义,因为很少有应用程序查找此位置,但不知何故Sourcetree会这样做,因此如果您无法按照Sourcetree的位置设置使其正常工作,请运行Process Monitor并创建一个规则以仅记录包含gitconfig的路径,并且您可以找到真正的全局配置所在位置,以防网络映射用户目录的情况。

而且这甚至可能不是Sourcetree的错,因为我现在写这篇文章时发现git.exe正在加载它,但这仅适用于由Sourcetree执行的git.exe,而直接使用命令行Git的%USERPROFILE%\.gitconfig

Enter image description here

最后,我将Process Monitor记录的所有结果导入SQL Server中,并运行了一个查询以获取不同的结果(没有特定的执行顺序,只按路径排序):

Enter image description here

我不知道这些配置之间的关系,但我知道一些会覆盖另一些,有些设置从一个位置起作用,有些从另一个位置起作用。
而上面的列表由Sourcetree调用,再次使用Git命令行似乎可以正常工作,使用%USERPROFILE%\.gitconfig,而它不在这个列表中,但它看起来像这样(在Windows 7上):C:\Users\pawel.cioch\.gitconfig

-1
在Mac上,它是/usr/local/git/etc/gitconfig。-_-

1
不适用于所有情况。可能取决于您如何配置您的git。我的在/usr/local/etc/gitconfig~/.gitconfig。这就是为什么最好只使用其他答案中描述的--show-origin - Gino Mempin
好观点,吉诺。感谢您的澄清! - ahnbizcad

-1

如果你想找到实际的文件位置,它将在你的主目录中。

它是隐藏的,并且前面带有“.”。

因此,如果你在Mac上,在终端中可以使用cd ~ && open .gitconfig命令打开它,或者使用你喜欢的文本编辑器打开,例如cd ~ && atom .gitconfig


1
这已经被说过了,不需要通过建议(非)替代方案来增加混淆。 - Stim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接