Git vs. Mercurial
GIT 在当年的 Subversion、BitKeeper、Monotone 、Arch、Bazaar、Mercurial、Darcs 、Fossil 版本控制系统纷争中脱颖而出,成为绝对主流,但对 Git 的质疑从未停止过,其复杂、繁多、晦涩的命令,奇怪的 staged area、stash、rebase、detached heads,难用的 submodule 和 partial clone、sparse checkout、LFS、Annex、LOP,虽然这些年 Git 一直在改善,但要么积习难改繁上加繁,要么知者甚少依然晦涩,因此不断有人试图造轮子替代 Git,如 Got,Gitless,本文简要介绍三个有潜力的替代品 Jujutsu、Sapling 和 Pijul,它们不仅仅是对 Git CLI 的简化,而是从使用流程、思维上有了很大革新,其中 Jujutsu 和 Sapling 支持 Git 存储格式和网络协议,但 UI 体验向 Mercurial 靠齐,也可以一定程度上说 Mercurial 赢在了最后!
- Google 的版本管理工具变迁: CVS → Perforce → Piper → CitC + Piper → CitC + Piper + Mercurial (aka. Fig) → CitC + Piper + jj (aka. Fig NG);
- Facebook 的版本管理工具变迁: Subversion → Git → Mercurial → 重写的 Mercurial server + hg watchman + hg EdenSC + hg absorb → Sapling;
Jujutsu (jj)
- 主页: https://jj-vcs.github.io/jj/latest/
- 作者: Martin von Zweigbergk, 2011 加入 Google,2014 全职开发 Jujutsu
- 受启发:Git, Piper + CitC, Mercurial, Sapling, Darcs
- 开源时间: 2020-12
- 实现语言:Rust
Google 的下一代版本管理工具,与 Git 兼容,主要改进:
- 极大简化模型
- 去掉了 staged area、stash、detached heads 概念,将工作区直接视为一个可操作的提交,消除了 Git 中索引(暂存区)的复杂性,是更优雅、更一致的设计;
- 弱化了 branch 概念,不再必须创建分支,分支管理接近 Mercurial;
- 工作目录即提交,简化了 dirty files 管理,再也不用担心丢文件、丢修改、stash 混乱;
- 将冲突本身作为数据结构存储,允许用户先提交冲突状态,之后再解决,避免了 Git 中
rebase --continue的中间状态,使操作更具原子性
- 比
git rebase -i更强大方便的提交历史改写能力,促成 Git 增加了试验性的git replay命令- 引入稳定的 Change ID,再也不用烦恼 rebase 后 Commit ID 变化;
- 改写历史后自动 rebase 后续提交,管理 stacked commits 更方便;
jj split、jj move、jj amend等命令提供了比 Git 更灵活、更强大的方式来拆分、移动和修改提交,即使是历史提交也能轻松处理;
- 与 Git reflog 相比,Jujutsu 的操作日志(jj op)将复杂操作视为单个原子条目,使得
jj undo命令非常强大和可靠,极大地降低了误操作导致数据丢失的风险; - 比 Git revisions 更强大方便的 revsets 语法(源自 Mercurial);
- 底层存储与 Jj 上层命令实现解耦,Git 是目前最成熟的底层存储;
所谓的 stacked commits/changes/diffs、stacking 指 https://www.stacking.dev/ 所描述的工作流:下一个 feature branch B 可以依赖还没完成代码评审的 feature branch A,并在 feature branch A 有变更时能自动 rebase feature branch B 和更新对应的 pull request。这个工作流需要两方面能力的配合:(1) 在 local repo 里自动 rebase 下游分支,例如 git rebase --update-refs,Jujutsu、Sapling、Pijul 也都支持这个特性;(2) 自动创建、更新多个 feature branches 所对应的 pull requests,例如 Sapling、Git Town、spr、Ghstack、revup、Graphite(不开源)。
Jujutsu 的 working copy as commit 设计默认会提交所有文件,这对习惯了 git add 的人可能很不适应,可以用如下方法之一解决:
- 【不投荐】用
jj config set --repo snapshot.auto-track 'none()'以及jj file track xxx来显式增加文件,用jj split或jj commit -i达到git add -i/-p和git commit --interactive/--patch的效果; - 在
.gitignore里增加一个tmp目录用作 scratch area,用于存放无需版本管理的文件,并用jj file untrack xxx来去掉失误提交的文件,用jj split或jj commit -i达到git add -i/-p和git commit --interactive/--patch的效果;
注意截止 2025-10 Jujutsu 还不支持 Git submodule,而 Sapling 支持。
Sapling
- 主页: https://sapling-scm.com/
- 作者:Meta(原 Facebook)
- 受启发:Mercurial
- 开源时间:2022.11(实际开发时间开始自 2005.4)
- 实现语言:Rust
Meta 的下一代版本管理工具,与 Git 兼容,主要改进:
- 对巨型单库 partial clone、sparse checkout 的良好支持(已回馈给 Git,Microsoft 也贡献了 Scalar);
- 对 stacked commits 管理的良好支持,且支持管理 stacked PRs;
- 弱化了 branch 概念,不再必须创建分支,分支管理接近 Mercurial;
- 去掉了 staged area 概念;
- 更强大方便的 undo 能力;
- 支持 sparse profile 方便同组的同事工作在同一个文件集合上;
Pijul
- 主页: https://pijul.org/
- 作者:Pierre-Étienne Meunier
- 受启发:Darcs
- 开源时间:2016.2
- 实现语言:Rust
不兼容 Git,不是基于快照而是基于补丁,天然方便 stacked commits 的管理,UI 比 Git、Jujutsu 和 Sapling 更简洁,有更好的多路合并正确性。
快速入门
Sapling 的 Git 桥接思路主要是改进 Git 使用体验,可以认为是个更好的 Git client,而 Jujutsu 要激进点,目标是下一代的 DVCS,只是目前开源的存储后端是 Git。 两者都能很方便的与 Git 一起使用。
Jujutsu:
brew install jj # on macOS
# 克隆 Git 库
jj git clone URL
# or 在已有的 Git work copy 里
jj git init
jj help
进一步使用见 Jujutsu 教程: https://jj-vcs.github.io/jj/latest/tutorial/
Sapling:
brew install sapling # on macOS
# 不要用 sl clone 和 sl init,这个模式不能与 Git 一起使用
git clone URL
sl help
进一步使用见 Sapling 教程: https://sapling-scm.com/docs/introduction/getting-started
参考
- Jujutsu: a new, Git-compatible version control system
- Is Git Finally Getting a Successor? Jujutsu (jj), Sapling, and Pijul for Stacked Diffs and Monorepos in 2025
- Ask HN: Git Alternatives – Sapling vs. Jj 这篇提到一个介于 Git 和 Jujutsu/Sapling 之间的工具 git-branchless
- Ask HN: on Steve’s Jujutsu Tutorial
- https://en.wikipedia.org/wiki/Comparison_of_version-control_software