合并方法
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
您为项目选择的合并方法决定了合并请求中的更改如何合并到现有分支。
本页面的示例假设有一个包含提交 A、C、E 的 main 分支,以及一个包含提交 B、D 的 feature 分支:
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: 合并示意图
accDescr: 一个包含两个分支上五个提交的 Git 图,将在本页面的其他图中展开说明。
commit id: "A"
branch feature
commit id: "B"
commit id: "D"
checkout main
commit id: "C"
commit id: "E"
配置项目的合并方法
- 在左侧边栏,选择 搜索或跳转至 并找到您的项目。
- 选择 设置 > 合并请求。
- 从以下选项中选择您想要的 合并方法:
- Merge commit(合并提交)
- Merge commit with semi-linear history(合并提交并保持半线性历史)
- Fast-forward merge(快进合并)
- 在 合并时压缩提交 中,选择处理提交的默认行为:
- 不允许:从不执行压缩,用户无法更改此行为。
- 允许:默认不压缩,但用户可以更改此行为。
- 鼓励:默认压缩,但用户可以更改此行为。
- 要求:始终执行压缩,用户无法更改此行为。
- 选择 保存更改。
合并提交
默认情况下,当分支合并到 main 时,GitLab 会创建一个合并提交。无论是否在合并时压缩提交,都会创建一个单独的合并提交。此策略可能导致压缩提交和合并提交都添加到您的 main 分支。
这些图表展示了如果您使用 合并提交 策略,feature 分支如何合并到 main。它们等同于命令 git merge --no-ff <feature>,以及在 GitLab UI 中选择 合并方法 为 合并提交:
-
使用 合并提交 方法合并功能分支后,您的
main分支如下所示:%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main', 'fontFamily': 'GitLab Sans'}} }%% gitGraph accTitle: 合并提交示意图 accDescr: 展示在 GitLab 中功能分支合并时如何创建合并提交的 Git 图。 commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E" merge feature -
相比之下,压缩合并会构建一个压缩提交,即
feature分支所有提交的虚拟副本。原始提交(B 和 D)在feature分支上保持不变,然后在main分支上创建一个合并提交来合并压缩后的分支:%%{init: { 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main', 'fontFamily': 'GitLab Sans'}} }%% gitGraph accTitle: 压缩合并示意图 accDescr: 展示压缩提交添加到主分支后仓库和分支结构的 Git 图。 commit id:"A" branch feature checkout main commit id:"C" checkout feature commit id:"B" commit id:"D" checkout main commit id:"E" branch "B+D" commit id: "B+D" checkout main merge "B+D"
压缩合并图等同于 GitLab UI 中的以下设置:
- 合并方法:合并提交。
- 合并时压缩提交 应设置为:
- 要求。
- 允许或鼓励,并且必须在合并请求中选择压缩。
压缩合并图也等同于以下命令:
git checkout `git merge-base feature main`
git merge --squash feature
git commit --no-edit
SOURCE_SHA=`git rev-parse HEAD`
git checkout main
git merge --no-ff $SOURCE_SHA合并提交并保持半线性历史
每次合并都会创建一个合并提交,但只有在可以进行快进合并时才会合并分支。这确保了如果合并请求构建成功,目标分支在合并后构建也会成功。使用此合并方法生成的示例提交图:
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: 合并提交示意图
accDescr: 展示分支使用合并提交合并时的提交流程。
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
当您访问合并请求页面并选择了 合并提交并保持半线性历史 方法时,只有在可以进行快进合并时才能接受它。当无法进行快进合并时,用户可以选择变基,请参阅 (半)线性合并方法中的变基。
此方法等同于 合并提交 方法中的相同 Git 命令。但是,如果您的源分支基于目标分支的过时版本(如 main),您必须变基您的源分支。此合并方法创建更简洁的历史记录,同时仍然让您能够看到每个分支的起始位置和合并位置。
快进合并
有时,工作流策略可能要求没有合并提交的清晰提交历史。在这种情况下,快进合并是合适的。使用快进合并请求,您可以保持线性的 Git 历史,并且无需创建合并提交即可接受合并请求。使用此合并方法生成的示例提交图:
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: 快进合并示意图
accDescr: 展示快进合并请求如何保持线性 Git 历史,但不添加合并提交。
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>后跟git commit。
当启用了快进合并 (--ff-only) 设置时,不会创建合并提交,所有合并都是快进的。只有在分支可以快进时才允许合并。当无法进行快进合并时,用户可以选择变基,请参阅 (半)线性合并方法中的变基。
当您访问合并请求页面并选择了 快进合并 方法时,只有在可以进行快进合并时才能接受它。
(半)线性合并方法中的变基
在这些合并方法中,只有当您的源分支与目标分支保持最新时才能合并:
- 合并提交并保持半线性历史。
- 快进合并。
如果无法进行快进合并但可以进行无冲突变基,GitLab 提供:
/rebase快速操作。- 用户界面中选择 变基 的选项。
如果以下两个条件都为真,您必须在本地变基源分支才能进行快进合并:
- 目标分支领先于源分支。
- 无法进行无冲突变基。
即使压缩本身可以被视为等同于变基,在压缩之前可能也需要变基。
无 CI/CD 管道的变基
要触发 CI/CD 管道来变基合并请求的分支,请在合并报告部分选择 无管道变基。
此选项:
- 在无法进行快进合并但可以进行无冲突变基时可用。
- 在启用 管道必须成功 选项时不可用。
在没有 CI/CD 管道的情况下进行变基,在需要频繁变基的半线性工作流项目中可以节省资源。