关于 gh-stack
gh-stack 是面向开发者的 GitHub CLI 扩展,用于将相互依赖的分支和拉取请求组织成有序堆栈。它支持创建、提交、同步和合并堆栈,并可用 JSON 查看状态。
主要功能
- 01创建和切换有序分支堆栈
- 02将堆栈分支提交为拉取请求
- 03同步分支并刷新拉取请求状态
- 04将变更向上变基到依赖分支
- 05以 JSON 查看堆栈状态
适用场景
- 01将多部分变更作为依赖拉取请求提交
- 02修改底层后对上层分支变基
- 03将本地堆栈与 GitHub 同步
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jssblck/ agents --skill gh-stack安装后在 Claude Code 中输入/gh-stack确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/commands.mdstack-design.mdtroubleshooting.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 | gh stack 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,而不是草稿。分支名称会原样使用: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。
合并
Jess 默认通过 Forge 按顺序合并多个 PR。 使用 merge-open-prs:先合并父 PR,然后按照仓库的基准更新和验证要求处理下一个 PR。 不要将合并开放 PR 的请求变成一次性合并整个堆栈的操作。
只有当用户请求合并整个堆栈时,才使用以下命令。 通过参数指定合并范围:
gh stack merge 42 --yes # PR #42 plus every unmerged PR below it
gh stack merge 7 --yes # every unmerged PR in stack #7
gh stack merge 42 --yes --squash # or --merge, --rebase, --merge-method <method>
传入 PR 编号可合并该 PR 及其下方所有尚未合并的 PR;传入堆栈编号可合并该堆栈中所有尚未合并的 PR。该操作要么全部成功,要么全部失败:如果集合中有任何 PR 无法合并,则不会合并其中任何 PR。
如果未指定方法标志,则会沿用上次使用的方法。如果基准分支使用合并队列,则会将堆栈加入队列,由队列选择合并方法,并忽略你传入的任何标志,同时发出警告;排队的 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。
退出代码
| 代码 | 含义 | 恢复方法 |
|---|---|---|
| 0 | 成功 | (无) |
| 1 | 通用错误 | 阅读 stderr |
| 2 | 不在堆栈中 | 执行 gh stack init,或 gh stack checkout <target> |
| 3 | 变基冲突 | 按照下方的退出代码 3 恢复步骤操作 |
| 4 | GitHub API 失败 | 检查 gh auth status,然后重试 |
| 5 | 参数无效 | 修正调用;参见 <command> --help |
| 6 | 需要消除歧义 | 分支属于多个堆栈;切换到一个非共享分支 |
| 7 | 变基已在进行中 | 执行 gh stack rebase --continue 或 --abort |
| 8 | 堆栈文件已锁定 | 另一个 gh stack 进程正在写入;约 5 秒后重试 |
| 9 | 堆栈式 PR 不可用 | 仓库未启用此功能;告知用户 |
| 10 | 需要修改恢复操作 | 执行 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>仅会在本地堆栈中查找。请使用堆栈编号或 PR 编号从 GitHub 拉取堆栈。
更多详情
gh stack <command> --help 是标志和参数的权威说明(gh stack help <command> 会打印顶层帮助,而非子命令帮助)。请阅读与任务相符的参考资料:
references/stack-design.md:创建堆栈前,以及决定使用多少层、每层包含哪些内容时阅读。references/commands.md:命令意外失败,或需要了解其前置条件、副作用、原子性或顺序保证时阅读。references/troubleshooting.md:发生变基冲突、压缩合并后、本地与远程分歧时,或需要调整堆栈结构时阅读。