@guowenzhang/dsh-worktree
v2.3.0
Published
Git worktree isolation for DeepSeek Harness: create a worktree, register it as its own workspace, and start the session inside it
Maintainers
Readme
@guowenzhang/dsh-worktree
English | 中文
为什么做这个插件
我们的项目由多个仓库组成,也需要并行开发,因此需要用 Git worktree 创建隔离的工作区,避免不同任务的文件改动互相干扰。
这个插件让 DeepSeek Harness(DSH)在新会话界面勾选 worktree,就能创建独立工作区并在其中启动会话;也支持同时创建子模块和嵌套仓库的工作区。
插件列表的显示名称与介绍支持英文和中文,随 Harness 语言设置显示,英文为默认回退;英文名称为去掉 npm scope 的原包名,中文名称说明用途,安装仍使用不变的真实包名。
截图
选择起始分支,勾选 worktree 即可创建工作区并进入新会话。输入框中尚未发送的文字、引用和附件会一起迁移,不会自动发送;创建或切换失败时保留原草稿。

设置页分成两张卡片:上面「Worktree 设置」配置新会话是否自动开启 worktree、子仓库、扫描层级和存储位置,下面「自动备份」是改动前保护的开关与变更记录页开关。有效修改自动保存并立即生效,无需「保存」或「恢复默认」按钮。

改动前保护
默认已开启。 AI 第一次改动某个已存在的文件之前,这个文件的当前内容会被复制到工作区外面,所以改坏了、或者被删了,都还能捡回来。
设置页下面的「自动备份」卡片里有三行开关可以随时改:会话文件保护(默认开)、拦截删除命令(默认开)和显示变更记录侧边栏(默认开)。改动即时生效,不需要重启。
副本放在 ~/.agents/file-guard/<会话哈希>/,目录结构和原工作区一致,恢复就是把文件复制回去——不需要任何工具或索引。工作区外的文件(其他目录、其他盘)放在 external/ 下并保留自己的路径。字节级复制,与格式无关:.docx、.pptx、.xlsx 和 .txt 一视同仁。
触发方式有两条:
- 自动:仅
write、edit在写入之前复制目标文件,每个文件约 1 毫秒。read、read_image等只读工具不会创建备份。 - 模型申报:AI 在改那些参数里看不出目标的文件时,应先调用
worktree_backup工具申报路径。它没有范围限制,工作区外与其他盘的路径都接受。返回结果里带着副本的绝对路径,恢复不需要再去检索。
删除类命令会被拦下。 bash / pwsh 里看起来要删文件的命令(rm、del、rd、Remove-Item 等)会被拒绝执行一次,并告诉 AI 先调 worktree_backup 申报目标再重试——因为删除一旦执行就无法恢复。命令里的引号内容不算,所以 echo "rm -rf /" 不会误伤。这一项可以在设置里关掉。
几条要知道的规则:
- 每个文件只备份一次。 同一会话里再改它不会覆盖第一份,因为值得留的正是"被改之前"那一版。
- 只备份已存在的文件。 AI 新建的文件没有"改动前"状态。但下个会话里再改它就会备份——那时它已经存在了。
- 每个会话一份,会话归档时整个删除。 触发就是归档那次写入本身——落盘即清理,普通归档与「停止并归档」一样立即。删除失败会记录会话、目录和原因,并在后续归档相关事件中重试;取消中的工具不会重建已归档会话的备份。只处理宿主运行期间发生的归档,不会追溯删除更早的。
- 没有大小上限。 一份完整副本约等于工作区体积;本机实测 243,529 个文件共 12.72 GB。
- 工作区外与其他盘的写入不在自动范围内,要靠 AI 调用
worktree_backup申报。如果 AI 没申报就改了,那个文件不会被备份——这也是为什么删除命令会被拦下来要它先申报。
需要完整的历史、跨机器或跨时间恢复,仍然应该用 Git 提交;这个功能解决的是"AI 刚刚改坏了、我想要回改动前那一版"。
侧边栏里的变更记录
默认开启。 右侧边栏提供一个「变更记录」页——在侧边栏自己的「开始」页里打开它,页内可用侧栏的刷新快捷键重新读取。它把这个会话里被改动或删除的文件平铺成一行一个,不展示目录层次,每行只显示文件路径和一个还原按钮,不显示状态标签;已删除的文件路径加删除线,还原成功后移除删除线。
- 已修改指文件内容与副本不一致;已删除指文件已经不在了。内容仍与副本逐字节一致的文件不会列出——没有可还原的东西。
- 还原把那一份副本写回它对应的文件,文件被删过就连目录一起建回来。副本本身保留,所以同一行在之后又被改动时可以再还原一次。
- 对比:点一行的路径打开左右两栏——左边是本次会话首次改动这个文件之前的副本,右边是当前文件,按行对齐。改动的行着色并左右相对;折叠的横条代表一段没有改动的行。两栏各自横向滚动(两边的行长度可能不同),纵向滚动联动,打开时定位到第一处改动。
- 对比读取的是磁盘上的两份文件,不涉及 Git,所以装没装 Git 都一样能用。左侧是"本次会话第一次改动之前"的状态,因此显示的是那之后的所有变化——共享工作区里别的会话改的也会算进去。
- 二进制文件(
.docx、.xlsx、图片)、任一侧超过 2 MiB、或路径已经不是普通文件时,只显示大小而不做逐行对比;还原仍然可用。很大的文本文件只显示对比的开头并注明已截断。 - 每行各自显示结果:还原中、已还原、或宿主拒绝的原因。已还原的行会在下次读取时消失,因为文件此时与副本一致。
- 列表只包含当前会话的副本:副本随会话存在,会话归档即删除。
- 设置页的显示变更记录侧边栏开关控制这个页面本身:关掉后不再注册——没有标签类型,侧栏的「开始」页里也没有入口——侧栏只留你选过的页面。关开关之前已经打开的标签会显示宿主的"这类内容还没有可用的查看方式",直到它被关闭。
安装
npx @deepseek-ai/dsh plugin --profile web add @guowenzhang/dsh-worktree安装后重启 DSH。宿主需已安装 Git,且能通过 PATH 找到它。
注意事项
升级到 2.x:已移除面向模型的 Worktree 工具,请通过新会话控件创建;归档通知可能清理没有未提交改动的 worktree。调用旧模型工具的集成需要更新。
多仓库支持默认关闭:在设置中打开「创建子仓库」,按目录结构调整扫描层级(默认 1 层)。子模块按父仓库记录的提交检出,处于 detached HEAD;独立嵌套仓库会创建新分支。
未提交改动不会带入新工作区:worktree 从所选分支的提交创建,分支名自动生成。
默认存放在工作区内:路径为
<工作区>/.agents/worktree/<分支>。建议将.agents/worktree/加入 Git 忽略规则,或选择「仓库同级」「用户目录」。新会话可以自动开 worktree:打开「新会话默认开启 worktree」后,仓库里的第一个空白会话会自己建一个 checkout 并搬进去,不再询问。默认关闭。
归档可能清理 worktree:归档写入落盘即触发删除尝试(普通归档与「停止并归档」一样立即);有未提交改动时保留,分支不会删除。关闭宿主不会清理,手动移除工作区记录也不会删除文件。
清理前确认没有其他会话使用该目录:删除 worktree 不检查仍在运行的会话。
更多安装方式、配置与开发说明见 AGENTS.md。
许可
Apache-2.0,另见 NOTICE。
