合并方法

您为项目选择的合并方法决定了合并请求中的更改如何合并到现有分支中。

本文的示例假设有一个包含提交 A、C 和 E 的 main 分支,以及一个包含提交 B 和 D 的 feature 分支:

gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E"

配置项目的合并方法

  1. 在左侧边栏中,选择 搜索或转到 并找到您的项目。
  2. 选择 设置 > 合并请求
  3. 从以下选项中选择您所需的 合并方法
    • 合并提交
    • 带有半线性历史的合并提交
    • 快进式(Fast-forward)合并
  4. 合并时压缩提交 中,选择处理提交的默认行为:
    • 不允许:从不执行压缩,用户无法更改行为。
    • 允许:默认情况下压缩处于关闭状态,用户可以更改行为。
    • 鼓励:默认情况下压缩处于启用状态,用户可以更改行为。
    • 必须:始终执行压缩,用户无法更改行为。
  5. 选择 保存更改

合并提交

默认情况下,当分支合并到 main 时,极狐GitLab 会创建合并提交。 无论提交合并时是否被压缩,都会创建单独的合并提交。此方法可能会导致压缩提交和合并提交都添加到您的 main 分支中。

下图显示了如果您使用合并提交方法,feature 分支如何合并到 main 中,相当于使用命令 git merge --no-ff <feature>,并在 UI 中选择 Merge commit 作为合并方法

合并方法:

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E" merge feature

使用合并提交方法合并功能分支后,您的 main 分支如下所示:

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" commit id: "C" commit id: "E" commit id: "squash commit" commit id: "merge commit"

相比之下,压缩合并生成一个压缩提交,即来自 feature 分支的所有提交的虚拟拷贝。原始提交(B 和 D)在 feature 分支上保持不变,而压缩提交被放置在 main 分支上:

%%{init: { 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id:"A" branch feature checkout main commit id:"C" checkout feature commit id:"B" commit id:"D" checkout main commit id:"E" commit id:"squash commit" type: HIGHLIGHT

压缩合并相当于在 UI 中进行以下设置:

  • 合并方法:合并提交。
  • 合并时压缩提交 应设置为:
    • 必须
    • 在合并请求中选择 允许鼓励压缩

压缩合并方法相当于使用以下命令:

  git checkout `git merge-base feature main`
  git merge --squash <feature>
  SOURCE_SHA=`git rev-parse HEAD`
  git checkout <main>
  git merge --no-ff $SOURCE_SHA

带有半线性历史记录的合并提交

每次合并都会创建一个合并提交,但只有在可以进行快进合并时才会合并分支,这确保了如果合并请求构建成功,则目标分支构建在合并后也成功。使用此合并方法生成的示例提交图:

gitGraph commit id: "Init" branch mr-branch-1 commit commit checkout main merge mr-branch-1 branch mr-branch-2 commit commit checkout main merge mr-branch-2 commit branch squash-mr commit id: "Squashed commits" checkout main merge squash-mr

当您访问选择了 Merge commit with semi-linear history 方法的合并请求页面时,仅当可以进行快进合并时,您可以接受它。 当无法进行快进合并时,用户可以选择变基,请参阅(半)线性合并方法中的变基

此方法等效于合并提交方法中的相同 Git 命令。但是,如果您的源分支基于目标分支的过时版本(例如 main),则必须重新定位源分支。 这种合并方法创建了一个看起来更清晰的历史记录,同时仍然使您能够查看每个分支的开始和合并位置。

快进式合并

有时,工作流程规则可能会要求一个干净的提交历史,而不需要合并提交。在这种情况下,快进式合并是合适的。使用快进式合并请求,您可以保留线性 Git 历史记录,以及在不创建合并提交的情况下接受合并请求的方式。使用此合并方法生成的示例提交图:

gitGraph commit id: "Init" commit id: "Merge mr-branch-1" commit id: "Merge mr-branch-2" commit id: "Commit on main" commit id: "Merge squash-mr"

此方法等效于常规合并的 git merge --ff <source-branch>,以及压缩合并的 git merge --squash <source-branch>

当快进式合并(--ff-only)设置已启用,不创建合并提交并且所有合并都是快进的,这意味着只有当分支可以快进时才允许合并。 当无法进行快进合并时,用户可以选择变基,请参阅(半)线性合并方法中变基

note使用快进式合并策略的项目无法按部署日期过滤合并请求,因为没有创建合并提交。

当您访问选择了 Fast-forward merge 方法的合并请求页面时,仅当可以进行快进合并时,您可以接受它。

Fast-forward merge request

(半)线性合并方法中的变基

在以下合并方法中,您只能在源分支与目标分支保持同步时进行合并:

  • 带有半线性历史记录的合并提交。
  • 快进式合并。

如果无法进行快进式合并但可以进行无冲突的变基,系统为您提供:

如果以下两个条件都成立,则必须在快进合并之前在本地对源分支进行变基:

  • 目标分支位于源分支之前。
  • 无法进行无冲突变基。

Fast forward merge rebase locally

在压缩之前可能需要重新变基,即使压缩本身可以被认为等同于重新变基。

没有 CI/CD 流水线的变基

  • 引入于 14.7 版本,功能标志为 rebase_without_ci_ui。默认禁用。
  • 一般可用于 15.3 版本,功能标志 rebase_without_ci_ui 已删除。

要在不触发 CI/CD 流水线的情况下重新调整合并请求的分支,请从合并请求报告部分选择 没有流水线的变基。 当无法进行快进合并但可以进行无冲突的变基时,此选项可用。

在没有 CI/CD 流水线的情况下进行变基,可以在需要频繁变基的半线性工作流程的项目中节省资源。

相关主题