mcpField
G
gh-stack

gh-stack

github.com/github开发1.7k19.5k 次安装2 天前更新
代码仓库

关于 gh-stack

用于管理堆叠分支和 Pull Request 的 GitHub CLI 扩展,面向按依赖关系拆分开发工作的团队。它支持线性分支栈的提交、同步、变基和按栈合并,并提供 JSON 状态输出。

主要功能

  1. 01创建并浏览线性分支栈
  2. 02提交分支并创建 PR
  3. 03同步远程栈并执行变基
  4. 04按 PR 或栈合并
  5. 05以 JSON 输出栈状态

适用场景

  1. 01将多阶段功能拆成依赖分支
  2. 02逐层提交代码供审查
  3. 03同步栈并处理分支变基
  4. 04按顺序合并关联 PR

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/gh-stack --skill gh-stack

安装后在 Claude Code 中输入/gh-stack确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
commands.md
stack-design.md
troubleshooting.md

详细介绍

gh-stack

gh stack 是用于堆叠分支和拉取请求的 GitHub CLI 扩展。堆叠是以主干分支为根的有序分支链,每个分支都有一个基于其下方分支的 PR,因此审查者只会看到该层的差异。

gh stack 会从主干开始,从左向右打印堆叠:

(main) <- auth <- api <- frontend

左侧是底部,右侧是顶部。auth 基于 main,并最先合并;frontend 最后合并。up 朝顶部移动,远离主干;down 则朝主干移动。基础工作放在底部,依赖它的代码放在上方。有关如何选择各层,请阅读 references/stack-design.md。

设置

需要 Git 2.36+ 和已通过身份验证的 GitHub CLI。

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 harness 的行为各异,因此请始终传入下方的标志,不要依赖这种检测机制。

多个远程仓库: 除非已配置 remote.pushDefault,否则运行 push、submit、sync、rebase 或 link 时必须指定 --remote <name>。checkout 和 trunk 没有 --remote 标志,因此需要配置该项。

始终运行切勿直接运行原因
gh stack view --jsongh stack view在 PTY 下会打开 TUI
gh stack submit --autogh stack submit每个新 PR 都会提示输入标题
gh stack merge <target> --yesgh pr mergegh 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 / bottomgh stack switchswitch 仅支持菜单操作
—gh stack modify仅支持 TUI,没有非交互式用法
  • view --short 在两种模式下都安全,但输出格式面向用户。要解析输出,请使用 --json。
  • 当其他本地堆叠已包含目标分支时,无法强制执行 checkout <pr>。 先运行 gh stack unstack --local(这会保留 GitHub 上的堆叠),然后重试。
  • 工作树: 本地堆叠共用一个公共目录目录。使用 --print-path 配合导航命令或指定目标的 checkout,以定位由其他工作树持有的分支,而不抢占其检出状态。未被占用的目标会优先在当前工作树中检出。更改目录前请检查退出状态;仅解析路径模式成功时的 stdout,切勿解析状态消息。

分支放置

  • 开始多部分工作: 在编写文件前创建堆叠。不要先在主干上实现所有内容,再将其拆分。每层放置一个有依赖关系的关注点,从底部向上排列。
  • 编辑现有堆叠: 编辑前先检出负责该更改的层。切勿在当前顶部提交属于较低层的关注点。运行 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。

合并

使用参数限定合并范围:

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 可能会分成不同批次合并。

读取状态

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 恢复步骤操作
4GitHub 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 重新触发冲突,然后按照上述步骤解决冲突并继续。

限制

  • 堆栈严格线性:只有一个父分支,最多有一个子分支。并行工作请使用独立的堆栈。
  • rebase 和 sync 会自动更新受影响的干净工作树;它们不会自动暂存更改,也不会创建或删除工作树。修改操作在整个克隆中串行执行;暂停的操作必须在其记录的所属位置恢复。
  • modify 支持分布式堆栈分支,但其编辑器仍仅支持 TUI。操作会在受影响的干净所属工作树中运行;未被占用的分支使用 origin。被丢弃或折叠的源分支和工作树会保留。恢复标志可从任何工作树运行,并使用记录的原生操作所属位置;除非诊断信息明确指出,否则切勿在调用方的工作树中解决冲突或暂存更改。
  • 不支持以非交互方式重新排序或移除。错误可能会建议运行 gh stack modify,但它仅支持 TUI——请改用 unstack,然后运行 init 来调整结构。
  • PR 标题和正文会自动生成。之后可使用 gh pr edit 修改。

更多详情

关于标志和参数,以 gh stack <command> --help 为准。请注意,gh stack help <command> 无法使用——它会打印顶层帮助信息。

打开触发条件与任务匹配的参考文档;无需预先加载全部三份。

  • references/stack-design.md——创建堆栈、决定使用多少层、确定每层的内容,或判断工作是否应属于新堆栈之前,请阅读此文档。
  • references/commands.md——命令意外失败,或需要了解其前置条件、副作用、原子性或顺序保证时,请阅读此文档。
  • references/troubleshooting.md——发生变基冲突、压缩合并后、本地与远程分叉、调整堆栈结构,或通过其他工具操作堆栈时,请阅读此文档。

评论

支持 Markdown