
一台机器上同时伺候 Gitee 和 GitHub几乎是每个国内开发者绕不开的日常。我最早的做法很简单哪个平台用得多就把git config --global的user.email设成哪个remote 地址复制粘贴push 的时候弹出密码框就输一次能跑就行。直到有一天一个仓库的提交记录里混进了另一个平台的邮箱代码评审时被人指出来才发现这套能跑就行的配置其实一直在埋雷。后来帮几个朋友处理过类似问题也见过有人把两把私钥覆盖成一把握手失败才意识到这件事值得单独写一篇。这篇内容讲的是同一台机器、同一套 Git 环境里让 Gitee 和 GitHub 各自用各自的密钥、各自的提交身份、互不干扰的完整配置方法。适合已经用过 Git 基本命令、但在多平台切换时总遇到权限报错或者提交信息错乱的朋友刚接触 Git 的新手也能照着步骤走我会把每一步为什么这么做讲清楚而不是只丢一串命令让你抄。1. 两平台共存的真实痛点与配置总思路1.1 一个 remote 地址背后其实藏着三件事很多人以为配置两个平台就是加两个 remote真出问题时才发现一个远程仓库地址背后至少绑着三件互相独立的事认证凭据决定你有没有权限推拉代码提交身份决定别人看到的作者是谁远程地址的解析方式决定 Git 到底往哪台服务器发请求。这三件事在单平台时代被默认配置糊在一起一旦变成双平台任何一件没拆开都会出乱子。举个最常见的场景你用 SSH 方式克隆了 Gitee 的仓库又克隆了 GitHub 的仓库两边的 remote 都是gitxxx.com:user/repo.git这种形式。Git 本身不区分域名背后的身份它只认 SSH 握手时递过去的那把私钥。如果你的~/.ssh目录里只有一把id_rsa那么两个平台收到的都是同一把公钥其中一个平台没登记过这把公钥握手就会直接失败报Permission denied (publickey)。这不是网络问题也不是账号被封纯粹是密钥没分家。提交身份的问题更隐蔽。Git 在提交时会读取user.name和user.email如果全局配置只写了一个邮箱那么你在另一个平台提交的代码作者信息依然是那个邮箱。平台侧通常会用邮箱去匹配账号匹配不上就显示成一个没有头像、没有主页的陌生提交者。短期看只是不好看长期看会影响贡献统计、代码归属甚至在团队协作时引发这段代码到底谁写的的争议。所以配置双平台的核心不是记住几条命令而是把认证、身份、地址这三条线分别理清楚。1.2 两条技术路线SSH 多密钥与 HTTPS 凭据分流真正落地时主流做法就两条路线选哪条取决于你的使用习惯和所在网络环境。我把它们的差异整理成一张表你可以对着自己的情况选。对比维度SSH 多密钥方案HTTPS 凭据分流方案认证载体本地私钥文件账号密码或访问令牌是否需要每次输入配置 ssh-agent 后免输入首次输入后由凭据助手缓存多平台区分方式靠 SSH config 里的 Host 段匹配靠 URL 域名匹配凭据条目网络适应性需要 22 端口可通走 443 端口适应性更广迁移成本拷贝密钥并重新授权重新登录并缓存令牌常见故障密钥权限、config 匹配错误令牌过期、凭据缓存串号SSH 方案的优势是一次配好、长期安静适合经常在同一台机器上长期开发的人。它的门槛在于要理解 SSH config 的匹配逻辑尤其是 Host 别名和 HostName 的区别很多人卡在这里。HTTPS 方案的优势是对网络环境更宽容公司内网、临时网络都能用代价是要管理访问令牌令牌一过期就得重新配而且凭据助手如果配置不当两个平台的账号容易互相覆盖。我的建议是主力开发机用 SSH临时环境或者受限网络用 HTTPS。两者不冲突可以同时存在后面我会讲混用时要注意什么。关键是先把其中一条走通再考虑另一条不要一上来就两套一起配出问题时排查面会翻倍。1.3 配置分层全局、仓库、条件包含Git 的配置是分层覆盖的理解这个层次比记住命令更重要。最底层是系统级配置一般不用动中间是全局配置--global存在用户目录下的.gitconfig最上层是仓库级配置--local存在仓库的.git/config里。上层会覆盖下层的同名配置项这就是我们做双平台隔离的基础。举个实际例子全局配置里写user.email meexample.com某个 GitHub 仓库里写user.email megithub.example那么在这个仓库里提交就用后者其他仓库仍然用全局值。这个机制让我们可以做到默认身份 特例覆盖不需要每次提交都手动指定。再往上一层是条件包含也就是includeIf。它允许你按目录路径自动加载某段配置比如所有放在~/work/gitee-projects/下的仓库自动使用 Gitee 的身份放在~/work/github-projects/下的自动使用 GitHub 的身份。这个功能很多人不知道但它是长期维护双平台配置最省心的方式。我一般建议目录规划和includeIf一起做前期多花十分钟后面几年都不用再想这件事。2. 动手前的环境盘点和基础准备2.1 先确认 Git 版本和配置来源动手改配置之前先花两分钟看清楚当前环境。不同版本的 Git 对includeIf、credential.helper的支持程度不完全一样尤其是老版本可能存在行为差异。先跑这两条命令git --version git config --list --show-origin第一条确认版本建议在 2.20 以上includeIf的目录匹配在较新版本里更稳定。第二条会列出所有生效的配置项并且标注每一项来自哪个文件。这一步非常关键因为很多人改了半天没生效最后发现是某个配置文件里有重复项或者某个仓库的.git/config里残留了旧值。看输出时重点盯三类信息user.name和user.email出现在哪个文件、credential.helper当前是什么值、有没有已经存在的url.*.insteadOf重写规则。最后这个规则很容易被忽略它会把某个前缀的地址自动替换成另一个如果你之前配过但忘了后面改 remote 地址时会发现怎么改都不对。提示--show-origin这个参数值得养成习惯排查任何配置问题都先看它。没有来源信息的配置列表等于看一本没有页码的书。2.2 旧密钥的清理要谨慎先备份再动手很多人一上来就rm -rf ~/.ssh这是最危险的操作。旧密钥可能还绑着其他服务删掉之后恢复不了只能重新授权。正确做法是先列目录、看内容、做备份ls -la ~/.ssh cat ~/.ssh/config 2/dev/null看看现有文件里有没有id_rsa、id_ed25519、config、known_hosts。known_hosts不要删它记录的是你信任过的服务器指纹删了之后首次连接会重新询问虽然不影响使用但会多一道确认。备份建议把整个.ssh目录复制一份到安全位置命名带上日期比如ssh-backup-20240115。备份时注意权限目录本身应该是700私钥文件是600。如果你在 Windows 上权限模型不一样但原则相同私钥文件不要被其他用户可读。我见过有人把私钥放在共享目录里结果被同步工具传到了不该去的地方这种事故排查起来非常麻烦。如果确实要重新生成密钥也不要直接覆盖同名文件。ssh-keygen在目标文件已存在时会询问是否覆盖手快一回车旧密钥就没了。我的习惯是给新密钥起带平台后缀的名字从源头上避免覆盖。2.3 目录与命名约定为后面的自动化打基础命名约定看起来是小节实际上是整套方案能不能长期维护的关键。我的建议是密钥文件带平台标识仓库目录按平台分文件夹配置文件和这两者保持一致的命名逻辑。密钥文件我一般这样命名id_ed25519_gitee和id_ed25519_gitee.pubid_ed25519_github和id_ed25519_github.pub仓库目录这样分~/projects/gitee/放 Gitee 相关仓库~/projects/github/放 GitHub 相关仓库这样命名的好处是SSH config 里的IdentityFile和includeIf里的路径都能一眼对应上出问题时不需要回忆这个文件到底是干嘛的。而且以后写脚本做批量操作比如批量检查 remote 地址、批量切换提交身份有规律的命名能让脚本简单很多。目录规划还有一个隐性收益它让身份错乱这类问题在物理层面就很难发生。你在这个目录下新建仓库条件配置自动生效不需要每次手动检查git config user.email。人都会忘让目录结构替你记住比靠自律靠谱。3. SSH 多密钥方案一次配置长期省心3.1 生成两把独立密钥参数怎么选生成密钥用ssh-keygen关键是给每把密钥独立的文件名和注释。注释-C建议写清楚用途它会出现在公钥末尾方便你在平台侧辨认。ssh-keygen -t ed25519 -C gitee-dev-machine -f ~/.ssh/id_ed25519_gitee ssh-keygen -t ed25519 -C github-dev-machine -f ~/.ssh/id_ed25519_github这里选ed25519而不是默认的rsa原因是 ed25519 密钥更短、签名更快现代平台基本都支持。如果你维护的是很老的系统可能只支持 RSA那就用-t rsa -b 4096。算法选择不用纠结太多关键是两把密钥必须独立不能一把通吃两个平台。执行过程中会询问是否设置口令。设口令的好处是私钥文件即使泄露攻击者也需要口令才能用坏处是每次使用都要输入除非配合 ssh-agent。我的建议是开发机设口令并配置 ssh-agent临时环境可以不设。如果你选择不设口令直接回车两次即可但要确保私钥文件权限严格。生成完成后你会得到四个文件两把私钥、两个公钥。公钥以.pub结尾内容可以公开私钥没有后缀内容绝对不能外传。下一步的 config 文件里引用的是私钥路径登记到平台的是公钥内容别搞反了。3.2 config 文件的关键字段与匹配逻辑~/.ssh/config是 SSH 客户端的行为说明书它按顺序匹配 Host 段找到第一个匹配的就用那段配置。理解这一点就能明白为什么有时候配置写了却不生效——可能是前面的通配段先匹配上了。一个可用的双平台配置大概长这样Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_ed25519_gitee IdentitiesOnly yes Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github IdentitiesOnly yes逐字段解释一下。Host是你连接时使用的名字也是匹配的键HostName是真实服务器地址User对这两个平台固定是git不是你的账号名这一点新手最容易写错IdentityFile指定私钥路径IdentitiesOnly yes表示只使用这里指定的密钥不要让 SSH 挨个尝试默认密钥。最后这个参数很关键没有它SSH 可能先拿id_rsa去试试失败了才轮到你指定的密钥某些服务器会因为尝试次数过多直接拒绝。还有一种写法是用别名区分比如Host gitee-work配HostName gitee.com这样 remote 地址就要写成gitgitee-work:user/repo.git。别名适合需要为同一平台配置多套身份的场景比如个人号和工作号。但如果只是两个平台各一套直接用域名做 Host 更直观remote 地址和平台官网给的完全一致复制粘贴不会错。注意config 文件里的缩进不是必须的但建议统一用四个空格方便阅读。文件名必须是config放在~/.ssh/下权限建议600。权限过宽时 SSH 会忽略这个文件而且不一定报错排查起来很隐蔽。3.3 公钥登记与文件权限的一次性检查公钥登记在两个平台的操作路径不同但逻辑一样找到 SSH 公钥设置页粘贴.pub文件的完整内容保存。粘贴时注意不要带多余的空格或换行有些终端复制会带上换行符导致平台侧解析失败。建议用cat命令输出后整体选中复制cat ~/.ssh/id_ed25519_gitee.pub cat ~/.ssh/id_ed25519_github.pub登记完成后做一次权限检查。这一步很多人跳过结果遇到密钥明明对却认证失败的怪问题。Linux 和 macOS 下执行chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519_gitee ~/.ssh/id_ed25519_github chmod 644 ~/.ssh/id_ed25519_gitee.pub ~/.ssh/id_ed25519_github.pub chmod 600 ~/.ssh/config权限的原则是目录只允许自己进入私钥只允许自己读写公钥和 config 可以稍微宽松但也不建议放开。Windows 下没有这套权限模型但要确保密钥文件不在同步盘或者共享目录里。我见过因为把.ssh放进了会自动同步的文件夹导致私钥被传到云端的情况这类问题不是权限命令能解决的得从存放位置入手。3.4 连接测试与首次握手的确认流程配置写完后用ssh -T测试。两个平台返回的提示文案不一样但成功时都会表明身份认证通过ssh -T gitgitee.com ssh -T gitgithub.com如果看到类似欢迎你某某或者successfully authenticated的提示说明认证通了。如果看到Permission denied (publickey)先别急着改配置按下面的顺序排查公钥是否完整粘贴、IdentityFile路径是否正确、文件权限是否合规、IdentitiesOnly是否加上。这四个点覆盖了绝大多数情况。首次连接还会询问是否信任服务器指纹输入yes回车即可。这个指纹会被写入known_hosts以后不再询问。如果你在自动化脚本里跑可以用-o StrictHostKeyCheckingaccept-new参数但手动操作时建议还是看一眼指纹再确认养成习惯没坏处。测试通过后别忘了把私钥加入 ssh-agent这样设了口令的密钥不用每次输入eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519_gitee ssh-add ~/.ssh/id_ed25519_githubmacOS 可以把密钥存入钥匙串用ssh-add --apple-use-keychain参数Linux 桌面环境一般配合自启动脚本。Windows 的 Git Bash 里 agent 行为略有不同建议单独确认。这一步不做也能用只是每次 push 都要输口令时间长了容易烦最后干脆把口令去掉反而降低安全性。4. 仓库级身份与远程地址的正确写法4.1 远程地址到底该用别名还是原域名这是双平台配置里最容易出错的地方因为 remote 地址必须和 SSH config 里的Host对得上。如果你 config 里写的是Host gitee.com那么 remote 就用gitgitee.com:user/repo.git如果你写的是Host gitee-workremote 就必须用gitgitee-work:user/repo.git写成原域名反而匹配不到你指定的密钥。我倾向于直接用原域名做 Host理由是平台文档、复制按钮、同事分享的地址都是原域名形式不需要二次转换减少出错机会。只有在需要多套身份时才用别名比如同一个 GitHub 账号既有个人仓库又有组织仓库但要求不同的提交邮箱这时候用别名区分会更清晰。修改已有仓库的 remote 地址用git remote set-urlgit remote set-url origin gitgitee.com:user/repo.git git remote -v改完一定要用git remote -v确认别只看命令有没有报错。我遇到过改了一个 remote、另一个同名 remote 还在的情况push 的时候 Git 选了错的那个排查了半天。remote -v会把 fetch 和 push 两个地址都列出来如果它们不一致说明之前配过单独的 push 地址需要一并处理。4.2 用局部配置覆盖提交身份认证解决的是能不能推身份解决的是推上去是谁。全局配置只能有一个默认身份所以每个仓库要单独设置cd ~/projects/gitee/some-repo git config --local user.name 你的显示名 git config --local user.email 你的 Gitee 绑定邮箱 cd ~/projects/github/another-repo git config --local user.name 你的显示名 git config --local user.email 你的 GitHub 绑定邮箱邮箱必须和平台账号绑定的邮箱一致否则提交不会关联到你的账号。有些人用隐私邮箱比如 GitHub 提供的xxxusers.noreply.github.com形式这也是可以的但要确保平台侧开启了相应选项。用错邮箱的后果不是提交失败而是提交成功但不归属你这种静默错误最难发现。显示名可以两个平台用同一个不影响归属判断归属主要看邮箱。但如果你的工作身份和个人身份需要区分显示名也可以不同比如工作仓库用真实姓名个人仓库用昵称。这些都属于仓库级配置互不干扰。4.3 用 includeIf 按目录自动切换身份仓库多了之后每个都手动git config --local太累而且容易漏。includeIf可以按目录自动加载配置一劳永逸。先在全局.gitconfig里加两段[includeIf gitdir:~/projects/gitee/] path ~/.gitconfig-gitee [includeIf gitdir:~/projects/github/] path ~/.gitconfig-github然后分别建两个文件。~/.gitconfig-gitee内容[user] name 你的显示名 email 你的 Gitee 绑定邮箱~/.gitconfig-github内容类似邮箱换成 GitHub 的。这样放在对应目录下的仓库会自动使用对应身份新建仓库也不用再手动设。这里有几个细节要注意。gitdir:后面的路径建议用绝对路径用~时不同 Git 版本展开行为可能不一致。路径末尾的斜杠表示目录前缀匹配加上它~/projects/gitee/下的所有子目录都会命中。如果你只想匹配特定后缀可以用gitdir:~/projects/**/gitee-*这种通配写法但通配越复杂越容易出意外建议先从简单的前缀匹配开始。验证是否生效进入一个仓库执行git config user.email git config --show-origin user.email第二条会告诉你这个值来自哪个文件。如果显示的是includeIf加载的那个文件说明配置生效了。如果还是全局值检查路径拼写、斜杠、以及全局配置里includeIf段的位置——它应该放在[user]段之后因为后面的配置会覆盖前面的。4.4 克隆与存量仓库的改造步骤新克隆仓库时直接按目录放好身份配置会自动生效cd ~/projects/gitee git clone gitgitee.com:user/repo.git cd ~/projects/github git clone gitgithub.com:user/repo.git存量仓库的改造分三步移目录、改 remote、验身份。移目录用mv即可Git 仓库对路径不敏感移完照样能用。改 remote 用前面说的set-url。验身份就是git config user.email加一次测试提交。测试提交建议用git commit --allow-empty -m test identity不产生实际文件改动推上去看一眼作者信息对不对确认没问题再删除这条提交记录。直接拿真实代码试也行但万一身份错了还得改写历史成本更高。空提交这个小技巧在验证配置时很好用值得记住。5. HTTPS 凭据分流与混合使用场景5.1 credential.helper 的选择与差异HTTPS 方式下Git 需要知道把账号密码存在哪、怎么取。这就是credential.helper的作用。常见取值有store、cache、manager几类。store把凭据明文存在文件里简单但不安全cache存在内存里有过期时间manager是跨平台的凭据管理器Windows 上常见安全性更好。查看当前值git config --global credential.helper如果没有输出说明没配每次操作都会询问。设置成store的话凭据会写到用户目录下的.git-credentials文件格式是https://user:tokenhost。这个文件是明文的机器多人共用时要注意。我在个人开发机上用store在共享环境里一律用cache或者系统的凭据管理器。需要强调的是现在两个平台基本都不建议用账号密码直接认证而是用访问令牌。令牌有独立的作用域和过期时间泄露了可以单独撤销比密码安全。配置时把令牌当密码用即可但要注意令牌权限别开太大只给仓库读写就够不要给账号管理权限。5.2 按域名区分凭据条目的写法HTTPS 方式下两个平台的凭据是按域名存的。store模式下.git-credentials文件里会有两行分别对应两个域名。正常情况下 Git 会根据 remote 地址的域名自动选对应的条目不需要手动干预。但有两种情况会串号一是域名写错比如把gitee.com写成www.gitee.com匹配不上就会用错条目二是凭据助手缓存了错误的值需要手动清除。清除单个域名的缓存不同助手命令不同。store模式直接编辑文件删对应行cache模式用git credential-cache exit清空系统凭据管理器则要在系统设置里删。清完之后下次操作会重新询问输入正确的令牌即可。还有一种更精细的控制方式用credential.url.helper给特定域名单独指定助手git config --global credential.https://gitee.com.helper store git config --global credential.https://github.com.helper store这种写法适合你想让某个平台用不同存储策略的场景比如一个用内存缓存、一个用持久存储。配置项里的 URL 要带协议匹配是按前缀来的。5.3 SSH 与 HTTPS 混用的注意事项同一个仓库里 SSH 和 HTTPS 混用是允许的比如 fetch 用 SSH、push 用 HTTPS但不建议这么做。混用会让排查变复杂认证失败时你分不清是密钥问题还是令牌问题日志里的错误信息也不一样。我的原则是一个仓库只用一种协议要换就整体换。如果确实需要混用比如公司网络限制 22 端口只能用 HTTPS push那就把 remote 的 fetch 和 push 地址分开设置git remote set-url origin gitgithub.com:user/repo.git git remote set-url --push origin https://github.com/user/repo.git git remote -vremote -v会显示两行不同地址这是正常的。但要记得HTTPS push 需要凭据SSH fetch 需要密钥两套配置都得对。换机器时也容易漏掉其中一套迁移前最好把git remote -v的输出记下来。6. 常见问题与排查速查6.1 Permission denied 的几类原因与定位顺序Permission denied (publickey)是最高频的报错原因至少有五类。按下面的顺序排查基本能覆盖排查项检查方法典型现象公钥是否登记平台设置页对照公钥指纹平台侧显示未使用过的密钥私钥路径是否正确ssh -vT githost看加载了哪个文件日志显示尝试了错误的密钥文件权限是否合规ls -l ~/.ssh权限过宽导致密钥被忽略Host 是否匹配ssh -G githost看最终配置实际生效的配置与预期不符是否被其他规则拦截检查url.*.insteadOf请求发到了意料之外的地址ssh -vT的-v会输出详细握手过程重点看Offering public key和Server accepts key这两行。如果提供的密钥根本不对说明 config 匹配或路径有问题如果提供了正确的密钥但服务器不接受说明平台侧没登记或者登记的不是这把。还有一个容易忽略的点有些网络环境会拦截 22 端口表现也是连接超时或者拒绝但错误信息不同。区分方法是看报错是Connection refused还是Permission denied前者是网络层后者是认证层。网络层的问题不在本文讨论范围但知道这个区分能让你少走弯路。6.2 提交作者信息错乱的修复思路发现提交作者不对先确认是哪个环节错了。用git log -1 --format%an %ae看最近一次提交的作者如果这里就错了说明提交时的配置不对如果这里对但平台上显示不对说明平台没匹配上邮箱。修复最近一次提交的作者用git commit --amend --author显示名 正确邮箱 --no-edit这只改最近一次。如果错了好几次需要交互式变基或者批量改写操作前一定先备份分支。改写历史会影响已经推送的提交团队协作的仓库要谨慎改完需要强制推送并且通知其他人重新拉取。个人仓库随便改团队仓库建议先沟通。预防比修复重要。我现在的习惯是新建仓库后第一件事就是确认git config user.email配合includeIf之后这一步基本可以省略但第一次在新目录建仓库时还是会扫一眼。这个动作花不了十秒钟能省掉后面改写历史的麻烦。6.3 远程地址写错与 remote 管理git remote -v是排查 remote 问题的第一命令没有之一。地址写错的表现通常是推到了错误的仓库或者提示仓库不存在。常见错误包括用户名拼错、仓库名大小写不一致、协议和配置不匹配、多了或少了.git后缀。修改用set-url删除用remove重命名用rename。一个仓库可以有多个 remote比如origin指向自己的 forkupstream指向原仓库。多 remote 场景下 push 要指定名字git push origin main和git push upstream main去的是不同地方别顺手就推。还有一个细节insteadOf重写规则会改变实际请求的地址但remote -v显示的还是你写的地址。如果怀疑被重写用git config --get-regexp url\..*\.insteadof查一下有没有相关规则。这个规则一般在迁移平台或者统一协议时才会配平时不会有但接手别人机器时值得看一眼。6.4 换机迁移时哪些要带走、哪些不能带换机器时.ssh目录下的私钥、公钥、config、known_hosts 都可以带走但要注意新机器的权限设置要重做一遍。.gitconfig和两个条件配置文件也要带走否则身份配置全丢。仓库目录直接拷贝即可Git 仓库是自包含的。不能随便带的是凭据缓存文件。store模式下的.git-credentials里是明文令牌拷贝过程如果经过不安全渠道等于泄露。建议到新机器重新登录一次让凭据助手重新生成。令牌本身也要检查有效期迁移前顺手轮换一次是个好习惯。迁移后按这个顺序验证ssh -T测两个平台、进一个仓库看git config user.email、做一次空提交测试推送。三步都过说明环境完整。少做一步可能在几天后某个 push 时才暴露问题到时候还得回头查。7. 实操心得与长期维护建议7.1 我踩过的几个坑你可以直接跳过第一个坑是密钥覆盖。早期我用ssh-keygen不加-f参数默认生成id_rsa第二次生成时提示覆盖我习惯性回车结果把第一次的密钥覆盖了另一个平台瞬间失去访问权限。后来改成带平台后缀的命名再也没出过这个问题。这个习惯的成本几乎为零收益是避免一次很难恢复的事故。第二个坑是IdentitiesOnly没加。有段时间某个平台总是间歇性认证失败重试几次又能过。后来用ssh -vT看日志发现 SSH 在挨个尝试所有密钥尝试次数多了被服务器限流。加上IdentitiesOnly yes之后问题消失。这个参数不会让配置变得更好看但能让行为变得确定。第三个坑是邮箱不一致。我在一个仓库里用了备用邮箱提交平台没关联上贡献统计少了一大块。发现时已经过去两个月只能改写历史。从那以后我在includeIf的配置文件里写死邮箱不再依赖记忆。第四个坑是权限。有次在 Linux 上把.ssh目录权限改成了755结果 SSH 直接忽略 config 文件而且不报错只是行为不对。查了半天才发现是权限问题。现在我的检查清单里权限是必查项。7.2 让配置长期稳定的几个习惯配置这件事配好只是开始能不能长期稳定取决于习惯。我总结了几条自己一直在用的新机器先跑一遍git config --list --show-origin确认没有意外的全局配置新建仓库先看user.email确认条件配置生效改完 remote 一定用remote -v复核定期检查令牌和密钥的有效期别等到过期那天才发现。还有一条是文档化。我会在~/.ssh/下放一个简单的说明文件记录每把密钥对应哪个平台、什么时候生成的、公钥指纹是什么。这个文件不含任何私密内容只有索引信息。换机器或者帮别人排查时看一眼就能对上号。很多人觉得这是多余动作但真出问题时能快速确认这把钥匙是开哪扇门的价值很高。最后说一个观念上的转变。双平台配置的目标不是配一次就永远不管而是让日常操作不需要思考。密钥分家、身份分层、目录规划这些动作的本质都是把需要记忆的事情变成环境的一部分。环境对了人就不会错靠人记住迟早会错。我现在的状态是新建仓库直接克隆到对应目录提交、推送全程不需要想我现在在哪个平台这套配置才算真正配好了。