跳至主要内容

关于拉取请求合并

您可以通过保留功能分支中的所有提交、将所有提交压缩成单个提交或将单个提交从head分支重新定位到base分支来合并拉取请求

合并您的提交

当您在 GitHub.com 上的拉取请求中点击默认的合并拉取请求选项时,功能分支中的所有提交都会在合并提交中添加到基础分支。拉取请求使用--no-ff选项进行合并。

要合并拉取请求,您必须在存储库中具有写入权限

Diagram of a standard merge and commit flow, where commits from a feature branch and an additional merge commit are both added to main.

压缩并合并您的提交

当您在 GitHub.com 上的拉取请求中选择压缩并合并选项时,拉取请求的提交会被压缩成单个提交。您将不会看到贡献者从主题分支提交的所有单个提交,而是将这些提交合并成一个提交并合并到默认分支。使用压缩提交的拉取请求使用快进选项进行合并。

要压缩并合并拉取请求,您必须在存储库中具有写入权限,并且存储库必须允许压缩合并

Diagram of commit squashing, where multiple commits from a feature branch are combined into only one commit that is added to main.

您可以使用压缩并合并来在存储库中创建更简洁的 Git 历史记录。在功能分支上工作时,工作进度提交非常有用,但它们并不一定需要保留在 Git 历史记录中。如果您在合并到默认分支时将这些提交压缩成一个提交,则可以保留原始更改并保持清晰的 Git 历史记录。

压缩合并的合并消息

当您压缩并合并时,GitHub 会生成一个默认的提交消息,您可以对其进行编辑。根据仓库的配置和拉取请求中提交的数量(不包括合并提交),此消息可能包含拉取请求标题、拉取请求描述或有关提交的信息。

提交数量摘要描述
一个提交单个提交的提交消息标题,后跟拉取请求编号单个提交的提交消息正文
多个提交拉取请求标题,后跟拉取请求编号所有压缩提交的提交消息列表,按日期排序

拥有仓库维护者或管理员访问权限的人员可以配置其仓库的默认合并消息,以便所有压缩提交都使用拉取请求标题、拉取请求标题和提交详细信息,或拉取请求标题和描述。有关更多信息,请参阅“配置拉取请求的提交压缩”。

压缩并合并长期分支

如果您计划在拉取请求合并后继续在拉取请求的头部分支上工作,建议您不要压缩并合并拉取请求。

当您创建拉取请求时,GitHub 会识别头部分支和基础分支上最新的共同提交:共同祖先提交。当您压缩并合并拉取请求时,GitHub 会在基础分支上创建一个提交,其中包含您自共同祖先提交以来在头部分支上所做的所有更改。

由于此提交仅在基础分支上,不在头部分支上,因此两个分支的共同祖先保持不变。如果您继续在头部分支上工作,然后在两个分支之间创建新的拉取请求,则拉取请求将包含自共同祖先以来的所有提交,包括您在先前拉取请求中压缩并合并的提交。如果没有冲突,您可以安全地合并这些提交。但是,此工作流程会使合并冲突更有可能。如果您继续压缩并合并长期头部分支的拉取请求,则您将不得不重复解决相同的冲突。

变基并合并您的提交

当您在 GitHub.com 上的拉取请求中选择 **重新基线并合并** 选项时,主题分支(或头部分支)中的所有提交将单独添加到基线分支,而不会创建合并提交。这样,重新基线和合并的行为类似于 快进合并,通过保持线性项目历史记录。但是,重新基线通过在基线分支上用新提交重写提交历史记录来实现这一点。

GitHub 上的重新基线和合并行为与 git rebase 略有不同。GitHub 上的重新基线和合并将始终更新提交者信息并创建新的提交 SHA,而 GitHub 之外的 git rebase 在重新基线发生在祖先提交之上时不会更改提交者信息。有关 git rebase 的更多信息,请参阅 Git 文档中的 git-rebase

要重新基线并合并拉取请求,您必须在存储库中具有 写入权限,并且存储库必须 允许重新基线合并

有关 git rebase 的可视化表示,请参阅 Pro Git 书籍中的“Git 分支 - 重新基线”一章

当以下情况发生时,您无法在 GitHub.com 上自动重新基线并合并。

  • 拉取请求存在合并冲突。
  • 将基线分支中的提交重新基线到头部分支会导致冲突。
  • 重新基线提交被认为是“不安全的”,例如,当重新基线可以在没有合并冲突的情况下进行,但会产生与合并不同的结果时。

如果您仍然想重新基线提交,但无法在 GitHub.com 上自动重新基线并合并,则必须

  • 在命令行上将主题分支(或头部分支)本地重新基线到基线分支
  • 在命令行上解决任何合并冲突.
  • 将重新基线的提交强制推送到拉取请求的主题分支(或远程头部分支)。

任何具有存储库写入权限的人都可以使用 GitHub.com 上的重新基线和合并按钮 合并更改

间接合并

如果拉取请求的头部分支直接或间接合并到基线分支,则可以自动合并拉取请求。换句话说,如果头部分支的尖端提交从目标分支的尖端变得可达。例如

  • 分支main位于提交C
  • 分支feature已从main分支出来,目前位于提交D。该分支有一个指向main的拉取请求。
  • 分支feature_2feature分支出来,现在位于提交E。该分支也有一个指向main的拉取请求。

如果拉取请求E --> main首先被合并,拉取请求D --> main自动标记为已合并,因为feature中的所有提交现在都可以从main访问。将feature_2合并到main并将main推送到服务器的命令行将标记两个拉取请求为已合并。

间接合并只能在以下两种情况下发生:拉取请求的头部分支中的提交直接推送到存储库的默认分支,或者拉取请求的头部分支中的提交存在于另一个拉取请求中,并使用创建合并提交选项合并到存储库的默认分支。

如果包含另一个拉取请求的头部分支中存在的提交的拉取请求使用压缩合并变基合并选项合并,则将在基础分支上创建一个新的提交,另一个拉取请求将不会自动合并。

即使分支保护规则未满足,间接合并的拉取请求也会标记为已合并

进一步阅读