Skip to main content
Skip to content

堆叠式拉取请求

关于堆栈拉取请求如何工作及其规则和要求 GitHub

堆栈是同一存储库中的一系列拉取请求,每个拉取请求都面向其下方的拉取请求的分支,形成位于单个分支(通常是主分支)上的有序链。 获取一组较小的拉取请求,而不是一个大型拉取请求。 由于每个拉取请求都有自己的重点差异,因此团队成员可以独立评审和批准每个层。

堆栈中的每个拉取请求都会根据 堆栈的基础分支(通常为 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。

有关说明,请参阅“管理堆叠式拉取请求”。

延伸阅读