我知道可以设置覆盖用户级配置的 per-repo 配置(即 /path/to/my/repo/.gitconfig
覆盖 ~/.gitconfig
)。是否可以设置 git configs 来覆盖给定文件夹的所有子文件夹的用户级设置?即,我有
|--topLevelFolder1
|--\
| ---.gitconfig_override
|--\
| ---childFolder1
| \---[...]
|--\
| ---childFolder2
| \---[...]
我希望 .gitconfig_override
中定义的设置适用于 childFolder1
和 childFolder2
。
我这样做的动机如下:我有一台工作笔记本电脑,我也会在业余时间用于个人项目。我所有的工作代码都嵌套在一个文件夹中。当我推动工作 git repos 时,我需要使用我的工作角色 - 工作登录而不是姓名,以及工作电子邮件。当我推送到我自己的个人 (github) 存储库时,我想用我的真实姓名和个人电子邮件这样做。
我想到的其他可能的解决方案(和问题):
为“工作”和“娱乐”创建单独的用户,适当地设置他们的用户级别设置,并在我切换上下文时以适当的用户身份登录(麻烦,而且我很容易忘记切换)
创建一个在“workFolder”中搜索 git repos 的脚本,并添加/更新他们的 .gitconfig 文件以保存适当的详细信息(如果我创建了一个 repo 并忘记在推送之前运行脚本,我将作为错误的人推送)
“hack” git,这样每次它创建一个 repo 时,它都会检查文件路径,并在适当的情况下更新 .gitconfig 文件(复杂、混乱,而且几乎可以肯定是错误的做法——另外,我不会有第一个线索如何去做!)
我检查了 this question,它似乎只包含单个 repos 的解决方案,而不是多个。希望有人会看到这个错过了这个问题的问题!
--global
用户设置应包含您更多使用的身份。应该使用另一个身份的每个存储库都应该相应地设置 user.name
和 user.email
。
user.name
和 user.email
设置,并设置一个 cron 脚本以将它们添加到任何新添加的存储库中,但如果我可以将它们设置在一个地方会容易得多“过滤”到子文件夹中的任何存储库。
正如 NateEag's edit 所提到的,git 的 Conditional Includes 非常适合这一点。因为这个答案是 git < 上的人的答案。 2.13,这是为那些拥有较新版本的人准备的。
首先,在某个位置创建一个新的配置文件,其中包含要在子文件夹中生效的设置 - 使用原始问题的文件夹,假设它位于 ~/topLevelFolder1/.gitconfig_include
在 ~/.gitconfig
中,添加:
[includeIf "gitdir:~/toplevelFolder1/"]
path = ~/topLevelFolder1/.gitconfig_include
~/topLevelFolder1
的任何子文件夹现在都将包含 ~/toplevelFolder1/.gitconfig_include
中的配置 - 无需手动更改每个子文件夹的存储库中的 .git/config
。 (这不会 覆盖 子文件夹配置中的任何内容 - 它只是 添加 到它,正如“包含”所暗示的那样。)
笔记:
此设置应位于您要在 ~/.gitconfig 中覆盖的配置之后,因为 includeIf 将被其后的任何配置再次覆盖。
仅当您位于给定路径下的存储库中时,此设置才包含该文件。如果您在任何非存储库子路径中,它将被忽略。
gitdir 条件中的尾部正斜杠 (/) 很重要。
git config --list 非常适合测试它。您将在输出中的 includeIf 行下方看到任何覆盖。您还可以使用例如 git config --get user.email 检查特定条目
在适用于 Windows 的 Git 上,使用 ~/ 指定相对于用户目录的路径,使用 Windows 样式的驱动器指定绝对路径,例如 C:/ 仅使用正斜杠。反斜杠和 Unix 风格的挂载点(如 /c/)不起作用。此外,在 includeIf 部分中,您必须指定大小写正确的路径,因为比较区分大小写。
编辑:Git 2.13 引入了 conditional includes,旨在解决这个确切的问题。
为了历史的缘故,我的原始答案保留在下面(并且用户坚持使用旧版本的 git)。
=====================================
根据阅读 gitconfig 手册页,不支持您想要的确切行为。
但是,从 git 1.7.12 开始,Git 从 four different sources 读取配置数据,其中两个是用户特定的:
$XDG_CONFIG_HOME/git/config
和 ~/.gitconfig
。 ~/.gitconfig
中的条目会覆盖 $XDG_CONFIG_HOME/git/config
中的条目。
这意味着您可以将您的个人 gitconfig 存储在 $XDG_CONFIG_HOME/git/config
并将特定于机器的覆盖放在 ~/.gitconfig
中。就像是
[user]
email = username@example.com
~/.gitconfig
中的内容应涵盖您的电子邮件案例。
请注意,如果 $XDG_CONFIG_HOME 未设置,git 将查找 ~/.config/git/config
。
这对我很有效,因为我在工作机器上只有两个个人存储库(我的 emacs 配置和我的 dotfiles)。如果您经常将个人存储库添加到您的工作机器,这对您来说可能还不够好。
在这种情况下,围绕 git init
和 git clone
的自定义包装器将是您的最佳选择。
$PATH 上名称与“git-*”匹配的任何二进制文件都可以作为 git 命令调用,因此您只需要一对 shell 脚本,使用所有传递的参数调用原始命令,然后将正确的配置文件复制到.git/config
。
direnv
。有关所有详细信息,请参阅下面的答案。
您可以使用 direnv
命令设置适用于所有子文件夹的环境变量。您可以在该目录层次结构中的任何位置。如果您尝试设置的 git 设置可以由环境变量控制,那么您很幸运。
阅读direnv
基本页面http://direnv.net/,为您的 shell 进行设置。对于 zsh,只需将此行粘贴在 .zshrc
的底部并重新启动 shell 即可。
eval "$(direnv hook zsh)"
检查您想要的 git 设置是否可以由环境变量控制。您似乎想要控制特定目录树的 author.email
,它由环境变量 GIT_AUTHOR_EMAIL
控制。注意,环境变量优先于配置。 git 支持的环境变量的完整列表在这里:https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables
由于 direnv
的页面指定,在层次结构的根目录创建一个名为 .envrc
的文件;在您的情况下,topLevelFolder1
例如:
echo export GIT_AUTHOR_EMAIL=myotheremail@esp.com > .envrc
“允许” envrc:direnv allow .
就是这样!
每次跳入层次结构时,direnv
都会找到上述 .envrc
文件并加载它。
$ cd ~/topLevelFolder1/childFolder1/project_name
direnv: loading ../../../.envrc
direnv: export +GIT_AUTHOR_EMAIL
$ echo ${GIT_AUTHOR_EMAIL}
myotheremail@esp.com
跳出目录结构,direnv
将卸载那些变量
cd ~
direnv: unloading
git config (.git/config
, ~/.gitconfig
...) 中的 [include]
部分就是您要查找的内容。
[include]
path = /path/to/foo.inc ; include by absolute path
path = foo ; expand "foo" relative to the current file
path = ~/foo ; expand "foo" in your $HOME directory
查看详细回答的问题:Is it possible to include a file in your .gitconfig
请参阅 git-config 文档:http://git-scm.com/docs/git-config#_includes
编辑
添加 childFolder1/.git/config
和 childFolder2/.git/config
:
[include]
path = ../.gitconfig_override
../.gitconfig_override
中)定义 user.name
和 user.email
的问题,但我认为它实际上并没有回答原始问题?如果 childFolder1
和 childFolder2
是 parentFolder
的子级,我正在寻找一种在 parentFolder
中设置配置值的方法,该值将过滤到任何以子文件夹为根的存储库。
gitdir
条件中的尾部斜杠 (/
) 很重要。includeIf
(以及一些尝试和错误),我现在已经在我的工作 PC 上配置了一个特定的文件夹树,其中每个 Git 操作都将我标识为我的个人帐户并使用我的个人 SSH 密钥,以及用于我个人 PC 上工作内容的类似文件夹。同时,每个系统的其余部分在两台机器上都使用适当的电子邮件、名称和 SSH 密钥。我只希望我不止一次赞成这个答案..(:if
部分真的有必要吗?如果引用的path
不存在,则该条目似乎被忽略。.git
目录......