Gitconfig选项是否可以有条件地设置?

42

通过 Github,我在几台不同的电脑和服务器上使用相同的“dot文件”。在我直接控制的Mac和Linux设备上,我安装了Sublime Text 2,并将其设置为我的git合并和提交编辑器。然而,在远程(即不在我直接控制之下)的服务器上,我会选择使用vim。

我不想为那些远程服务器创建和维护第二个.gitconfig。有没有办法做到这样的事情:

[core]
    if [[ $IS_REMOTE -eq 1 ]]; then
        editor = "vim"
    else
        editor = "subl -n -w"
    fi

我该如何根据主机名设置$IS_REMOTE变量?


为什么不直接使用一个脚本文件作为“editor”值,在其中进行检查呢?(因为不行,git config 不是有条件的) - Nevik Rehnel
从Git 2.13开始,条件包含gitconfig变得可能。请参见我的回答 - VonC
7个回答

28

在 Git 2.13 及更高版本中,您可以根据 Git 目录或分支条件性地包含另一个 Git 配置文件。

将默认配置放在文件~/.gitconfig中,像往常一样。最后,条件性地包含另一个配置文件:

[user]
    email = john@personal.com
    name = John McGehee

# All work Git repositories are in a subdirectory of ~/work.
# All other Git repositories are outside ~/work.
[includeIf "gitdir:~/work/"]
    path = .gitconfig.work

然后,在~/.gitconfig.work中添加或覆盖您在位于~/work或其任何子目录中的存储库中使用时想要的配置值:

[user]
    email = john@work.com

当您切换到位于~/work下的Git目录并运行以下命令时,您可以观察到差异:

git config user.email

在一个不在 ~/work 目录下的 Git 目录中尝试相同的命令。


8
请注意,[includeIf] 部分必须位于您想要覆盖值的任何部分(例如 [user])之 下方。这可能对其他人而言很明显,但是由于这使我困惑了一下,所以我想分享一下。请注意不要改变原文的意思,并尽量使翻译通俗易懂。 - mefryar

21

不,Git配置文件不支持检查或条件语句。但是你所使用的底层Shell可能支持,因此你可以使用类似以下的语句:

[core]
    editor = "if [[ $IS_REMOTE -eq 1 ]]; then ED='vim'; else ED='subl -n -w'; fi; $ED"


如果你需要做比那更复杂的事情,当然可以将shell代码放入脚本中,就像这样:


[core]
    editor = "my_edi_script.sh"

使用类似于my_edit_script.sh的脚本,其中包含以下内容:

#!/bin/bash
if [[ $IS_REMOTE -eq 1 ]]; then
    ED="vim"
else
    ED="subl -n -w"
fi

$ED some argument or other

编辑:当然,my_edit_script.sh必须在$PATH中。


除了编辑器设置外,合并工具和差异工具的设置也会针对远程机器进行更改。我认为最终的解决方案是拥有两个.gitconfig文件。 - Mark Nichols
我尝试了你提供的两种方法,但它们都不能用于credential.helper设置。我遇到了如下错误:"git: 'credential-my_credential_script.sh' 不是一个 git 命令。" - metakermit
[alias]NEWLINEHEREb = "!if [ -z $1 ]; then git branch -av; else git branch $1 $2 $3 $4; fi" 有没有什么方法可以使其正常工作而不显示语法错误? - Unknow0059
我尝试了你的解决方案,第一个可行,第二个('my_edit_script.sh')失败了,出现了“command not found: ED”之类的消息。 - ChrisZZ
@ChrisZZ 在脚本中,最后一行应该是 $ED,这意味着调用命令。 - Honghao Z
更正:最后一行应该是 $ED "$@" # 调用编辑器 - Honghao Z

14

通过在 v1.7.9 中 git-config 学到的 [include] 部分,您可以完成大部分操作。

