原文: How to manage multiple GitHub accounts on a single machine with SSH keys

对大多数开发者来说,有时候需要在同一台机器上管理多个 GitHub 账户。当我碰巧换了 Mac,或者需要用新的工作账户进行 Git 推送时,我经常都需要停下来去搜索如何实现。

我的懒惰使我没有把过程记录下来,也没有能力记住步骤,这使我花了相当多的时间从网上找零碎的东西,然后以某种方式使它发挥作用。

我相信你们当中有很多人都有过这样的经历,也有很多人只是在等待下一次发生同样的事情(包括我自己!)。本文介绍的方法是为了帮助我们所有人。

1. 生成 SSH 密钥

在生成 SSH 密钥之前,我们可以检查一下我们是否有任何现有的 SSH 密钥:ls -al ~/.ssh 这将列出所有现有的公钥和私钥对,如果存在的话。

如果 ~/.ssh/id_rsa 是可用的,我们可以重新使用它,否则我们可以先通过运行以下代码来生成一个默认 ~/.ssh/id_rsa 的密钥:

ssh-keygen -t rsa

对于保存密钥的位置,按回车键接受默认位置。一个私钥和公钥 ~/.ssh/id_rsa.pub 将在默认的 SSH 位置 ~/.ssh/ 创建。

让我们为我们的个人账户使用这个默认的密钥对。

对于工作账户,我们将创建不同的 SSH 密钥。下面的代码将生成 SSH 密钥,并将标签为 “email@work_mail.com” 的公钥保存到 ~/.ssh/id_rsa_work_user1.pub 中。

$ ssh-keygen -t rsa -C "email@work_mail.com" -f "id_rsa_work_user1"

我们创建了两个不同的密钥:

~/.ssh/id_rsa
~/.ssh/id_rsa_work_user1

2. 将新的 SSH 密钥添加到相应的 GitHub 账户中

我们已经准备好了 SSH 公钥,我们将要求 GitHub 账户信任我们创建的密钥。这是为了避免每次进行 Git 推送时都要输入用户名和密码的麻烦。

复制公钥 pbcopy < ~/.ssh/id_rsa.pub,然后登录你的个人 GitHub 账户:

  • 转到 Settings
  • 在左边的菜单中选择 SSH and GPG keys
  • 点击 New SSH key,提供一个合适的标题,并将密钥粘贴在下面的方框中
  • 点击 Add key - 就完成了!

对于工作账户,使用相应的公钥(pbcopy < ~/.ssh/id_rsa_work_user1.pub),在 GitHub 工作账户中重复上述步骤。

3 . 在 ssh-agent 上注册新的 SSH 密钥

为了使用这些密钥,我们必须在我们机器上的 ssh-agent 上注册它们。使用 eval "$(ssh-agent -s)" 命令确保 ssh-agent 运行。像这样把密钥添加到 ssh-agent 中:

ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_work_user1

让 ssh-agent 为不同的 SSH 主机使用各自的 SSH 密钥。

这是最关键的部分,我们有两种不同的方法:

使用 SSH 配置文件(第 4 步),以及在 ssh-agent 中每次只有一个有效的 SSH 密钥(第 5 步)。

4. 创建 SSH 配置文件

在这里,我们实际上是为不同的主机添加 SSH 配置规则,说明在哪个域名使用哪个身份文件。

SSH 配置文件将在 ~/.ssh/config 中。如果有的话,请编辑它,否则我们可以直接创建它。

$ cd ~/.ssh/
$ touch config           // Creates the file if not exists
$ code config            // Opens the file in VS code, use any editor

~/.ssh/config 文件中为相关的 GitHub 账号做类似于下面的配置项:

# Personal account, - the default config
Host github.com
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa
   
# Work account-1
Host github.com-work_user1    
   HostName github.com
   User git
   IdentityFile ~/.ssh/id_rsa_work_user1

