合并策略和 Squash 合并

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020

完成 拉取请求时,通常会 main将主题分支合并到默认分支中。 此合并将主题分支的提交添加到主分支,并创建合并提交以协调默认分支和主题分支之间的任何冲突。 拉取请求中的注释和讨论为主题分支中所做的更改提供了更多上下文。

从拉取请求中常规合并的示例。

分支(或其他默认分支)上的main历史记录不遵循直线,因为相关的主题分支历史记录。 随着项目的增长,同时处理的主题分支数量会增加,使得默认分支历史记录越来越难遵循。

默认分支是每个主题分支历史记录的准确表示形式,但很难用于回答有关项目开发的广泛问题。

先决条件

类别 要求
项目访问权限 项目的成员。
权限 - 查看专用项目中的代码:至少 是基本 访问权限。
- 克隆或参与专用项目中的代码: 参与者 安全组的成员或项目中的相应权限。
- 设置分支或存储库权限: 管理 分支或存储库的权限。
- 更改默认分支: 编辑存储库的策略 权限。
- 导入存储库: 项目管理员 安全组的成员或 Git 项目级 “创建存储库 ”权限设置为 “允许”。 有关详细信息,请参阅 “设置 Git 存储库权限”。
Services 已启用存储库
工具 可选。 使用 az repos 命令: Azure DevOps CLI

注释

在公共项目中,具有 利益干系人 访问权限的用户具有对 Azure Repos 的完全访问权限,包括查看、克隆和参与代码。

类别 要求
项目访问权限 项目的成员。
权限 - 查看代码:至少 基本 访问权限。
- 克隆或参与代码: 参与者 安全组的成员或项目中的相应权限。
Services 已启用存储库

Squash 合并

Squash 合并是一个合并选项,可用于在完成拉取请求时压缩主题分支的 Git 历史记录。 squash merge 将主题分支上的每个提交添加到默认分支的历史记录中,而不是将所有文件更改添加到默认分支上的单个新提交。 Squash 合并提交没有对主题分支的引用。 它生成一 个新的提交 ,其中包含主题分支中的所有更改。 建议删除主题分支以防止出现任何混淆。

Azure Repos 中的拉取请求中的 squash 合并关系图。

考虑此问题的一种简单方法是,squash merge 仅提供文件更改,常规合并提供文件更改和提交历史记录。

壁球合并有何帮助?

Squash 合并使默认分支历史记录保持干净且易于遵循,而无需对团队进行任何工作流更改。 主题分支的参与者在主题分支中的工作方式,默认分支使用壁球合并来保留线性历史记录。 使用壁球合并更新的 main 分支的提交历史记录为每个合并分支都有一个提交。 可以逐步完成此历史记录,以准确了解工作完成时间。

壁球合并时的注意事项

Squash 合并会压缩默认分支中更改的历史记录,因此请务必与团队协作,确定何时将合并与保留主题分支的完整提交历史记录。 当壁球合并时,最好删除源分支。 删除源分支可防止混淆,因为主题分支本身没有将其合并到默认分支中的提交。

使用 squash merge 完成拉取请求

在 Azure Repos 中完成拉取请求时,可以选择对合并进行挤压。

在“完成拉取请求”对话框中的“合并类型”下选择 Squash 提交,以将主题分支合并。

在 Azure Repos 中使用 squash 合并关闭拉取请求的屏幕截图。

多个合并基

拉取请求中的 “文件 ”选项卡通过三方比较检测差异。 该算法将考虑目标分支中的最后一个提交、源分支中的最后一个提交及其 通用合并基(例如,最佳常见上级)。 该算法是检测更改的快速、经济高效且可靠的方法。 遗憾的是,在某些情况下,存在多个真正的基础。 在大多数情况下,这种情况很少见,但在具有许多活动用户的大型存储库中,这很常见。 可以手动检查分支之间的多个合并基是否存在。 为此,请运行 git merge-base --all feature master 命令。 Azure DevOps 检测到每个 PR 存在多个合并基。 检测到这些内容后,Azure DevOps 会显示消息“检测到多个合并基。 PR 显示的提交列表可能不完整。 虽然 Azure DevOps 正在运行多个合并基的检测,但它不会检查潜在的合并基是否已合并。 此类检查由 git merge-base. 这就是为什么即使只报告一个合并基, git merge-base Azure DevOps 也会显示消息。

注释

如果在 PR 评审期间丢失了更改,请确保多个合并基不是根本原因。

Azure DevOps 将以下示例方案检测为多个基,其中合并基数由第一个和二个数字指示:

  • 不同分支之间的交叉合并(也称为交叉)(由 Azure DevOps 报告)git merge-base
---1---o---A
    \ /
     X
    / \
---2---o---o---B
  • 将一个分支合并到另一个分支(由 Azure DevOps 报告,但不能通过 git merge-base 它来消除合并基 2)
---1---o---o---o---A
    \         /
     \-------2
      \       \
       \---o---o---o---B
  • 处理主分支的后遗体会还原,例如,修改合并提交
*   42bb2d2 (HEAD, A) Amended merge commit
|\  
| | *   67c9bb8 (other) Merge branch 'A' into B
| | |\  
| |/ /  
|/| /   
| |/    
| * fa78e32 add second commit
* | 15845c9 add first commit
|/  
* 6a52130 add init
  • 主动重复使用功能分支
  • 具有还原、樱桃选取和合并的其他非预期作和卷积作

多个合并基检测是安全意识的一部分。 如果有多个合并基,用户界面的文件差异算法可能无法正确检测文件更改,具体取决于它选择的合并基。 如果拉取请求中的文件在合并基之间具有不同的版本,则会发生多个合并基警告。

有关更多详细信息,请查看官方 git 文档

从多个基地合并的潜在安全风险

  • 恶意用户可能会滥用 UI 算法来提交 PR 中不存在的恶意更改。
  • 如果 PR 中建议的更改已在目标分支中,它们将显示在“ 文件 ”选项卡中,但它们可能不会触发映射到文件夹更改的分支策略。
  • PR 中可能不存在对来自多个合并基的相同文件的两组更改。 这种情况可能会造成危险的逻辑差距。

如何解决多个合并基问题

有多个合并基并不一定不好,但你应该仔细检查一切是否正常。 若要删除多个合并基,请将分支绑定到单个公共上级,方法是将分支重新放在目标上,或将目标合并到分支中。 这些作会消除警告消息,并帮助检查实际更改是否正常。

一种方法是在重新设置或合并之前软重置和存储进度。 然后,可以创建新的分支或重新设置空分支,并从明确点应用更改。 如果更改已存在,此过程可能需要强制推送到远程。

如何避免多个合并基问题

下面是避免多个合并基问题的一般提示:

  • 准备拉取请求时,请从主分支或发布分支的最新版本创建功能分支。
  • 除非需要,否则请避免创建不直接源自存储库的稳定分支。

如果多个合并基问题再次出现,该怎么办

在具有许多活动参与者的大型存储库中,此问题尤其不方便。 即使通过合并删除多个基数,这种情况也可能再次出现。 如果有人关闭了长期拉取请求,则可以重新创建这种情况。 即使生成策略和测试正在运行,也无需完成拉取请求。 重置和启动新分支可能会有所帮助。 如果未更改任何更改,则即使情况重复,更改也可能很清楚。

后续步骤