虽然它不能让您编写运行时条件,但是它确实为将 ~/.gitconfig 重构为多个部分(共享 部分和 特定于环境 部分)提供了框架。之后,您可以将类似于 ~/.gitconfig.local 的东西符号链接到相关的特定于环境的配置文件中,并从 ~/.gitconfig 中包含 ~/.gitconfig.local

符号链接部分可以作为 dotfiles' 启动脚本的一部分进行脚本化和自动完成。

从命令行中,该包含路径可以通过以下方式添加:

git config --global include.path '~/.gitconfig.local'

我使用上述引号是为了防止shell将~扩展为绝对路径。

这将向您的~/.gitconfig添加以下部分:

[include]
    path = ~/.gitconfig.local

以下是来自git-scm book的代码片段,展示了一般格式:

[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

2

从Git v2.31开始,您也可以在.bashrc或其他地方设置环境变量,例如在WSL2上,我使用以下内容来配置git以使用来自Windows的缓存git https凭据:

export GIT_CONFIG_COUNT=2 \
GIT_CONFIG_KEY_0="credential.helper" GIT_CONFIG_VALUE_0="/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-credential-manager-core.exe" \
GIT_CONFIG_KEY_1="credential.https://dev.azure.com.usehttppath" GIT_CONFIG_VALUE_1="true"

感谢 VonC 的指出。https://dev59.com/PWgu5IYBdhLWcg3winc3#65963666。此处涉及到 IT 技术相关内容。

2
我认为你无法做到这一点,但是与其维护您的.gitconfig文件,不如维护一个生成您的.gitconfig文件的脚本?这样,您可以根据变量和命令输出等任何内容进行自定义。例如:
#!/bin/sh
if [ "$#" -eq 0 ]
then
    IS_REMOTE=
else
    case "$1" in
        remote)
            IS_REMOTE=1
            ;;
        local)
            IS_REMOTE=
            ;;
        *)
            echo "value $1 not supported" >&2
            ;;
    esac
fi

# config for both remote and local
git config --global color.ui true
git config --global alias.top '!pwd -L'

# config for remote
if [ "$IS_REMOTE" ]
then
    git config --global core.editor vim
    ...
else
    git config --global core.editor 'subl -n -w'
    ...
fi

因此,如果您在不带参数或带有“local”参数的情况下调用脚本,它将会为您的.gitconfig文件生成一些配置信息。如果您向其传递“remote”参数,则会生成其他一些配置信息。


虽然我很喜欢使用脚本来生成.gitconfig文件的想法,但是考虑到我经常需要更新两个.gitconfig变量,我认为这比我愿意付出的努力更费力。 - Mark Nichols
这在技术上是可行的,但不是正确的方法。上面的答案更简单、更整洁。 - sferencik

1

虽然不是你问题的确切答案,但与相关用例有关的内容很有趣: 自从 git 1.8.5 版本以来,您可以使用 urlmatch 语法

详细信息请参见http://git-scm.com/docs/git-config

有关远程的配置条目是唯一可以有条件地定义的,例如 [http "https://localhost" ] sslVerify = false

^ 这将仅为 localhost 的“远程”关闭 ssl 验证


1

由于无法测试环境变量并以编程方式更改.gitconfig,而且编写两个.gitconfig文件的脚本感觉比我想要付出的工作还要多,因此我将创建两个.gitconfig文件。在那些我可以将Sublime Text 2设置为编辑器并控制合并工具和差异工具的机器上,我将使用“主”gitconfig作为符号链接的目标。在那些我没有ST2选项的机器上,我将使用“次要”gitconfig文件。


你可以将常见的配置拆分到第三个文件中,并在其他文件中包含它:https://dev59.com/2m865IYBdhLWcg3wBJwq - chtenb
2
这不应该被标记为最佳答案。它只是展示了您的偏好,而这种偏好受到您放弃实际目标的影响。如果有人仍然想要这样做,最佳答案应该是以上其中之一。 - sferencik

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