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

时间:2014-01-23 12:11:55

标签: git

我知道可以设置覆盖用户级配置的per-repo配置(即/path/to/my/repo/.gitconfig覆盖~/.gitconfig)。是否可以设置git配置覆盖给定文件夹的所有子文件夹的用户级设置?即,我有

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

我希望.gitconfig_override中定义的设置适用于childFolder1childFolder2

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

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

  • 为“工作”和“播放”创建单独的用户,适当地设置他们的用户级设置,并在切换上下文时以适当的用户身份登录(麻烦,加上我很容易忘记切换)
  • 创建一个脚本,在“workFolder”中搜索git repos,并添加/更新他们的.gitconfig文件以保存相应的详细信息(如果我创建一个repo并忘记在推送之前运行脚本,我将推送为错误人)
  • “hack”git,这样每次创建一个repo时,它都会检查文件路径,并在适当的情况下更新.gitconfig文件(复杂,混乱,几乎肯定是错误的方法去做 - 加上,我不会'有第一个线索如何去做!)

我检查了this question,它似乎只包含单个回购的解决方案,而不是多个。希望有人会看到错过那个问题的这个问题!

4 个答案:

答案 0 :(得分:25)

NateEag's edit所述,git的Conditional Includes非常适合这一点。因为那个答案是git< 2.13,这是一个适用于那些拥有较新版本的人。

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

~/.git/config中,添加:

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

~/topLevelFolder1的任何子文件夹现在都会在~/toplevelFolder1/.gitconfig_include中包含配置 - 无需手动更改每个子文件夹的repo中的.git/config。 (这不会覆盖子文件夹配置中的任何内容 - 它只是添加,因为“include”意味着。)

答案 1 :(得分:20)

编辑: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 initgit clone的自定义包装将是您最好的选择。

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

答案 2 :(得分:10)

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

阅读direnv基本页面http://direnv.net/,为您的shell设置它。对于zsh,只需将此行粘贴在.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

答案 3 :(得分:6)

git config中的[include]部分(.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

查看详细解答的问题:Is it possible to include a file in your .gitconfig

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

修改

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

[include]
    path = ../.gitconfig_override