把 Jujutsu 理解错,最快的方法,就是把它叫作“命令行更易用的 Git”,然后停在这里。这句话并非全错,却遮住了真正重要的那一层。Jujutsu 的改动,并不主要发生在命令名字或交互措辞上。它更像是在改写用户被要求当成“真实”的那套对象关系:工作副本被当成普通提交,所有会改动仓库的动作都被写进操作日志,而 Git 则被收缩成兼容与存储层,不再继续充当全部语义的中心。[1][2][3][4]

把这个变化放到 2026 年来看,分量已经和几年前不同。它已经并非一个可以轻易丢进“有趣实验”抽屉里的小项目。截至 2026-04-10T23:04:07Z UTC,GitHub API 显示 jj-vcs/jj 仓库有 27,740 stars、1,001 forks、1,040 个 open issues,最近一次 push 时间是 2026-04-10T20:15:23Z。[7] 最近几个标签版本包括 2026-04-02 发布的 v0.40.02026-03-04v0.39.02026-02-05v0.38.0。[8] 这些数字不能替代架构判断,却足以说明一件事:这套设计已经有了持续发布与持续维护的现实基础,值得被单独阅读。

配图说明:题图使用 Martin von Zweigbergk 的真实 GitHub 头像,而没有选 Git logo、命令截图或抽象分支图。这个选择合适,因为 Jujutsu 并非在熟悉的管线外面再包一层新皮,它更像是一场由维护者主导的版本控制重构,重新决定什么应当构成仓库的真相,什么只应当留在兼容边界。[1][9]

工作副本不再是缓冲地带

第一层断裂,发生在工作副本。Jujutsu 的文档写得很直接:和大多数版本控制系统不同,工作副本内容会被自动提交,绝大多数 jj 命令在发现文件变化之后,都会创建或修改当前的工作副本修订。[2] 新增文件默认会被隐式跟踪,删除文件会被隐式取消跟踪,整套系统把工作副本当成提交图里的一员,而并非当成某种“提交之前的暂存区”。[2][5]

这听上去像是界面层的便利,一旦顺着文档往下看,就会发现它的影响远比界面深。Git 的 index 既是缓存,又是用户必须亲自管理的一块灰色地带。Jujutsu 的 Git 对比文档给出的判断很明确:既然想把当前状态的一部分变成提交,本来就应该直接在提交之间做切分与移动,也不用先把内容送进一个中间层,再从中间层拿出来。[5] 于是,最重要的可见对象被压缩成了一类:提交。[1][2][5]

也正因为如此,Jujutsu 在历史重写这件事上显得比 Git 自然得多。工作副本既然已经是提交,后续的 amend、split、squash 与改写,处理的就是图结构,而并非一套围绕 index 摆动的前置手势。[2][5] 把文档和 Chris Krycho 的长期使用记录并排来看,可以更清楚地看见这一层:Jujutsu 让人觉得“像是真的能替代 Git”,关键并不在新命令更好记,而在它先把概念压平了。[5][10]

操作日志才是这套系统真正的控制面

第二层断裂,发生在操作日志。Jujutsu 会把每一次修改仓库的动作写成一个 operation object,而每个 operation 都保存了该动作结束时仓库的状态快照。[3] 这个快照在文档里被叫作 view,其中包括 bookmark、tag、Git ref、当前 heads,以及每个 workspace 对应的 working-copy commit。[3] 正因为操作图是显式存在的,jj undojj op revertjj op restore 就不属于后补上的恢复工具,它们来自存储模型自然长出来的能力。[3]

这也是它和 Git reflog 最大的差别。Git 对比文档说 operation log 替代了 reflog,但更重要的一层在于,它记录的是整仓状态迁移,而并非若干条 ref 各自的局部历史。[3][5] 于是,“刚才到底发生了什么”这件事,不再需要靠人脑去拼接分支移动、HEAD 变化与工作目录状态,而可以被当成仓库历史本身来追问。

并发设计把这一层照得更亮。操作日志文档说明,这套机制被发明出来的重要原因之一,就是支持无锁并发,包括多个 jj 命令在不同机器上共享分布式文件系统时同时运行,只要底层能保证可见性顺序即可。[3] 这并非边角趣味。它暴露了项目设计所面对的尺度。Jujutsu 并非只想把单人本地工作流做得舒服,它还想让仓库在重叠编辑、延迟汇合和跨工作区修改里保持可恢复、可追问、可合并的状态。[1][3][6]

Git 是存储边界,并非语义边界

