Jujutsu(jj)同类工具对比指南:从 git-branchless、Sapling 到 GitButler,理解下一代版本控制系统的差异化定位
2026/9/10 16:29:07 网站建设 项目流程

Jujutsu(jj)同类工具对比指南:从 git-branchless、Sapling 到 GitButler,理解下一代版本控制系统的差异化定位

【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj

Jujutsu(jj)是一个与 Git 兼容、既简单又强大的版本控制系统。本篇指南以官方文档中的 Related work(相关工作) 为核心骨架,逐一剖析jj与 git-branchless、Sapling、GitUp、Gitless、Breezy、GitButler 六款同类工具的关系与差异,并结合仓库内 Sapling 对比文档、Git 对比文档 以及源码实现,帮助你快速建立对版本控制生态的全局认知,并回答一个核心问题:既然已有这么多类似工具,Jujutsu 的设计取舍究竟独特在哪里。

引言:Jujutsu 在版本控制生态中的位置

Jujutsu 的官方文档用一个独立的 Related work 页面列出了六款与它功能相似的现代工具。这些工具共享一个共同的时代背景:传统 Git 的"暂存区 + 分支模型 + 冲突阻塞式工作流"让许多开发者感到繁琐,于是社区从不同角度尝试重新设计版本控制的交互方式——有的通过包装 Git 提供更友好的界面(Gitless、GitButler),有的在 Git 之上叠加撤销与匿名分支能力(git-branchless),有的则是完整重写的独立 VCS(Sapling、Breezy、Jujutsu 本身)。

要理解这份列表,关键是先抓住 Jujutsu 的三个底层设计支柱(它们在 Git 对比文档 中被详细展开):

  • 工作副本自动提交:几乎每个jj命令都会先自动快照工作副本(详见 working-copy.md);
  • 冲突是一等公民:冲突可以被记录在提交里,而不是阻塞任何操作(详见 conflicts.md);
  • 操作日志(operation log)驱动撤销:每次修改仓库的操作都被记录,jj undo等能力都由它支撑(详见 operation-log.md)。

有了这三根支柱,再去看每一款同类工具,就能立刻看出它们与 Jujutsu 的重合点与分岔点。

git-branchless:在 Git 之上叠加"无分支"工作流

"Helps you use a branchless workflow in your Git repo. Supports anonymous branching, undo, and faster rebase (git move). Under heavy development and quickly gaining new features."

git-branchless 的思路与 Jujutsu 高度重合:它鼓励用户放弃传统命名分支,改用**匿名分支(anonymous branching)**工作流——即所有提交都叠在一条或多条匿名线上,需要时再打标签。这与 Jujutsu 的"无当前分支"模型几乎同构:Jujutsu 的提交图会跟踪所有可见的匿名头(anonymous heads),提交不会因为"没有分支指向"而丢失或被垃圾回收(参见 glossary.md 中的 Anonymous branch 词条)。

两者都提供undo。但底层机制完全不同:

  • git-branchless 构建在 Git 的 reflog 与 refs 之上;
  • Jujutsu 拥有独立的操作日志:每个操作对象记录整仓库的 view 快照(所有 bookmark、tag、Git ref 的位置,可见头集合,以及每个工作区的工作副本提交),并指向其父操作形成 DAG。在 cli/src/commands/undo.rs 中,jj undo的实现(UndoArgs)非常简单,因为"撤销一步"本质上就是从操作日志里选择前一个操作并恢复其 view。

git-branchless 的快速 rebase 功能叫git move;Jujutsu 对应的则是jj rebase,并且由于"自动 rebase 后代提交"机制,jj rebase之后所有后代提交、指向它们的 bookmark 以及工作副本都会自动跟随更新(详见 git-comparison.md)。

关键差异:git-branchless 始终是"Git 之上的一层壳",它无法改变 Git 本身的数据模型;而 Jujutsu 拥有自己的存储层与提交模型(尽管默认后端就是 Git 仓库,见 git-compatibility.md),因此能实现 git-branchless 做不到的能力,例如把冲突本身作为提交内容提交。

Sapling:来自 Meta 的 Mercurial 深度改造分支

"A heavily modified fork of Mercurial developed and used at Meta. It is compatible with Git, has undo functionality, and a graphical interface."

Sapling(sl)是这份列表中最重量级的对手,官方文档专门为它撰写了一篇完整的对比文档:Comparison with Sapling。由于 Jujutsu 从 Mercurial 借鉴了大量思想(revset 语言、堆叠提交、匿名头、split、amend 后自动 rebase 后代等),两者有不少共同点:

  • 友好的 CLI;
  • 用于选择修订版本的 revset 语言;
  • 对堆叠提交的良好支持,包括跟踪匿名头(没有 Git 的 detached HEAD 状态)与split命令;
  • 通过 templates 灵活定制输出。

