这可能是一种非常不寻常的情况,但我想指定在本地计算机上执行shell(git)命令时要使用的私有SSH密钥。

基本上是这样的:

git clone git@github.com:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser"

或者更好(用Ruby):

with_key("/home/christoffer/ssh_keys/theuser") do
  sh("git clone git@github.com:TheUser/TheProject.git")
end

我见过使用Net::SSH连接到远程服务器的示例,该服务器使用指定的私钥,但这是一个本地命令。有可能吗?


当前回答

使用git 2.10+(2016年第三季度:2016年9月2日发布),您可以为git_SSH_COMMAND设置配置(而不仅仅是Rober Jack Will的回答中描述的环境变量)

参见Nguy的承诺书(2016年6月26日)ễn Thái Ng先生ọc杜伊(pclouds)。(2016年7月19日,Junio C Hamano--gitster在提交dc21164中合并)

新的配置变量core.shCommand已添加到指定每个存储库要使用的GIT_SSH_COMMAND值。

core.sshCommand:

如果设置了此变量,gitfetch和gitpush将在需要连接到远程系统时使用指定的命令而不是ssh。该命令的格式与GIT_SSH_command环境变量的格式相同,并且在设置环境变量时被覆盖。

这意味着git pull可以是:

cd /path/to/my/repo/already/cloned
git config core.sshCommand 'ssh -i private_key_file' 
# later on
git pull

您甚至可以只为一个命令(如gitclone)设置它:

git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git

这比设置GIT_SSH_COMMAND环境变量更容易,正如Mátyás Kuti Kreszács所指出的,在Windows上

set "GIT_SSH_COMMAND=ssh -i private_key_file"

对于所有这些命令,可以添加-o IdentitesOnly=yes以将SSH限制为指定的私钥/公钥:

git config core.sshCommand 'ssh -i private_key_file -o IdentitiesOnly=yes' 
# or
git -c core.sshCommand="ssh -i private_key_file -o IdentitiesOnly=yes" clone host:repo.git
# or
set "GIT_SSH_COMMAND=ssh -i private_key_file -o IdentitiesOnly=yes"

gsullins在注释中建议将以下别名添加到.zshrc中:

alias git.key1="git config core.sshCommand 'ssh -i <absolute path to private key>'"

其他回答

我使用zsh,不同的密钥会自动加载到我的zsh shell的ssh代理中,用于其他目的(即访问远程服务器)。我修改了@Nick的答案,并将其用于我的一个需要经常刷新的转发。(在本例中,无论我在哪里工作,我都希望在所有计算机上使用相同的最新版本的点文件。)

bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID'

生成ssh代理向代理添加只读密钥将目录更改为我的git repo如果cd到repo目录成功,则从远程repo中拉出杀死派生的ssh代理。(我不希望有很多特工在身边徘徊。)

有很多好答案,但其中一些人假定事先具备管理知识。

我认为必须明确强调,如果您通过克隆web URL开始项目- https://github.com/<用户名>/<项目名称>.git那么您需要确保.git/config中[remote“origin”]下的url值已更改为SSH url(请参见下面的代码块)。

除此之外,请确保添加sshCommand,如下所述:

user@workstation:~/workspace/project-name/.git$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    sshCommand = ssh -i ~/location-of/.ssh/private_key -F /dev/null <--Check that this command exist
[remote "origin"]
    url = git@github.com:<user-name>/<project-name>.git  <-- Make sure its the SSH URL and not the WEB URL
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

在这里了解更多信息。

使用git 2.10+(2016年第三季度:2016年9月2日发布),您可以为git_SSH_COMMAND设置配置(而不仅仅是Rober Jack Will的回答中描述的环境变量)

参见Nguy的承诺书(2016年6月26日)ễn Thái Ng先生ọc杜伊(pclouds)。(2016年7月19日,Junio C Hamano--gitster在提交dc21164中合并)

新的配置变量core.shCommand已添加到指定每个存储库要使用的GIT_SSH_COMMAND值。

core.sshCommand:

