Welcome to mirror list, hosted at ThFree Co, Russian Federation.

index.md « methods « merge_requests « project « user « doc - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 249a98f1779058f98b3f2d5bb1c17789582c44d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
---
stage: Create
group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
type: reference, concepts
---

# Merge methods **(FREE)**

The merge method you select for your project determines how the changes in your
merge requests are merged into an existing branch.

The examples on this page assume a `main` branch with commits A, C, and E, and a
`feature` branch with commits B and D:

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

## Configure a project's merge method

1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. Select your desired **Merge method** from these options:
   - Merge commit
   - Merge commit with semi-linear history
   - Fast-forward merge
1. In **Squash commits when merging**, select the default behavior for handling commits:
   - **Do not allow**: Squashing is never performed, and the user cannot change the behavior.
   - **Allow**: Squashing is off by default, but the user can change the behavior.
   - **Encourage**: Squashing is on by default, but the user can change the behavior.
   - **Require**: Squashing is always performed, and the user cannot change the behavior.
1. Select **Save changes**.

## Merge commit

By default, GitLab creates a merge commit when a branch is merged into `main`.
A separate merge commit is always created, regardless of whether or not commits
are [squashed when merging](../squash_and_merge.md). This strategy can result
in both a squash commit and a merge commit being added to your `main` branch.

These diagrams show how the `feature` branch merges into `main` if you use the
**Merge commit** strategy. They are equivalent to the command `git merge --no-ff <feature>`,
and selecting `Merge commit` as the **Merge method** in the GitLab UI:

The merge strategy:

```mermaid
%%{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
```

After a feature branch is merged with the **Merge commit** method, your `main` branch
looks like this:

```mermaid
%%{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"
```

In comparison, a **squash merge** constructs a squash commit, a virtual copy of all commits
from the `feature` branch. The original commits (B and D) remain unchanged
on the `feature` branch, and the squash commit is placed on the `main` branch:

```mermaid
%%{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
```

The squash merge graph is equivalent to these settings in the GitLab UI:

- **Merge method**: Merge commit.
- **Squash commits when merging** should be set to either:
  - Require.
  - Either Allow or Encourage, and squashing must be selected on the merge request.

The squash merge graph is also equivalent to these commands:

  ```shell
  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
  ```

## Merge commit with semi-linear history

A merge commit is created for every merge, but the branch is only merged if
a fast-forward merge is possible. This ensures that if the merge request build
succeeded, the target branch build also succeeds after the merge. An example
commit graph generated using this merge method:

```mermaid
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
```

When you visit the merge request page with `Merge commit with semi-linear history`
method selected, you can accept it **only if a fast-forward merge is possible**.
When a fast-forward merge is not possible, the user is given the option to rebase, see
[Rebasing in (semi-)linear merge methods](#rebasing-in-semi-linear-merge-methods).

This method is equivalent to the same Git commands as in the **Merge commit** method. However,
if your source branch is based on an out-of-date version of the target branch (such as `main`),
you must rebase your source branch.
This merge method creates a cleaner-looking history, while still enabling you to
see where every branch began and was merged.

## Fast-forward merge

Sometimes, a workflow policy might mandate a clean commit history without
merge commits. In such cases, the fast-forward merge is appropriate. With
fast-forward merge requests, you can retain a linear Git history and a way
to accept merge requests without creating merge commits. An example commit graph
generated using this merge method:

```mermaid
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"
```

This method is equivalent to `git merge --ff <source-branch>` for regular merges, and to
`git merge --squash <source-branch>` for squash merges.

When the fast-forward merge
([`--ff-only`](https://git-scm.com/docs/git-merge#git-merge---ff-only)) setting
is enabled, no merge commits are created and all merges are fast-forwarded.
Merging is only allowed if the branch can be fast-forwarded.
When a fast-forward merge is not possible, the user is given the option to rebase, see
[Rebasing in (semi-)linear merge methods](#rebasing-in-semi-linear-merge-methods).

NOTE:
Projects using the fast-forward merge strategy can't filter merge requests
[by deployment date](../index.md#filter-merge-requests-by-environment-or-deployment-date),
because no merge commit is created.

When you visit the merge request page with `Fast-forward merge`
method selected, you can accept it **only if a fast-forward merge is possible**.

![Fast-forward merge request](../img/ff_merge_mr.png)

## Rebasing in (semi-)linear merge methods

In these merge methods, you can merge only when your source branch is up-to-date with the target branch:

- Merge commit with semi-linear history.
- Fast-forward merge.

If a fast-forward merge is not possible but a conflict-free rebase is possible,
GitLab provides:

- The [`/rebase` quick action](../../../../topics/git/git_rebase.md#rebase-from-the-gitlab-ui).
- The option to select **Rebase** in the user interface.

You must rebase the source branch locally before a fast-forward merge if both
conditions are true:

- The target branch is ahead of the source branch.
- A conflict-free rebase is not possible.

![Fast forward merge rebase locally](../img/ff_merge_rebase_locally.png)

Rebasing may be required before squashing, even though squashing can itself be
considered equivalent to rebasing.

### Rebase without CI/CD pipeline

> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118825) in GitLab 14.7 [with a flag](../../../../administration/feature_flags.md) named `rebase_without_ci_ui`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350262) in GitLab 15.3. Feature flag `rebase_without_ci_ui` removed.

To rebase a merge request's branch without triggering a CI/CD pipeline, select
**Rebase without pipeline** from the merge request reports section.
This option is available when fast-forward merge is not possible but a conflict-free
rebase is possible.

Rebasing without a CI/CD pipeline saves resources in projects with a semi-linear
workflow that requires frequent rebases.

## Related topics

- [Commits history](../commits.md)
- [Squash and merge](../squash_and_merge.md)