专栏文章
可以全面代替 Git 的新一代版本控制工具 —— Jujutsu
科技·工程参与者 6已保存评论 6
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @mlia3dj7
- 此快照首次捕获于
- 2026/02/12 01:03 上周
- 此快照最后确认于
- 2026/02/19 01:12 14 小时前
如果一年前问我最强大的版本控制软件是哪个,我会说是 Git;而现在,我会毫不犹豫地回答:Jujutsu(特别是将其与 Vibe-Coding/AI 辅助编程配合使用时)。
截止目前,
jj-vcs/jj 仓库在 GitHub 上已斩获超过 25.4k Stars。我已经将大量开源项目迁移到了 Jujutsu 进行管理。最令人惊奇的是,它完全兼容现有的 Git 工作流以及 GitHub、GitLab 等托管服务,Jujutsu 生成的提交在旁人看来与 Git 生成的没有任何区别。(你甚至可以将其和 Git 同时工作,一会用 Jujutsu,一会用 Git 都是完全可以的!)如果你也像我一样,受够了 Git 的合并冲突、破坏性变更以及复杂的
rebase 操作,我强烈推荐你尝试一下 Jujutsu。Jujutsu 一词源于日语中的“柔术”。在 Vibe Coding(沉浸式编程)时,最打断“心流”的往往是 LLM 写错了功能需要撤回,或者是与他人的 PR 产生冲突,导致必须先
resolve 才能继续开发。而 Jujutsu 通过全新的理念极大地缓解了这些问题,显著提升了我的开发效率。而且,最关键的是,我还发现了 Jujutsu 不但与工程项目配合良好,而且还可以极大地方便我们做题和打比赛,特别是在 ABC、CodeForces 和洛谷月赛等线上短时赛中。注意
在阅读本文前,我们假设您具有基础的 Git 知识,对提交(Commit)、变基(Rebase)、合并(Merge)以及 PR(Pull Request)等概念有一定了解。
注意
本文旨在介绍 Jujutsu 这一新兴工具的核心概念与优势,而非详尽的使用教程。如果您希望深入学习,建议查阅官方文档。
对版本控制的“版本控制”
使用 Git 时,最让我焦虑的问题是:如果执行了错误的指令,我的仓库可能会遭受不可逆的损坏。出于这种顾虑,我很长一段时间不敢在 Git 里“整活”,比如直接切到历史提交上修复 Bug。长期以来,我仅把 Git 当作一个存档工具,只有在把工程彻底搞坏时才指望它来救命。
现在,Jujutsu 引入了针对版本控制的控制(我们可以称之为“元版本控制”)。与 Git 那简陋且难以理解的 Reflog 不同,Jujutsu 的元版本控制是完整且直观的。这意味着你的任何操作都是可恢复的,甚至可以完美回退到历史状态。妈妈再也不用担心我把仓库玩坏了!
要使用这个功能,最简单的方式是使用
jj op 命令组:jj op log:打印你的操作日志(Operation Log)。jj op undo:创建一个新的操作,逆转指定的操作。jj op restore:将仓库恢复到某个特定操作时的状态。这类似于“时间旅行”。如果你把仓库搞得一团糟,想回到昨天下午 2 点的状态,一条命令即可解决。
这也是我钟爱 Jujutsu 的原因(或许也是我喜欢 Rust 的原因之一):它极大地降低了开发者的心智负担。确信操作可撤销,让我敢于大胆使用各种技巧来优化开发效率。
Change ID:重新定义提交
熟悉 Git 的读者都知道 Commit ID,它是一个表示提交内容的不可变哈希值。这带来了一个棘手的问题。假设我们有如下的提交树:

如果我们回到
8a30ca57 (Commit C) 修改了内容,它的哈希值必然改变。由于父节点哈希变了,它的所有子节点(如果有的话)的哈希值也必须跟着变。结果就是,这棵树会分裂成两棵树! 这不仅令人不爽,而且非常反直觉。而这一切,仅仅是因为 Commit ID 与内容强绑定。Jujutsu 为了解决这一问题,引入了 Change ID 的概念。
与 Commit ID 不同,Change ID 是与提交的具体内容解耦的。对于任何一个提交,Change ID 在其整个生命周期中保持不变。即便你修改了代码、改变了父节点,甚至将其变成悬空提交,它的 Change ID 都不会变。
回到上面的例子(假设字符串是 Change ID),如果我们要切回
8a30ca57 修复 Bug,修完之后直接切回 2375d516 即可。Jujutsu 会自动将修改应用(Rebase)到它的所有子节点上。这一切都是全自动的,无需像 Git 那样手动执行复杂的交互式变基。注意
虽然 Jujutsu 中 Change ID 和 Commit ID 都可以用来表示一个提交,但 Commit ID 纯粹是为了保持对 Git 的兼容而存在的。在 Jujutsu 的语境下,我们应尽可能使用 Change ID。
Revsets:强大的查询语言
在 Git 中查找特定的提交 ID 往往很繁琐。Jujutsu 引入了 Revsets 查询语言来解决这个问题。
Revsets 是一种解释型的函数式编程语言,它的唯一作用就是对提交树上的各个节点进行筛选与查询。这门语言非常强大,本文无法穷尽其用法,建议读者自行查阅文档或询问 AI。
简单来说,Revsets 允许你用人类和机器都可读的方式,表示任意一个(或一组)相对于当前节点或绝对位置的提交。
以下是一些 Revsets 的使用示例:
trunk()..@:选择从主分支(trunk或main)的后代开始,直到当前工作副本(@)的所有提交。main..feature-a:查看feature-a分支上有,但main分支上没有的提交。file("README.md"):查找所有修改了README.md文件的提交。
不再需要“分支”
在 Git 中,提交图通常由基干分支
main 和多个旁系分支(如 develop、feat/xxx)组成。这看起来很规范,但管理一大堆分支名称本身就是一种负担。Jujutsu 干脆抛弃了强制性的“分支”概念。你可以直接从任意提交上拉出一个新的子节点(Revision),然后直接开始写代码。
为了保证极致的“心流”体验,在 Jujutsu 中你甚至不需要给提交命名,也不需要先创建分支。你的代码写得乱也没关系,甚至每写一行打一个提交都可以。等你完成了功能,回过头看哪些部分是不需要的,直接
jj absorb + jj squash 一下,提交历史瞬间变得干净整洁。当你完成了功能开发,再使用
jj bookmark 命令组创建一个书签(Bookmark)。在 Git 看来,这个 Bookmark 在哪里,分支就在哪里。这是 JJ 为了兼容 Git 而保留的设计,让你能方便地标记特定位置。与 Git 不同的是,这个书签是可以随意移动的,甚至可以移动到它之前的历史位置,完全没有心智负担。
完全兼容 Git 生态
任何新工具如果不能兼容旧生态,都很难生存。幸运的是,Jujutsu 对 Git 的兼容性堪称完美。
Jujutsu 底层维护着两个仓库结构:
.jj:Jujutsu 自己的核心仓库,记录着它认可的所有提交记录和操作历史。.git:标准的 Git 仓库目录。
.jj 目录只会同步 Jujutsu 认为对 Git 有意义的数据(例如分支结构、变更历史等)到 .git 中。由于 Jujutsu 不依赖 Git CLI,而是直接通过 Rust 的 git2 crate 进行读写,它避开了 Git 的许多历史包袱和限制,同时保留了对 Git 现有工具链和生态 100% 的兼容性。正如我们所见,Jujutsu 的官方仓库
jj-vcs/jj 本身就是用 Jujutsu 维护的,它与 GitHub 等托管平台的配合天衣无缝。在 OI 中的应用
虽然 Jujutsu 是为软件工程设计的,但我发现它在 OI 训练中也大有可为:
首先是打网络赛(如 ABC、ARC、洛谷月赛)时,我们常遇到写到一半发现思路错误(假做法),需要重写的情况。为了防止把旧代码弄丢(万一旧代码是对的呢?),我们可以直接从历史提交拉出一个新分支继续写。如果需要找回旧代码(例如作为暴力程序进行对拍),直接打开历史版本复制即可,无需担心覆盖文件。
而且,还有一点就是,提交记录就是最好的做题日志。每刷一道题就提交一次,注明题号。配合 Revsets,你可以非常方便地统计做题量,甚至回顾某类题目的解法演变。
以下是我常用的一个提交信息模板(基于 Conventional Commits 修改得到),各位 dalao 可以参考一下:
CPPsolve(<平台>/<题号>): 涉及知识点
Rating: 难度
Contest: 比赛链接
URL: 题目链接
Solution: 个人笔记题解
实际使用中,例如:
CPPsolve(NFLSOJ/离散跳跃): DP、单调栈、数据结构优化
Rating: CF 2200
Contest: http://nflsoi.cc:20035/contest/2410
URL: http://nflsoi.cc:20035/contest/2410/problem/4
Gen AI 使用说明:本文写作过程中仅使用 Gemini 3 Pro 辅助查询资料。
画大饼
我后续可能开源一套我自己使用的,基于上述这一 OI 训练工作流专用的做题情况分析工具。理想地,它应该具有如下功能:
- 筛选自己做过的某种知识点的题目
- 将题目导出到 Anki 中进行复习(如果你不知道什么是 Anki,请参见 https://docs.ankiweb.net/)
相关推荐
评论
共 6 条评论,欢迎与作者交流。
正在加载评论...