第三层断裂,发生在 Git 仍然留下来的位置。Jujutsu 的 README 说得很清楚:今天可用于生产的后端仍然是 Git,这让它能继续和 Git-based tools 以及 forge 协同工作。[1] 但 README 紧接着就划出了一道 adoptor 最不该看漏的边界:放进 Git 的只有提交和文件;bookmark 以及更高层的元数据,落在 Git 之外的自定义存储里。[1] 技术架构文档把这层又向前推进了一步。GitBackend 通过 gitoxide 读写提交与 refs,又额外在 refs/jj/keep/ 命名空间里保留引用,避免那些仍被 operation log 触达的提交被 Git 的垃圾回收删除;而 change ID 与 predecessors 之类 Jujutsu 自己的数据,则写在 .jj/repo/store/extra/ 下面。[6]

于是,Jujutsu 的 Git compatibility 是真的,却并不等于“Git 的全部语义原样保留”。兼容文档对边界写得非常坦白:branches 可以通过 bookmarks 对接,认证沿用 Git 做远程操作,merge commits 与 signed commits 都可用;但 .gitattributes、hooks、submodules、partial clones、git-worktree、sparse checkouts 与 Git LFS 仍然缺失,或者只有部分支持。[4] staging area 会被明确忽略;在 colocated workspace 里混用 gitjj 虽然允许,但 Jujutsu 往往会让 Git 落在 detached HEAD,因为它没有 Git 意义上的 current branch。[4][5]

Bookmarks 恰好是这条语义分界最好的例子。Jujutsu 把它定义成“像 Git branches 一样的具名指针”,但系统里没有 active bookmark 这件事,本地 bookmark 也可以同时跟踪多个同名远端 bookmark。[4][5] 这说明 Git 分支兼容被保留在协作层,项目内部真正稳定的概念中心,仍是提交图和 Jujutsu 自己的元数据层。[4][5][6]

哪类团队会真正关心它

落到采用层面,判断并不复杂。若一支团队希望继续使用 Git hosting、pull request 与普通远程协作,同时又想把 stacked changes、history rewrite 和 undo 做得更少脆裂,Jujutsu 确实打在了正确层级上。[1][3][4][5] 你的痛点若来自 index、reflog、detached HEAD 与脆弱 rebase 这套老问题,它给出的回答落在模型替换这一层,流程补丁不足以解释这套设计。

它的错位边界也同样清楚。若你的工作流高度依赖 Git-native hooks、submodules、LFS,或者别的兼容文档仍标成 unsupported 或 partial 的能力,那么 Jujutsu 还称不上语义上的 drop-in replacement。[4] 项目给出的信号已经足够明确:把 Git 当成互操作底座,而并非当成每一个 Git 时代假设都还能继续成立的保证。

所以,对 Jujutsu 最准确的一句概括,更接近“仍会说 Git 的另一套仓库真相模型”,而“更好的 Git”这句口号过于扁平。顺着这个角度回看,整套架构就会变得很连贯:工作副本提交取消了中间地带,操作日志记录整仓现实,Git 留在传输与存储边缘,而不再统治全部思维方式。[1][2][3][4][6]

来源

  1. Jujutsu README —— 项目概览、后端模型、working-copy-as-commit 设计、操作日志,以及当前 Git 后端定位。
  2. Jujutsu 文档,《Working copy》—— 自动快照、隐式跟踪、stale working copy 与多工作区行为。
  3. Jujutsu 文档,《Operation log》—— view 快照、undo/restore,以及无锁并发设计。
  4. Jujutsu 文档,《Git compatibility》—— Git 功能的支持边界、colocated workspace,以及 import/export 行为。
  5. Jujutsu 文档,《Comparison with Git》与《Bookmarks》—— 无 index、无 current branch、bookmark 语义,以及 operation log 对 reflog 的替代。
  6. Jujutsu 文档,《Architecture》—— storage-independent APIs、GitBackend 细节、.jj 元数据,以及 refs/jj/keep/ 的作用。
  7. GitHub API,jj-vcs/jj 仓库快照 —— 文章写作时的 stars、forks、open issues、默认分支与最近 push 时间。
  8. GitHub releases,jj-vcs/jj —— 最近标签版本,包括 v0.40.0、v0.39.0 与 v0.38.0。
  9. GitHub 上的 Martin von Zweigbergk 个人页 —— 本文题图所用维护者肖像的来源页面。
  10. Chris Krycho,《jj init》—— 来自独立实践者的长篇使用记录,解释 Jujutsu 为何在日常工作里显得比 Git 更简洁。