堆栈是同一存储库中的一系列拉取请求,每个拉取请求都面向其下方的拉取请求的分支,形成位于单个分支(通常是主分支)上的有序链。 获取一组较小的拉取请求,而不是一个大型拉取请求。 由于每个拉取请求都有自己的重点差异,因此团队成员可以独立评审和批准每个层。
堆栈中的每个拉取请求都会根据 堆栈的基础分支(通常为 main)的规则进行评估,而不管它直接面向哪个分支。 这意味着,堆栈中间的 pull request 与底部 pull request 的标准相同。
注意
- 堆积拉取请求要求所有分支都位于同一存储库中。 不支持跨分支堆栈。
- 不支持堆叠拉取请求 GitHub Desktop。
堆叠拉取请求可用性
该 gh stackGitHub CLI 扩展支持本地开发工作流。 它按正确的依赖项顺序创建和跟踪分支,使分支保持变基状态,推送分支,创建和链接拉取请求,并在层之间导航。
GitHub CLI 不是必需的。 底层 Git 操作是标准的,你也可以改为从 GitHub 网站创建 Stack。
如果使用 Jujutsu 或 Sapling 等其他工具来管理和推送本地分支,仍可使用 GitHub CLI 或 GitHub 网站从这些分支创建一组拉取请求。 请参阅“将其他工具与堆叠式拉取请求配合使用”。
堆叠式拉取请求(PR)的主干
堆栈的 主干 是底部拉取请求的基分支。 堆栈中的其余每个拉取请求都基于它构建。 主干默认为存储库的默认分支,例如 main,但它也可以是任何分支,例如发布分支或长期存在的功能分支。
设置中继:
- 从 GitHub CLI 开始,将
--base BRANCH选项传递给gh stack init命令(例如gh stack init --base release auth-layer)。 - 从GitHub网站创建底部的拉取请求,并针对你想作为主干的任意分支。 堆栈的其余部分建立在其基础上。
分支保护规则、所需的检查和 CI 均根据堆栈所针对的任何主干进行评估,而不仅仅是针对默认分支。
分支保护和所需检查
以下是所有评估结果,都是按每个拉取请求以堆栈基为目标,而不是它正下方的分支来进行评估的:
| 规则 | 评估方式 |
|---|---|
| 必要的审查 | 根据栈基址进行评估。 |
| 必需状态检查 | 根据堆栈基址进行评估。 |
| CODEOWNERS | 从栈基址求值。 对较低层级的拉取请求中 CODEOWNERS 的更改会产生影响,但不会影响其上方的拉取请求。 |
| 代码扫描工作流 | 相对于堆栈基址进行求值。 |
GitHub Actions
GitHub Actions 工作流会触发,就像堆栈中的每个拉取请求都以该堆栈的底部分支为目标一样。 配置为在针对main的pull_request事件上运行的工作流会对堆栈中的每个拉取请求运行,而不只是最底部的那个,因此不需要对工作流做任何更改。
堆栈元数据(如堆栈的基分支)可在工作流表达式中通过 github.event.pull_request.stack 使用。 仅当拉取请求属于堆栈时,此属性才存在。
有关用于减少冗余 CI 使用的完整元数据字段和模式集,请参阅 优化堆叠式 PR 的 CI。
变基
当可进行变基或需要变基时,合并框将通过显示 Rebase 堆栈 按钮来指示这一点。 例如,当对拉取请求的更改使堆栈变为非线性时,可能会发生这种情况。 当合并下面的拉取请求(PR)时,会自动进行变基,通常不需要手动变基。
当堆栈被变基时,可以期待以下各项:
- 重定提交栈将生成已签名的提交。
- 如果差异未更改,则对提交栈进行变基不会算作新的可评审提交。 在这种情况下,即使启用 在推送新提交时撤销过时的拉取请求批准 规则,批准也会被保留。
合并要求
在堆栈中的拉取请求可以合并之前,以下所有内容都必须为 true:
- 拉取请求满足堆栈基底的每个分支保护要求,包括所需的评审、所需的状态检查和 CODEOWNERS 批准。
- 该堆栈中位于其下方的所有拉取请求也满足这些要求。
- 堆栈在其分支之间具有 完全线性历史记录 。
例如,在堆栈 main ← PR1 ← PR2 ← PR3中,要合并 PR #3,还要求 PR #1 和 PR #2 也通过检查、获得所需的评审并满足所有分支保护规则。
注意
堆叠式拉取请求支持使用 绕过规则 进行合并,但只有最底部的拉取请求才能通过这种方式合并。 存在绕过规则时,不能合并整个堆栈。 请参阅“创建存储库的规则集”
合并方法
堆栈支持所有三种合并方法。 在每种情况下,拉取请求(PR)都会作为单个原子操作合并:
- 合并提交 为每个正在合并的拉取请求创建一个合并提交,并保留每个拉取请求的完整提交历史记录。
- Squash 为每个合并请求创建一个干净、已压缩的提交。 合并
n合并请求会在n基分支上创建压缩提交。 - 变基将每个拉取请求中的提交重放到基分支上,创建不含合并提交的线性历史记录。
通过合并队列合并
堆栈完全支持合并队列。 堆栈中的所有拉取请求都按正确的顺序添加到队列中。 如果从队列中删除或弹出拉取请求,也会删除堆栈中其上方的所有拉取请求。
注意
为了使变更栈保持在一起,合并队列允许合并组超过其配置的最大大小,高达 50%。 如果堆栈太大而无法容纳在该缓冲区中,它将自动作为单个单元放入下一个合并组。
线性历史
堆栈中各个分支形成的完全线性历史记录是进行合并的严格要求。 当更改推送到较低分支或主干向前移动时,堆叠可能会丢失其线性历史记录。
若要还原线性历史记录,请运行级联 rebase:
- 从 CLI — 运行 ,然后用 推送。
- 从GitHub网站中,单击合并框中的 “Rebase stack” 以触发服务器端级联 rebase。
有关说明,请参阅“管理堆叠式拉取请求”。