dsh-multi-root-changes:把多仓库 Git 改动收进一个面板

前言

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(后者决定附加根从哪来)。

用法

右侧栏点 +,选「多根改动」,或在页签条里切到它。

  1. 顶部显示文件总数与刷新按钮。
  2. 每个目录一节,点标题折叠或展开。
  3. 点文件在底部打开 diff,点 × 关闭,点 ↻ 重读。
  4. 展开某节底部的「提交历史」,查看该仓库自己的最近 30 条提交,点一条看 patch。
  5. 在提交框里写信息或点「✦ 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。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