DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

mays-hi /

mays-hi/dsh-git-idea

Verified

A git panel inside the DSH session: repository chip, branch tree, commit graph, working tree and commit detail, Settings page, and 8 git model tools.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@4af1f4f7

dsh-git-idea

在 DSH 会话里看 Git:输入框左侧一个仓库 chip,点开是浮层面板 —— 分支树、提交历史与提交图、变更与暂存、提交详情、文件差异,外加一个设置页。

不向 DSH 注册任何模型工具(模型要跑 git 本来就有 bash,见不注册工具)。 面板属于会话,不属于窗口:同一页面里的每个会话各看各的工作区。

A git panel for DeepSeek Harness — a repository chip in the composer and a floating panel with the branch tree, commit graph, working tree, commit detail and file diff. Registers no model tools.

仓库:https://github.com/mays-hi/dsh-git-idea


安装

要求 DSH 0.1.5-rc.1 及兼容版本(peer:@deepseek-ai/cordis ^4.0.2)。

dsh plugin --profile web add dsh-git-idea                    # npm
dsh plugin --profile web add github:mays-hi/dsh-git-idea      # GitHub
dsh plugin --profile web add /path/to/dsh-git-idea            # 本地

装完重启 dsh web。报 ERR_PNPM_ADDING_TO_ROOT 就在包名前加 -w。

已经跑着旧版动态插件(<DSH_HOME>/dsh-git-idea 那个桥)就先停掉 —— 两个都装着就是两份 chip、两个面板抢同一个 slot。


用法

chip(输入框左侧)

操作 结果
看 当前分支 + 未提交文件数(工作区干净 / 3 个改动)
悬停 分支切换卡片,点一下切过去(可在设置里关)
点击 开 / 收面板

面板

变更 3 │ 历史    ⟳ ⇣ ↓ ↑    feature-risk ↑2 ↓1    树 扁平
─────────────┬──────────────────────┬──────────────────────
分支树        │ 变更树 / 提交列表      │ 差异 / 提交详情 /
HEAD 本地 远程 │                      │ 提交信息与提交按钮
区域 内容
顶栏 变更(带数量)/ 历史 页签;⟳ 重读、⇣ fetch、↓ pull、↑ push(带领先/落后角标);中间是当前分支,点开切换器;右端「树 / 扁平」切换变更页视图
左栏 分支树:HEAD / 本地 / 远程,带搜索、收藏、排序;行尾 › 是该分支的动作(检出、从此分支新建分支、合并到当前分支、删除)
中栏 变更 页是工作区,历史 页是提交列表 + 提交图
右栏 差异 patch / 提交详情 / 提交信息与提交按钮

历史页:分支树、提交列表、提交详情

历史 页:左边分支树(HEAD / 本地 / 远程),中间提交列表与提交图,右边是选中提交的详情、改动文件与提交信息。

变更页:勾选文件、写提交信息、暂存或提交

变更 页:没跟踪的文件也在树里(红色 ?);右边写提交信息,下面是「全部暂存并提交(N 项)」和「全部暂存」,右上角切「树 / 扁平」。

面板的边角可拖动,尺寸记得住。

手势(与 IDEA 的树一致)

行 单击 双击 / 点三角
目录行(分支树、变更树、提交文件树) 只选中 展开 / 折叠
未跟踪目录(git 折叠成一行的那种) 只选中,不发读取 读取并展开
分支行 只选中 把历史切到该分支
分组标题(HEAD / 本地 / 远程) 只选中 展开 / 折叠
文件行 打开差异 —
分组标题最左的复选框 整组进 / 出索引 —

常见动作

想做什么 怎么做
提交 变更 页勾选 → 右栏写提交信息 → 「全部暂存并提交(N 项)」或「全部暂存」
只提交一部分 只勾那几个文件;再点一次勾选框 = 取消暂存
看某个文件的改动 在变更树或提交详情里点该文件,patch 占满正文,左上角箭头返回
切分支 点顶栏分支名(或悬停 chip)→ 选分支 → 检出
新建分支 切换器底部「新建分支」,可从某个提交或分支起
合并 / 拣选 / 还原 分支行 › → 合并到当前分支;提交详情右上角图标 → 拣选 / 还原
打标签 提交详情 → 标签图标 → 填名字
拉取 / 推送 顶栏 ⇣ ↓ ↑;没有上游时右栏给出「设置上游并推送」
冲突 顶栏横幅「正在合并:N 个文件冲突」+ 继续 / 跳过 / 中止;解决并暂存后点继续
搜索历史 默认字面匹配,.* 切正则,Cc 区分大小写;分支: 作者: 时间 路径 各是一个筛选
更早的提交 列表底部「加载更多」,一次 200 条

提交被 git 拒了

git commit 要署名,而名字和邮箱写在 git 自己的配置里,不在仓库里。这台机器没配过时,提交会被 git 拒绝。

两条路,都留着:设置页 dsh-git-idea配置 → 提交身份 里填一次(面板并不总是开着),或者在终端里跑

git config --global user.name "你的名字"
git config --global user.email "你的邮箱"

