I have the following use case: I would like to be able to push to git@git.company.com:gitolite-admin using the private key of user gitolite-admin, while I want to push to git@git.company.com:some_repo using 'my own' private key. AFAIK, I can't solve this using ~/.ssh/config, because the user name and server name are identical in both cases. As I mostly use my own private key, I have that defined in ~/.ssh/config for git@git.company.com. Does anyone know of a way to override the key that is used for a single git invocation?

(另外:gitolite根据键来区分谁在进行推送,所以就访问、所有权和审计而言,user@server字符串对于不同的用户是相同的,这不是问题。)


当前回答

使用~/的一种可能性。ssh/config将使用Match限制而不是Host限制。特别是Match Exec调用shell命令来决定是否应用声明。在bash中,您可以使用以下命令:

[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]

它使用bash[命令来验证两个字符串是否相等。在这种情况下,它正在测试字符串git@git.company.com:gitolite-admin是否与从$(git config——get remote.origin.url) "命令获得的输出匹配。

您可以使用任何其他命令来标识shell所在的存储库。要做到这一点,重要的是在SHELL中定义$SHELL变量,在我的例子中是/bin/bash.完整的示例如下~/.ssh/config:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Match Exec "[ git@git.company.com:some_repo = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

在这个例子中,我假设~/。ssh/yourOwnPrivateKey包含您自己的私钥和~/。Ssh /gitolite-admin包含gitolite-admin用户的私钥。我加入了IdentitiesOnly yes声明,以确保只有一个密钥提供给git服务器,Mark Longair提到过。其他声明只是git的标准ssh选项。

如果您有几个some_repo,想要与不同的键一起使用,您可以添加此配置。如果您在git@git.company.com上有多个存储库,并且大多数存储库使用~/。将此密钥作为主机的默认密钥更有意义。在这种情况下,~/。Ssh /config将是:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes

Host git.company.com
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

注意,顺序很重要,Host git.company.com限制应该出现在Match Exec一个或多个限制之后。

其他回答

我在Win7上使用Git Bash。下面的方法对我很有效。

在~/处创建一个配置文件。Ssh /config或c:/users/[your_user_name]/. Ssh /config。在文件中输入:

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa

我想主机必须是一个URL,而不仅仅是一个“名称”或参考您的主机。例如,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa

也可以写入“/c/users/[user_name]/....”格式

Giordano Scalzo提供的解决方案也很棒。 https://stackoverflow.com/a/9149518/1738546

正如其他人提到的,核心。sshCommand config可以覆盖SSH密钥和其他参数。

下面是一个示例,其中有一个名为~/的替代键。Ssh /workrsa,并希望将其用于~/work下克隆的所有存储库。

在~/work下创建一个新的.gitconfig文件:

[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"

在全局git配置中~/。gitconfig,添加:

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

另一种替代方法是使用ssh-ident来管理您的ssh身份。

它会根据您当前的工作目录、ssh选项等自动加载和使用不同的密钥……这意味着您可以轻松地拥有一个工作/目录和一个私有/目录,它们在ssh中透明地使用不同的密钥和身份。

你最多在文件配置键ssh中指定:

# Default GitHub user
Host one
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-one
 IdentitiesOnly yes

#two user
Host two
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-two
 IdentitiesOnly yes

如果你已经有默认的ssh密钥配置,但想要对特定的存储库使用不同的配置,那么这应该可以做到:

git config core.sshCommand "ssh -i ~/.ssh/github-personal -o IdentitiesOnly=yes -F /dev/null"