前言¶
在 DeepSeek Harness(DSH)里跑智能体时,版本控制往往还是按 Git 的习惯来:git status、git commit、git push。若工作区实际是 Jujutsu(jj)仓库,尤其是与 Git 共存的 colocated 布局,同一条 git status 和 jj status 可能给出不一致的结论,模型按 Git 推理容易做错事。
维护者 viztor 的 dsh-jujutsu(社区目录 viztor/dsh-jujutsu,源码 GitHub)属于 DSH 生态里的「工作流」类插件:在 Jujutsu 工作区内拦截会误导的 Git 命令,并返回应对应执行的 jj 命令或原因说明;同时提供 11 个结构化 jj 工具,并在系统提示里说明 Jujutsu 的工作方式。DSH 本身奉行「一切皆插件」;SkillHub 等目录站由社区维护,与 DeepSeek / 幻方无官方从属关系。
下面介绍插件定位、能力、安装与典型行为。
这是什么¶
一句话:Refuses Git inside a Jujutsu workspace and hands the model jj commands instead——在 Jujutsu 工作区内拒绝误用 Git,并把等价的 jj 用法交给模型。
在已有 .jj 的目录(自身或父目录)里,插件会挂载 Git 守卫、注册 jj 工具、注入与 Jujutsu 相关的提示;在普通纯 Git 仓库里默认不介入,除非你显式开启相关选项。npm 包名为 dsh-jujutsu,当前资料中的版本为 0.2.0,许可证 MIT。
核心功能¶
拦截 Git,并给出可执行的 jj 替代¶
守卫做的是翻译而不是固定模板:解析你实际输入的 Git 命令,尽量返回可粘贴的 jj 命令。例如:
| 输入 | 行为 |
|---|---|
git log --oneline -6 |
拒绝,并建议 jj log -r ::@ --limit 6 --no-graph |
git diff HEAD~1 |
拒绝,并建议 jj diff --from @- |
git push origin main |
拒绝,并建议 jj git push --remote origin --bookmark main |
git add src/a.ts |
拒绝并说明原因:Jujutsu 没有暂存区 |
git rebase -i |
拒绝(需要终端),并提示 jj rebase、jj squash、jj absorb 等 |
jj status、jj log 等 |
正常执行 |
翻译规则强调三点:Git 修订号会改写为 revset(如 HEAD~2 → @--);无法精确映射时退回目录式说明,避免半翻译命令;参数会做 shell 引用。只读 Git 与 写入类 Git 可分别配置,允许模型「看一眼」不等于允许它提交或推送。
十一个 jj 工具(结构化 JSON)¶
模型可通过工具读写历史,而无需反复解析 shell 输出。工具包括:
| 工具 | 作用 |
|---|---|
jj_status |
工作副本状态,含是否 conflicted |
jj_log、jj_diff、jj_op_log |
历史、变更与操作日志 |
jj_new、jj_describe、jj_squash |
新建变更、写描述、折叠变更 |
jj_bookmark、jj_op_restore |
书签与操作恢复 |
jj_hunk_list、jj_hunk_apply |
按 hunk 选择与应用(依赖可选的 jj-hunk) |
返回值均为 JSON;修订优先用 change ID(重写后仍稳定),而非仅依赖 commit ID。
在提示里「教」模型 Jujutsu¶
在 Jujutsu 工作区内,系统提示会说明:无暂存区、@ 始终对应一次提交、change ID 在重写后仍可用等。在纯 Git 仓库或无版本控制的目录,相关规则不会错误注入;无仓库时会告知模型,并可建议 jj git init(colocated,保留 Git 工具链)。
更细的 Git→jj 动词表与各工具返回字段,以名为 jujutsu 的 runtime skill 按需加载(可用配置关闭「提供 jj 手册」以节省上下文)。工作区状态与守卫规则则必须在首次 Git 命令之前进入系统提示。
可选:在 Git 仓库中采纳 Jujutsu¶
开启 Use Jujutsu in Git repos 后,在尚无 .jj 的 Git 仓库里首次会话会执行 jj git init --colocate:导入历史、启用 jj,且不改动 .git。LFS、sparse checkout、浅克隆、linked worktree、进行中的 Git 操作等场景会被拒绝采纳;子模块不作为硬性阻碍。
设置面板与项目级标记¶
在 Harness 的 Plugins → Jujutsu 可配置守卫、Git 读写策略、是否在提示中解释 Jujutsu、是否提供手册、是否强制在非工作区也走 Jujutsu 等。项目根目录可放置 .dsh-jujutsu.json 关闭或覆盖行为,例如:
{ "enabled": false }
从工作目录向上查找时,最近的标记文件生效,便于在 monorepo 内对子目录单独开关。
安装与依赖¶
- 在 Harness Plugins 页面安装,或执行:
dsh plugin install dsh-jujutsu
- 打开 Plugins → Jujutsu 按需调整;默认配置偏向安全、开箱可用。
环境要求(来自 README):
| 组件 | 要求 |
|---|---|
jj |
必需,0.46.0 及以上(示例安装:brew install jj) |
jj-hunk |
可选;未安装时 hunk 相关工具会报告不可用而非直接失败 |
| Node | 24 及以上(插件宿主侧) |
可选安装 jj-hunk(插件文档给出的 pinned 方式):
cargo install --git https://github.com/laulauland/jj-hunk --tag v0.5.1 jj-hunk
文档明确不建议 cargo install jj-hunk(crates.io 版本与插件测试接口不一致)。若 jj 未配置 user.name / user.email,创建提交的 jj 命令可能被拒绝,以避免无法推送的空作者提交。
典型用法与配置要点¶
日常 Jujutsu 工作区:安装插件后,让智能体在已有 .jj 的项目里工作即可;模型若习惯性跑 git status,会收到 jj status 等替代建议,并可直接调用 jj_log、jj_diff 等工具。
仍想偶尔用 Git 只读:将 Read-only Git 设为 allow 或 ask;写入类操作单独看 Writing Git,避免误放开推送。
纯 Git 仓库想逐步切到 jj:在设置中打开 Use Jujutsu in Git repos,确认仓库不属于文档列出的不可采纳类型后,由首次会话触发 jj git init --colocate。
无 .jj 但希望一律按 Jujutsu 约束:开启 Force Jujutsu,在非工作区内 jj 也会被拒绝并提示初始化命令。
高级场景可在 profile 配置中设置 jjPath、jjHunkPath、hunkInstall(ask / never / auto),用于自定义可执行文件路径或 jj-hunk 缺失时的策略。
适用场景与注意¶
适合已经在用或计划用 Jujutsu 管理仓库、又希望通过 DSH 让模型稳定走 jj 语义的场景:colocated 布局、强调 change ID、希望减少「Git 与 jj 状态不一致」带来的误操作。
不适合指望插件替你在非 Jujutsu 环境里自动改造工作流的场景——默认在纯 Git 仓库中几乎无感;需要显式采纳或强制模式。
安装前请自行查看 GitHub 仓库 源码与 MIT 许可证。插件以当前 DSH 进程权限运行,守卫与工具会直接调用本机的 jj / jj-hunk;对安全与合规敏感的环境,应在信任边界内评估后再启用。
结尾¶
dsh-jujutsu 把 Harness 里的版本控制叙事从「默认 Git」改成「在 Jujutsu 工作区内以 jj 为准」:拦截误导性 Git、给出可执行的 jj 映射、提供 JSON 工具与按需手册,并保留对纯 Git 仓库的显式采纳路径。