一台机器配置多个 GitHub 账号
一台开发机上同时维护个人项目和工作项目,提交记录希望用不同的 GitHub 账号。不想每次 clone 后手动改
user.email,也不想搞全局切换脚本。SSH 密钥隔离 + Git 条件配置就能解决,配完一劳永逸。
1. 场景
典型需求:
- 个人项目(
~/personal/*)用个人 GitHub 账号提交 - 工作项目(
~/work/*)用公司 GitHub 账号提交 - 每个账号有独立的 SSH 密钥,互不干扰
- 进入不同目录自动切换身份,无需手动配置
额外痛点:
- 公司网络可能封 SSH 默认端口 22,需要走 443
- 有些项目需要用别名(如
work.github.com)区分 remote URL
2. 整体思路
三层配置协同工作:
- SSH 层(
~/.ssh/config):为不同账号配置独立密钥和 Host 别名 - Git 全局层(
~/.gitconfig):设置默认账号和 SSH 命令 - Git 条件层(
~/.gitconfig-work):按目录路径自动覆盖账号信息
关键机制:includeIf 让 Git 在特定目录下加载额外配置文件。
3. 步骤
3.1 生成 SSH 密钥对
为每个账号生成独立密钥:
# 个人账号密钥
ssh-keygen -t rsa -b 4096 -C "personal@example.com" -f ~/.ssh/id_rsa_personal
# 工作账号密钥
ssh-keygen -t rsa -b 4096 -C "work@company.com" -f ~/.ssh/id_rsa_work
生成后会得到:
~/.ssh/id_rsa_personal+~/.ssh/id_rsa_personal.pub~/.ssh/id_rsa_work+~/.ssh/id_rsa_work.pub
将 .pub 公钥分别添加到对应 GitHub 账号的 SSH keys 设置页面。
3.2 配置 SSH Host 别名
编辑 ~/.ssh/config(没有则创建):
# 个人账号(默认)
Host github.com
HostName ssh.github.com
User git
IdentityFile ~/.ssh/id_rsa_personal
Port 443
# 工作账号(使用别名 work.github.com)
Host work.github.com
HostName ssh.github.com
User git
IdentityFile ~/.ssh/id_rsa_work
Port 443
重点说明:
- Port 443:绕过防火墙对 22 端口的封锁,GitHub 官方支持
ssh.github.com:443 - Host 别名:
work.github.com是本地别名,实际连接的还是ssh.github.com - IdentityFile:指定使用哪个密钥
测试连接:
# 测试个人账号
ssh -T git@github.com
# 预期输出:Hi personal-username! You've successfully authenticated...
# 测试工作账号
ssh -T git@work.github.com
# 预期输出:Hi work-username! You've successfully authenticated...
3.3 配置 Git 全局默认
编辑 ~/.gitconfig:
[user]
name = Your Name
email = personal@example.com
[core]
# 全局强制使用个人账号密钥
sshCommand = ssh -i ~/.ssh/id_rsa_personal -F /dev/null
# 条件配置:work 目录自动切换账号
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
关键点:
sshCommand强制使用指定密钥,-F /dev/null阻止~/.ssh/config干扰(可选,取决于你的优先级策略)includeIf匹配路径时,gitdir:后的路径必须以/结尾才能匹配子目录- 路径支持
~展开和通配符*
3.4 配置工作账号条件文件
创建 ~/.gitconfig-work:
[user]
name = Your Name
email = work@company.com
[core]
sshCommand = ssh -i ~/.ssh/id_rsa_work -F /dev/null
现在逻辑是:
- 默认用个人账号(
~/.gitconfig) - 进入
~/work/任何子目录,自动切换到工作账号(~/.gitconfig-work覆盖)
3.5 使用 Host 别名 clone 工作项目
工作项目 clone 时需要修改 URL:
# 原始 URL(会用个人账号)
git clone git@github.com:company/project.git
# 改用 Host 别名(会用工作账号密钥)
git clone git@work.github.com:company/project.git
或者 clone 后修改 remote:
git remote set-url origin git@work.github.com:company/project.git
为什么需要别名?
即使在 ~/work/ 目录下,如果 remote URL 是 git@github.com,SSH 会优先匹配 ~/.ssh/config 中的 Host github.com 配置。Host 别名让你在 URL 层面就区分账号。
4. 验证配置
4.1 检查当前目录生效的配置
# 在个人项目目录
cd ~/personal/my-project
git config user.email
# 输出:personal@example.com
# 在工作项目目录
cd ~/work/company-project
git config user.email
# 输出:work@company.com
4.2 检查 SSH 连接使用的密钥
# 查看实际使用的 SSH 命令
git config core.sshCommand
# 手动测试(带详细日志)
GIT_SSH_COMMAND="ssh -v" git ls-remote origin
# 输出中会显示 "Offering public key: /path/to/id_rsa_xxx"
4.3 测试提交身份
# 创建测试提交
echo "test" > test.txt
git add test.txt
git commit -m "test commit"
# 查看提交的 author
git log -1 --format="%an <%ae>"
5. 常见问题
5.1 端口 22 被墙
症状:ssh -T git@github.com 超时
解决:在 ~/.ssh/config 中添加:
Host github.com
HostName ssh.github.com
Port 443
GitHub 官方在 ssh.github.com 的 443 端口提供 SSH 服务,专门用于绕过防火墙。
5.2 密钥权限问题
症状:Permissions 0644 for 'id_rsa_work' are too open
解决:
chmod 600 ~/.ssh/id_rsa_*
chmod 644 ~/.ssh/id_rsa_*.pub
私钥必须只有所有者可读写(600),公钥可以宽松一些(644)。
5.3 includeIf 不生效
检查清单:
- 路径必须以
/结尾:gitdir:~/work/(对)vsgitdir:~/work(错) - Git 版本:
includeIf需要 Git 2.13+,运行git --version确认 - 路径展开:
~会展开,但相对路径不会,建议用绝对路径或~/ - 调试:运行
git config --show-origin user.email查看配置来源
5.4 已有项目切换账号
如果项目已经用错误账号提交过:
# 1. 修改 remote URL(如果需要)
git remote set-url origin git@work.github.com:company/project.git
# 2. 修改最近一次提交的 author(如果还没 push)
git commit --amend --reset-author
# 3. 批量修改历史提交(慎用,会改写历史)
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_EMAIL" = "wrong@example.com" ]; then
export GIT_COMMITTER_EMAIL="correct@example.com"
export GIT_AUTHOR_EMAIL="correct@example.com"
fi
' --tag-name-filter cat -- --branches --tags
6. 进阶:更细粒度的控制
6.1 按项目单独配置
如果某个项目需要特殊配置,在项目内运行:
git config user.email "special@example.com"
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_special"
项目级配置(.git/config)优先级最高,会覆盖全局和条件配置。
6.2 多个工作目录
如果有多个工作目录:
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/company-a/"]
path = ~/.gitconfig-company-a
[includeIf "gitdir:~/company-b/"]
path = ~/.gitconfig-company-b
6.3 HTTPS 协议多账号
本文聚焦 SSH,但 HTTPS 也可以多账号:
- macOS Keychain 存储凭据,
git-credential-osxkeychain管理 - 或用 GitHub CLI:
gh auth login支持多账号切换 - 条件配置中可以设置不同的
credential.helper
7. 总结
配置后的工作流:
- 个人项目放在
~/personal/,自动用个人账号 - 工作项目放在
~/work/,自动用工作账号 - Clone 工作项目时记得用
git@work.github.com - 忘记配置也没关系,提交前
git config user.email检查一下
核心收益:
- 零手动切换:进入目录自动生效
- 隔离彻底:密钥、身份、目录三层隔离
- 可验证:每步都有明确的测试方法
这套配置用了两年,再没有提交记录用错账号的情况。