概述
用公司电脑写个人项目,git log 里却全是公司邮箱?推送到 GitHub 却提示权限拒绝?这是每个同时使用公司 GitLab 和个人 GitHub 的开发者都会遇到的问题。
本文基于一次真实的配置过程,采用 SSH 多密钥 + Git 条件包含 方案,实现不同目录自动切换 Git 身份。从密钥生成到推送成功,包含完整步骤、原理图解,以及公司网络下端口被封、Host Key 验证失败等实际踩坑的解决方案。
你也可以将当前网页保存,然后用Claudecode参考这个网页内容直接完成。
适用场景:公司 GitLab + 个人 GitHub 并存(也适用于任意两个 Git 平台的多账号管理)
阅读时间 :约 10 分钟 | 配置时间:约 15 分钟
需求场景
(任意目录)"] A --> C["个人项目
(指定目录)"] B -->|公司密钥 + 公司邮箱| D["公司 GitLab"] C -->|个人密钥 + 个人邮箱| E["个人 GitHub"] style B fill:#4A90D9,color:#fff style C fill:#7B68EE,color:#fff style D fill:#FC6D26,color:#fff style E fill:#238636,color:#fff
配置前的准备
在开始之前,请先确认你有以下信息:
| 信息 | 示例 | 你的值 |
|---|---|---|
| 公司 GitLab 地址 | git.company.com | ______ |
| 公司邮箱 | zhangsan@company.com | ______ |
| 公司 Git 用户名 | zhangsan | ______ |
| 个人 GitHub 邮箱 | zhangsan@qq.com | ______ |
| 个人 GitHub 用户名 | zhangsan | ______ |
| 个人项目目录 | D:/obsidian/ | ______ |
下面的步骤以 Windows 为例。macOS/Linux 路径稍有不同,会在对应步骤标注。
Step 1: 生成个人 SSH 密钥
打开 Git Bash,执行:
bash
ssh-keygen -t ed25519 -C "你的个人邮箱" -f ~/.ssh/id_ed25519_personal
会提示输入密码(passphrase),直接按两次回车跳过即可。
执行成功后会在 ~/.ssh/ 目录下生成两个文件:
id_ed25519_personal--- 私钥(不要给任何人)id_ed25519_personal.pub--- 公钥(后面要添加到 GitHub)
注意:如果你还没有公司的 SSH 密钥,也用类似命令生成一份:
bashssh-keygen -t ed25519 -C "你的公司邮箱" -f ~/.ssh/id_ed25519
Step 2: 配置 SSH config
创建或编辑 SSH 配置文件:
- Windows :
C:\Users\你的用户名\.ssh\config - macOS/Linux :
~/.ssh/config
写入以下内容(根据你的实际信息修改):
bash
# ====================================
# 公司 GitLab(使用公司密钥)
# ====================================
Host git.company.com
HostName git.company.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
# ====================================
# 个人 GitHub(使用个人密钥)
# ====================================
Host github-personal
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
逐行解释:
| 配置项 | 含义 |
|---|---|
Host |
给这个连接起个别名,后面 git 操作会用到 |
HostName |
实际连接的服务器地址 |
Port 443 |
使用 443 端口(很多公司网络封了默认的 22 端口,443 端口更通用) |
User git |
SSH 用户名,Git 服务固定为 git |
IdentityFile |
指定使用哪个私钥文件 |
IdentitiesOnly yes |
只使用指定的密钥,不尝试其他密钥 |
为什么 GitHub 用
ssh.github.com和 443 端口? 很多公司防火墙会封锁 22 端口,导致ssh -T git@github.com超时。 GitHub 官方提供了 443 端口的替代方案,用ssh.github.com即可绕过限制。 如果你不在公司网络环境下,也可以用标准配置:
bashHost github-personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal IdentitiesOnly yes
Step 3: 把个人公钥添加到 GitHub
3.1 复制公钥内容
bash
cat ~/.ssh/id_ed25519_personal.pub
会输出类似这样的一行内容(选中并复制):
css
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...... your@email.com
3.2 添加到 GitHub
- 打开浏览器,登录 GitHub
- 点击右上角头像 → Settings
- 左侧菜单找到 SSH and GPG keys
- 点击 New SSH key
- Title :随便填个名字,比如
work-laptop - Key:粘贴刚才复制的公钥内容
- 点击 Add SSH key
公司 GitLab 同理:如果还没添加过公司密钥,把
~/.ssh/id_ed25519.pub的内容添加到 GitLab 的 SSH Keys 设置中。
Step 4: 添加 GitHub 的 Host Key
首次连接 GitHub 时,SSH 需要确认服务器身份。提前添加可以避免后续报错:
bash
ssh-keyscan -p 443 ssh.github.com >> ~/.ssh/known_hosts 2>/dev/null
如果你在 Step 2 中用的是标准 22 端口配置,则执行:
bashssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null
Step 5: 测试 SSH 连接
bash
# 测试个人 GitHub
ssh -T git@github-personal
# 测试公司 GitLab
ssh -T git@git.company.com
期望结果:
vbnet
# GitHub 成功输出(退出码 1 是正常的):
Hi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.
# GitLab 成功输出:
Welcome to GitLab, 你的名字!
如果失败了怎么办? 见文末 常见问题 。
Step 6: 配置 Git 用户身份(条件包含)
目标:不同目录自动使用不同的用户名和邮箱,无需手动切换。
6.1 编辑全局 Git 配置
打开全局配置文件:
- Windows :
C:\Users\你的用户名\.gitconfig - macOS/Linux :
~/.gitconfig
确保文件中有以下内容(在文件末尾添加 includeIf 部分):
gitconfig
[user]
name = 公司用户名
email = 公司邮箱@company.com
# 当在个人项目目录下操作时,自动加载个人配置
[includeIf "gitdir:D:/obsidian/"]
path = ~/.gitconfig-personal
macOS/Linux 路径写法不同:
gitconfig[includeIf "gitdir:~/obsidian/"] path = ~/.gitconfig-personal
注意 :
gitdir:后面的路径末尾必须带/,否则不会生效。
6.2 创建个人配置文件
新建文件 ~/.gitconfig-personal(跟 .gitconfig 同目录),写入:
gitconfig
[user]
name = 你的GitHub用户名
email = 你的个人邮箱
6.3 验证配置是否生效
bash
# 在个人项目目录下
cd D:/obsidian
git init # 如果还不是 git 仓库的话
git config user.name
git config user.email
# 应该输出你的个人用户名和个人邮箱
# 在公司项目目录下
cd /path/to/company/project
git config user.email
# 应该输出你的公司邮箱
Step 7: 初始化个人仓库并推送
7.1 在 GitHub 上创建仓库
- 打开 GitHub → 点击右上角 + → New repository
- 填写仓库名(如
obsidian) - 不要勾选任何初始化选项(不要添加 README、.gitignore 等)
- 点击 Create repository
为什么不要勾选初始化选项? 如果 GitHub 自动创建了一个
master分支(带 README),而你本地也创建了提交, 两边的 Git 历史是独立的,推送时会遇到refusing to merge unrelated histories错误,需要额外处理。 空仓库则不会有这个问题。
7.2 本地初始化并推送
bash
cd D:/obsidian
# 初始化 Git 仓库
git init
# 添加远程仓库(注意用 github-personal,不是 github.com)
git remote add origin git@github-personal:你的用户名/仓库名.git
# 添加所有文件并提交
git add .
git commit -m "chore: 初始化仓库"
# 推送到远程(首次推送需要 -u 设置上游分支)
git push -u origin master
关键点 :远程地址中用
github-personal而不是github.com。 这样 SSH 才会匹配到 Step 2 中配置的个人密钥。
7.3 后续日常推送
首次推送设置了 -u 之后,以后只需:
bash
cd D:/obsidian
git add .
git commit -m "你的提交信息"
git push
完整配置文件参考
~/.ssh/config
bash
# 公司 GitLab
Host git.company.com
HostName git.company.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
# 个人 GitHub(443 端口,适配公司网络)
Host github-personal
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
~/.gitconfig
gitconfig
[user]
name = 公司用户名
email = 公司邮箱@company.com
[includeIf "gitdir:D:/obsidian/"]
path = ~/.gitconfig-personal
~/.gitconfig-personal
gitconfig
[user]
name = GitHub用户名
email = 个人邮箱
常见问题
Q1: ssh -T 超时(Connection timed out)
原因:公司网络封了 22 端口。
解决 :在 ~/.ssh/config 中将 GitHub 配置改为 443 端口:
markdown
Host github-personal
HostName ssh.github.com
Port 443
...
Q2: Host key verification failed
原因:首次连接服务器,SSH 不认识对方身份。
解决:手动添加服务器的 host key:
bash
# GitHub(443 端口)
ssh-keyscan -p 443 ssh.github.com >> ~/.ssh/known_hosts 2>/dev/null
# GitHub(22 端口)
ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null
# 公司 GitLab
ssh-keyscan git.company.com >> ~/.ssh/known_hosts 2>/dev/null
Q3: Permission denied (publickey)
排查步骤:
bash
# 1. 查看详细连接日志
ssh -vT git@github-personal
# 2. 确认密钥文件存在
ls -la ~/.ssh/id_ed25519_personal*
# 3. 确认公钥已添加到 GitHub(对比本地公钥和 GitHub 设置页面的内容)
cat ~/.ssh/id_ed25519_personal.pub
Q4: refusing to merge unrelated histories
原因:GitHub 上创建仓库时勾选了初始化选项(生成了 README),导致远程和本地是两个独立的 Git 历史。
解决:
bash
# 先拉取远程分支
git fetch origin
# 合并时允许不相关历史
git merge origin/master --allow-unrelated-histories -m "merge: 合并远程分支"
# 推送
git push
建议:创建 GitHub 仓库时不要勾选任何初始化选项,可以避免这个问题。
Q5: git config user.email 显示的还是公司邮箱
排查步骤:
bash
# 1. 确认当前目录
pwd
# 2. 确认目录是个 git 仓库(必须有 .git 目录,条件包含才会生效)
git status
# 3. 检查 .gitconfig 中 includeIf 的路径是否正确(末尾要有 /)
cat ~/.gitconfig
# 4. 手动设置(仅当前仓库,作为兜底方案)
git config user.name "你的GitHub用户名"
git config user.email "你的个人邮箱"
原理小结
整体架构
公司密钥"] KEY2["id_ed25519_personal
个人密钥"] end subgraph Git 身份层 ["Git 身份层(条件包含)"] GC[".gitconfig
公司身份(默认)"] GP[".gitconfig-personal
个人身份"] end subgraph 项目目录 P1["公司项目
C:/work/project/"] P2["个人项目
D:/obsidian/"] end end subgraph 远程服务器 GITLAB["公司 GitLab
git.company.com"] GITHUB["个人 GitHub
github.com:443"] end P1 --> GC P2 -->|"includeIf gitdir:D:/obsidian/"| GP GC --> KEY1 GP --> KEY2 KEY1 -->|"Host: git.company.com"| GITLAB KEY2 -->|"Host: github-personal"| GITHUB style KEY1 fill:#4A90D9,color:#fff style KEY2 fill:#7B68EE,color:#fff style GC fill:#4A90D9,color:#fff style GP fill:#7B68EE,color:#fff style P1 fill:#4A90D9,color:#fff style P2 fill:#7B68EE,color:#fff style GITLAB fill:#FC6D26,color:#fff style GITHUB fill:#238636,color:#fff
git push 执行流程
以在 D:/obsidian/ 目录下执行 git push 为例:
匹配 gitdir:D:/obsidian/ Config->>Git: 加载 .gitconfig-personal
覆盖为个人身份 Git->>SSH: 连接 github-personal SSH->>SSH: 匹配 ~/.ssh/config 中的
Host github-personal SSH->>SSH: 使用 id_ed25519_personal 密钥 SSH->>GH: SSH 连接 ssh.github.com:443 GH->>GH: 验证公钥 GH-->>SSH: 认证成功 SSH-->>Git: 连接建立 Git->>GH: 推送代码(身份: 个人邮箱) GH-->>U: 推送完成
概述
用公司电脑写个人项目,git log 里却全是公司邮箱?推送到 GitHub 却提示权限拒绝?这是每个同时使用公司 GitLab 和个人 GitHub 的开发者都会遇到的问题。
本文基于一次真实的配置过程,采用 SSH 多密钥 + Git 条件包含 方案,实现不同目录自动切换 Git 身份。从密钥生成到推送成功,包含完整步骤、原理图解,以及公司网络下端口被封、Host Key 验证失败等实际踩坑的解决方案。
适用场景:公司 GitLab + 个人 GitHub 并存(也适用于任意两个 Git 平台的多账号管理)
阅读时间 :约 10 分钟 | 配置时间:约 15 分钟
目录匹配时加载"| GP end subgraph 远程平台 GL["GitLab
添加 id_ed25519.pub"] GH["GitHub
添加 id_ed25519_personal.pub"] end K1 -.->|公钥认证| GL K2 -.->|公钥认证| GH style SC fill:#f5f5f5,stroke:#333 style GC fill:#f5f5f5,stroke:#333 style GP fill:#f5f5f5,stroke:#333 style GL fill:#FC6D26,color:#fff style GH fill:#238636,color:#fff
配置步骤总览
生成个人 SSH 密钥"] S2["Step 2
编写 SSH config"] S3["Step 3
公钥添加到 GitHub"] S4["Step 4
添加 Host Key"] S5["Step 5
测试 SSH 连接"] S6["Step 6
配置 Git 条件包含"] S7["Step 7
初始化仓库并推送"] S1 --> S2 --> S3 --> S4 --> S5 S5 -->|成功| S6 --> S7 S5 -->|失败| FAQ["查看常见问题排查"] FAQ -.-> S5 style S1 fill:#4A90D9,color:#fff style S2 fill:#4A90D9,color:#fff style S3 fill:#4A90D9,color:#fff style S4 fill:#4A90D9,color:#fff style S5 fill:#7B68EE,color:#fff style S6 fill:#238636,color:#fff style S7 fill:#238636,color:#fff style FAQ fill:#D9534F,color:#fff