我有两个 GitHub 帐户,一个用于工作,一个用于个人使用。
由于工作中的 IT 要求,我已经使用 SSH 好几年了,但对于我的个人项目,我一直使用基本身份验证,因为它更简单。
GitHub弃用基本身份验证,所以我现在想为我的个人项目使用 SSH 密钥。
我已经知道如何创建 SSH 密钥并将其与我的 GitHub 帐户关联,但我只能将一个 SSH 密钥与一个帐户关联。因此,我创建了第二个 SSH 密钥并将其与我的个人帐户关联,但现在当我克隆我的个人存储库时,我的 git 客户端会尝试使用我的工作 SSH 密钥而不是我的个人密钥。
如何配置我的个人存储库以使用我的个人 SSH 密钥以及我的工作存储库以使用我的工作密钥?
我正在使用 Mac。
答案1
您可以配置您的个人存储库以使用 SSH“别名”(我为了简单起见这样称呼它)。
假设您有两个 repos,work-repo
并且magnum-opus-repo
(当您有一天完成它时,它将永远改变人类对位图进行位块传输的方式)。
首先,在命令行中运行git remote -v
你的工作仓库。你会看到类似以下内容:
origin [email protected]:day-job-co/work-repo.git (fetch)
origin [email protected]:day-job-co/work-repo.git (push)
冒号前的前缀[email protected]:
告诉您的 SSH 客户端登录 GitHub 时要使用的主机名和用户名。(注意:使用 git 时,您必须使用用户git
名。您的实际用户名将始终被拒绝访问。)
但是,你可以为该前缀添加别名!打开后~/.ssh/config
,你可能会看到类似以下内容:
Host github.com
IdentityFile ~/.ssh/day-job-co
UseKeychain yes
(如果你还没有该位置的配置文件,或者需要有关格式的更多详细信息,请参阅https://linuxize.com/post/using-the-ssh-config-file/)
这告诉 SSH 客户端~/.ssh/day-job-co
在连接到主机时使用您的 SSH 密钥文件github.com
。
如果您想使用不同的密钥文件,那么您可以轻松添加别名,如下所示:
Host github-personal
IdentityFile ~/.ssh/personal
User git
HostName github.com
UseKeychain yes
请注意,创建别名时,您需要明确指定实际的User
(必须是git
)和HostName
(必须是github.com
)。
现在,在您的个人仓库中运行git origin -v
,如果您还没有更改它,您可能会看到类似这样的内容:
origin https://github.com/bit-blitter/magnum-opus-repo.git
您将需要更改此 URL 以使用 SSH,但不是使用默认[email protected]:
前缀,而是使用您创建的别名:github-personal
。
在您的 magnum opus repo 中运行以下命令:
git remote set-url "origin" "github-personal:bit-blitter/magnum-opus-repo"
当 git 使用 SSH 登录时,它会找到github-personal
别名,使用配置的User
和HostName
,[email protected]
以及你个人项目的 SSH 身份密钥文件~/.ssh/personal
。
最后,最后一个配置项UseKeychain yes
是完全可选的。它只是让你在每次推送/拉取/获取等操作时无需输入 SSH 密码。
这只是配置存储库的一种方式,但设置和维护起来非常容易和直接。
答案2
不幸的是,所有提出的解决方案都不适合我。
我的用例:
- 我有私人和工作 GitHub 帐户。
- 账户也可以是组织的成员,但并不都属于同一个组织。
- 我也在 GitLab 和其他网站上有账户。
- 我将所有代码都组织在结构中,
~/work/
在这里我可以使用子文件夹进行进一步区分,例如,,,,~/work/priv/
等等。然而,这不是必须遵循的结构。它也可以是:和 ~/my_work_account`,或者任何你喜欢的。~/work/comp1/
~/work/comp2/
~/my_private_account/
- 我仅使用 SSH 来拉取/推送代码。
我的解决方案
解决方案是创建一个自定义.gitconfig
文件,其中包含针对特定配置的条件包含。在本例中,是不同的帐户。
更多模式和进一步阅读内容可在官方文档。
我的~/.gitconfig
文件:
[user]
name = Dusan Milojkovic
email = [email protected]
; START CUSTOM CONFIG BLOCK FOR PRIVATE ACCOUNT
; include for all repositories inside $HOME/work/priv/
[includeIf "gitdir:~/work/priv/"]
; The import is relative to the importer (this file)
; But, it can also be an absolute path
path = .gitconfig-dmilojkovic.inc
; END CUSTOM CONFIG BLOCK FOR PRIVATE ACCOUNT
; START CUSTOM CONFIG BLOCK FOR WORK ACCOUNT
; include for all repositories inside $HOME/work/comp1/
[includeIf "gitdir:~/work/comp1/"]
; The import is relative to the importer (this file)
; But, it can also be an absolute path
path = .gitconfig-comp1.inc
; END CUSTOM CONFIG BLOCK FOR WORK ACCOUNT
有条件地包括~/.gitconfig-dmilojkovic.inc
[core]
SshCommand = "ssh -i ~/.ssh/ssh_key_for_private_account"
有条件地包括~/.gitconfig-comp1.inc
[core]
SshCommand = "ssh -i ~/.ssh/ssh_key_for_work_account"
[user]
name = dmilojkovic
email = [email protected]
诀窍在于,SshCommand =
它定义了用于子文件夹中所有存储库的确切 SSH 密钥。将语句保留IncludeIf
在.gitconfig
文件的最后位置,因为最后读取的变量将是 git 将使用的变量,但如果您不将一个条件包含嵌套在另一个条件包含中,则条件包含不会相互影响。
因此,我现在可以.gitconfig-<ACCOUNT_NAME>.inc
为不同的帐户和我需要的任何其他覆盖创建具有不同 SSH 密钥的自定义文件,并创建一个IncludeIf
只有满足我的条件才会有条件包含的新语句。
我希望这有帮助。