统一管理提交推送与拉取请求,自动同步不留脏树
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/stansz/dsh-git.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 18 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 19 处,展示前 18 条)
- 读取本地文件lib/actions.mjs:128
if (!existsSync(dir)) { - 读取本地文件lib/actions.mjs:172
entries = readdirSync(current.dir, { withFileTypes: true }); - 发起网络请求lib/actions.mjs:591
const fetched = await git.fetch(repoDir, remote, { timeoutMs: Math.max(config.timeoutMs, 30000), signal }); - 发起网络请求lib/actions.mjs:975
const fetched = await git.fetch(repoDir, 'origin', { timeoutMs: Math.max(config.timeoutMs, 30000), signal }); - 读取本地文件lib/actions.mjs:1591
if (!existsSync(parent)) { - 读取本地文件lib/actions.mjs:1595
if (existsSync(target)) { - 读取本地文件lib/actions.mjs:1636
if (!existsSync(parent)) { - 读取本地文件lib/actions.mjs:1640
if (existsSync(target) && await git.isRepo(target)) { - 写入本地文件lib/turn-commit.mjs:112
mkdirSync(dir, { recursive: true, mode: 0o700 }); - 写入本地文件lib/turn-commit.mjs:114
appendFileSync(file, new Date().toISOString() + ' ' + line + '\n', { encoding: 'utf8', mode: 0o600 }); - 读取本地文件lib/turn-commit.mjs:120
if (statSync(file).size > BOUNDARY_LOG_CAP_BYTES) { - 读取本地文件lib/turn-commit.mjs:121
const kept = readFileSync(file, 'utf8').split('\n').filter((entry) => entry !== '').slice(-BOUNDARY_LOG_KEEP_LINES); - 写入本地文件lib/turn-commit.mjs:122
writeFileSync(file, [...kept, - 读取本地文件lib/turn-commit.mjs:240
if (existsSync(repoRoot)) found.set(repoRoot, true); - 读取本地文件lib/turn-commit.mjs:640
for (const name of readdirSync(join(base, 'touched'))) { - 读取本地文件lib/turn-commit.mjs:643
const text = readFileSync(join(base, 'touched', name), 'utf8'); - 读取本地文件lib/turn-commit.mjs:664
for (const name of readdirSync(join(base, 'sessions'))) { - 执行外部命令固定命令lib/github.mjs:351
execFile(
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
为 DSH 提供统一的 git 和 GitHub 操作入口:状态、按任务隔离的 worktree、提交、推送、同步、拉取请求,并强制拦截 bash 里的裸 git 命令,避免留下脏工作区和未推送的提交。
README
由 DeepSeek 最新模型翻译生成dsh-git
让 DSH 用统一的方式操作 git 和 GitHub,并配上自动化,让「没有留下未提交的东西」成为事实,而不是靠模型自己记住。
这是 DeepSeek Harness 的第三方套件。MIT 协议——见 LICENSE。不是 DeepSeek 官方包。
在配置档目录里运行——这是安装目标,不是全局前缀
pnpm add github:stansz/dsh-git
每项设置都有可用的默认值,所以不做任何配置就能挂载并发挥作用。值得改的两项在修改设置里。
为什么会有这个包
直接用 bash 跑裸 git 太不一致:会话结束时工作没提交、没推送,也没人报告。这个套件贡献了四样东西,后两样才是解决问题的关键:
| 贡献 | 是什么 |
| ctx.tools.register() | git 工具:clone、init、fetch、branch、checkout、stash、status、start、commit、push、sync、pr、merge、finish、prune |
| ctx.commands.register() | /git,把同样的状态打印给人看 |
| ctx.on('tools/pre-execute') | 一道守卫,把 bash 里裸的写操作 git 重定向到能干净处理的工具,并拒绝那些会丢弃工作的命令 |
展开完整文档(README 剩余 1 节)
dsh-git
让 DSH 用统一的方式操作 git 和 GitHub,并配上自动化,让「没有留下未提交的东西」成为事实,而不是靠模型自己记住。
这是 DeepSeek Harness 的第三方套件。MIT 协议——见 LICENSE。不是 DeepSeek 官方包。
在配置档目录里运行——这是安装目标,不是全局前缀
pnpm add github:stansz/dsh-git
每项设置都有可用的默认值,所以不做任何配置就能挂载并发挥作用。值得改的两项在修改设置里。
为什么会有这个包
直接用 bash 跑裸 git 太不一致:会话结束时工作没提交、没推送,也没人报告。这个套件贡献了四样东西,后两样才是解决问题的关键:
| 贡献 | 是什么 |
| ctx.tools.register() | git 工具:clone、init、fetch、branch、checkout、stash、status、start、commit、push、sync、pr、merge、finish、prune |
| ctx.commands.register() | /git,把同样的状态打印给人看 |
| ctx.on('tools/pre-execute') | 一道守卫,把 bash 里裸的写操作 git 重定向到能干净处理的工具,并拒绝那些会丢弃工作的命令 |
| ctx.on('agent/turn-stopping')、ctx.on('session/event')、ctx.on('tools/pre-execute') | 自动同步:在回合边界,或者回合的编辑停下几秒后仍没等到边界时,提交被改动的仓库,并推送可以安全推送的内容 |
git 工具
一个工具,十五个动作。模型能看到每个动作的完整描述;这里只是它们的轮廓。
- clone —— 从 URL 克隆仓库。path 是落地位置,branch 在克隆时检出分支。返回克隆后的状态。
- init —— 创建新的空仓库。path 是落地位置,branch 命名初始分支。
- fetch —— 从远端拉取,不合并。remote 默认是 origin。
- branch —— 列出、创建或删除分支。带上 name 和 delete: true 就删除一个(传 apply: true 才真正删除)。
- checkout —— 切换到分支。create: true 在分支不存在时创建它。有未提交的工作时拒绝切走。
- stash —— 暂存进行中的工作。pop: true 恢复它,list: true 显示栈。
- status —— 某个仓库的状态,或者某目录下每个仓库的状态:分支、领先/落后、改动的路径、工作树、任何打开的拉取请求。只读。
- start —— 为这个任务创建工作树(分支 <prefix><slug>,从 origin/ 切出)并返回它的路径;复用这个会话已经拥有的那个。
- commit —— 暂存指定的路径并提交;不带路径就暂存全部。push: true 在同一次调用里推送。
- push —— 推送当前分支。受保护的分支会被拒绝,除非 allowProtected 为 true。
- sync — 拉取 origin,然后只做快进:当分支落后于基线、且自己没有提交时,把分支快进到基线;否则快进基线分支本身。绝不 merge,也绝不 rebase。
- pr — 开一个 pull request;如果这个分支已经有开着的,就返回那一个。绝不重复开第二个。
- merge — 按编号 merge 一个 pull request,或者 merge 当前分支上开着的那个,然后删掉它来自的分支,并让本会话为它准备的 worktree 退役。
- finish — 一个工作单元的收尾动作:提交所有脏改动、push、开或复用 pull request,然后汇报。cleanup: true 会在之后删掉 worktree,且只在分支已推到远端、worktree 里没有未提交内容时才删。
- prune — 先 dry-run,再清掉这个工具留下的东西。apply: true 执行删除;还带着工作的分支只汇报,绝不删除。
/git 会把同样的状态打印给人看。
文档
本文件是总览。细节就在旁边:
| 文件 | 里面写了什么 |
| docs/turn-sync.md | 自动的那一半:提交和 push 了什么、什么时候拒绝、怎么盯着它 |
| docs/guard.md | bash 里哪些裸 git 会被拒绝或追问,以及为什么没有钩子 |
| docs/worktrees.md | 任务生命周期、归属与路径标识,以及唯一会删东西的那个动作 |
| docs/install.md | 全新机器,以及 link: 安装与 GitHub 安装的区别 |
| docs/testing.md | 测试:关键的那三个是什么,以及旧测试套件为什么没了 |
配置
有一个开关值得了解。其余都是插件内部用的,很少需要动。
| 字段 | 默认值 | 含义 |
| worktrees | false | worktree 模式的开关。 true 会拒绝落在受保护分支上的编辑,并指向 action: "start",于是工作进入任务分支上的 worktree。false 是普通模式——随便在哪编辑,不需要 worktree。它同时设置 autoWorktree 和 protectedBranches;旁边写了具名键则以具名键为准 |
| worktreeRoot | (推导得出) | 每个任务的 worktree 放在哪:不设置时是 <session workspace>/.worktrees。设成绝对路径就放到别处 |
| stateRoot | ~/.dsh/state | 记录会话归属和 push 退避的地方 |
| branchPrefix | dsh/ | 任务分支命名空间;自动 push 能推的就是这些分支 |
| baseBranch | (空) | 空值会先解析 origin/HEAD,再解析 main |
| protectedBranches | [] | 插件自己的分支名列表,与检出的分支字面匹配。绝不自动 push,autoWorktree 也会拒绝落在这些分支上的编辑。显式写 [] 会让 push 到 main 无需 allowProtected 就能通过。worktrees: true 会把它设为 [main, master] |
| autoWorktree | off | off 从不拒绝编辑。protected 拒绝落在受保护分支上的编辑。always 拒绝落在 worktree 之外的编辑。worktrees: true 会设为 protected |
| guardMode | redirect | off \| warn \| redirect |
| guardAsk | ask | 守卫无法归类的命令怎么处理:ask \| deny \| allow |
| guardTools | [bash, pwsh] | 守卫检查哪些工具 |
| turnCommit | true | 每轮提交改动 |
| turnCommitMessage | (empty) | 留空会生成 dsh: turn <N> — <paths>,没有轮次编号时生成 dsh: <paths>。{turn} 和 {paths} 会被替换 |
| turnPush | true | 分支安全时每轮推送 |
| turnSyncScope | session | session 只提交本会话改过的仓库;workspace 还会扫描任何有未提交改动的仓库 |
| turnCommitMaxFiles | 200 | 改动路径超过这个数量就跳过 |
| turnSyncTimeoutMs | 20000 | 一次轮次结束同步的时间预算 |
| githubHost | github.com | GitHub Enterprise 用这个设置 |
| prDraft | false | 默认以草稿形式打开 pull request |
| timeoutMs | 30000 | 每条 git 命令的时限 |
plainMode 是旧开关,等价于 worktrees: false 加上 turnCommit: false 和 turnPush: false。除非你也想关掉自动同步,否则优先用 worktrees。
修改设置
在配置档的补丁层 ~/.dsh/profiles/<name>/cordis.patch.yml 里覆盖这个 bundle 的行:
- id: dsh-git
name: 'dsh-git'
config:
worktrees: true
只有你写出的字段会生效,其他字段都保留默认值。行 id 是 dsh-git。重启 Harness 才会加载——插件的行配置在插件挂载时读取。
还有一个 Configure 页面(Plugins → dsh-git → Configure),只有一个控件:worktrees 开关。它只写这一个键,所以不会留下别的东西。其他设置仍然要用上面那个文件来改。
认证
这里不存任何东西。git 运行时保留 HOME 和 PATH,所以凭据由机器自己的 credential helper 解析——在这台机器上是系统 gitconfig 里的 osxkeychain。GitHub API 调用按 GH_TOKEN → GITHUB_TOKEN → gh auth token --hostname <host> 的顺序取——前两个不需要装任何东西——惰性读取,从不记日志,从不写盘,并且会从每个错误里抹掉。两半都不交互:提示已关闭(GIT_TERMINAL_PROMPT=0,没有 askpass),所以不会卡在一个没人回答的问题上——而且远程 URL 里内嵌的凭据在报告远程时会被丢掉,所以 status 显示主机和路径,从不显示 userinfo。
两半互不共享,新机器通常只有其中一个:读公开仓库根本不需要凭据,所以新机器看起来一切正常,直到第一次 push,而 GH_TOKEN 对 push 从来没用。一次 push 或者一次 fetch** 失败时如果缺凭证,会连同修复办法一起报出来:fetch 会把它写成 next:,而 push 则会在回合结束时的提示和 status 打印的记录里都点名一个凭证 helper、一个 SSH 远程,或者——如果装了 GitHub CLI——gh auth setup-git。失败不会被记住:下次调用会重新问一遍链路,所以在终端里跑 gh auth login 不用重启 Harness 就能生效。docs/install.md 是给从未登录过的机器准备的检查清单。
跟 GitHub 通信走 REST,不走 gh,因为结构化的状态码比匹配错误文本更可靠——也因为 gh pr merge --delete-branch 会在当前目录所属仓库里做本地分支清理,只按分支名匹配,可能删掉无关 worktree 里尚未推送的提交。
环境要求
PATH 里有 git。gh 可选,只当 token 来源用;没有它就设置 GH_TOKEN。全局 fetch 需要 Node 18+。没有 npm 依赖——lib/*.mjs 只 import node: 内置模块,@deepseek-ai/schemastery 是防御性加载的,这样 link: 安装不会在激活时把插件搞挂。
在 Harness 这一侧,它在 inject 里声明了 tools、commands 和 sessions,所以缺这些的 Harness 会让这一行保持 pending,而不是半挂载。它防御性地取用 agents 和 workspaceChanges——没有它们的构建照样能用,只是提交主题不够精确——并注册在 tools/pre-execute 和 agent/turn-stopping 上。
测试
npm test
这个 checkout 里没有测试目录——旧的测试套件测的是内部模块,而不是插件承诺的行为。CI 已禁用(工作流触发器只有 workflow_dispatch)。如果哪天恢复测试套件,该测什么写在 docs/testing.md。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
stansz/dsh-git
统一管理提交推送与拉取请求,自动同步不留脏树
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,025未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,358已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13938 个插件含 PR 收录与…
★ 350已汉化DSH
71.8
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这是你的仓库?认领条目