# 合并拉取请求

了解合并拉取请求的策略，包括合并提交、压缩合并和变基，以便有效地管理存储库的历史记录。

可以通过不同的方式合并拉取请求。 最佳策略取决于团队希望仓库历史记录呈现成什么样子，以及希望从拉取请求分支中保留多少细节。

| Strategy   | Result                        | 选择时间                             |
| ---------- | ----------------------------- | -------------------------------- |
| 合并提交       | 保留拉取请求分支中的每一次提交，并添加一个显式的合并点。  | 你的团队重视完整的历史记录，或者单个提交本身就有意义。      |
| Squash 并合并 | 将拉取请求中的所有提交合并到基分支上的单个提交中。     | 拉取请求应代表一个逻辑上的变更，尤其是在包含许多小型修复提交时。 |
| 变基和合并      | 对于线性历史记录，将每个提交添加到基分支，而无需合并提交。 | 你的团队希望保留线性历史，并且这些提交已经整理得很清晰。     |

## 合并你的提交

在拉取请求上单击默认的“合并拉取请求”选项\*\*\*\* 时，来自功能分支的所有提交都会在合并提交中添加到基础分支。 使用[ `--no-ff` 选项](https://git-scm.com/docs/git-merge#_fast_forward_merge)合并拉取请求。

若要合并拉取请求，必须在存储库中拥有[写入权限](/zh/enterprise-cloud@latest/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization)。

![标准合并和提交流的关系图，其中从功能分支提交和附加合并提交都添加到 main。](/assets/images/help/pull_requests/standard-merge-commit-diagram.png)

合并提交会保留拉取请求分支中的完整提交历史记录。 这样一来，就能更轻松地查看促成最终变更的每一次提交，包括评审修改和中间过程中的工作。 它还会在基本分支历史记录中创建显式合并点。

当你的团队重视完整的历史记录，或者拉取请求中的单个提交本身就具有意义时，请选择此策略。

## 压缩和合并提交

在拉取请求上选择“压缩并合并”\*\*\*\* 选项时，拉取请求的提交会压缩为单一提交。 不是从主题分支查看所有贡献者的个别提交，而是所有提交合并成一个提交并合并到默认分支。 使用[快进选项](https://git-scm.com/docs/git-merge#_fast_forward_merge)合并包含已压缩提交的拉取请求。

若要压缩并合并拉取请求，必须在存储库中具有[写入权限](/zh/enterprise-cloud@latest/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization)，并且存储库必须[允许压缩合并](/zh/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-squashing-for-pull-requests)。

![提交压缩关系图，其中功能分支中的多个提交合并为将添加到 main 的一个提交。](/assets/images/help/pull_requests/commit-squashing-diagram.png)

您可以使用压缩并合并在仓库中创建更简化的 Git 历史记录。 在功能分支上工作时，提交正在进行的工作会有帮助，但它们不一定必须留在 Git 历史记录中。 如果在合并到默认分支时将这些提交压缩为一个提交，更改将被整合，并生成清晰的 Git 历史记录。

压缩合并会将拉取请求中的所有提交压缩为目标分支上的一个提交。 这将保持默认分支历史记录简洁，并可以更轻松地稍后进行扫描。 代价是，拉取请求中的中间提交不会作为单独的提交保留在基础分支上。

当拉取请求对应一次逻辑上的变更时，可选择此策略，尤其是在该分支包含许多小的修正提交时。

### 合并按需压缩的消息

进行压缩合并时，GitHub 会生成一条可供您编辑的默认提交信息。 默认消息可以包括拉取请求标题、拉取请求说明或提交信息，具体取决于存储库设置和拉取请求中的提交次数。

维护人员和管理员可以为已压缩的提交配置默认消息。 请参阅“[为拉取请求配置提交压缩](/zh/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-squashing-for-pull-requests)”。

### 压缩合并长时间运行的分支

压缩合并最适合短生命周期的分支。 如果在压缩合并后继续在同一个头分支上工作，则后续的拉取请求可能会包含已经被压缩合并到基础分支中的提交。 这会使合并冲突的可能性更大，并可以强制你多次解决相同的冲突。

对于长时间运行的分支，请考虑在打开下一个拉取请求之前使用合并提交或重新分组分支。

## 对提交进行变基和合并

在拉取请求中选择**变基并合并**选项时，来自主题分支（或头部分支）的所有提交都会单独添加到基分支，而无需合并提交。 这样，通过维护线性项目历史记录，变基和合并行为类似于[快进合并](https://git-scm.com/docs/git-merge#_fast_forward_merge)。 但是，变基是通过在基分支上用新的提交重写提交历史记录来实现的。

在 GitHub 之外，GitHub 上的变基和合并行为与 `git rebase` 略有不同。 GitHub 上的变基和合并：

* 始终更新提交者信息并创建新的提交 SHA，而在上级提交的基础上发生变基时，`git rebase` 不会更改提交者信息。
* 删除以空开头的提交，例如使用 `git commit --allow-empty`创建的提交，而 `git rebase` 默认情况下保留最初为空的提交。

有关 `git rebase` 的详细信息，请参阅 Git 文档中的 [git-rebase](https://git-scm.com/docs/git-rebase)。

若要变基并合并拉取请求，必须在存储库中具有[写入权限](/zh/enterprise-cloud@latest/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization)，并且存储库必须[允许变基合并](/zh/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-rebasing-for-pull-requests)。

有关 `git rebase` 的可视化表示形式，请参阅 *《Pro Git》一书中的“Git 分支 - 变基”章节*。

Rebasing 会将每个提交从拉取请求分支添加到基分支，而无需创建合并提交。 这会生成线性历史记录，同时保留拉取请求中的单个提交。

当你的团队希望保留线性历史记录，且拉取请求中的提交已整理清楚时，请选择此策略。 如果 GitHub 无法安全地自动为拉取请求执行变基，您可以在本地进行变基，解决冲突，然后推送更新后的分支。 请参阅 [Resolving a merge conflict using the command line](/zh/enterprise-cloud@latest/pull-requests/how-tos/merge-and-close-pull-requests/resolving-a-merge-conflict-using-the-command-line) 和 [Merging a pull request](/zh/enterprise-cloud@latest/pull-requests/how-tos/merge-and-close-pull-requests/merging-a-pull-request)。

## 间接合并

如果某个拉取请求的头分支上的提交在该拉取请求之外已可从基分支到达，则该拉取请求可标记为已合并。 当同一提交通过另一个拉取请求合并或直接推送到默认分支时，可能会发生这种情况。

间接合并并不常见，但它们可能会影响自动化和分支保护预期。 即使该拉取请求未满足分支保护规则，被间接合并的拉取请求也会被标记为 `merged`。

## 延伸阅读

* [拉取请求](/zh/enterprise-cloud@latest/pull-requests/reference/pull-requests)
* [合并、关闭拉取请求](/zh/enterprise-cloud@latest/pull-requests/how-tos/merge-and-close-pull-requests)