过去大半年高强度用 AI agent 写代码的人,大概都撞上过同一个隐形的墙:模型能力越来越强、prompt 写得越来越顺、上下文窗口越拉越长,但真正拖后腿的,反而是那个被默认了二十年的工具——Git。不是 Git 不好,而是它的设计前提是'人类手工编程':一个人坐在编辑器前,想清楚要改什么,改完检查一遍,然后 add、commit、push。staging area 给你'最后再看一眼'的缓冲,branch 帮你隔离工作流,stash 让你临时放下手头的活。这套机制本质上是在给人类留喘气的时间,但 Agent 不需要喘气,它的干活方式是'先哗哗生成一大堆,回头再整理历史',而 Git 的模型是'边想边提交'——这两件事天然拧着。
每次你打断自己,跟 agent 说'提交一下''先 stash''切到那个分支',都是一次从'想产品想代码'到'想 Git 状态管理'的脱轨。以前节奏慢还能忍,现在人机配合越密,每次打断的代价就越高。于是 jj(Jujutsu)进入了视野。它是个可以和 Git 无缝共存的版本控制工具:本地用 jj 管理变更,远端依然通过 `jj git push/fetch` 和标准 Git 交互,对 GitHub 和同事来说看到的还是普通 commit 和 branch。担心锁定的问题也不存在,不喜欢随时退回 Git,`brew install jj` 加上 `jj git init --colocate` 一行就能开始。
jj 的核心概念是 change,一个跨 rebase 不变的唯一 ID。它最大的特点是没有 staging area:你的 working copy 本身就是一个 change,改了文件,它就自动跟着变,没有'改了但还没 add'的中间态。`jj describe -m "..."` 写描述,随时能改;`jj new` 把当前 change 定格并创建新的工作台;`jj edit` 直接跳回某个 change 继续改,后续 change 自动 rebase,没有 detached HEAD;`jj split` 可以把一个 change 按文件或 hunk 拆分。这些操作在传统 Git 里要么需要 `git add -p` 这种脆弱交互,要么需要 rebase -i 整理历史,每一步都可能让 agent 卡住或漏掉东西。而 jj 的哲学就是把为人类心理安全感设计的中间状态全部砍掉,让版本控制的心智模型回到最简单。
最让我觉得必须推荐给别人的,是 jj 和 agent 工作流之间的天然契合。举几个实际场景:开始下一项工作时,Git 时代你得指挥 agent 走'检查 → add → commit → push'的仪式,还得建分支;jj 下你只说'开始实现头像上传',agent 无脑 `jj new` 就行。做到一半临时切去修 bug,Git 时代要 stash、checkout、pull、建 hotfix 分支再切回来,链条上任何一步出错都可能搞出更大问题;jj 下 `jj new master` 修完 `jj edit` 就回去了。完成一坨大改动要拆分时,Git 时代 agent 得理解整个 diff、`git reset` 再 `git add -p` 来回选 hunk,漏掉文件或混入不相关改动几乎难以避免;jj 下 `jj split` 两三次就拆成逻辑清晰的提交,拆分错了就回去 edit,后面的 change 自动 rebase,永远不会丢东西。
更野的玩法是'先规划骨架,再让 agent 分段实现'——用 `jj commit -m` 一次性创建一串空 change,每个描述写清楚这一阶段要做什么,甚至把测试方法和验收标准直接写进 `-m` 里,然后对 agent 说'参考各 change 的描述,从某个 ID 开始顺次处理'。agent 每填完一个 change,下一个自动 rebase,它还能拿描述当验收标准,跑完自己对照描述确认达标再往下走,形成自驱动循环。这在 Git 里得额外维护一份文档,让 agent 来回对照,远没有把标准直接写进 change 描述来得顺手。多 agent 并行时,jj 的 workspace 和 Git worktree 能力对等,但不需要提前建分支,也不会搞出一堆 merge commit。至于 agent 搞砸了要回退,Git 时代你得判断该用 reset --hard、checkout .、revert 还是翻 reflog,选错了可能一天白干;jj 下一条 `jj undo` 撤回上一个操作,`jj op log` + `jj op restore <id>` 能恢复到任意操作节点,什么都不会真正丢。
回头看这些场景,jj 的好处不只是少打几个命令。更重要的是,你跟 agent 说话时可以只说业务上的事,不再需要'先 stash''切到那个分支''interactive rebase 一下'这些版本控制术语,沟通带宽被真正释放了。你脑子里想的是产品逻辑和代码设计,而不是 Git 的状态机怎么转。在 AI 时代,关键能力不是一次生成完美的提交历史,而是低成本地把已有结果整理成合理的历史——jj 恰好就是做这件事的。
如果你心动了,起步只需要十个命令:`jj log` 看状态,`jj describe -m` 写描述,`jj new` 开始下一段,`jj edit <change>` 切回去继续编辑,`jj split` 拆分 change,`jj undo` 撤回,`jj git fetch` 拉远端,`jj rebase -d master` 同步最新,`jj bookmark create feat -r @` 标记推送,`jj git push` 推送。会这些就够了,剩下的边用边学。让 agent 直接用 jj 也很简单,在 AGENTS.md 或 CLAUDE.md 里写一句'本 repo 用 jj 管理',agent 基本能无缝切换;想要更精确的操作指南,作者还提供了一个 jj agent skill(onevcat-jj),支持 skills.sh 的话一行 `npx skills add onevcat/skills --skill onevcat-jj` 就能装。
Git 在过去二十年定义了软件开发协作的标准,这个地位短期不会动摇。但'协作'和'本地工作'是两码事:Git 在协作这头依然无可替代,而在本地这头——怎么组织变更、怎么整理历史、怎么跟 agent 配合——确实到了该重新想想的时候。jj 给出的答案很朴素:砍掉那些为人类安全感设计的中间状态,让版本控制回到最简单的样子。当 agent 越来越深地参与日常开发,这种低成本重写、拆分、回退和并行的能力会越来越重要。Git 是你和世界协作的语言,而 jj 可能是你和 agent 一起思考的更好方式。
内容与图片版权归原作者所有 · 原文: https://onevcat.com/2026/03/jj-for-agent-era/