前言¶
DSH 自带的「Git / 文件变动」面板按会话工作目录向下扫描来找仓库。实际项目经常是若干个平级仓库:主工作目录下有一个 Git 仓库,旁边还有几个同级仓库。配套的 multi-root-workspace 插件能把它们登记成附加根,Agent 可以读写,但自带面板仍然只显示主仓库的改动,其余仓库的变更在界面上完全看不到。
soulzhou/dsh-multi-root-changes 补的就是这一块:读取附加根的登记信息,对主根和每个附加根各跑一次只读的 git status,在一个页签里分组展示改动与提交历史。下面介绍这个插件。
这是什么¶
一个客户端插件(作者 SoulZhou,版本 0.3.3,MIT 许可),给 DeepSeek Harness 侧栏增加一个「多根改动」页签,覆盖会话主工作目录和所有已登记的附加工作目录的 Git 改动。README 里给出的实测例子:同一会话下三个仓库分别有 4、5、35 个改动文件,面板合计显示 44 个。
它依赖两个宿主侧的东西:
dsh-better-sidebar:页签通过它的ctx.betterSidebar.registerTab注册,落在 DSH 自己的右侧栏里,所以这个依赖实际是必装的。@dsh-electron/dsh-plugin-multi-root-workspace:附加根的来源。没装这个插件时,本插件退化为只显示主目录。
核心功能¶
按根分组。主目录和每个附加目录各一节,显示目录名、分支、ahead/behind、增删行数和文件数。改动路径按 VS Code SCM 的方式折成目录树,单链目录压缩成一行(a/b/c)。重命名按 porcelain v2 的 2 记录处理,显示为 旧 → 新,两侧路径都进 pathspec。冲突(u 记录)单独标红。新文件按「全文新增」渲染;二进制文件显示为「二进制文件 · N KB」。
行级 diff 与左右分栏。点文件读该文件的 unified diff,含 hunk 头和 +/- 行号。打开文件或提交时列表在左、预览在右并排显示,而不是上下堆叠,这样侧栏窄列里文件树仍然可读。
每个目录的提交历史。每节下方可展开该仓库自己的最近 30 条提交,显示短 hash、作者、相对时间和 ref 徽章(如 HEAD -> master),点任意一条看该提交的 patch。三个平级仓库各看各的历史,互不混用。
提交与 AI 生成。每个有改动的目录都带一个提交框:可以手写信息,也可以点 ✦ AI 生成 让模型根据当前改动起草一条提交信息。提交只针对该目录当前列出的文件,用 git add -- <files> + git commit -- <files>,不用 git add -A,不会把他人已暂存的内容一并带走。
跟随会话与省电。主根由宿主按 sessionId 解析,不用客户端传来的 cwd,切换会话或工作区时面板自动跟随。页签不可见时停止轮询(可见时 8 秒一次),因为宿主会保留已访问页签的挂载,不门控就会一直空转。
不误判仓库归属。rev-parse --show-toplevel 与登记路径不一致时,标为「该目录属于另一个仓库」,不会把父仓库的改动算到这个目录头上。
实心底色。面板自己画不透明的 layer-1 底色并建立独立层叠上下文。主题类插件(如 dsh-background-studio 的毛玻璃)会把 --dsw-alias-bg-base 改成 transparent,面板若跟着透明,后面的对话会透出来,全屏时叠成错位。这里专门避免了这种情况。
安装与启用¶
安装命令来自 README,指向本地目录或已有副本:
dsh plugin --profile desktop add /path/to/dsh-multi-root-changes
也可以用 npm 包名或本地目录,在 DSH 的「插件 → 添加插件」里安装。
装完必须完全退出并重新打开 DeepSeek Harness,只刷新页面不够:宿主侧的路由需要重新加载。
然后按顺序装好两个依赖:dsh-better-sidebar 和 @dsh-electron/dsh-plugin-multi-root-workspace(后者决定附加根从哪来)。
用法¶
右侧栏点 +,选「多根改动」,或在页签条里切到它。
- 顶部显示文件总数与刷新按钮。
- 每个目录一节,点标题折叠或展开。
- 点文件在底部打开 diff,点
×关闭,点↻重读。 - 展开某节底部的「提交历史」,查看该仓库自己的最近 30 条提交,点一条看 patch。
- 在提交框里写信息或点「✦ AI 生成」起草,再点「提交」。
访问级别与安全¶
面板大部分时间在做读操作,机制上只有提交是写操作:
- 读操作只有
status/rev-parse/log/show/diff,不改动任何东西。 - 唯一的写操作是提交框的「提交」,对显式列出的文件执行
git add -- <files>+git commit -- <files>,不用git add -A。 - AI 生成只读:起草时只把当前目录的 diff 和文件名喂给模型,由宿主
ctx.llm解析 provider,只取text-delta,模型的思考过程不会混进提交信息。本机没有配置可用模型路由时会明确报出原因,而不是静默失败。 - 提交 hash 在进入命令行前只放行十六进制对象 id,不会被当作 flag 或 rev 表达式。
插件以当前 DSH 进程的权限运行。安装前建议先检查源码和许可证(MIT)。
适用场景与注意¶
适合这样的项目结构:会话主目录是一个 Git 仓库,另外还有若干同级独立仓库已经通过 multi-root-workspace 登记为附加根,想在统一界面里查看和提交它们的改动。
需要知道的边界:
- 没有暂存区操作(stage / unstage / discard),也不切换分支。提交框直接提交它列出的改动文件。
- 没有完整的提交图(泳道连线),只有线性列表和单提交 patch。分支树、合并、变基等操作要用 better-sidebar 自带的 Git 页签。
- 合并提交不显示 patch(git 本身也要
-m才有单一差异),只显示元数据和父提交数。 - 附加根里若登记的是另一个仓库的子目录,会被判为「属于另一个仓库」而不是独立仓库——这是有意设计,避免把父仓库的改动记到子目录上。
- 资源上限:单文件 diff 2 MiB,未跟踪文件预览 1 MiB,单根条目 3000,每根提交 30 条,超出会明确提示截断。
- Windows 下经受限 token 启动的进程可能读不到某些路径,此时该目录显示读取失败原因,不会静默消失。
结尾¶
这个插件的价值是把「多根登记但只能看主仓库改动」的缺口补上:一个只读为主的面板,按根分组展示改动、diff、提交历史和提交操作,不碰暂存区,也不越权到父仓库。目录页在 https://www.skillhub.cn/plugins/SoulZhou/dsh-multi-root-changes,源码在 https://github.com/SoulZhou/dsh-multi-root-changes。