两者之间的具体差异(均来自 sapling-comparison.md):

维度Jujutsu(jj)Sapling(sl)
工作副本每个命令自动快照,新文件自动跟踪、删除文件自动取消跟踪需要用户显式提交,冲突时命令会失败("abort: 1 conflicting file changes"),需要sl shelve
冲突可以提交冲突(存储的是冲突的逻辑表示,而非<<<<<<<标记),可随时解决、可继续 rebase提交前必须解决冲突,自动 rebase 遇到冲突会失败
Undo由操作日志驱动,jj op log可直观查看仓库历史并选择回退多远有 MetaLog,但sl debugmetalog看起来只展示单个提交的历史而非整仓库历史
Git 互操作克隆/推送/拉取之外,还支持与 Git 仓库共享同一个工作副本(colocated workspace)支持 Git 远端互操作,但不共享工作副本
打磨程度相对更朴素更完善,自带交互式 Smartlog 网页 UI(可拖拽提交进行 rebase)
代码托管平台(forge)工作流无直接集成;用jj git push --change为指定提交自动建分支sl pr submit --stack可将提交栈拆成多个 GitHub PR(仅支持 GitHub)

其中"工作副本"的差异尤其值得展开。Jujutsu 将工作副本视为一个普通提交(即@),因此在 working-copy.md 中可以看到如下推论:

  • 每次运行命令,工作副本都被隐式备份;
  • 没有任何命令会因为"工作副本有改动"而失败;
  • CLI 更简单一致,因为工作副本与其他提交没有任何区别对待。

这一差异还延伸到 undo:jj undo一次jj commit后,jj diff会显示与提交前完全相同的改动(因为工作副本的改动已被快照进提交,撤销操作能还原它);而sl undo一次sl commit后,工作副本是干净的——改动已经丢进提交里了。

GitUp:Mac 专用的 Git GUI,最早实现"仓库快照式撤销"

"A Mac-only GUI for Git. Like Jujutsu, supports undo and restoring the repo to an earlier snapshot. Backed by its GitUpKit library."

GitUp 的价值在于它证明了"把仓库恢复到任意历史快照"这一交互模式是可行的:它底层由 GitUpKit 库驱动,可以让用户随时回到仓库的早期状态。这正是 Jujutsu 操作日志的核心能力:

  • jj undo:逐条撤销最近的操作;
  • jj op revert:回退一个并非最新的指定操作;
  • jj op restore:把整个仓库恢复到某个较早操作时的状态。

区别在于,GitUp 是 Mac 平台的 GUI 工具,其撤销能力建立在 Git 的内部结构之上;而 Jujutsu 把"操作历史"做成了仓库数据模型的一等组成部分——操作日志本身就是一个由操作对象构成的 DAG(参考 glossary.md 的 Operation log 词条),并且通过顶层选项--at-operation/--at-op可以把任意命令加载到历史中的某个操作视角上执行(详见 operation-log.md)。

Gitless:简化 Git 界面,但没有暂存区概念的先行者

"Another attempt at providing a simpler interface for Git. Like Jujutsu, does not have an 'index'/'staging area' concept."

Gitless 与 Jujutsu 的核心共鸣点是取消暂存区(index/staging area)。Git 对比文档 git-comparison.md 指出:暂存区本质上就是HEAD与工作副本之间的一个中间提交,因此依赖它的工作流完全可以改用"真正的提交"来建模——Jujutsu 正是这么做的:

  • 想要只提交工作副本的一部分改动?Git 习惯用git add -p; git commit,Jujutsu 用jj split把工作副本提交拆成两个;
  • 想把改动并回父提交?Git 用git add -p; git commit --amend,Jujutsu 用jj squash -i选择要移动的改动,或用jj squash <file>移动指定文件。

Gitless 与 Jujutsu 的一个关键分岔点是:Gitless 不会在不同分支之间搬动工作副本的改动,而 Jujutsu 因为把工作副本本身做成一个提交,搬动改动只是 rebase 的自然结果("we do simply as a consequence of making the working copy a commit")。在 Jujutsu 中,从工作副本提交创建新提交、切换基础、合并改动,全部统一为对提交图的改写操作,这是"无暂存区"设计能够成立的根本原因。

Breezy:多存储后端的另一个实践者

"Another VCS that's similar in that it has multiple storage backends, including its own format as well as .git support."