(不加 --global 只对当前仓库生效。)面板不会替你署名 —— 署谁的名字只有你知道 —— 但它会在提交区先说这件事,被拒之后把上面那两条原样写出来,连 git 自己最后一行一起。写完之后不用重启,下一次读取(30 秒的时钟,或任意一次暂存 / 提交)就不再提醒。

同一类失败不只出现在「提交」上:拣选、还原、合并的继续、pull 都要造提交对象,它们走同一个判据(git var GIT_AUTHOR_IDENT,也就是 git commit 自己拼身份时走的那条路,任何语言下都是同一个退出码);而 git add、git branch -d、中止这些在没有身份的机器上照跑,面板不会把它们说成身份问题。

看哪个仓库

只看会话工作区那一个目录,且 <dir>/.git 必须存在 —— 不向上找父目录,也不往里看子目录。 引导页可以改成别的目录:「打开这个目录」进那个路径;那里还不是仓库时旁边有「在此初始化仓库」(git init,默认分支见设置)。

读不动时

每一种理由说自己的话,能做的事不同:

情况 chip 面板
路径还没定 还没确定看哪个目录 —— 点击填写 「无法确定要查看的仓库路径」+ 路径框
路径不存在 目录不存在:… —— 点击修改路径 「目录不存在」+ 路径框
路径是个文件 这不是一个目录:… —— 点击修改路径 「这不是一个目录」+ 路径框
目录在,不是仓库 … 这个目录不是 Git 仓库 —— 点击查看 「这个目录不是 Git 仓库」+「打开这个目录」/「在此初始化仓库」
git 在,读不动它 … 读取失败 —— 点击查看原因 「git 命令执行失败」+ git 的原话
机器上没有 git …:这台机器上找不到 git —— 点击查看 同一页改说这件事,路径框和初始化按钮都收起(都不是出路),装好 git 再点「打开这个目录」

「不是 Git 仓库」那一页故意没有路径框:路径不是问题,没什么可填的。

不是一个 Git 仓库时的说明页


设置

Settings → dsh-git-idea配置。

插件级(写 $DSH_HOME/dsh-git-idea.json,默认 ~/.dsh/dsh-git-idea.json,换浏览器一致)。这份文件在工作区之外,所以它和这个插件改的其它东西走同一条路:能不能写由这个会话的沙箱策略决定,写不进去时页面上会明说(而不是安静地什么也没发生):

项 默认 说明
初始化仓库的默认分支 main 引导页「在此初始化仓库」执行 git init -b <值>;留空用 git 自己的默认值
cherry-pick 时记录来源(-x) 关 提交时是否带 -x
git 位置 空(用 PATH 上的 git) 面板每一条命令都以这一个词开头;装在不在这条 PATH 上的地方(Homebrew 前缀、IDE 自带的 git、nix profile)时写绝对路径。旁边实时显示它解析到哪、什么版本、能不能跑
fetch 时删掉远端已删的远程分支(--prune) 开 关掉就是 git fetch --all
pull 用 rebase(--rebase) 关 关掉就是 git pull(merge)
推送没有上游的分支时自动设上游(push -u) 关 关掉时推送失败后面板问一句「推送并设为上游」

这三条网络项是面板给 git 的实参,不是 git 设置的副本:没勾的就是 git 原本的行为,push.default、pull.rebase 照旧生效。设置页底部还照着实参写一遍会执行成什么(git fetch --all --prune · git pull · …)。

git 自己的配置(不在上面那个 json 里):设置页的「提交身份」直接读写 user.name / user.email,也就是终端里的 git、IDEA、钩子看到的同一份。它先显示此刻生效的那一份和它的来源(.git/config 还是 ~/.gitconfig),然后让你选写进哪里 —— 这台机器的所有仓库(--global)或只这一个仓库(--local)。空着的框一个字节都不写:git config user.name '' 正是「empty ident name」那个错误的来路。

浏览器级(只写当前浏览器 localStorage):

项 默认 说明
后台监测仓库变化并自动刷新 开 关掉后下面的节奏选项一并失效
面板打开时每 N 秒检查 3(1–120)
面板关着时每 N 秒检查 5(2–600) 只发一次廉价签名(读者那台机器 0.12s),所以问得比过去勤 —— 15 秒的话,终端里提交完要过十几秒 chip 才改口
面板关着时也监测 开 让 chip 的分支名和改动数保持实时
悬停弹出分支切换卡片 开
面板尺寸 跟随输入框宽度 / 74vh 可恢复默认
变更页视图 树 或平铺列表
切换器记忆 — 可清除最近使用与收藏

一次「仓库动过了」之后,插件要花多久才排空

这条 RPC 通道一次只跑一个处理函数(实测:一次 8 秒的读在飞的时候,连不 spawn 的 git/flush、git/config 都要等 8 秒才回)。所以一次全树 git status 不只是慢,它把 整块 UI 按在那里 —— 读者那台机器上(Windows 挂载的工作区、5093 个文件、全树 status 8.1s 冷 / -uno 也要 5.3s)量到过:

