关于 dsh-merging-stacked-prs
dsh-merging-stacked-prs 是一项技能,用于通过 GitHub 原生堆栈支持合并存在依赖关系的拉取请求。它指导维护者核实堆栈、检查就绪状态、执行合并并验证结果,不以逐个 PR 合并替代堆栈操作。
主要功能
- 01核实原生堆栈支持及成员关系
- 02检查 PR 作者、基准、分支头和顺序
- 03按允许的方法更新堆栈分支
- 04预先检查评审、状态和必需检查
- 05通过 gh stack merge 合并并核验结果
适用场景
- 01合并完整的依赖 PR 堆栈
- 02合并明确指定范围的堆栈前缀
- 03在主干或仓库规则要求时更新分支
- 04部分合并后核验剩余 PR
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ deepseek-ai/ deepseek-harness --skill dsh-merging-stacked-prs安装后在 Claude Code 中输入/dsh-merging-stacked-prs确认已加载。
详细介绍
合并官方 GitHub PR 堆栈
通过 GitHub 原生堆栈对象和 gh stack merge 合并有依赖关系的 PR。不要通过逐个合并并重新指定目标分支的方式,用 gh pr merge 和 gh pr edit 重现堆栈语义。根目录的 AGENTS.md 规定了允许的向前合并和变基历史;堆栈审查指南 规定了审查修复的传播方式。
要求原生堆栈支持
更改 GitHub 状态前,运行 gh stack --version。如果官方扩展或服务端堆栈功能不可用,立即停止;不要退回到逐个手动合并并重新指定目标分支。如果堆栈中有分支来自不同仓库,也要立即停止,因为 GitHub 堆栈要求所有头部分支都位于同一仓库。
使用干净的专用工作树。获取当前 PR 元数据和准确的头部 OID,不要依赖分支名称或先前的报告:
gh pr view <pr> --json number,author,baseRefName,baseRefOid,headRefName,headRefOid,isCrossRepository,state,isDraft,reviewDecision,mergeStateStatus,statusCheckRollup
对每个明显的链至少选一个 PR,查询 PullRequest.stack 和 stackEntry.position;官方 GitHub 对象才是堆栈成员关系的权威来源,不能只靠推断基分支。如果 size 大于返回的页面数,请对 entries 分页:
gh api graphql -F owner=<owner> -F name=<repo> -F number=<pr> -f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
number
author { login }
baseRefName
headRefName
stackEntry { position }
stack {
number
baseRefName
size
entries(first: 100) {
nodes {
position
pullRequest { number author { login } baseRefName headRefName state isDraft }
}
}
}
}
}
}'
根据当前 PR 的基分支确定预期的自底向上顺序:最底层 PR 以主干为目标,每个更高层 PR 都以其正下方 PR 的头部分支为目标。
链接缺失的堆栈成员
首先将现有堆栈条目与预期链进行比较。一个现有堆栈可以包含请求链中顺序不变的子集;多个堆栈编号、意外条目或顺序冲突,都需要在进行任何更改前征求用户指示。
如果任何有依赖关系的 PR 尚未加入该官方堆栈:
- 精确比较每个
author.login。 - 如果所有作者都相同,则按自底向上的顺序自动链接该链:
gh stack link --base <trunk> <bottom-pr> <next-pr> ... <top-pr>
- 如果作者不同或任何作者信息不可用,请先询问用户是否要进行链接,再更改 GitHub 状态。
- 重新查询 GraphQL,并确认只有一个堆栈编号、主干符合预期、PR 集合完整,且位置和基分支链均符合预期。
绝不要自动拆解、重排或重建现有堆栈;gh stack link 只会添加成员,已合并或已排队的条目无法从堆栈中移除。
仅在需要时刷新
不要仅仅因为存在刷新机制就重写分支。当当前合并状态或仓库规则要求更新主干时,选择以下任一种允许的历史:
- 原生级联变基: 如果远程堆栈尚未在本地跟踪,使用
gh stack checkout <pr-or-stack>检出,然后运行gh stack sync。该命令可能会在本地验证前,对每个活动层进行变基并通过租约保护的强制推送。立即检查重写范围,对每个受影响层运行相关检查;检查通过前不得合并或声称已准备就绪。如果 sync 检测到变基冲突,请使用gh stack rebase,解决并验证冲突,然后用gh stack push发布。如果 checkout 或 sync 报告本地与远程堆栈组成存在分歧,请取消操作并询问用户,不要自动删除或重建远程堆栈。 - 增量向前合并: 将主干合并到受影响链最底层的分支,然后按自底向上的顺序,将每个更新后的父分支传播到其子分支,并正常推送。如果进行中的合并期间基分支有更新,请先保留当前检查点,再合并更新后的最新提交。
审查完成后允许重写任何历史记录,但这会使基于提交 OID 的假设失效。推送后,重新获取准确的头部,并重新审计未解决的审查讨论串、审批、可合并状态和检查。绝不要使用原始的 --force,也不要覆盖并发更新的远程头部。
预检合并范围
在合并前立即重新查询官方堆栈。要求所有选定的 PR 均处于开放状态、非草稿、顺序符合预期,并满足仓库的审核与检查要求。分别处理每个 PR 的状态;顶部层已就绪并不代表其依赖项也已就绪。
“合并整个堆栈”会选中整个堆栈。部分合并必须明确指定边界 PR,并包含从底部到该边界的所有层。
通过堆栈 API 合并
通过官方堆栈编号合并整个堆栈:
gh stack merge <stack-number> --yes --merge
对于明确请求的部分合并,合并到边界 PR 为止:
gh stack merge <boundary-pr> --yes --merge
不要传入 --delete-branch、手动重新指定依赖项的目标分支,也不要逐个发出 PR 合并命令。GitHub 会从底部开始合并所选范围,并重新指定或变基剩余的上层。直接合并堆栈要么全部成功,要么全部失败;当主干使用合并队列时,GitHub 会将所选范围一起加入队列,但可能分成多个组分别合并。
不要绕过合并要求。如果原生合并报告阻碍,请通过对应 PR 检查并解决该问题,或停止操作并报告;绝不能改用 gh pr merge。
验证已合并状态
等待每个选定的 PR 都报告 MERGED;已排入队列的请求并不代表合并已完成:
gh pr view <pr> --json number,state,mergedAt,mergeCommit,baseRefName,headRefName
对于部分合并,重新查询官方堆栈,并验证每个剩余 PR 仍按预期顺序关联,且目标是堆栈主干或下方的那一层。重新检查当前分支头、审核状态和 CI,因为 GitHub 可能已对剩余层执行变基。
只有在相应 PR 报告 MERGED 后,才能在单独的最后阶段删除分支。删除每个分支前,必须确认 GitHub 报告没有仍以其为基分支的开放 PR:
gh pr list --state open --base <branch> --json number --jq length
任何非 0 的值都禁止删除。
检查清单
- 已提供原生
gh stack支持;每个 PR 分支都位于同一仓库中。 - 实时 PR 基分支和确切分支头组成一条从底部到顶部的依赖链。
- GraphQL 报告了一个具有预期主干、条目和顺序的官方堆栈;符合条件的同作者未堆叠链已自动关联。
- 任何经过重写的层都通过了相关验证;之后重新审核了审核线程、批准、可合并状态和检查结果。
- 整个堆栈或明确界定的前缀已通过
gh stack merge --yes --merge提交。 - 每个选定的 PR 都报告
MERGED;任何剩余的上层仍组成预期的官方堆栈。 - 仅在确认已合并状态且依赖数量为零后删除分支。