Breezy 与 Jujutsu 的相似点在于多后端存储架构。Jujutsu 的存储层通过 backend 抽象隔离(参见 glossary.md 的 Backend 词条):目前唯一生产可用的内置提交后端是 Git 后端(把提交存进 Git 仓库),另外还有用于测试的多款后端;同时操作日志、工作副本等也各有可插拔的存储后端。Jujutsu 的 Git 后端能力细节可见 git-compatibility.md,包括:

  • jj git init --git-repo=<path>基于已有 Git 仓库或裸仓库创建 jj 仓库;
  • jj git clone <URL>从远端克隆;
  • colocated workspace 模式下jjgit命令可在同一工作副本中混用,每次jj命令自动执行 import/export。

相比 Breezy"自带格式 + .git 支持"的路线,Jujutsu 的 Git 兼容性设计得更深入——它可以在不打断 Git 工具链的前提下,与 Git 用户无缝协作。

GitButler:虚拟分支与多分支并行工作的 Git 客户端

"A Git client that works with multiple virtual branches simultaneously, first-class conflicts, and operations history."

GitButler 是一个 Git 客户端(GUI),它提出的**虚拟分支(virtual branches)**概念允许同时并行维护多个逻辑分支,配合一等冲突处理与操作历史。这与 Jujutsu 的工作流殊途同归:Jujutsu 虽然没有 GUI,但在 CLI 层面天然支持多条并行开发线——因为提交图的任何位置都可以长出匿名分支,而 bookmarks(命名指针)只是可选的标签,可以随时移动而不影响其指向提交的身份。

值得注意的差异:GitButler 是构建在 Git 之上的客户端层,而 Jujutsu 是完整的 VCS 实现。Jujutsu 的"一等冲突"意味着冲突可以存在于提交中并被继续 rebase、merge 或 revert(详见 conflicts.md),而不仅仅是在客户端 UI 里被友好地展示。

横向对比:一张表看懂六款工具与 Jujutsu 的关系

工具类型与 Jujutsu 的共同点与 Jujutsu 的关键差异
git-branchlessGit 之上的增强层(CLI)匿名分支工作流、undo、快速 rebase受限于 Git 数据模型,无法提交冲突
Sapling独立 VCS(Mercurial 分支,Meta 开发)revset、堆叠提交、撤销、Git 兼容需显式提交、冲突阻塞、无 colocated 共享工作副本、有图形界面
GitUpMac 专用 Git GUI仓库级撤销与快照恢复平台绑定、构建于 GitUpKit 之上
GitlessGit 之上的简化 CLI无暂存区概念不搬动工作副本改动跨分支
Breezy独立 VCS多存储后端(自有格式 + .git)走传统提交模型
GitButlerGit 客户端(GUI)多分支并行、一等冲突、操作历史是客户端而非 VCS 本体

从源码看 Jujutsu 差异化能力的实现锚点

如果你希望验证上述对比中"Jujutsu 独有能力"的真实性,可以在本仓库中找到对应的实现与测试证据:

  • 自动快照工作副本:实现位于 lib/src/local_working_copy.rs,配套文档见 working-copy.md,测试见 lib/tests/test_local_working_copy.rs;
  • 一等冲突(commit 可携带冲突):核心逻辑在 lib/src/conflicts.rs 与 lib/src/merged_tree.rs,测试见 lib/tests/test_conflicts.rs;冲突标记的"快照 + 多个 diff"式物化格式详见 conflicts.md;
  • 操作日志与 undojj op logjj undojj op restore的命令实现位于 cli/src/commands/operation/ 与 cli/src/commands/undo.rs,操作存储抽象见 lib/src/op_store.rs;
  • 匿名分支 / 可见头跟踪:view 对象记录所有可见头,相关概念见 glossary.md,view 实现见 lib/src/view.rs;
  • Git 后端与 colocated 工作区:见 lib/src/git_backend.rs 与 cli/src/commands/git/,jj git colocation命令在 cli/src/commands/git/colocation.rs。

结语:Jujutsu 的差异化定位

纵观六款同类工具,"简化 Git"是共同目标,但实现的层次不同:git-branchless、Gitless、GitButler 是在 Git 之上做增强或包装,受制于 Git 的数据模型;Sapling、Breezy 是完整重写的 VCS,但保留了传统"显式提交、冲突阻塞"的交互;GitUp 则是单平台 GUI。

Jujutsu 的独特之处在于:它重新设计了数据模型(提交可携带冲突、操作日志记录一切、工作副本即提交),同时保证与 Git 仓库深度兼容——这使得它既拥有下一代 VCS 的表达能力,又能无缝融入现有 Git 协作生态。判断它是否适合你,可以从这三个问题入手:你是否厌倦了显式git add/git commit与"先解决冲突才能继续"的阻塞式流程?你是否频繁需要撤销/回退仓库状态?你的团队是否愿意在一个"用 jj 命令操作、底层仍是 Git 仓库"的环境里协作?如果答案是肯定的,那么 Jujutsu 值得你花一个下午用 tutorial.md 实际体验一番。

【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询