场景 改之前 改之后
终端里提交一次(引用变了),面板开着 16 条请求,队列 21.3s 排空,其中 13s 是两次全树读 队列 0.4s:面板问屏上那 7 条路径(0.2s),chip 问身份(0.4s)+ 同样那几条路径(Host 那边是同一个问题,只起一个进程)
同样一次,面板关着 4 条请求,排空 11.1s(chip 一次全树读 10.6s) 队列 0.5s:chip 只问身份 + 上次那些脏路径
这个仓库这个浏览器第一次看 11s+ 一样要一次全树读(没量过就没有数字),但那一次之后走上面两条

屏幕上的样子是「面板反应过来了,chip 还没」—— 面板那条 0.2s 的路径读排在 chip 那条 8–10s 的全树读后面。现在:

  • 「工作区有几个改动」全局只有一份读数(面板量的、chip 量的都写在同一处), chip 上那个数字就是面板「变更」页签上那个数字,两块屏幕不可能各说各话;

  • 一次 bump 之后只问屏上那些路径,整棵树不在那条路上。这里还有个量出来的坑: git 把没跟踪的目录折叠成一条,而那条本身就是自己的子树 —— 再顺手带上「它所在的 目录」就等于把旁边整棵大树扫一遍。读者那个仓库上:

    问哪些路径 耗时
    7 条(快照里那些路径本身,含 3 条折叠目录) 280ms
    12 条(每条再带上它所在的目录) 6138ms ← holox-modules 一条吃掉了全部
    9 条(折叠目录不带所在目录) 295ms

    所以折叠目录那条只问它自己;文件的所在目录留着(「旁边新出现的文件」还靠它看见)。 另外量到一次路径读本身超过 1.5s 时,这个仓库整个收窄成只问那几条路径本身;

  • 整棵树有自己的时钟,间隔按上一次实测的代价来定:max(30 秒, 8 × 上次耗时), 上限 5 分钟。快盘上照旧 30 秒一次;读者那台机器上一次 8 秒,于是 64 秒一次 —— 不再每 30 秒把整条通道冻 8 秒。⟳ 按钮永远立刻整棵树重读一次;

  • 还没核对出来的时候 chip 说的是「正在核对改动…」,不谎称「工作区干净」。

代价说清楚:「本来干净、刚刚被改」的那个文件(以及干净目录里新出现的文件)任何 路径读都看不见,只有整棵树读能看见 —— 它由上面那个时钟兜着,所以最坏情况下要等一个 间隔(快盘 30 秒,慢盘 64 秒)才出现在「变更」页里。⟳ 是立刻拿到它的办法。


不注册工具

插件给 DSH 的只有 UI 和它自己的 RPC 通道:27 条 host.call('git/…')(面板、chip、设置页走的就是它们)。模型要跑 git 本来就有 bash,所以不注册工具。

撤掉那 8 个工具(git、git_status、git_log、git_diff、git_commit、git_branch、git_stash、git_sync)时量到的:

量到的 数
8 个工具的 schema 7210 字节/每次请求(约 1800 token,与这一轮是否碰 git 无关)
只为它们存在的 Host 代码 约 908 / 2577 行(35%):40-tools 533 行、20-safety 中 160 行、30-render 中 215 行
客户端调用工具的次数 0 —— 面板只走 host.call('git/…'),撤工具对 UI 零影响

代价:git_diff 原先把差异渲染成 GUI 里的原生 diff 卡,现在记录里只有文本。


开发

源码按功能拆片段,构建就是按顺序拼接,没有转译、打包或压缩。改代码改 src/。

node build-package.mjs          # 正式包:lib/index.js + client/client.js
node build.mjs                  # 动态桥:host.js + client.js
node test/run-all.mjs           # 全部断言(829 条)
node build.mjs --check && node build-package.mjs --check   # 产物是否最新
node test/bench.mjs             # 基准:200 条提交的历史列表
node test/bench-branch.mjs      # 基准:300 个分支的切换器

test/run-all.mjs 跑断言前先检查三样东西是否落后于源码:动态桥产物、正式包产物、每个套件文件。

验证快照:829 条断言全绿,以及性能对照

开发时的验证记录:test/run-all.mjs 829 条断言、0 失败,以及「一次仓库动过之后要排空多久」的对照。

package.json          npm / DSH manifest(dsh.bundle patch + dsh.client web)
cordis.patch.yml      bundle 层插入的插件行
lib/index.js          构建产物:Host 半侧(ESM,插件对象 + 同源 RPC 路由)
client/client.js      构建产物:Client 半侧(__ModuleLoader__ bundle)
src/host/*.js         Host 源码片段(12 个)
src/client/*.js       Client 源码片段(23 个)
src/pkg/*.js          正式包的 prelude / postlude
build-package.mjs     正式包构建
build.mjs             动态桥构建
host.js client.js     构建产物:动态桥读取的两个半侧(旧运行方式,保留)
docs/                 README 的图
test/                 断言套件与性能基准

Host 与 Client 的片段各自共享一个作用域:一个片段可以用它上面片段定义的东西,反之不行。


许可

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 4af1f4f751ac

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout