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

我知道可以设置覆盖用户级配置的每回购配置(即 /path/to/my/repo/.gitconfig覆盖 ~/.gitconfig)。是否可以设置 git 配置来覆盖给定文件夹的所有子文件夹的用户级设置?也就是说,我见过

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

我想在 .gitconfig_override中定义的设置应用于 childFolder1childFolder2

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

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

  • 为“工作”和“娱乐”创建单独的用户,适当设置他们的用户级设置,并在切换上下文时作为合适的用户登录(麻烦,另外我很容易忘记切换)
  • 创建一个在“ workFolder”中搜索 git 回购的脚本,并添加/更新它们的。Gitconfig 文件来保存适当的细节(如果我创建了一个回购并忘记在推送之前运行脚本,那么我将以错误的人的身份推送)
  • “ hack”git 使得它每次创建回购时都会检查文件路径,并在适当的时候更新。Gitconfig 文件(复杂,混乱,而且几乎肯定是错误的方式做它-加上,我不会有第一个线索如何去做!)

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

20987 次浏览

编辑: 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 配置和我的 dotfiles)。如果你经常在你的工作机器上添加个人回购协议,这对你来说可能不够好。

在这种情况下,围绕 git initgit clone的自定义包装器将是您的最佳选择。

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

The [include] section in git config (.git/config, ~/.gitconfig ...) is what you are looking for.

[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

可以使用 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

For example:

echo export GIT_AUTHOR_EMAIL=myotheremail@esp.com > .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

正如 NateEag 的编辑所提到的,git 的 有条件的包括非常适合这种情况。因为这个答案适用于 git < 2.13的用户,这里有一个适用于那些拥有更新版本的用户。

First, create a new config file somewhere with the settings you want to take effect in the sub-folders - using the original question's folders, let's say it's at ~/topLevelFolder1/.gitconfig_include

~/.gitconfig中,添加:

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

Any subfolder of ~/topLevelFolder1 will now include the config in ~/toplevelFolder1/.gitconfig_include - there isn't a need to manually change the .git/config in each subfolder's repo. (This doesn't 重写 whatever's in the subfolder config - it just 补充道 to it, as "include" implies.)

Notes:

  • 这个设置应该定位在 ~/.gitconfig中要重写的配置 之后中,因为 includeIf将被后面的任何配置再次重写。
  • 此设置仅当您是指定路径下的 在一个仓库里时才包含该文件。如果您处于任何非存储库子路径中,它将被忽略。
  • gitdir条件下,后面的正斜杠(/)很重要。
  • git config --list is good for testing this. You'll see any overrides below includeIf lines in the output. You can also check specific entries with, e.g., git config --get user.email
  • 适用于 Windows 的 Git上,使用 ~/指定相对于用户目录的路径,使用 Windows 风格的驱动器指定绝对路径,如 C:/,仅使用正斜杠。像 /c/这样的反斜杠和 Unix 风格的挂载点不起作用。此外,在 includeIf部分中,必须指定带有正确大小写的路径,因为比较是 大小写敏感