关于 pr-stack
用于管理堆叠分支及其拉取请求的技能,会根据仓库现有配置使用 Graphite、git-town 或 GitHub gh stack。它检测可用工具,并指导创建、同步、提交和冲突恢复,不用普通 Git 命令模拟该流程。
主要功能
- 01检测已配置的堆叠工具
- 02创建并检查分支堆叠
- 03同步并提交堆叠拉取请求
- 04使用工具专属命令恢复冲突
- 05比较三种工具的工作流
适用场景
- 01维护相互依赖的拉取请求链
- 02主干变更后重新排列分支
- 03提交或更新整个堆叠
- 04恢复堆叠变基冲突
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ skillz-that-grillz --skill pr-stack安装后在 Claude Code 中输入/pr-stack确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/gh-stack.mdgit-town.mdgt.md详细介绍
pr-stack
堆叠分支:由一系列小型分支组成,每个分支对应一个 PR;即使经过变基,它们仍会保持顺序,并作为一个组推送。
目前有三种工具可以实现此工作流。它们采用相同的思路,但各自属于不同的生态系统:
- Graphite(
gt) — 第三方 CLI,成熟,需要 Graphite 账户(gt auth)。堆栈元数据存储在.git/.graphite_repo_config中。 - git-town(
git town) — 第三方 CLI,成熟,无需账户且与代码托管平台无关(GitHub / GitLab / Gitea / Bitbucket / Forgejo / Azure DevOps)。分支谱系存储在本地 git 配置中(git-town-branch.<name>.parent),因此无需注册账户。 - GitHub
gh stack— 第一方gh扩展(github/gh-stack),截至 2026-05 处于私有预览阶段;仓库必须通过 gh.io/stacksbeta 加入允许列表。堆栈元数据存储在.git/gh-stack中。使用标准的gh auth login,无需第三方账户。
本技能会选择用户已安装的工具并使用它来执行操作。它不会通过普通 git 模拟堆叠操作。
检测 — 在执行任何其他操作前运行
# gt available?
command -v gt >/dev/null 2>&1 && gt --version >/dev/null 2>&1
# gt initialized in this repo?
test -f "$(git rev-parse --git-dir)/.graphite_repo_config"
# gh stack extension installed?
# (gh extension list output is TAB-separated: <short-name>\t<owner/repo>\t<version>)
# Guard with `command -v gh` so the probe stays quiet when gh itself is missing
# — `2>/dev/null` on the pipeline doesn't catch the shell's own "command not
# found" message.
command -v gh >/dev/null 2>&1 \
&& gh extension list 2>/dev/null | awk -F '\t' '$2 == "github/gh-stack"' | grep -q .
# git-town available?
command -v git-town >/dev/null 2>&1 && git town --version >/dev/null 2>&1
# git-town configured for this repo? (non-empty trunk = set up)
git config --local --get git-town.main-branch >/dev/null 2>&1
选择仓库已配置好的工具。 当工具已安装且已针对此仓库完成配置时,才算可用:
| 工具 | 已安装探测 | 仓库配置探测 |
|---|---|---|
gt | command -v gt | .git/.graphite_repo_config 存在 |
git town | command -v git-town | git config --local --get git-town.main-branch 返回非空值 |
gh stack | gh extension list 中包含 github/gh-stack | 无需预检 — 当远程操作以状态码 4 退出时再延迟检测 |
然后:
- 恰好有一个可用工具 → 使用它;阅读该工具的参考文档。
- 有多个可用工具 → 优先使用
gt(已正式发布,成熟,且仓库可能已跟踪堆栈),其次是git town(已正式发布,无需账户,与代码托管平台无关),最后是gh stack(第一方,但处于私有预览阶段)。告知用户还安装了哪些工具,并提出是否切换。 - 已安装但未配置 → 提供一次性设置方案(
gt init,或git config --local git-town.main-branch <trunk>— 你的主干分支名称,例如main/master;gh stack无需初始化仓库),然后继续。 - 没有可用工具 → 停止。 不要尝试使用一系列
git push命令。请参见下方的“未安装任何工具”。
每次调用都要运行这些探测 — 用户的环境可能会在不同会话之间发生变化。
未安装任何工具
如果检测未发现 gt、git town 或 gh stack 扩展,请原样显示以下内容并停止:
此机器/此仓库无法使用堆叠 PR 工具。请安装以下任一工具:
- Graphite CLI —
brew install withgraphite/tap/graphite(或npm install -g @withgraphite/graphite-cli@stable),然后在此仓库中运行gt auth --token <token from https://app.graphite.com/activate>和gt init。- git-town —
brew install git-town(或在 Windows 上使用choco/scoop),然后在此仓库中运行git config --local git-town.main-branch <trunk>(你的 主干分支名称,例如main/master;也可以使用git town config setup向导),并执行以下任一配置:git config --local git-town.github-connector gh(复用你的gh身份验证),或配置git-town.github-tokenPAT。支持 GitHub、GitLab、Gitea 等平台。- GitHub 原生
gh stack—gh extension install github/gh-stack, 然后确保仓库已加入 gh.io/stacksbeta 允许列表(截至 2026-05,仍为私有预览版)。安装其中任一工具后,重新调用
/pr-stack,我会负责处理。
不要尝试用普通的 git push 链式命令、父分支目标配置或手动关联 PR 来变通——此技能的价值在于支持堆叠的工具机制,而伪造这种机制的效果还不如直接告知用户缺少工具。
第三种失败情况——已安装 gh stack,但仓库未加入允许列表。
CLI 可以安装在任何地方,但如果仓库不在私有预览版允许列表中,远程操作(submit、sync、link)会以退出代码 4 失败。
如果看到退出代码 4,请告知用户此情况,并引导其访问
gh.io/stacksbeta。如果本地也安装了 gt,可以提议在此仓库中改用它。
心智模型(通用)
- 主干是
main(或仓库使用的其他名称)。 - 堆叠是一串分支,每个分支都以之前的分支为父分支。每个堆叠的底部都是主干。
- 每个分支对应一个 PR,每个 PR 都以其父分支为目标。审查按从底到顶的顺序进行。
- 提交会推送整个分支链,并为每个分支新建或更新一个 PR。
- 同步会拉取主干,将所有仍保留的分支重新基于主干最新提交,并清理 PR 已合并的分支。
这三种工具都实现了此模型。命令名称各不相同——请参阅各工具的参考文档。
堆栈中的 PR 合并后
底部的 PR(或任何已合并的 PR)合并后,堆栈中的其余分支需要跟进 trunk,已合并的分支也需要移除。这是一个独立的操作时机——不要等到常规“同步”时再处理。
运行工具的同步命令:
| 工具 | 命令 | 作用 |
|---|---|---|
gt | gt sync,然后运行 gt submit --stack | 获取 trunk,将未合并的分支在本地重新基于 trunk 最新提交,并提示删除已合并或已关闭的分支。随后,submit 会推送重新变基后的分支。 |
gh stack | gh stack sync(仅当你有尚未推送的本地提交时才运行 gh stack submit) | GitHub 已在合并时于服务端级联完成重新变基;sync 主要用于拉取该状态并更新本地引用。 |
git town | git town sync --stack | 获取 trunk,移除已合并的分支,在本地将未合并的分支重新基于 trunk 最新提交,并强制推送,以便代码托管平台重新设置其 PR 的目标分支。 |
关键区别:使用 gh stack 时,底部的 PR 合并后,GitHub 服务端已经为未合并的分支完成了重新变基——你的任务是拉取该状态,而不是重新计算。使用 gt 时,重新变基在本地进行,因此 gt sync 会在你的计算机上实际执行这项工作。
如果 sync 遇到冲突(trunk 和某个未合并分支修改了相同行),请进入工具的冲突恢复流程:gt continue / gt abort、git town continue / git town skip,或 gh stack rebase --continue / --abort。切勿使用裸的 git rebase --continue;工具的元数据不会更新。
sync 成功后,运行 gt log short / git town branch / gh stack view,确认分支链正确无误,再进行下一次提交。
工具等效操作速查表
| 操作 | gt | git town | gh stack |
|---|---|---|---|
| 初始化堆栈元数据 | gt init(仓库级) | git town config setup(仓库级) | gh stack init(每个堆栈) |
| 从 trunk 开始创建堆栈 | 在 trunk 上运行 gt create | git town hack <name> | gh stack init + gh stack add |
| 在当前分支上创建分支 | gt create -am "msg" | git town append <name>(然后提交) | gh stack add -Am "msg" |
| 修改最新提交并重新变基子分支 | gt modify -a | 编辑,然后运行 git town sync --stack | (编辑,然后运行 gh stack push) |
| 新建提交并重新变基子分支 | gt modify -cam "msg" | 提交,然后运行 git town sync --stack | (提交,然后运行 gh stack push) |
| 查看堆栈 | gt log short(gt ls) | git town branch | gh stack view(-s 表示简洁输出) |
| 拉取 trunk 并重新变基 | gt sync | git town sync --stack | gh stack sync |
| 仅级联重新变基 | gt restack | git town sync --stack --no-push | gh stack rebase |
| 提交 / 更新 PR | gt submit --stack(gt ss) | git town propose --stack | gh stack submit |
| 接管普通 Git 分支 | gt track(随时可用) | git town set-parent(随时可用) | gh stack init --adopt (仅初始化时可用) |
| 在堆栈中上移 / 下移 | gt up / gt down | git town switch(选择器) | gh stack up / gh stack down |
| 冲突后继续 | gt continue | git town continue | gh stack rebase --continue |
| 中止 / 跳过暂停的操作 | gt abort | git town skip / git town undo | gh stack rebase --abort |
| 将现有 PR 作为堆栈打开 | 不适用 | 不适用(设置父分支,然后运行 propose --stack) | gh stack link <PRs...> |
不确定标志的用法时,务必查阅各工具的参考文档,不要凭记忆操作——这三个 CLI 的行为会随版本变化。
规则(适用于这三种工具)
- 不要在堆栈中途使用
git rebase。 使用工具的 sync / restack / modify 命令,确保子分支始终正确指向父分支。 - 不要在堆栈中对单个分支执行
git push。 使用工具的 submit / push 命令——直接 push 会跳过父分支目标关联,并导致堆栈其余部分过时。 - 明确暂存文件。 这三种工具都像
git commit一样,遵循已暂存的文件集。按名称暂存;避免使用git add -A。 - 每个分支只处理一个关注点。 这正是使用堆栈的意义——让每个 PR 都能单独审查。
- rebase 冲突后,使用工具的
continue/abort命令,切勿直接使用git rebase --continue/--abort——否则工具的元数据不会更新。
交接
- 暂存和编写提交消息 →
/commit - PR 审查、CI 检查、合并、评论 →
/gh - pre-commit 钩子报错 →
/prek
何时阅读参考文档
references/gt.md— 完整的gt命令集(create / modify / sync / submit / track / log)、安装和身份验证、restack 操作指南、冲突恢复、 单体仓库 / 多主干注意事项。检测结果为gt时阅读。references/git-town.md— 完整的git town命令集(hack / append / sync / propose / set-parent / ship)、安装和 Forge 身份验证、冲突恢复、 配置键、压缩合并的注意事项。检测结果为git town时阅读。references/gh-stack.md— 完整的gh stack命令集、安装和候补名单、 退出代码、冲突恢复,以及与gt的差异。检测结果为gh stack时阅读。