jj (Jujutsu):Agent 时代的版本控制,Git 的本地替代
> 来源: onevcat.com/2026/03/jj-for-agent-era/
> 作者: onevcat(王巍,iOS 知名开发者,Kingfisher 作者,53k+ stars)
> 发布时间: 2026-03
> 研究时间: 2026-03-30
🎯 一句话版本
jj 是一个和 Git 无缝共存的版本控制工具——远端还是 Git,但本地用 jj 管理代码变更。核心卖点:没有 staging area、没有 stash、没有 detached HEAD,特别适合人和 AI agent 来回切着干活的开发方式。
🧨 问题:Git 的设计假设过时了
Git 的机制是为二十年前"人类手工编程"设计的:
| Git 机制 | 为人类解决的问题 | 对 Agent 的影响 |
|---|---|---|
| staging area | "最后再看一眼" | 多余的中间态,浪费 token |
| branch | 隔离不同工作流 | 需要额外指令切换/创建 |
| stash | 临时放下手头的事 | 冲突时 agent 容易卡住 |
| detached HEAD | — | agent 不理解,出事故 |
关键矛盾:Agent 的习惯是"先哗哗生成一堆,回头整理历史",Git 的模型偏向"边想边提交"。天然拧着。
每次你打断心流跟 agent 说"提交一下""先 stash 一下""切到那个分支",都是一次从业务思考到Git 状态管理的脱轨。频率越高,代价越大。
🔧 jj 的解法:砍掉中间状态
jj (Jujutsu) 的核心设计——
与 Git 完全兼容
brew install jj
cd your-repo
jj git init --colocate # 就在现有 Git repo 里启用
远端还是 Git。对 GitHub 和同事来说,看到的就是普通 commit 和 branch。随时可退,零迁移成本。
核心概念:Change
- working copy = change:文件一改就属于当前 change,没有
git add - Change ID 跨 rebase 不变:不用记 branch name 或 commit hash
jj new= 定格当前 + 创建新工作台(≈ git commit + 继续编辑)jj edit= 跳回任意 change 继续改,后续 自动 rebasejj split= 拆分 change(不需要git reset + add -p反复操作)jj undo= 撤回任何操作(不需要翻 reflog)- bookmark = 只在推送时才需要的 Git branch 映射
⚔️ 6 个场景对比
场景 1:开始下一项工作
Git 时代:
> 你:看看改动,提交推送,然后新建分支,开始下一项工作
jj:
> 你:开始下一项工作:实现用户头像上传
Agent 执行 jj new,直接干活。版本控制从"每次都要交代的仪式"变成"背景里自然发生的事"。
场景 2:临时切去修 bug
Git:git stash → checkout master → pull → checkout -b hotfix → ... → checkout - → stash pop(任何一步出岔子 agent 就卡住)
jj:jj new master → 修 bug → jj edit 回去继续。没有 stash,没有状态恢复。
场景 3:拆分变更
Git:git reset HEAD~1 + git add -p 反复操作,agent 容易漏文件、混 commit
jj:jj split,选文件/hunk,剩下自动成为第二个 change。拆错了 edit 回去改,后面自动 rebase。
场景 4:骨架模式 ⭐ 最亮眼
先创建一串空 change当骨架,每个只有描述:
jj commit -m "refactor: extract auth module"
jj commit -m "feat: add token refresh logic"
jj commit -m "test: update auth tests"
jj commit -m "docs: update API documentation"
然后对 agent 说:
> 参考各 change 的描述,从第一个开始,顺次处理每个 change 的实现
Agent jj edit 到第一个 change 写代码,写完 edit 到下一个。后续 change 自动 rebase。
更进一步:把验收标准写在 change 描述里,agent 对照描述确认达标才往下走——自驱动循环。Git 里做这种事得额外维护文档 + Ralph Loop 之类的工具。
场景 5:多 Agent 并行
jj workspace add ../agent-1
jj workspace add ../agent-2
jj workspace add ../agent-3
独立磁盘目录、共享底层 store。做完后 jj new b1 b2 b3 合并。和 git worktree 对等,但不需要提前建 branch。
场景 6:Agent 搞砸了
Git:git reset --hard? checkout .? revert? reflog?(每种副作用不同,选错可能丢一天工作)
jj:jj undo。一个命令。jj op log 查看操作级历史,jj op restore 恢复到任意节点。什么都不会真正丢。
🤖 Agent Skill
onevcat 配套做了 jj 的 agent skill:
- GitHub: onevcat/skills/onevcat-jj
- 安装:
npx skills add onevcat/skills --skill onevcat-jj - 支持 skills.sh 生态和 OMA (Oh My Agents)
📊 最小命令速查
| 操作 | jj | Git 等效 |
|---|---|---|
| 查看状态/历史 | `jj log` | `git log --oneline --graph` + `git status` |
| 写描述 | `jj describe -m "..."` | `git commit -m "..."`(但 jj 可随时改) |
| 开始下一段工作 | `jj new` | `git commit` + 继续编辑 |
| 切到某个 change | `jj edit | `git checkout |
| 拆分 | `jj split` | `git reset HEAD~1` + 反复 `add -p` |
| 撤回 | `jj undo` | `git reflog` + `git reset` |
| 拉取 | `jj git fetch` | `git fetch` |
| Rebase | `jj rebase -d master` | `git rebase master` |
| 标记推送 | `jj bookmark create feat -r @` | `git branch feat` |
| 推送 | `jj git push` | `git push` |
💡 与我们的关联
1. 我们的 Agent 工作流正好受这个痛
我们用 Codex 和 Claude Code 写代码,每次都得在 prompt 里提"提交""推送""切分支"。如果切到 jj,这些仪式性操作全部消失——agent 专注于代码本身。
2. 骨架模式可以直接用
场景 4 的"先规划骨架、agent 逐个填充"模式非常适合我们的工作方式:Jay 规划任务结构,agent 按骨架执行。这比在外部文档里列步骤优雅得多。
3. 多 Agent 并行的方向
jj workspace 天然支持多 agent 在同一 repo 并行工作。我们的 ub2 服务器跑多个 agent 时,这比 git worktree 顺手。
4. onevcat 的 skill 生态贡献
作为 iOS 社区的知名开发者(Kingfisher 53k+ stars),onevcat 亲自做 agent skill 并推广 skills.sh 生态,这是技术社区对 agent 工具链的认可信号。
5. "Git 协作 + jj 本地"的分层思路
和飞书插件的"Bot 通道 + User 操作"分层类似——底层标准不变(Git/WebSocket),上层用更适合的工具(jj/OAuth)优化体验。
📊 评分
| 维度 | 评分(/10) |
|---|---|
| 技术深度 | 9.0 — 6 个对比场景、完整命令速查、骨架模式原创 |
| 实用性 | 9.5 — 零迁移成本、随时可退、10 个命令覆盖日常 |
| 洞察质量 | 9.0 — "版本控制的心智模型需要适配 agent"——精准 |
| 写作质量 | 9.0 — 结构清晰、对比直观、有实操步骤 |
| 与我们的相关度 | 8.0 — 我们用 agent 写代码,切 jj 有实际收益 |
| **综合** | **9.0** |
报告由深度研究助手自动生成 | 2026-03-30
来源: onevcat.com / jj GitHub / onevcat-jj skill