首先,安排您的 ssh 命令将您的“GitHub 身份”(实际上是:密钥)发送到 GitHub,并将您的“Bitbucket 身份”发送到 Bitbucket。这意味着您的 ssh 配置1(不是 Git 配置!)将包括:
Host github.com
IdentityFile ~/.ssh/id_rso
IdentitiesOnly yes
(最后一行不是必需的,但这是个好主意)和:
Host bitbucket.org
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
(假设我这里的 ID 文件是正确的)。然后使用ssh://git@github.com/path/to/repo.git 和ssh://git@bitbucket.com/path/to/repo.git 作为您的两个遥控器的URL(如果您愿意,可以使用git@$hostingsite:path 语法,这没有区别,我自己就是喜欢ssh:// 语法)。单独的遥控器将保持独立,您只会在您告诉 Git 从每个遥控器获取或推送到每个遥控器时从每个遥控器获取或推送到每个遥控器。
技术说明
从技术上讲,GitHub 和 Bitbucket 都不会使用您的电子邮件帐户。好吧,他们都使用它——但向您发送电子邮件,而不是将某些传入数据流识别为“您”。他们还使用它来识别“由您进行”的提交以用于显示目的;但是这样的提交可以被其他人注入。
特别是,每当您使用 SSH 连接到任一 Bitbucket 或 GitHub 时,您都会运行以下非交互式等效项:
ssh -T git@$hostingsite
其中$hostingsite 是bitbucket.org 或github.com。这意味着您要求这些系统以名为git 的用户身份登录,而不是您自己!那么他们怎么知道你是你呢?
本次讨论的其余部分实际上是关于 Gitolite 的工作原理
下面的描述假设对整个 authorized_keys 文件进行线性扫描,这对于繁忙的 Bitbucket 和 GitHub 服务器来说可能太慢了。不过,原则应该是一样的。 Gitolite 系统实际上就是这样工作的,以便在未经修改的 Unix / Linux 服务器上工作。
用户git,在这些系统上,不允许做太多事情。但是,该特定用户有一个很长的 authorized_keys 文件,而不是通常的 ssh-rsa AAAA... 行,以以下开头的行:2
restrict,command="<path>/gl-auth-command <user>" ssh-rsa AAAA...
当机器上的sshd 服务器接受传入的密钥并将其与存储在用户git 的authorized_keys 文件中的公钥匹配时,此受限且特殊的命令行使其运行其他东西比通用外壳。在这个特定的示例中,我们提供了 Gitolite 授权步骤的路径,并且 用户 ssh 的名称刚刚基于此密钥进行了授权。
您的 Git 发送的运行 git upload-pack 或类似请求的请求保存在环境变量 ($ORIGINAL_SSH_COMMAND) 中。因此,刚刚运行的实际命令知道让你进入的密钥是谁的,以及你要求执行的 Git 操作(如果你要求做一个 - 如果没有,你会得到“成功授权, 但是”$hostingsite 打印的消息)。
Running a “secure” git server over SSH without gitosis/gitolite? 和this superuser.com Q&A 中有更多讨论。
1ssh 配置文件通常命名为$HOME/.ssh/config。
2我在这里使用restrict,而不是费力地列举所有要禁用的 ssh 功能。我认为一些较旧的 sshd 版本不支持restrict,因此链接问题中的版本较长。