告诉Git使用哪个SSH配置文件

33

我有多个用于不同系统的SSH配置文件夹,例如:

ssh -F ~/.ssh/system-a/config user@system-a
ssh -F ~/.ssh/system-b/config user@system-b
每个文件夹都有一个配置文件和一组身份文件,如下所示。
Host system-a
    HostName <some_hostname>
    User <some_username>
    IdentityFile ~/.ssh/system-a/keys/system-a.pem

如何告诉git在执行git任务时使用特定的ssh配置文件或特定的ssh密钥?

如果可能的话,我希望可以为每个git项目单独设置。


这篇文章介绍了如何告诉git使用哪个ssh密钥。 - therobinkim
1
可能是为给定域名指定git push的SSH密钥的重复问题。 - umläute
1
@therobinkim 不是的,那个解释了如何为GitHub创建一个段落,而不是如何让git使用特定的配置文件。 - 1615903
@pfwd 你是否不小心忘记接受符合你需求的答案了? - umläute
4个回答

29

在命令行中,您可以为当前的代码库更改 Git 配置:

git config core.sshCommand "ssh -F ~/.ssh/system-a/config"

或在您本地存储库中的.git/config中添加到[core]节:

sshCommand = "ssh -F ~/.ssh/system-a/config"

这只适用于git 2.10及更高版本。否则,需要使用环境变量$GIT_SSH_COMMAND进行设置,例如:

GIT_SSH_COMMAND="ssh -F ~/.ssh/system-a/config" git pull

1
@AndrejsCainikovs 感谢您的纠正。我没有找到实际的发布说明,2.9版本也没有这个功能。 - Jakuje
我喜欢直接在GitHub存储库的.git/config文件中使用-i选项将我创建的标识文件添加为引用。sshCommand = "ssh -i ~/.ssh/github_reponame_rsa" - WeakPointer
1
由于某些原因,-F 配置在我的 git 2.25 版本中无法正常工作,因此我使用 -i 选项直接指定了 ssh 密钥。 - Ingo Steinke

16
根据 Andrejs Cainikovs 和 Jakuje 的指出,使用足够新的 git 可以使用多个 ssh-config 文件。
然而,您可以通过一个单独的 ssh-config 文件实现几乎相同的结果,可能所有配置都指向一个真实主机。
Host SOMELABEL
    HostName <some_hostname>
    User <some_username>
    IdentityFile ~/.ssh/system-a/keys/system-a.pem

Host OTHERLABEL
    HostName <other_hostname>
    User <other_username>
    IdentityFile ~/.ssh/system-b/keys/system-a.pem

然后像这样克隆存储库:
  git clone SOMELABEL:foo/bar.git
  git clone OTHERLABEL:frobnozzel.git

这将使用位于~/.ssh/system-a/keys/system-a.pem的ssh密钥,以<some_username>@<some_hostname>身份访问bar仓库,而对于frobnozzel仓库,则会使用位于~/.ssh/system-b/keys/system-a.pem的ssh密钥,以<other_username>@<other_hostname>身份访问。

@AndrejsCainikovs 我已经更正了(并更新了我的答案);我仍然不明白为什么多个ssh-config文件比单个文件更受欢迎(但当然这取决于@pfwd)。 - umläute
当然,拥有单个的~/.gitconfig~/.ssh/config是正确的方法。但我认为OP遇到了一个特殊情况。也许是测试自动化或其他什么... - Andrejs Cainikovs
@umläute 这只是我喜欢工作的方式。我喜欢为我的项目拥有单独的配置文件和目录,而不是把它们全部混在一起。 - pfwd
@umläute 谢谢您实际列出了 git clone 命令。没有其他相关答案 :) - rjurney
2
这个方法是可行的,但你必须认识到,为了使用 git@github.com 克隆地址,你必须在配置文件中使用地址的主机名和 git 用户,所以 Host 指令应该设置为 github.com,而 User 指令应该设置为 git - 否则你将无法使用 git@github.com 克隆指令进行克隆 - 对于其他 git 远程地址/主机名也是如此。 - Arcsector
当然,这就是我使用占位符的原因;此外,这个问题不仅仅是关于GitHub,而是关于一般情况下如何使用git+ssh。如果我列出所有可能的用户名/主机名组合,我认为这并没有太大帮助。 - umläute

15

我想介入这个话题,因为最近我一直在尝试解决这个问题,而不必每次克隆新版本时都执行git config core.sshCommand

因此,我在Jakuje 的实现基础上进行了一些扩展。

我有两个 Gitlab 帐户。一个是用我的工作电子邮件注册的,另一个是个人电子邮件注册的。

为此,我有两个不同的私钥:

  • 个人: ~/.ssh/keys/personal.id_rsa
  • 工作: ~/.ssh/keys/work.id_rsa

现在,我有一个全局 Git 配置位于~/.gitconfig,还有一个备用配置位于~/work.gitconfig。工作 Git 配置仅包含与全局配置不同的设置。

所以在这种情况下,

~/work.gitconfig

[core] 
    sshCommand = ssh -i ~/.ssh/keys/work.id_rsa

我将所有与工作相关的代码仓库克隆到~/source/work目录下。

接下来的魔法发生在我的~/.gitconfig文件中。我加入了以下部分(git includeIf):

[includeIf "gitdir:~/source/work/**"]
    path="~/work.gitconfig"

现在,这将告诉git~/source/work中的所有repo中包括我的工作git配置。然后,此配置将自动设置用于推送/拉取的ssh密钥为我用于工作repo使用的密钥。
您需要确保克隆到正确的文件夹中。
您可以将此与使用通用ssh配置结合使用。
Host gitlab.com
    HostName gitlab.com
    User git
    IdentityFile ~/.ssh/keys/personal.id_rsa

默认情况下,Git会使用personal.id_rsa(个人账户)进行操作,但当代码仓库位于work目录下时,则会使用工作账户(基于SSH密钥)。


3
这个答案应该更高 - [includeIf "glob_pattern"] 是一个天才的解决方案,完全解决了我的问题,无需额外的配置/工具。 - srigi

1

git 2.10+

请查看Jakuje的答案

git 2.9-

使用core.gitproxy指向执行特殊操作的自定义脚本。


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