← 返回列表
未验证
你正要写入的这个工作副本,是不是你以为的那个?
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/18 · 已提供中文文档
Git 工作副本的飞行前检查:你即将写入的检出真的是你以为的那个吗?分支身份、与远端的漂移以及该数值有多陈旧、你下一次提交将携带的身份、已在索引中的工作,以及重复克隆。只读,默认离线。
综合分
26.1
GitHub 分
26.1
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add LeslieWylie/dsh-checkout-guard该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
信任档位:仅索引本站尚未对其实装验证,仅收录元数据
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站尚未做安装检查
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 更新放缓:最近一次提交在 38 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
数据截至 2026/9/26(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools@deepseek-ai/dsh-system-prompt用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-checkout-guard
你正要写入的这个工作副本,是不是你以为的那个?
一个 DSH 插件,在你编辑、提交、推送之前回答这个问题,而不是之后。它读取一个
git checkout,告诉你:它相对远端处在什么位置、这个答案有多陈旧、你下一个提交会
署谁的名、暂存区里已经躺着什么、以及本机是否还有同一个仓库的另一份 clone 已经
跑到了你前面。
只读。不显式要求就不联网。从不占用 index 锁。
为什么
这里每一项检查都对应一次真实发生过的事故,通常发生在同时操作多个仓库的 agent 身上:
| 出了什么事 | 你事后才看到 |
| --- | --- |
| 在落后 8 个提交的 checkout 里改代码 | 你的"修复"把别人的工作退回去了,或者推送被拒 |
| 同一个仓库有两份 clone,你在陈旧的那份里 | 改动凭空消失,forge 上永远看不到 |
| 并发进程把 HEAD 切到了别的分支 | 你的提交落在一个你没听说过的分支上 |
| 你 git add 之前暂存区里已经有东西 | 你的提交打包进了别人的半成品 |
| 仓库没有本地 user.email | 一个工作邮箱被永久钉在公开提交上 |
| detached HEAD | 提交存在过,然后不存在了,全程无提示 |
这些都不会报错。git 完全照你说的做了;是你在误读的状态下说的。这就是本插件覆盖的
全部问题域。
安装
npm install dsh-checkout-guard
然后在 profile 的 cordis.yml 追加:
- id: checkout-guard
name: 'dsh-checkout-guard'
需要 Node 22.19+ 或 24+。运行期唯一依赖是 PATH 上有 git。
工具
checkout_guard —— 单个工作副本,深度检查
{ "path": "/abs/path/to/repo", "expectBranch": "main" }
{
"branch": { "current": "main", "detached": false, "upstream": "origin/main", "linkedWorktree": false },
"sync": { "ahead": 1, "behind": 1, "fetchAgeSeconds": 255600, "fetchedNow": false },
"remote": { "normalized": "github.com/acme/widget", "host": "github.com", "publicForge": true },
"identity":{ "email": "you@example.com", "source": "global", "repositoryOverride": false },
"workingTree": { "staged": [], "unstaged": ["package.json"], "untracked": [], "clean": false },
"duplicateCheckouts": [ { "path": "/elsewhere/widget", "branch": "main", "ahead": 3, "aheadOfThisOne": true } ],
"blockers": [ "diverged from origin/main by 1 commit(s) (and 1 ahead) ...",
"another checkout of the same remote is ahead of this one: /elsewhere/widget ..." ],
"warnings": [ "remote refs were last updated 71h ago ..." ],
"verdict": "blocked",
"safeToWrite": false
}
调用方只需要看 safeToWrite 一个字段。blockers 是继续下去会丢失或错置工作的
状态;warnings 是值得知道、但不必然是错的情况。
| 参数 | 作用 |
| --- | --- |
| path(必填) | 工作副本的绝对路径,或它内部任意子目录 |
| fetch | 先联系远端,让 ahead/behind 是当下的。唯一联网的选项,默认 false |
| expectBranch | 你认为自己在哪个分支。不符即 blocker |
| expectIdentity | 你期望的提交署名邮箱。不符即 blocker |
| remote | 对比哪个远端(默认 origin) |
| staleAfterHours | 远端 ref 多久算陈旧(默认 24) |
| findDuplicates / duplicateRoots / maxDepth / maxRepos | 控制重复 clone 的搜索范围 |
expectBranch 和 expectIdentity 是把"报告"变成"断言"的开关。不传,插件只描述;
传了,插件会拒绝。
checkout_guard_scan —— 某个根目录下的所有工作副本
{ "roots": ["/abs/path/to/projects"], "maxDepth": 3 }
每个 checkout 返回一行——分支、upstream、ahead/behind、未提交数量、上次 fetch
距今多久——外加:
- needsAttention:落后、分叉、detached、或没有 upstream 的那些
- duplicateRemotes:按远端分组的路径,一眼看出同一个仓库有几份 clone
先跑这个找出值得细看的 checkout,再把路径逐个交给 checkout_guard。
刻意不做的事
- 不告诉你远端是否已归档。 那需要调 forge 的 API,本插件不发带认证的 HTTP
请求。remote.normalized 会给你 host/owner/repo,你可以自己去查。
- 不修任何东西。 不 pull、不 rebase、不 stash、不 checkout。"落后"和"分叉"
的正确恢复方式不一样,在两者之间做选择不该由一个 guard 替你决定。
- 不评判你的身份。 它只报告署名来自哪份配置,并且仅在涉及公开 forge 且仓库
没有本地覆盖时才警告。你传 expectIdentity,它就严格按你给的值比对——它从不
猜测你的邮箱"应该"是什么。
安全性质
- 不对任何仓库写入。 唯一可能修改东西的命令是 git fetch --dry-run,仅在
fetch: true 时执行,且只动 FETCH_HEAD。
- 每次调用都带 GIT_OPTIONAL_LOCKS=0。 普通的 git status 会刷新并重写
index,从而占用 .git/index.lock。一个立足于"此刻可能有另一个 agent 在这个
checkout 里"的 guard,绝不能反过来卡住那个 agent。
- GIT_TERMINAL_PROMPT=0、空 GIT_ASKPASS。 对私有远端 fetch 会快速失败,
而不是停在一个没人看得见的凭据提示上。
- URL 归一化时先剥掉内嵌凭据,凭据不可能进入结果对象或日志。
- 路径白名单。 两侧都做 realpath,所以放在允许目录里的软链接无法读到外面。
配置
- id: checkout-guard
name: 'dsh-checkout-guard'
config:
roots:
- /Users/you/projects
roots 限定插件能看的一切范围。不设时默认为你的 home 目录。
开发
npm install
npm test # 在临时目录里对真实 git 仓库跑的单元测试
npm run test:boot # 把插件装载进真实 cordis Context
没有构建步骤。 src/index.js 逐字节就是发布出去的入口。编译到 lib/ 再把
产物提交上去的插件,得永远维持两者同步,而所有 import src/ 的测试都会通过——
与此同时,安装者真正运行的那份产物是过期的。去掉构建,就去掉了这整类问题。
单元测试创建真实仓库——真实远端、真实推送、真实分叉——而不是给 git 打桩。手写的
测试替身会按作者的预期作答,而作者对仓库状态的预期,恰恰就是被测对象本身。
tests/boot.test.mjs 在裸 clone 下打印 SKIP 并退出 0,不挡贡献者;在 CI 设置的
DSH_BOOT_STRICT=1 下退出 1。一个被跳过却报告为绿的集成测试,比没有测试更糟。
English · MIT