Facebook 为什么不用 Git?
Git 今天已能扛 monorepo(scalar),Mercurial 社区却日渐沉寂……技术决策,70% 是人,30% 是码。下次你的团队要选工具——别只 benchmarkgit clone速度,Issue 回复快不快?PR 被认真 review 吗?Maintainer 会说“thanks”还是“RTFM”?因为——你选的不是工具,是未来三年愿意陪你 debug 到凌晨的战友。🤝。
“Git 是水,Mercurial 是椰子水 ——
你喝惯了自来水,突然有人递来一瓶‘Facebook 特供电解质水’,
你第一反应:这玩意儿……能喝?”
2012 年,Facebook 工程师面对一个灵魂拷问:
“我们的 monorepo 已有 200 万+ 文件,
git status跑一次,够我泡三碗泡面……还要加蛋。” 🍜🥚
他们尝试拯救 Git ——
结果 Git 社区回了句:
“建议:分库。
—— 毕竟,一个 repo 装不下整个世界(和扎克伯格的梦想)。”
于是……Facebook 转头牵起了 Mercurial 的手。
今天,我们就来扒一扒:这场“分手-再恋”的技术三角恋,到底发生了什么?
🕵️♂️ 一、事故回放:当 git status 比咖啡机还慢
时间:2012 年
地点:Facebook Menlo Park 总部
人物:一群头发日渐稀疏的 SWE
事件:git status 开始卡成 PPT
📉 性能崩坏实录:
| 操作 | 小型 repo | Facebook monorepo | 工程师反应 |
|---|---|---|---|
git status |
0.02s | 45+ 秒 | 🥱 “趁这会儿我去趟厕所?” |
git checkout main |
瞬间 | 2 分钟 | 🚶♂️ “我先去楼下买杯咖啡……” |
git commit -m "fix" |
0.1s | 37 秒 | ⏳ “这 commit 时间够写首诗了:啊~我的青春~在等待 index.lock~” |
💡 技术真相:
Git 的核心瓶颈在stat()系统调用 ——
每次操作都要遍历 所有文件 的 metadata(mtime/inode),
200 万文件?≈ 200 万次stat()→ 磁盘 I/O 直接拉满 💥
Facebook 团队甚至做了个“地狱模拟”:
“我们建了个 dummy repo,模拟 2015 年的 FB 代码量……
git status跑了 47 分钟。
那一刻,我们决定:不能再等 Git 醒了。”
📧 二、求救信石沉大海:Git 社区的“人间真实”回复
Facebook 没直接分手,先发了封“求救邮件”给 Git 维护者,大意是:
“大佬,我们 repo 有点大,能优化下性能吗?我们出人出力!”
📜 收到的回复:
✉️ Git Maintainer A:
“sounds like you have everything in a single .git.
Split up the massive repository to separate smaller .git repositories.”
(人话:建议分库。你们这 repo,像把全家行李塞进一个登机箱——能不炸吗?)
✉️ Git Maintainer B:
“I concur. … there is IMHO no downsides.”
(翻译:我附议。分库?百利无一害!—— 仿佛没听过“微服务地狱”)
✉️ Git Maintainer C:
“…only so much you can do about stat-ing 1.3 million files.”
(人话:130 万文件?那……祝你好运 🙏)
🤯 Facebook 工程师内心 OS:
“我们不是不能分库……
但我们有 5 万工程师,每天 10 万次提交,
分库 = 每次改个 log level,要提 20 个 PR 跨 repo 同步……
这不是优化,这是人工制造 CI 海啸啊!”
🔥 三年后,Git 社区悄悄变了口风(Mercurial 已被 FB 喂饱):
“fwiw, the situation has changed pretty drastically today…”
(人话:咳……现在 Git 也能扛大 repo 了哈~)
🥥 三、Mercurial:那个被“椰子水”拯救的备胎
既然 Git 不愿“健身”,Facebook 开始相亲:
- Perforce?销售连自己架构缺陷都不知道 ❌
- BitKeeper?闭源 + 老古董 ❌
- Mercurial?Python 写的,架构清晰,社区……居然愿意让我们改代码?! ✅
✅ Mercurial 的“撩人”三招:
| 特性 | Git | Mercurial | Facebook 眼神 |
|---|---|---|---|
| 代码风格 | C + Bash 混搭(像一锅乱炖) | Python + OOP(像米其林摆盘) | 👀 “这代码……能 review!” |
| 扩展性 | “别动核心!” | “PR 甩过来,我们边喝咖啡边 merge” | ☕ “这社区……有温度!” |
| 态度 | “分库吧” | “来,我们一起重构!” | ❤️ “找到了!我的 soulmate!” |
🎯 关键转折:Facebook 团队飞去 阿姆斯特丹 Mercurial Hackathon
—— 见面发现:维护者不仅技术强,还请他们喝了 Heineken 🍺
“那一刻我们懂了:DevTools 的终极性能,是人情味。”
🧩 四、神操作:如何让 5 万工程师集体“换水”?
换版本控制系统 ≈ 让全公司集体换母语。
稍有不慎,就是:
“git commit -m ‘紧急修复’ → hg ci -m ‘救命’ → 世界崩塌”
hg是Mercurial简称。
🛠 Facebook 的“温柔刀”三步走:
1️⃣ 先做“Git → Hg”对照表(连 alias 都给你写好)
# .bashrc 自动注入
alias git-commit="hg commit"
alias git-checkout="hg update"
alias git-pull="hg pull && hg update"
→ 工程师:“咦?今天命令怎么格外丝滑?”
2️⃣ 监控全公司 git 命令热力图
“发现 83% 的工程师只用 7 个 Git 命令 ——
我们就把这 7 个,1:1 映射到 Hg。”
3️⃣ 开“吐槽大会”收 edge case
预想:会有人吼 “我的 octopus merge 怎么办?!”
实际:全场安静 5 秒,然后有人说:
“其实……我 octopus merge 三年前就删了” 😅
📊 结果:迁移零事故,工程师反馈:
“好像……没感觉?只是git变快了?”
(没错,他们甚至没发现底层换了!)
🏗 五、蝴蝶效应:Facebook 带飞的“Stacked Diffs”宇宙
Facebook 不仅换了工具,还重新定义了工作流:
| 传统 Git Flow | Facebook Hg Flow |
|---|---|
feature → PR → review → merge |
diff1 → diff2 → diff3 → review in parallel |
| 阻塞式:后一个功能等前一个 merge | 流水线式:多个 diff 同时 review |
| PR 巨无霸(2000+ 行) | 原子级 diff(200 行/个) |
🌟 这就是 Stacked Diffs 的雏形 ——
后来演化成:
- Phabricator 的核心能力
- Uber / Pinterest 的内部标准
- Graphite 的创业起点 ✨
- Cursor 收购 Graphite 的底层逻辑 💰
💡 启示:
技术选型不是“哪个更快”,而是“哪个更愿意和你一起变快”。
Git 当年拒绝 FB,失去的不仅是 PR,
是塑造下一代 DevTools 的话语权。
🧠 六、给今天的我们:3 条血泪启示
1️⃣ “性能瓶颈”背后,常是“协作瓶颈”
Facebook 的真实瓶颈不是 stat(),而是:
“当你的需求,被 upstream 当成‘边缘 case’时——
你有两个选择:
A. 继续求他们;
B. 自己造轮子,顺便开源喂饱社区。”
→ FB 选了 B,并成了 Mercurial 的 最大贡献者。
2️⃣ 工具迁移 = 组织变革
- 别一上来就
rm -rf .git && hg init - 学 FB:先让工具隐形,再悄悄替换心脏 ❤️
3️⃣ 人情味,是开源的终极 API
Git 维护者技术极强,但当年缺了句:
“你们的具体场景是什么?我们拉个会,一起 design。”
而 Mercurial 团队说:
“来阿姆斯特丹,啤酒我请,代码你改。” 🍺→🚀
🎯 结语:工具没有银弹,但有“人弹”
Git 今天已能扛 monorepo(
git sparse-checkout/scalar),
Mercurial 社区却日渐沉寂……但 Facebook 的故事告诉我们:
技术决策,70% 是人,30% 是码。下次你的团队要选工具——
别只 benchmarkgit clone速度,
去 GitHub 看看:
- Issue 回复快不快?
- PR 被认真 review 吗?
- Maintainer 会说“thanks”还是“RTFM”?
因为——
你选的不是工具,是未来三年愿意陪你 debug 到凌晨的战友。 🤝
更多推荐



所有评论(0)