8 月 17 日上午(美东时间约 9:40 开始),GitHub 发生大规模宕机,持续约 7 个小时:网站打不开、Pull Request 和 Issues 不可用、Actions 流水线停摆、Webhooks 失联,连 Copilot 都跟着挂了,高峰期错误率一度到两成上下。几小时后,Cursor 趁势官宣了自家 AI 原生代码托管平台 Origin——而且它对付费用户默认开启,数据条款却还没公布,引发了一波讨论。
这件事给所有开发者提了个醒:代码托管是一个被严重低估的单点。代码本身在你本地有副本,但 PR 评审、CI 流水线、Issue 追踪、发布流程全都绑死在一家平台上。平台一挂,整个团队原地放假。
好消息是,Git 天生就是分布式的,容灾不需要什么高深技术。本文教你用纯 Git 原生命令,30 分钟给仓库配好「主远端 + 镜像远端 + 自动同步」,下次再宕机时团队照常干活。
一、先想清楚:你要备份的到底是什么
很多人以为"本地有 clone 就等于有备份",这是最常见的误区。一次完整的托管事故会让你失去:
- 代码之外的一切:PR 评论、review 记录、Issue、Wiki、Release 附件;
- CI/CD 能力:Actions 流水线、部署密钥、构建产物;
- 协作入口:团队成员连"最新代码在哪"都无法确认。
Git 多远端能救回的是第一项里的代码和完整提交历史(包括所有分支和 tag)——这是最重要、也最值钱的部分。CI 和协作流程则需要"第二平台随时能顶上来"。所以方案分两层:代码层多远端镜像 + 流程层备用平台预案。
二、第一步:给仓库加第二个远端
Git 的 remote 天然支持多个。假设你的主仓库在 GitHub,镜像选在 GitLab(国内团队可以选 Gitee 或自建 Gitea):
# 查看现有远端
git remote -v
# origin git@github.com:yourname/yourrepo.git (fetch/push)
# 添加镜像远端
git remote add mirror git@gitlab.com:yourname/yourrepo.git
# 全量推送:所有分支 + 所有 tag
git push mirror --all
git push mirror --tags
验证一下:
git ls-remote mirror | head -5
能看到和 GitHub 上一致的 commit hash,说明镜像已经完整。Git 的内容寻址特性保证了:只要 hash 一致,两边的就是同一份代码,不存在"镜像是不是旧版"的猜疑。
三、第二步:一次 push 推到两个地方
每次手动 push 两遍迟早会忘。两种解法,按需选一种。
方案 A:给 origin 配多个 push URL(推荐个人项目)
git remote set-url --add --push origin git@github.com:yourname/yourrepo.git
git remote set-url --add --push origin git@gitlab.com:yourname/yourrepo.git
之后 git push 会自动依次推到两个远端,fetch/pull 仍然只走 GitHub。零心智负担,缺点是第二个平台挂了会让 push 报错。
方案 B:用 shell alias 显式双推(推荐团队)
# 加到 ~/.zshrc 或 ~/.bashrc
alias pushall='git push origin --all && git push mirror --all && git push origin --tags && git push mirror --tags'
显式的好处是失败可控:主远端成功、镜像失败时你看得一清二楚,补一句 git push mirror --all 就行。
四、第三步:定时兜底同步
即使用方案 A,也建议加一个定时任务兜底——防的是"某个同事直接在他本地老配置上单推 GitHub"这种漏网之鱼。在镜像服务器或任何一台常开的机器上:
# 克隆一个裸仓库专门做同步
git clone --mirror git@github.com:yourname/yourrepo.git yourrepo-mirror.git
cd yourrepo-mirror.git
git remote add mirror git@gitlab.com:yourname/yourrepo.git
写进 crontab,每小时同步一次:
0 * * * * cd /path/to/yourrepo-mirror.git && git fetch -p origin && git push mirror --mirror >> /var/log/git-mirror.log 2>&1
--mirror 会把所有引用(分支、tag、甚至删除操作)原样复制过去,是最彻底的同步方式。注意它也会同步删除,所以镜像远端要当成"只读副本"管理,任何人不要直接往镜像上推代码。
五、第四步:流程层的备用预案
代码有了镜像,还要回答"GitHub 挂了,团队怎么继续协作"。把下面这些写进团队的 README 或运维手册,事前约定好:
- 紧急切换命令:全员知晓
git remote set-url origin <镜像地址>这一条命令,5 秒完成切换; - 备用评审渠道:镜像平台上提前建好项目、开好成员权限,评审临时降级为"镜像 MR + 群里口头 review";
- CI 平移:关键流水线(构建、发版)在镜像平台准备一份等价配置。GitHub Actions 和 GitLab CI 语法不同,这一步平时就要做,临时抱佛脚来不及;
- 发布物备份:Release 二进制附件定期同步到对象存储(S3/OSS),别只躺在 GitHub Releases 里。
六、要不要试试 Cursor Origin?
顺带聊聊这次宕机里的另一个主角。Cursor 的 Origin 定位是"AI 原生代码托管":让 Agent 直接参与代码托管层的操作,而不只是编辑器里的补全。方向值得关注,但作为备用远端之前,有三点要先确认:
- 数据条款:发布时它对付费用户默认开启,却还没公布明确的数据处理条款——你的代码会不会被用于训练、存在哪,要看到白纸黑字再决定;
- 导出能力:任何新平台,先验证能否完整导出(包括 git 历史),导出自由的才配当容灾选项;
- 默认开启的设置:检查团队账号的 Origin 开关状态,不打算用就显式关掉,避免代码在你不知情时进入新平台。
新平台当主力要慎重,但当"第三个镜像"反而是低成本的试水方式。
注意事项与常见问题
Q:镜像远端需要付费吗? GitLab 免费版私有仓库够用;Gitee 国内速度快但注意私有仓库的合规要求;注重可控性就用一台 2 核 VPS 自建 Gitea,十分钟装好。
Q:私有仓库的镜像会不会有泄露风险? 风险面确实多了一个。镜像平台同样要开双因素认证、最小化成员权限;高敏感度仓库建议镜像到自建 Gitea 而不是第三方 SaaS。
Q:LFS 大文件会被 --mirror 同步吗?
不会。git push --mirror 只同步 Git 引用,LFS 对象要单独执行 git lfs push --all mirror,别漏了。
Q:多久同步一次合适? 日常双推(方案 A/B)是实时的,定时兜底每小时一次足够。镜像滞后 1 小时在灾备场景下完全可以接受。
小结
GitHub 宕机 7 小时不是末日,但足以让"单平台依赖"的代价变得具体。容灾方案本身朴素得近乎无聊:加一个远端、配一次双推、挂一个 cron、写一页预案——全部加起来半天工作量。真正难的是在事故发生前把它做完。今天就动手,下次热搜上的宕机新闻对你来说就只是一条新闻。
