Skip to main content

关于 GitHub 上的合并方法

您可以允许能够推送到仓库的贡献者使用不同的合并选项在 GitHub.com 上合并其推送请求,或者对所有仓库的拉取请求实施特定的合并方法。

您可以在 GitHub.com 上配置拉取请求合并选项,以满足您的工作流程需要和用于管理 Git 历史记录的首选项。 更多信息请参阅“配置拉取请求合并”。 您可以只对仓库启用所需的方法,以实施一种合并方法,如提交压缩或变基。

注意:使用合并队列时,您将无法再选择合并方法,因为这由队列控制。 有关合并队列的信息,请参阅“管理合并队列”。

在 GitHub.com 上的拉请求上中单击默认的 Merge pull request(合并拉请求)选项时,来自功能分支的所有提交都会在合并提交中添加到基础分支。 拉取请求使用 --no-ff 选项合并。

要合并拉取请求,必须在仓库中拥有写入权限

standard-merge-commit-diagram

默认合并方法创建合并提交。 通过强制实施线性提交历史记录,可以防止任何人将合并提交推送到受保护分支。 更多信息请参阅“关于受保护分支”。

压缩合并提交

对 GitHub.com 上的拉取请求选择 Squash and merge(压缩并合并)选项时,拉取请求的提交会压缩为单一提交。 不是从主题分支查看所有贡献者的个别提交,而是所有提交合并成一个提交并合并到默认分支。 压缩了提交的拉取请求使用快进选项合并。

要压缩并合并拉取请求,必须在仓库中拥有写入权限,并且仓库必须允许压缩合并

commit-squashing-diagram

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

在启用压缩提交之前,请考虑以下缺点:

  • 您会丢失关于最初何时执行了特定更改以及是谁进行了压缩提交的信息。
  • 如果在压缩与合并后继续操作拉取请求的头部分支,然后在相同分支之间创建新的拉取请求,您先前被压缩与合并的提交将列于新的拉取请求中。 可能还有必须在每个连续的拉取请求中反复解决的冲突。 更多信息请参阅“关于拉取请求合并”。
  • 有些使用 "SHA" 或“哈希”ID 的 Git 命令可能更难使用,因为原始提交的 SHA ID 已经丢失。 例如,使用 git rerere 可能不像以前一样有效。

更多信息请参阅“为拉取请求配置提交压缩”。

变基和合并提交

在 GitHub.com 上的拉取请求中选择 Rebase and merge(变基并合并)选项时,来自主题分支(或头部分支)的所有提交都会单独添加到基础分支,而无需合并提交。 这样,通过维护线性项目历史记录,变基和合并行为类似于快进合并。 但是,变基可以通过使用新提交在基本分支上重写提交历史记录来实现此目的。

GitHub 上的变基和合并行为与 git rebase 略有偏差。 GitHub 上的变基和合并始终会更新提交者信息并创建新的提交 SHA,而 GitHub 外部的 git rebase 在提交原型上发生变基时不改变提交者信息。 有关 git rebase 的更多信息,请参阅 Git 文档中的 git-rebase

要变基并合并拉取请求,必须在仓库中拥有写入权限,并且仓库必须允许变基合并

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

在启用提交变基之前,请考虑以下缺点:

  • 仓库贡献者可能必须在命令行上变基,解决任何冲突,并且将其更改推送到拉取请求的主题分支(或删除头部分支),然后才可在 GitHub.com 上使用 Rebase and merge(变基和合并) 选项。 强制推送必须谨慎执行,以免贡献者覆盖别人在其工作基础上所做的工作。 要详细了解何时在 GitHub.com 上禁用 Rebase and merge(变基和合并)选项以及重新启用它的工作流程,请参阅“关于拉取请求合并”。

  • When using the Rebase and Merge option on a pull request, it's important to note that the commits in the head branch are added to the base branch without commit signature verification. When you use this option, GitHub creates a modified commit, using the data and content of the original commit. This means that GitHub didn't truly create this commit, and can't therefore sign it as a generic system user. GitHub doesn't have access to the committer's private signing keys, so it can't sign the commit on the user's behalf.

    A workaround for this is to rebase and merge locally, and then push the changes to the pull request's base branch.

更多信息请参阅“为拉取请求配置提交变基”。