“work_user1” 是工作账户的 GitHub 用户 ID。

“github.com-work_user1” 是用来区分多个 Git 账户的记号。你也可以使用 “work_user1.github.com” 记号。确保与你使用的主机名记号一致。当你克隆一个仓库或为本地仓库设置 remote origin 时,这一点很重要。

上面的配置要求 ssh-agent:

  • 使用 id_rsa 作为任何使用 @github.com 的 Git URL 的密钥
  • 对任何使用 @github.com-work_user1 的 Git URL 使用 id_rsa_work_user1 密钥

5. 在 ssh-agent 中每次有一个活跃的 SSH 密钥

这种方法不需要 SSH 配置规则。相反,我们手动确保在进行任何 Git 操作时,ssh-agent 中只有相关的密钥。

ssh-add -l 会列出所有连接到 ssh-agent 的 SSH 密钥。把它们全部删除,然后添加你要用的那个密钥。

如果是要推送到个人的 Git 账号:

$ ssh-add -D            //removes all ssh entries from the ssh-agent
$ ssh-add ~/.ssh/id_rsa                 // Adds the relevant ssh key

现在 ssh-agent 已经有了映射到个人 GitHub 账户的密钥,我们可以向个人仓库进行 Git 推送。

要推送到工作的 GitHub account-1,需要改变 SSH 密钥与 ssh-agent 的映射关系,删除现有的密钥,并添加与 GitHub 工作账号映射的 SSH 密钥。

$ ssh-add -D
$ ssh-add ~/.ssh/id_rsa_work_user1

目前,ssh-agent 已经将密钥映射到了工作的 GitHub 账户,你可以将 Git 推送到工作仓库。不过这需要一点手动操作。

为本地仓库设置 git remote url

一旦我们克隆/创建了本地的 Git 仓库,确保 Git 配置的用户名和电子邮件正是你想要的。GitHub 会根据提交(commit)描述所附的电子邮件 ID 来识别任何提交的作者。

要列出本地 Git 目录中的配置名称和电子邮件,请执行 git config user.namegit config user.email。如果没有找到,可以进行更新。

git config user.name "User 1"   // Updates git config user name
git config user.email "user1@workMail.com"

6. 克隆仓库

注意:如果我们在本地已经有了仓库,那么请查看第 7 步。

现在配置已经好了,我们可以继续克隆相应的仓库了。在克隆时,注意我们要使用在 SSH 配置中使用的主机名。

仓库可以使用 Git 提供的 clone 命令来克隆:

git clone git@github.com:personal_account_name/repo_name.git

工作仓库将需要用这个命令来进行修改:

git clone git@github.com-work_user1:work_user1/repo_name.git

这个变化取决于 SSH 配置中定义的主机名。@ 和 : 之间的字符串应该与我们在 SSH 配置文件中给出的内容相匹配。

7. 对于本地存在的版本库

如果我们有已经克隆的仓库:

列出该仓库的 Git remote,git remote -v

检查该 URL 是否与我们要使用的 GitHub 主机相匹配,否则就更新 remote origin URL。

git remote set-url origin git@github.com-worker_user1:worker_user1/repo_name.git

确保 @ 和 : 之间的字符串与我们在 SSH 配置中给出的主机一致。

如果你要在本地创建一个新的仓库:

在项目文件夹中初始化 Git git init

在 GitHub 账户中创建新的仓库,然后将其作为 Git remote 添加给本地仓库。

git remote add origin git@github.com-work_user1:work_user1/repo_name.git 

确保 @ 和 : 之间的字符串与我们在 SSH 配置中给出的主机相匹配。

推送初始提交到 GitHub 仓库:

git add .
git commit -m "Initial commit"
git push -u origin master

我们完成了!

依据正确的主机,添加或更新的本地 Git 目录的 Git remote,选择正确的 SSH 密钥来验证我们的身份。有了以上这些,我们的 git 操作应该可以无缝运行了。