关于 gh-stack
指导使用 GitHub CLI 扩展 `gh stack` 管理严格线性的分支链和堆叠拉取请求。内容涵盖非交互命令、同步、变基及范围明确的合并。
主要功能
- 01创建和切换分支栈
- 02提交并同步堆叠 PR
- 03跨分支变基
- 04以 JSON 查看栈状态
- 05处理冲突并按范围合并
适用场景
- 01将依赖工作拆分为可审查层级
- 02同步堆叠 PR
- 03将底层分支变基到其后续分支
- 04合并分支栈的指定部分
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ remotion-dev/ remotion --skill gh-stack安装后在 Claude Code 中输入/gh-stack确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/commands.mdtroubleshooting.mdstack-design.md详细介绍
gh-stack
gh stack 是一个用于管理堆叠分支和拉取请求的 GitHub CLI 扩展。堆栈是以主干分支为根、按顺序排列的分支链,其中每个分支都有一个基于其下方分支的 PR,因此审查者只会看到该层的差异。
gh stack 会从主干开始,由左向右打印堆栈:
(main) <- auth <- api <- frontend
左侧是底层,右侧是顶层。auth 基于 main,并最先合并;frontend 最后合并。up 向顶层移动,远离主干;down 则向主干移动。基础工作放在底层,依赖这些工作的代码放在上层。有关如何选择层级,请阅读 references/stack-design.md。
设置
gh extension install github/gh-stack
git config rerere.enabled true # remember conflict resolutions
git config remote.pushDefault origin # required if the repo has more than one remote
非交互式使用
gh stack 会根据 stdout 是否为 TTY 选择行为。通过管道运行时,大多数命令会正常报错或打印静态文本;在 PTY 下运行时,同样的命令会打开提示或全屏 TUI,并一直阻塞。不同的 Agent 框架行为各异,因此请始终传入下方列出的标志,不要依赖这种检测。
多个远程仓库: 除非配置了 remote.pushDefault,否则运行 push、submit、sync、rebase 或 link 时,务必指定 --remote <name>。checkout 和 trunk 没有 --remote 标志,因此需要该配置。
| 始终运行 | 切勿直接运行 | 原因 |
|---|---|---|
gh stack view --json | gh stack view | 在 PTY 下会打开 TUI |
gh stack submit --auto | gh stack submit | 会提示为每个新 PR 输入标题 |
gh stack merge <target> --yes --squash | gh pr merge | gh pr merge 无法合并堆栈 |
gh stack init <branch>... | gh stack init | 会提示输入分支名称 |
gh stack add <branch> | gh stack add | 会提示输入名称,即使通过管道运行也会失败 |
gh stack checkout <target> | gh stack checkout | 会打开选择菜单 |
gh stack up / down / top / bottom | gh stack switch | switch 只能通过菜单使用 |
| — | gh stack modify | 仅限 TUI,没有非交互式用法 |
view --short在两种模式下都可以安全使用,但其输出面向人类。要解析输出,请使用--json。- 当其他本地堆栈已覆盖这些分支时,无法强制执行
checkout <pr>。 请先运行gh stack unstack --local(这会保留 GitHub 上的堆栈),然后重试。
分支放置
- 开始多部分工作时: 先创建堆栈,再编写文件。不要在主干上实现所有内容后再拆分。每层放置一个有依赖关系的事项,从底层向上排列。
- 编辑现有堆栈时: 编辑前先检出负责该更改的层。切勿在当前顶层分支上提交属于较低层的更改。运行
gh stack view --json;如果无法确定归属,请检查git log --all -- <path>。然后检出负责该更改的分支,编辑、提交、向上游变基,最后回到顶层。
gh stack down # or: gh stack checkout api
git add ... && git commit -m "Add get-user endpoint"
gh stack rebase --upstack # replay every branch above onto the change
gh stack top # return to where you were
gh stack push
核心循环
gh stack init auth # create the stack and check out its branch
git add ... && git commit -m "Add auth middleware"
gh stack add api # next layer, branched from the current one
git add ... && git commit -m "Add API routes"
gh stack submit --auto # push every branch and open draft PRs
gh stack view --json # confirm
在 submit 中添加 --open,即可创建可供审查的 PR,而不是草稿 PR。分支名称会原样使用——gh stack add refactor/foo 会创建 refactor/foo。
保持同步
gh stack sync # fetch, reconcile with GitHub, rebase, push, refresh PR state
gh stack sync --prune # also delete local branches for merged PRs
非交互式运行时,只有指定 --prune 才会执行清理。如果本地堆栈与远程堆栈已发生分歧,sync 会打印两条分支链,不做任何更改,并以退出码 0 退出,同时显示 Sync aborted——请参阅 references/troubleshooting.md。
合并
只有在用户明确要求合并时才执行堆栈合并。先检查 gh stack view --json,确认用户要合并整个堆栈,还是只合并到某个特定 PR,并通过参数指定范围和明确的合并方式:
gh stack merge 42 --yes --squash # PR #42 plus every unmerged PR below it
gh stack merge 7 --yes --squash # every unmerged PR in stack #7
传入 PR 编号,可合并该 PR 及其下方所有尚未合并的 PR;传入堆栈编号,可合并该堆栈中所有尚未合并的 PR。此操作要么全部成功,要么全部失败:如果其中任何一个 PR 无法合并,则一个也不会合并。
虽然省略合并方式会沿用上次使用的方式,但 Agent 必须明确传入 --squash、--merge、--rebase 或 --merge-method <method>。如果基分支使用合并队列,则会改为将堆栈加入队列,由队列选择合并方式,并忽略该标志(同时发出警告);排队的 PR 可能会分成多个组分别合并。
读取状态
gh stack view --json 会将 JSON 写入 stdout。状态消息会写入 stderr——不要解析这些消息,而应根据退出码进行判断。
trunk string
currentBranch string
branches[] name, head, base, isCurrent, isMerged, isQueued, needsRebase
branches[].pr number, url, state ("OPEN" | "MERGED" | "QUEUED"); absent when no PR exists
base 是父分支已保存的 SHA,表示上次确认该分支包含的父分支提交。它可能早于父分支当前的最新提交。若父分支当前的最新提交不再是该分支的祖先,则 needsRebase 为 true。
退出码
| Code | 含义 | 恢复方式 |
|---|---|---|
| 0 | 成功 | — |
| 1 | 一般错误 | 阅读 stderr |
| 2 | 不在堆栈中 | gh stack init,或 gh stack checkout <target> |
| 3 | Rebase 冲突 | 按照下方的退出码 3 恢复步骤处理 |
| 4 | GitHub API 故障 | 检查 gh auth status,然后重试 |
| 5 | 参数无效 | 修正调用方式;参见 <command> --help |
| 6 | 需要消除歧义 | 分支属于多个堆栈;切换到一个非共享分支 |
| 7 | Rebase 已在进行中 | gh stack rebase --continue 或 --abort |
| 8 | 堆栈文件已锁定 | 另一个 gh stack 进程正在写入;约 5 秒后重试 |
| 9 | 堆叠 PR 不可用 | 仓库未启用此功能;告知用户 |
| 10 | 需要执行 Modify 恢复操作 | gh stack modify --abort |
退出码 3 的恢复步骤:
- 在
gh stack rebase之后:解决文件冲突,运行git add,然后运行gh stack rebase --continue;运行gh stack rebase --abort可恢复堆栈。 - 在
gh stack sync之后:堆栈已恢复。运行gh stack rebase重新产生冲突, 然后按照上述步骤解决冲突并继续。
限制
- 堆栈必须严格线性:一个父分支,最多一个子分支。并行工作请使用单独的堆栈。
- 不支持非交互式重排或移除。错误消息可能会建议使用
gh stack modify,但它仅支持 TUI——应改用unstack,然后执行init来重构堆栈。 - PR 标题和正文会自动生成。之后可使用
gh pr edit修改。 checkout <branch-name>仅在本地堆栈中查找。要从 GitHub 拉取堆栈,请使用堆栈编号或 PR 编号。
更多详情
gh stack <command> --help 是标志和参数的权威参考。请注意,gh stack help <command> 无法使用——它会显示顶层帮助信息。
打开触发条件与任务匹配的参考文档;无需预先加载全部三份。
references/stack-design.md— 创建堆栈前、决定使用多少层以及每层包含什么内容,或判断某项工作是否应放入新堆栈时阅读。references/commands.md— 命令意外失败,或需要了解其前置条件、副作用、原子性或顺序保证时阅读。references/troubleshooting.md— 发生变基冲突、完成压缩合并后、本地与远程发生分歧、重构堆栈,或通过其他工具操作堆栈时阅读。