# 堆积拉取请求

堆栈拉取请求如何运行 GitHub的规则和要求。

> \[!NOTE] 此功能以公共预览版提供，可能会发生更改。

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

堆栈中的每个拉取请求都会根据 **堆栈的基** 数（通常 `main` ）的规则进行评估，而不管它直接面向哪个分支。 这意味着，中堆栈拉取请求与底部拉取请求具有相同的标准。

> \[!NOTE]
>
> * 堆积拉取请求要求所有分支都位于同一存储库中。 不支持跨分支堆栈。
> * 不支持堆叠拉取请求 GitHub Desktop。

## 堆积拉取请求可用性

该 `gh stack`GitHub CLI 扩展处理本地开发工作流。 它按正确的依赖项顺序创建和跟踪分支，使分支保持基数，推送分支，创建和链接拉取请求，并在层之间导航。

GitHub CLI 不是必需的。 基础 Git 操作是标准的，你可以改为从 GitHub 网站创建堆栈。

如果使用 Jujutsu 或 Sapling 等其他工具来管理和推送本地分支，仍 GitHub CLI 可使用或 GitHub 网站从这些分支打开拉取请求堆栈。 请参阅“[将其他工具与堆积拉取请求配合使用](/zh/pull-requests/reference/use-other-tools-with-stacked-pull-requests)”。

## 堆积拉取请求的中继

堆栈的 **中继** 是底部拉取请求的基分支。 堆栈中的所有其他拉取请求都基于它构建。 中继默认为存储库的默认分支，例如 `main`，可以是任何分支，例如发布分支或长期功能分支。

设置中继：

* **发件人 GitHub CLI** 将 `--base BRANCH` 选项传递给 `gh stack init` 命令（例如， `gh stack init --base release auth-layer`）。
* **GitHub从网站**根据要作为中继的任何分支创建底部拉取请求。 堆栈的其余部分构建在堆栈的顶部。

分支保护规则、所需的检查和 CI 均根据堆栈目标的任何中继进行评估，而不仅仅是针对默认分支。

## 分支保护和所需检查

以下是所有计算结果，就像每个拉取请求面向堆栈基，而不是它正下方的分支：

| 规则         | 评估方式                                            |
| ---------- | ----------------------------------------------- |
| 必要的审查      | 根据堆栈基数计算。                                       |
| 必需状态检查     | 根据堆栈基数计算。                                       |
| CODEOWNERS | 从堆栈基计算。 对 `CODEOWNERS` 较低拉取请求的更改，但不会影响其上方的拉取请求。 |
| 代码扫描工作流    | 根据堆栈基数计算。                                       |

## GitHub Actions

GitHub 操作工作流会触发，就像堆栈中的每个拉取请求都面向堆栈的基础一样。 配置为针对`pull_request`堆栈**中的每个**拉取请求（而不仅仅是底部请求）运行的事件`main`上运行的工作流，因此不需要任何工作流更改。

堆栈元数据（如堆栈的基分支）可通过 `github.event.pull_request.stack`工作流表达式使用。 仅当拉取请求属于堆栈时，此属性才存在。

有关用于减少冗余 CI 使用的完整元数据字段和模式集，请参阅 [优化堆积拉取请求的 CI](/zh/pull-requests/how-tos/merge-and-close-pull-requests/optimizing-ci-for-stacked-pull-requests)。

## 合并要求

在堆栈中的拉取请求可以合并之前，以下所有内容都必须为 true：

* 拉取请求满足堆栈基础的每个分支保护要求，包括所需的评审、所需的状态检查和 CODEOWNER 审批。
* 堆栈**中其下方的所有拉取请求**也满足这些要求。
* 堆栈在其分支之间具有 **完全线性历史记录** 。

例如，在堆栈 `main ← PR1 ← PR2 ← PR3`中，合并 PR #3 需要 PR #1 和 PR #2 才能通过检查、具有所需的评审并满足所有分支保护规则。

## 合并方法

堆栈支持所有三种合并方法。 在每个情况下，拉取请求以单个原子操作的形式登陆：

* **合并提交** 为要合并的整个拉取请求组创建一个合并提交，从而保留每个拉取请求的完整提交历史记录。
* **Squash** 为每个拉取请求创建一个干净、已压缩的提交。 合并 `n` 拉取请求会在 `n` 基分支上创建已压缩的提交。
* **将** 每个拉取请求中的提交重播到基分支，创建线性历史记录而不进行合并提交。

## 通过合并队列合并

堆栈完全支持合并队列。 堆栈中的所有拉取请求都按正确的顺序添加到队列中。 如果从队列中删除或弹出拉取请求，也会删除堆栈中其上方的所有拉取请求。

> \[!NOTE]
> 为了将堆栈放在一起，合并队列允许合并组超过其配置的最大大小高达 50%。 如果堆栈太大而无法容纳在该缓冲区中，它将自动拆分为连续合并组。

## 线性历史记录

堆栈中每个分支之间的完全线性历史记录是合并的严格要求。 当更改推送到下分支或中继向前移动时，堆栈可能会丢失其线性历史记录。

若要还原线性历史记录，请运行级联 rebase：

* <c0>在 CLI 中</c0> 运行 <c1 />，然后使用 < a0/a0> 进行 <c2 />推送。
* **GitHub在网站**中，单击合并框中的 **“存储库堆栈**”以触发服务器端级联 rebase。

有关说明，请参阅“[管理堆积拉取请求](/zh/pull-requests/how-tos/create-pull-requests/managing-stacked-pull-requests#rebasing-your-stack)”。

## 延伸阅读

* [向组织推出堆积拉取请求](/zh/pull-requests/tutorials/roll-out-stacked-prs)