在同一台开发机上隔离多个 Git 账号
同一台开发机上经常会有多个 Git 身份:自己的账号、开源组织的账号,或者不同代码托管平台上的账号。每个身份都有自己的 SSH 密钥,一旦混用,轻则被服务器拒绝,重则把提交推到不该推的账号下。
与其每次手动切换,不如把目录和密钥的对应关系固定下来,让 Git 按路径自动选择。
生成密钥:每个身份一把
先给每套身份生成独立的 Ed25519 密钥,不要复用默认的 id_ed25519:
ssh-keygen -t ed25519 -C "alpha@example.com" -f ~/.ssh/id_ed25519_alpha-t ed25519:推荐的算法,密钥短、签名快,主流平台都支持-f:指定输出路径,避免覆盖已有的默认密钥-C:注释,写清用途,方便在平台上辨认
执行过程中会提示设置 passphrase。建议设置,并把它加入 ssh-agent,免得每次推送都要输入(如果 ssh-agent 尚未运行,先执行 eval "$(ssh-agent -s)"):
ssh-add ~/.ssh/id_ed25519_alpha接着收紧权限:
chmod 700 ~/.sshchmod 600 ~/.ssh/id_ed25519_alphachmod 644 ~/.ssh/id_ed25519_alpha.pub查看公钥,添加到对应平台或服务器:
cat ~/.ssh/id_ed25519_alpha.pub私钥(没有 .pub 后缀的那个文件)不要外传,也不要放进同步盘或仓库。另外,同一个公钥不能同时添加到两个 GitHub 账号,每套身份都要单独生成一对。
按目录加载不同配置
前提是不同身份的代码放在不同目录,比如 ~/workspace/alpha/ 和 ~/workspace/beta/。Git 的 includeIf 可以按仓库路径加载不同的配置文件(需要 Git 2.13 及以上)。
在 ~/.gitconfig 末尾加入:
[includeIf "gitdir:~/workspace/alpha/"] path = ~/.gitconfig-alpha然后创建 ~/.gitconfig-alpha:
[core] sshCommand = ssh -i ~/.ssh/id_ed25519_alpha -o IdentitiesOnly=yes两个细节:
gitdir:~/workspace/alpha/末尾的/不能省,它表示“该目录下的所有仓库”;不带/只匹配该路径本身。IdentitiesOnly=yes让 SSH 只使用-i指定的钥匙,不再把 ssh-agent 里的其他密钥逐个递给服务器。没有它,agent 里恰好有另一把被授权的钥匙时,Git 可能以错误的身份通过认证。
之后这个目录下的仓库自动使用 alpha 的密钥,其他地方不受影响。需要几套身份,就重复几组 includeIf 和对应的配置文件。
只对单个仓库生效
如果不想按目录管理,进入仓库后直接设置局部配置:
git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_alpha -o IdentitiesOnly=yes"这个值会写进该仓库的 .git/config,优先级高于全局配置。
顺带切换提交身份
SSH 密钥决定“以什么身份连接”,user.name 和 user.email 决定“以什么身份提交”,两者要一起改。在 ~/.gitconfig-alpha 里再加一段:
[user] name = Alpha email = alpha@example.com这样该目录下仓库的提交作者也不会串。
验证
在 ~/workspace/alpha/ 下任意仓库里查看配置来源:
git config --show-origin --get core.sshCommand--show-origin 会显示这条配置来自哪个文件,能确认 includeIf 确实命中了。再验证密钥本身:
ssh -i ~/.ssh/id_ed25519_alpha -o IdentitiesOnly=yes -T git@github.com这条命令直接调用 ssh,不会读取 Git 的 core.sshCommand,所以要手动带上同样的参数。若要连真实仓库测试:
git ls-remote git@github.com:your-org/your-repo.git小结
- 每个身份单独生成一对 Ed25519 密钥,私钥不外传,公钥只加到对应账号。
- 用
includeIf按目录加载配置,用core.sshCommand指定密钥,并加上IdentitiesOnly=yes。 - 密钥之外,别忘了同目录下的
user.name和user.email,否则连接身份对了,提交作者还是会串。 - 临时切换可以只对单个仓库设置
core.sshCommand,不必动全局配置。