dsh-auto-git
为每个新注册的 DSH 工作区自动 git init,让 git 相关插件(如 @linxin666/dsh-client-ui-git-graph 的分支胶囊 / Git 图谱)在每个工作区都能出现。
为什么需要它
git-graph 插件的 host 侧 /git/* 路由有两道门(见其 src/index.ts 的 createWorkspaceGate 与 src/host/git-service.ts):
- 请求路径的 realpath 必须恰好等于某个已注册工作区路径(
workspace.path === canonical,不接受子目录、不接受任意目录); - 该路径必须是 git 仓库(
git rev-parse --show-toplevel成功),否则status返回null。
前端 BranchChip 在 repo === null 时直接 return null —— 于是"非 git 工作区"里这个插件完全没有 UI。所以想让 git 功能"每个工作区都有",唯一办法是让工作区目录本身是仓库。
它做什么
- 注册时:监听
domain/changed(domain === 'workspace' && table === 'workspaces' && operation === 'put'),对新工作区根目录执行git init -b main。 - 启动时:对启动前已注册的工作区做一次同样的扫描(可用
sweepExisting: false关掉)。 - 默认补一个空提交(
git commit --allow-empty):仓库在"未出生 HEAD"状态下git rev-parse --abbrev-ref HEAD会失败,分支胶囊会退化成显示detached;有首个提交才有正常分支名。不会把任何现有文件纳入提交,不会写.gitignore,不碰远程。 - 不会嵌套仓库:先探测
git rev-parse --is-inside-work-tree,已在某个工作树内(父目录已是仓库、或本身就是git worktree检出)就跳过。 - 幂等:同一路径在一个 host 进程内只处理一次;已存在的仓库一律跳过。
配置
安装后由 profile 的 bundle patch(cordis.patch.yml)提供行配置,改完重启 dsh web 生效:
| 字段 | 默认 | 含义 |
|---|---|---|
enabled |
true |
总开关,false 时插件什么都不装 |
branch |
main |
初始分支名(git init -b <branch>,老版本 git 回退到 git symbolic-ref) |
initialCommit |
true |
是否补一个空提交(关闭则新仓库分支名可能显示为 detached) |
sweepExisting |
true |
是否也处理已注册的工作区;false 则只处理以后新注册的 |
timeoutMs |
30000 |
每条 git 命令的超时 |
安装
从 GitHub 安装(推荐):
dsh plugin --profile web add github:zhitiaojun/dsh-auto-git
或在 DSH 插件市场 / 目录站 里搜 dsh-auto-git 点安装。
本仓库的包没有 prepare/构建脚本,github: 安装不需要往 profile 的 pnpm-workspace.yaml 的 allowBuilds 里加任何 key。
本地开发用 link: 指向 checkout:
dsh plugin --profile web add link:D:/Project/1/dsh-auto-git
link: 指向本地目录(用正斜杠),改代码后重启即生效,无需重装。两种方式都必须重启 dsh web 才会装进 host 进程。
验证
不进 DSH 也能验证核心行为:
node D:\Project\1\dsh-auto-git\test\smoke.mjs它会用真实 git 在临时目录里跑:新建仓库、二次调用幂等、跳过已在工作树内的目录、自定义分支名、不建提交的模式、以及
apply()的 boot 扫描 /domain/changed钩子 /enabled:false/sweepExisting:false。安装后:
~/.dsh/profiles/web/.dsh-market/log.ndjson应有该包的install与随后的restart记录。运行时:host 日志里出现
auto-git: initialized: <path>;或选一个新目录加入工作区,随后git -C <新目录> log --oneline # 应看到 chore: initial commit端到端(可选):在空白会话里看分支胶囊是否出现(host 侧 SSE 每 30s 推送一次工作区状态,或切走窗口再切回来触发 focus 刷新)。
卸载
dsh plugin --profile web remove dsh-auto-git
卸载只移除插件,不会回滚已经建好的仓库。
安装前须知
sweepExisting 默认 true:装上并重启后,当前所有还不是仓库的已注册工作区都会被 git init(本机当时为 D:\Project\1、D:\Project、D:\Project\控制、D:\Project\我就要洗衣、D:\Project\race、D:\Project\race\before、D:\Project\race\nerv)。如果只想影响以后新建的工作区,把 cordis.patch.yml 里的 sweepExisting 改成 false。
实现要点
- 纯 host 侧插件,无
dsh.client声明 → 不向浏览器贡献任何代码。 - 零运行时依赖:只用
node:child_process/node:fs/promises。 - 包根声明
dsh.bundle.patch,profile 组合时把auto-git-init这一行插进插件树(与 git-graph 等社区 bundle 同机制)。 - 用
ctx.inject(['workspaceRegistry'], scope => …)拿服务、scope.effect(...)管生命周期、scope.on('domain/changed', ...)挂在工作区表的写入事件上。
No comments yet. Be the first to write one.