jj:用 29000 颗星告诉你,Git 该被重新设计了
你有没有在 git rebase 冲突后手足无措过?有没有误操作后翻遍 git reflog 找回丢失的提交?有没有觉得 git add → git commit 这套暂存区流程多余?
如果这些问题你都遇到过,那你应该认识一下 jj——一个用 Rust 编写、兼容 Git、却从根本上重新设计了版本控制模型的工具。它的 GitHub 仓库在 2026 年 6 月已经突破 29000 颗星,最新版本 v0.41.0 刚在 5 月发布,背后站着 Google 工程师 Martin von Zweigbergk。
一、jj 是什么
jj(Jujutsu 的缩写)是一个版本控制系统,但它不是要取代 Git——它坐在 Git 之上,用 Git 仓库作为底层存储,同时提供一套完全不同的用户接口。
简单说:你用 jj 操作,数据存在 Git 仓库里,GitHub、GitLab 照常能用。
这意味着什么?你不需要说服整个团队一起迁移。你可以一个人用 jj,队友继续用 Git,你们推拉代码互不影响。
二、工作副本 = 提交:告别暂存区
Git 有三层:工作区 → 暂存区(index)→ 仓库。每次修改文件后,你需要 git add 把变更放进暂存区,再 git commit 提交。
jj 砍掉了中间那层。你编辑文件,jj 自动在后台创建快照(snapshot),每次操作都会把当前工作区状态记录为一个提交。这意味着:
- 没有
git add——编辑即记录 - 没有
git stash——切换分支时工作区变更自动跟随 - 没有 detached HEAD——你永远在一个变更(change)上工作
这对新手来说是巨大的认知减负。你不需要理解「暂存区到底是什么」,只需要知道「编辑 → 描述 → 推送」。
三、操作日志:版本控制的时间机器
这是 jj 最让人安心的功能。
每一次操作——新建提交、变基、推送、合并——都被记录在操作日志里。你可以用 jj op log 查看完整历史,用 jj undo 撤销上一步操作,用 jj op revert @-- 回到任意历史状态。
和 git reflog 相比,jj 的操作日志是结构化的:每一步都有明确的操作类型、影响的提交、时间戳。你不需要猜 SHA,不需要在一堆哈希值里大海捞针。
一个真实场景:你误删了一个提交(jj abandon),过了两分钟才意识到。在 Git 里你需要翻 reflog 找到那个 SHA,然后 cherry-pick 回来。在 jj 里,jj undo 一条命令搞定。
四、Revset:用 SQL 的方式查询提交
jj 有一套查询语言叫 Revset,用来选择提交。它的表达能力远超 Git 的 --grep 和 --author。
几个例子:
jj log -r 'all()'——查看所有提交jj log -r 'author(张三) & date(after:2026-05-01)'——张三在 5 月后的提交jj log -r 'children(abc123)'——某个提交的所有子提交jj log -r 'heads(all())'——所有分支的头部提交
Revset 还支持集合运算(交集、并集、差集),可以用 :: 表示祖先/后代关系。这在处理复杂的分支历史时特别有用。
五、冲突是一等公民
Git 处理冲突的方式是「阻塞」:遇到冲突,rebase 暂停,你必须立刻解决,然后 git rebase --continue。
jj 不一样。冲突被记录为提交的一部分,你可以继续工作,稍后再解决。如果冲突在提交 A 里被解决,这个解决方案会自动传播到 A 的所有后代提交。
这像什么?像 Git 的 rerere(reuse recorded resolution),但是内建在设计里,不需要额外配置。
六、自动变基:改一个提交,后代自动跟上
在 jj 里,当你修改一个提交(比如 jj squash 合并变更、jj rebase 移动位置),所有后代提交会自动变基到新位置。
举个例子:你有三个提交 A → B → C。你用 jj rebase -r A -d main 把 A 移到 main 最新。Git 需要你手动 rebase B 和 C,或者用 --update-refs。jj 直接帮你做了,B 和 C 自动跟上。
七、与 Git 的兼容性
jj 使用 Git 仓库作为后端存储,这意味着:
- 你可以在任何现有的 Git 仓库上使用
jj git init --git-repo . jj git push和jj git fetch直接操作 Git 远程- GitHub PR、GitLab MR 都能正常使用
- 你的
.gitignore会被尊重
但有一些差异需要注意:
- jj 用 Change ID(而非 Git commit SHA)跟踪提交的「身份」
- 书签(bookmark)对应 Git 的分支,但语义不同
- 某些 Git 操作(如
git cherry-pick)需要用 jj 的原生命令替代
八、安装和上手
安装很简单。macOS 用 Homebrew:
1 | brew install jj |
Linux 用 cargo(需要 Rust 工具链):
1 | cargo install --git https://github.com/jj-vcs/jj jj-cli |
Windows 直接去 GitHub Releases 下载预编译包。
在现有 Git 仓库上初始化:
1 | cd your-git-repo |
然后就可以用 jj 命令操作了。所有变更通过 jj git push 推到远程 Git 仓库。
九、局限性
jj 不是银弹。几个现实问题:
学习成本:虽然 jj 比 Git 简单,但你的肌肉记忆是 Git 的。git add 变成不需要了,git checkout 变成 jj new,这些转换需要时间。
生态不成熟:VS Code 的 jj 插件还在开发中,CI/CD 集成不如 Git 丰富,教程和社区资源远少于 Git。
大仓库性能:在超大型仓库(monorepo)上,jj 的某些操作比 Git 慢。Google 内部有自己的后端(Piper/CitC),但开源版用的还是 Git 后端。
团队采纳摩擦:你一个人用 jj 没问题,但如果想让团队一起用,说服成本不低。
分支管理语义差异:jj 的「书签」(bookmark)和 Git 的「分支」(branch)概念不同,切换时需要适应。
十、为什么值得关注
jj 的价值不在于「替代 Git」,而在于它证明了版本控制的模型可以被重新设计。29000 颗星说明开发者社区对现状不满,对更好的工具有真实需求。
如果你是个人开发者,或者团队里只有你一个人想尝试新工具,jj 值得花一个下午体验一下。它不会改变你的 Git 仓库,但可能会改变你对版本控制的理解。
相关链接:
- 标题: jj:用 29000 颗星告诉你,Git 该被重新设计了
- 作者: Seven
- 创建于 : 2026-06-04 16:00:00
- 更新于 : 2026-06-04 11:36:33
- 链接: https://blog.oneiseven.top/2026/06/04/jj-jujutsu-重新定义版本控制/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。