为所有子文件夹设置git config值


77

我知道可以设置覆盖用户级配置的每个仓库配置(即/path/to/my/repo/.gitconfigoverrides ~/.gitconfig)。是否可以设置git configs来覆盖给定文件夹的所有子文件夹的用户级设置?即我有

|--topLevelFolder1
|--\
|   ---.gitconfig_override
|--\
|   ---childFolder1
|       \---[...]
|--\
|   ---childFolder2
|       \---[...]

我希望将中定义的设置.gitconfig_override应用于childFolder1和中childFolder2

我这样做的动机如下:我有一台工作用的笔记本电脑,在业余时间还用于个人项目。我所有的工作代码都嵌套在一个文件夹中。当我推动工作git repos时,我需要使用工作角色-工作登录名(而不是姓名)和工作电子邮件。当我推送到自己的个人(github)存储库时,我想使用我的真实姓名和个人电子邮件。

我想到的其他可能的解决方案(和问题):

  • 为“工作”和“娱乐”创建单独的用户,适当地设置他们的用户级别设置,并在切换上下文时以适当的用户身份登录(麻烦,再加上我很容易忘记切换)
  • 创建一个脚本,在“ workFolder”中搜索git仓库,并添加/更新其.gitconfig文件以保存适当的详细信息(如果我创建了一个仓库,而在推送之前忘记运行该脚本,则我将以错误的身份推送)
  • 对git进行“ hack”操作,以便每次创建一个repo时,它都会检查文件路径,并在适当的情况下更新.gitconfig文件(复杂,混乱且几乎肯定是错误的方法-而且,我不会首先提示如何去做!)

我检查了这个问题该问题似乎只包含单个存储库而不是多个存储库的解决方案。希望有人会错过这个问题!


您是否将与“工作”和“个人”一起使用相同的存储库?如果没有,您链接到的问题将包含我要给出的答案。您的--global用户设置应包含您更多使用的身份。每个应使用其他身份的存储库都应具有user.name并进行相应user.email设置。
克里斯(Chris

我永远不会和两个不同的用户在同一个仓库中工作-每个仓库都将是“工作”或“家”-但是问题出在以下事实:(至少对于工作而言)我有35个仓库,定期添加。我可以在每个现有存储库中添加user.nameuser.email设置,并设置一个cron脚本将其添加到任何新添加的存储库中,但是如果我可以将它们设置在一个“过滤”到任何位置的位置,则将更加容易。子文件夹中的存储库。
scubbo 2014年

Answers:


32

编辑:Git 2.13引入了条件包含,其旨在解决这个确切的问题。

为了历史的缘故,我的原始答案保留在下面(并且用户停留在git的旧版本上)。

===================================

根据阅读gitconfig联机帮助页,不支持您所需的确切行为。

但是,从git 1.7.12开始,Git从四个不同的源读取配置数据,其中两个是用户特定的:

$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配置和我的dotfile)。如果您经常在工作机中添加个人存储库,那么这可能对您来说不够好。

在这种情况下,定制包装器git init,并git clone会是你最好的选择。

$ PATH上名称与“ git- *”匹配的任何二进制文件都可以称为git命令,因此您只需要一对shell脚本,这些脚本将使用所有传递的args调用原始命令,然后将正确的配置文件复制到.git/config


一些git设置可以通过设置环境变量来控制。它们会覆盖配置文件中的值。用于按目录层次结构设置/取消设置环境变量的一个很好的实用工具是direnv。有关所有详细信息,请参见下面的我的答案。
阿杰M

87

正如NateEag的编辑所提到,git的Conditional Includes非常适合此操作。由于该答案是git <2.13上的人的答案,因此这是那些具有较新版本的人的答案。

首先,在您要在子文件夹中生效的设置的某个位置创建一个新的配置文件-使用原始问题的文件夹,假设它位于 ~/topLevelFolder1/.gitconfig_include

在中~/.gitconfig,添加:

[includeIf "gitdir:~/toplevelFolder1/"]
    path = ~/topLevelFolder1/.gitconfig_include

~/topLevelFolder1现在,任何子文件夹都将配置包含在其中~/toplevelFolder1/.gitconfig_include-无需手动更改.git/config每个子文件夹的存储库中的。(这不会覆盖子文件夹配置中的任何内容,它只是添加到其中,如“ include”所示。)


9
条件中的尾部斜杠(/gitdir很重要。
stefanct

2
应该被标记为这个问题的正确答案。多亏了提及includeIf(和一点点的反复试验),我现在在工作PC上配置了一个特定的文件夹树,其中每个Git操作都将我标识为我的个人帐户,并使用我的个人SSH密钥以及一个我的个人PC上用于工作资料的类似文件夹。同时,每个系统的其余部分在两台计算机上都使用适当的电子邮件,名称和SSH密钥。我只希望能多次

if零件真的必要吗?如果所引用的path不存在,则该条目似乎被忽略。
奥利弗·皮尔曼

如果只有git只是做逻辑上的事情,然后走到树上寻找.git每个父目录中的目录...
Ian Kemp

@OliverPearmain的目标不是要包含文件(如果存在),而是要在给定路径下的存储库中包含文件。
帕特里克

14

您可以使用direnv命令来设置适用于所有子文件夹的环境变量。您可以在该目录层次结构中的任何位置。如果您尝试设置的git设置可以由环境变量控制,那么您很幸运。

阅读direnv基本页面http://direnv.net/以为您的shell进行设置。对于zsh,只需将这一行粘贴在my的底部.zshrc并重新启动shell就很简单。

eval "$(direnv hook zsh)"

检查所需的git设置是否可以由环境变量控制。似乎您想控制author.email一个特定的目录树,该目录树由环境变量来控制GIT_AUTHOR_EMAIL。注意,环境变量优先于config。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

7

您正在寻找[include]git config(.git/config~/.gitconfig...)中的部分。

[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

查看详细的回答的问题:.gitconfig中是否可以包含文件

请参阅git-config文档:http : //git-scm.com/docs/git-config#_includes

编辑

添加childFolder1/.git/configchildFolder2/.git/config

[include]
    path = ../.gitconfig_override

2
好的-这样就解决了仅在一个位置(user.name和)user.email中定义和的问题../.gitconfig_override,但我认为它实际上并未回答原始问题吗?如果childFolder1childFolder2是的子代parentFolder,我正在寻找一种设置配置值的方法,parentFolder该方法可以过滤掉根于子文件夹的任何存储库。
scubbo

1
正如NateEag指出的那样,它仅在Git 2.13中引入。(Git 2.13.0的发布日期为2017年5月9日。)因此,如果任何人阅读此答案都想知道为什么它对他们不起作用,则可能是他们使用的是旧版Git。
sampablokuper

请注意,我最近遇到了一个问题,其中似乎不尊重这些条件包括。问题是git(至少,我的安装是-在MacOSX上为2.17.0)似乎需要在目录路径上添加斜杠。
scubbo '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.