Use when landing a stack of dependent GitHub PRs (A ← B ← C, where each bases on the one below) onto master, merging a PR whose base is another open PR's branch
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-dsh-merging-stacked-prs-d4871a12e517 ,按照其中的说明把「dsh-merging-stacked-prs」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Land dependent PRs through GitHub's native stack object and gh stack merge. Do not reproduce stack semantics by merging and retargeting individual PRs with gh pr merge and gh pr edit. The root AGENTS.md owns the allowed merge-forward and rebase histories; the stack review guide owns review-fix propagation.
Run gh stack --version before changing GitHub state. Hard-stop if the official extension or server-side stack feature is unavailable; do not fall back to manually merging and retargeting PRs one at a time. GitHub stacks require every head branch to live in the same repository, so hard-stop on a cross-fork chain.
Use a clean dedicated worktree. Fetch current PR metadata and exact head OIDs rather than trusting branch names or an earlier report:
gh pr view <pr> --json number,author,baseRefName,baseRefOid,headRefName,headRefOid,isCrossRepository,state,isDraft,reviewDecision,mergeStateStatus,statusCheckRollup
Query PullRequest.stack and stackEntry.position for at least one PR in each apparent chain; this official GitHub object, not base-branch inference alone, is the stack-membership authority. Paginate entries when size exceeds the returned page:
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 }
}
}
}
}
}
}'
Establish the expected bottom-to-top order from the live PR bases: the bottom targets the trunk, and each higher PR targets the head branch immediately below it.
First compare any existing stack entries with the expected chain. One existing stack may contain an order-preserving subset of the requested chain; multiple stack numbers, an unexpected entry, or a conflicting order requires user direction before any mutation.
When any dependent PR is not yet in that official stack:
author.login exactly.gh stack link --base <trunk> <bottom-pr> <next-pr> ... <top-pr>
Never dissolve, reorder, or rebuild an existing stack automatically; gh stack link is additive and merged or queued entries cannot be unstacked.
Do not rewrite branches merely because a refresh mechanism exists. When the live merge state or repository rules require an updated trunk, choose either allowed history:
gh stack checkout <pr-or-stack> when it is not tracked locally, then run gh stack sync. The command may rebase and lease-protected force-push every active layer before local validation. Immediately inspect the rewritten scope, run the relevant checks for every affected layer, and do not merge or claim readiness until they pass. If sync detects a rebase conflict, use gh stack rebase, resolve and validate it, then publish with gh stack push. If checkout or sync reports divergent local and remote stack compositions, cancel and ask rather than deleting or recreating the remote stack automatically.Any history rewrite is allowed after review, but it invalidates commit-OID assumptions. Re-fetch exact heads and re-audit unresolved review threads, approvals, mergeability, and checks after the push. Never use raw --force or overwrite a concurrently advanced remote head.
Re-query the official stack immediately before merging. Require every selected PR to be open, non-draft, in the expected order, and compliant with the repository's review and check requirements. Treat each PR's state independently; a ready top layer does not prove its dependencies are ready.
"Land the stack" selects the whole stack. A partial landing requires an explicit boundary PR and includes every layer from the bottom through that boundary.
Merge the whole stack by its official stack number:
gh stack merge <stack-number> --yes --merge
For an explicitly requested partial landing, merge through the boundary PR:
gh stack merge <boundary-pr> --yes --merge
Do not pass --delete-branch, manually retarget dependents, or issue per-PR merge commands. GitHub merges the selected range bottom-up and retargets/rebases any remaining upper layers. A direct stack merge is all-or-nothing; when the trunk uses a merge queue, GitHub queues the selected range together but may land it in separate groups.
Do not bypass merge requirements. If the native merge reports a blocker, inspect and resolve that blocker through the owning PR or stop and report it; never fall back to gh pr merge.
Wait for every selected PR to report MERGED; a queued request is not a completed landing:
gh pr view <pr> --json number,state,mergedAt,mergeCommit,baseRefName,headRefName
For a partial landing, re-query the official stack and verify that every remaining PR is still linked in the expected order and targets the stack trunk or the layer below it. Re-check current heads, review state, and CI because GitHub may have rebased the remaining layers.
Delete branches only in a separate final pass after the corresponding PRs report MERGED. Before deleting each branch, require GitHub to report no open PR still using it as a base:
gh pr list --state open --base <branch> --json number --jq length
Anything other than 0 blocks deletion.
gh stack support is available; every PR branch is in the same repository.gh stack merge --yes --merge.MERGED; any remaining upper layers still form the expected official stack.