ssh-github多用户

旨在单一机器使用 SSH 对应多个 GitHub 账户。

使用一台机器可以生成多个 SSH 密钥,可以分别指定多个 GitHub 用户,也可以绑定给一个账户。

但单一的 SSH 密钥不能绑定多个账户,在此之前不知道如何切换全局 Git 密钥,这会导致在全局密钥与仓库账户不对应时的报错,于是有了此文。

处理的方式是通过配置文件指定不同账户对应的密钥文件,但这样做也会导致无论推送到哪个仓库,最终的提交者都是本地的 Git 账户,而不是仓库所有者(也有可能是配置不完全的问题),这相当于使用密钥文件给本地的 Git 账户上传的权限,从而可以进行推送。

0. 处理步骤

  1. 创建多个 SSH 密钥

  2. 找到 SSH 的 config 文件:在 ~/.ssh 目录下,编辑或创建一个名为 config 的文件(没有文件类型后缀)

  3. 添加配置信息:在 config 文件中,可以为每个 GitHub 用户指定 Host,并且关联相应的 SSH 密钥,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 用户1
    Host github.com-user1
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_user1

    # 用户2
    Host github.com-user2
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_user2

    在上面的配置中,id_rsa_user1id_rsa_user2 分别是为两个不同的 GitHub 用户生成的私钥文件。Host字段是为每个连接自定义的别名,HostName 应始终是 github.com (使用 GitLab 与 Gitee 的时候需要修改),User 通常是 git

  4. 使用 SSH 密钥:当想要与 GitHub 上的仓库进行交互时,需要使用在 config 文件中指定的 Host 别名。例如,如果想要克隆用户1的仓库,应该使用:

    1
    git clone git@github.com-user1:用户名/仓库名.git

    使用 github.com-user1(或者对应用户2的配置 github.com-user2 )替换github.com,这样 git 就会使用正确的 SSH 密钥进行认证。

1. 使用示例

使用一个名为 ssx 的账户,并为这个账户配置 SSH 密钥,可以这样做:

1
2
3
4
5
# ~/.ssh/config
Host github.com-ssx
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_ssx

在这个配置中:

  • Host github.com-ssx 是为这个特定 GitHub 账户和 SSH 密钥对定义的别名。可以使用任何名字,只要它是有意义的。这里使用 github.com-ssx 仅仅是为了示例,如果可以记住,大可使用 a,b,c 这样的代号来指定。
  • HostName github.com 指定了 GitHub 的实际主机名,这一行对所有 GitHub 配置都是一样的。
  • User git 是 GitHub 仓库使用的标准用户名。
  • IdentityFile ~/.ssh/id_rsa_ssx 指向了 ssx 账户对应的私钥文件。确保路径和文件名与密钥匹配。

配置好 ~/.ssh/config 文件后,当要使用 ssx 账户与 GitHub 进行交互(例如,克隆一个属于 ssx 的仓库)时,可以使用如下命令:

1
git clone git@github.com-ssx:ssx/仓库名.git

通过这种方式,git 会根据 ~/.ssh/config 中的配置,使用 github.com-ssx 对应的私钥与 GitHub 进行认证。这种配置方式增加了使用多个 GitHub 账户和 SSH 密钥的灵活性和便捷性。

2. 提交者问题

在使用 SSH 密钥与 GitHub 进行交互时,确实可以实现免密登录和操作,但 GitHub 确定提交操作是由哪个用户执行的,是基于提交时使用的电子邮件地址,而不是 SSH 密钥。换句话说,SSH密钥用于身份验证(即证明连接者是谁),而连接者信息(包括用户名和电子邮件地址)则是基于 git 配置的user.nameuser.email设置。

所以,如果没有对项目的 Git 配置过对应用户信息,就会导致无论使用哪份密钥,提交者信息都回是同一个,都是 Git 的全局用户,解决方式就是为单个项目设置用户信息。

2.0 设置单项目用户信息

打开终端(或PowerShell),切换到 Git 项目目录下,然后执行以下命令来配置用户名和电子邮件地址:

1
2
git config user.name "新用户名"
git config user.email "新邮箱地址"

这将只影响当前项目的配置,覆盖全局信息。这样,即使使用的是同一台机器上的 SSH 密钥进行认证,不同的项目也可以显示为不同用户的提交。

而修改全局信息的执行的是以下命令,这应该是在安装 Git 时常使用的命令:

1
2
git config --global user.name "新用户名"
git config --global user.email "新邮箱地址"

这将更新您的全局~/.gitconfig文件,以后所有新的提交都会使用这个用户名和电子邮件地址,除非在项目级别进行了覆盖。

2.1 其他方式

这里只说大概逻辑,并不展开详谈:

  1. 使用条件式 Git 配置:Git 支持基于目录的条件配置,可以在全局 .gitconfig 中修改,为不同的目录指定不同的 .gitconfig 文件(每次可能都要去修改,还不如直接使用命令配置当前项目用户信息)

  2. 使用脚本或别名自动化:创建一个不同用户信息的别名,使用这个别名快速切换用户信息,比如为 user1 创建一个名为 switch-user1 的别名:

    1
    git config --global alias.switch-user1 '!git config user.name "user1" && git config user.email "user1@example.com"'

    然后使用 git switch-user1 来切换当前仓库的用户信息。(还算便捷)

  3. 使用 Git 钩子:利用Git的钩子(特别是pre-commit钩子)来在提交前自动设置用户信息。这需要一定程度的脚本编写能力,以在每次提交时检查项目路径或其他条件,并据此设置相应的用户信息。