如果设置了此变量,gitfetch和gitpush将在需要连接到远程系统时使用指定的命令而不是ssh。该命令的格式与GIT_SSH_command环境变量的格式相同,并且在设置环境变量时被覆盖。

这意味着git pull可以是:

cd /path/to/my/repo/already/cloned
git config core.sshCommand 'ssh -i private_key_file' 
# later on
git pull

您甚至可以只为一个命令(如gitclone)设置它:

git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git

这比设置GIT_SSH_COMMAND环境变量更容易,正如Mátyás Kuti Kreszács所指出的,在Windows上

set "GIT_SSH_COMMAND=ssh -i private_key_file"

对于所有这些命令,可以添加-o IdentitesOnly=yes以将SSH限制为指定的私钥/公钥:

git config core.sshCommand 'ssh -i private_key_file -o IdentitiesOnly=yes' 
# or
git -c core.sshCommand="ssh -i private_key_file -o IdentitiesOnly=yes" clone host:repo.git
# or
set "GIT_SSH_COMMAND=ssh -i private_key_file -o IdentitiesOnly=yes"

gsullins在注释中建议将以下别名添加到.zshrc中:

alias git.key1="git config core.sshCommand 'ssh -i <absolute path to private key>'"

这是@VonC答案的扩展。请先阅读。

用例是我需要使用SSH同时使用个人和工作GitHub帐户。我希望使用工作SSH密钥作为默认值,因为我的项目内部将有其他工作repo作为依赖项。因此克隆它们应该可以无缝工作。

我遵循的步骤是:

生成默认SSH密钥并将其添加到工作git帐户。在单独的文件中生成个人SSH密钥,并将其添加到个人git帐户。在.bashrc或.zshrc文件中添加以下函数代码并将其作为源代码。gclone(){#使用个人ssh密钥克隆回购urlgit-c core.sshCommand=“ssh-i path_to_personal_key”clone“$1”&&#使用“awk”从URL提取回购名称,并使用“cd”切换到该文件夹cd$(awk‘{sub(/.*\//,“”);sub(/\.git.*/,“””);print}‘<<“$1”)&&#将个人ssh密钥设置为此回购的默认密钥git-config-core.shCommand“ssh-i path_to_personal_key”;}使用gclone命令使用个人SSH密钥克隆repo,并将repo设置为默认使用该密钥。使用正常的gitclone命令以默认(工作)SSH密钥克隆repo。

如果你像我一样,你可以:

整理好ssh密钥保持gitclone命令简单为任意数量的存储库处理任意数量的密钥。减少ssh密钥维护。

我将密钥保存在~/.ssh/keys目录中。

我更喜欢约定而不是配置。

我认为守则就是法律;越简单越好。

步骤1-创建别名

将此别名添加到shell:alias git clone='git_SSH=SSH_wrapper git clone'

第2步-创建脚本

将此ssh_wrapper脚本添加到PATH中:

#!/bin/bash
# Filename: ssh_wrapper

if [ -z ${SSH_KEY} ]; then
    SSH_KEY='github.com/l3x'  # <= Default key
fi
SSH_KEY="~/.ssh/keys/${SSH_KEY}/id_rsa"
ssh -i "${SSH_KEY}" "$@"

示例

使用github.com/l3x密钥:

KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go

以下示例还使用github.com/l3x密钥(默认情况下):

git-clone https://github.com/l3x/learn-fp-go

使用bitbucket.org/lsheehan密钥:

KEY=bitbucket.org/lsheehan git-clone git@bitbucket.org:dave_andersen/exchange.git

笔记

将SSH_wrapper脚本中的默认SSH_KEY更改为大多数时间使用的SSH_KEY。这样,您不需要在大多数时间使用KEY变量。

你可能会想,“嘿!别名、脚本和一些密钥目录都是如此,”但对我来说,这是惯例。我几乎所有的工作站(以及服务器)都是类似的配置。

我的目标是简化我定期执行的命令。

我的约定,例如Bash脚本、别名等,创建了一个一致的环境,并帮助我保持简单。

KISS和名字很重要。

有关更多设计技巧,请参阅我的书《Go》中的第4章固体设计:https://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW

希望这有帮助。-莱克斯