dsh-ui-web/packages/dsh-git-graph

34Star2Fork0Issue0Watching

为 DSH Web 对话框提供 git 分支选择器和 Git 提交图谱面板,host 进程真实执行 git switch/create。

语言
TypeScript
License
Apache-2.0
分支
main
dsh-plugindsh-plugin-marketdsh-plugins

安装

$ dsh plugin --profile web add github:CAPTAIN1275/dsh-ui-web/packages/dsh-git-graph

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

一句话定位

为 DSH Web 在输入框上方加一个 git 分支选择器和 Git 提交图谱面板,git 操作在 host 进程的真实工作树上执行,UI 跑在浏览器里。

核心能力

  • 在对话输入框上方挂一个分支胶囊,显示当前分支名(含未提交改动数)
  • 弹出可搜索的本地分支列表,一键切换到任意本地分支
  • 创建并立即切换到新分支(基于当前 HEAD)
  • 打开 Git 图谱面板,按拓扑顺序查看跨分支/标签/远程的提交历史,支持分页加载
  • 通过 SSE 实时接收工作区分支状态变更,外部 git 操作后自动刷新
  • 切换守卫:拒绝未解决冲突、进行中的 git 操作、目标分支已被其他 worktree 检出等情况

技术实现

  • 语言: TypeScript + React (TSX)
  • 关键依赖: @deepseek-ai/dsh-host-webserver、@deepseek-ai/dsh-subprocess、@deepseek-ai/dsh-workspace、@deepseek-ai/dsh-client-ui-slots、@deepseek-ai/dsh-client-ui-primitives、@deepseek-ai/cordis
  • 架构模式: cordis 双面插件,host half(git 服务 + /git/* HTTP 路由 + SSE 推送)+ browser half(React 组件 + 路由客户端);通过 cordis.patch.yml 作为 profile bundle 激活,浏览器侧声明注入 @deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-conversation
  • 入口文件: src/index.ts(host 主入口)、src/client/index.ts(browser 主入口)、src/invariant.ts(不变式导出)

适用场景

在 DSH Web 中需要频繁切分支做对比实验、想随手查看当前仓库的提交图谱、又不想离开 IDE 去敲命令行的人。例如在 feature/x 分支调试时,想切到 main 看看某个改动是否存在,但又懒得开终端;同时希望通过图形化的提交图谱回顾近期合并历史。

前置依赖与兼容性

依赖最低版本说明
DSH (peerDependencies)^0.1.0-rc.6需要 host-webserver、subprocess、workspace、client-ui-conversation 等官方 SDK
Node^22.19.0 或 >=24.0.0由 package.json engines 声明
工作区必须是已注册的 DSH workspacehost 路由以 realpath 比对 workspaceRegistry 作为安全边界
系统 git二进制可用通过 ctx.subprocess 调用 git 命令,依赖机器 PATH 中有 git

安装方式

dsh plugin --profile web add github:CAPTAIN1275/dsh-ui-web/packages/dsh-git-graph

配置项

本插件无需额外配置。host 路由硬编码仅接受注册工作区路径,git 操作目录来自当前会话 cwd;分支胶囊只在 git 仓库内自动出现。

常见问题

Q: 切换分支会不会影响其他会话?

A: 会。切换作用于工作区根目录的磁盘工作树(git switch --no-guess <branch>),同一工作区所有会话都看到新分支;插件不会给已有会话单独换工作目录。

Q: 切换时弹出"unresolved conflicts"之类的错误怎么办?

A: 这是 host 的守卫在工作。打开终端在仓库根目录跑 git status 处理冲突、rebase/cherry-pick,或切到别的干净分支即可;插件检测到工作区存在未解决冲突或进行中操作时会拒绝切换。

Q: 切换按钮点了没反应?

A: 常见原因:目标分支不存在(已被删除)、重名分支恰好拼错、目标分支被其他 worktree 检出。胶囊会显示对应的中英错误文案,可以先在终端 git branch -a 确认分支名。

Q: 工作区不是 git 仓库时会怎样?

A: 分支胶囊直接隐藏,不渲染占位控件;插件不会误报"非仓库"错误;切换到 git 目录后下次刷新即出现。

Q: Git 图谱面板能查看多远的历史?

A: 默认一次拉取最近 200 条提交(/git/graph 接口 limit),底部出现"加载更多"时分页再加 100 条;超出返回 hasMore=true。面板仅展示当前仓库能看到的 refs(本地分支 + 标签 + 远程),不修改历史。

Q: 卸载会影响已有的 git 状态吗?

A: 不会。插件只是 UI + 路由层,git 操作直接走 git 二进制;卸载只是去掉分支胶囊和图谱面板,工作树原样保留。

上手难度

入门 — 安装一行命令,无需配置;切换和创建分支遵循 git 原生语义,工作区已是 git 仓库即可看见分支胶囊。

已知问题与限制

  • 分支胶囊只在工作区是 git 仓库时出现;非仓库目录打开 DSH Web 不会有胶囊
  • 浏览器端通过 host 的 /git/* 路由访问 git,路径必须命中已注册工作区(realpath 校验),任意目录无法直接执行 git
  • 切换是工作区级的,没有"为单个会话单独换分支"的能力;既有会话不会换 cwd
  • Git 图谱面板的提交信息以最近一次拉取为准;外部对仓库的改动通过 SSE 每 2 秒轮询一次反映(见 src/host/routes.ts:34)
  • 请求体大小上限 1 MiB(src/host/routes.ts:38-39),超大请求会被直接销毁而不解析