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

index.md « branches « repository « project « user « doc - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d6bcae573229361ca01d0ff821f5e1f9b865129a (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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
---
stage: Create
group: Source Code
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments"
---

# Branches **(FREE ALL)**

Branches are versions of a project's working tree. When you create a new
[project](../../index.md), GitLab creates a [default branch](default.md) (which
cannot be deleted) for your repository. Default branch settings can be configured
at the project, subgroup, group, or instance level.

As your project grows, your team creates more
branches, preferably by following [branch naming patterns](#prefix-branch-names-with-issue-numbers).
Each branch represents a set of changes, which allows development work to be done
in parallel. Development work in one branch does not affect another branch.

Branches are the foundation of development in a project:

1. To get started, create a branch and add commits to it.
1. When the work is ready for review, create a [merge request](../../merge_requests/index.md) to propose
   merging the changes in your branch. To streamline this process, you should follow
   [branch naming patterns](#prefix-branch-names-with-issue-numbers).
1. Preview changes in a branch with a [review app](../../../../ci/review_apps/index.md).
1. After the contents of your branch are merged, [delete the merged branch](#delete-merged-branches).

## Create branch

Prerequisites:

- You must have at least the Developer role for the project.

To create a new branch from the GitLab UI:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Branches**.
1. In the upper-right corner, select **New branch**.
1. Enter a **Branch name**.
1. In **Create from**, select the base of your branch: an existing branch, an existing
   tag, or a commit SHA.
1. Select **Create branch**.

### In a blank project

A [blank project](../../index.md#create-a-blank-project) does not contain a branch, but
you can add one.

Prerequisites:

- You must have at least the Developer role for the project.
- If you don't have the Maintainer or Owner role, the
  [default branch protection](../../../group/manage.md#change-the-default-branch-protection-of-a-group)
  must be set to `Partially protected` or `Not protected` for you to push a commit
  to the default branch.

To add a [default branch](default.md) to an empty project:

1. On the left sidebar, select **Search or go to** and find your project.
1. Scroll to **The repository for this project is empty** and select the type of
   file you want to add.
1. In the Web IDE, make any desired changes to this file, then select **Create commit**.
1. Enter a commit message, and select **Commit**.

GitLab creates a default branch and adds your file to it.

### From an issue

Prerequisites:

- You must have at least the Developer role for the project.

When viewing an issue, you can create an associated branch directly from that page.
Branches created this way use the
[default pattern for branch names from issues](#configure-default-pattern-for-branch-names-from-issues),
including variables.

Prerequisites:

- You must have at least the Developer role for the project.

To create a branch from an issue:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Plan > Issues** and find your issue.
1. Below the issue description, find the **Create merge request** dropdown list, and select
   **{chevron-down}** to display the dropdown list.
1. Select **Create branch**. A default **Branch name** is provided, based on the
   [default pattern](#configure-default-pattern-for-branch-names-from-issues) for
   this project. If desired, enter a different **Branch name**.
1. Select **Create branch** to create the branch based on your project's
   [default branch](default.md).

## Manage and protect branches

GitLab provides multiple methods to protect individual branches. These methods
ensure your branches receive oversight and quality checks from their creation to their deletion:

- The [default branch](default.md) in your project receives extra protection.
- Configure [protected branches](../../protected_branches.md)
  to restrict who can commit to a branch, merge other branches into it, or merge
  the branch itself into another branch.
- Configure [approval rules](../../merge_requests/approvals/rules.md) to set review
  requirements, including [security-related approvals](../../merge_requests/approvals/rules.md#security-approvals), before a branch can merge.
- Integrate with third-party [status checks](../../merge_requests/status_checks.md)
  to ensure your branch contents meet your standards of quality.

You can manage your branches:

- With the GitLab user interface.
- With Git on the [command line](../../../../gitlab-basics/start-using-git.md#create-a-branch).
- With the [Branches API](../../../../api/branches.md).

### View all branches

To view and manage your branches in the GitLab user interface:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Branches**.

On this page, you can:

- See all branches, or filter to see only active or stale branches.
- Create new branches.
- [Compare branches](#compare-branches).
- Delete merged branches.

### View branches with configured protections

> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88279) in GitLab 15.1 with a flag named `branch_rules`. Disabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/363170) in GitLab 15.10.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/363170) in GitLab 15.11

FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../../feature_flags.md) named `branch_rules`.
On GitLab.com, this feature is available.

Branches in your repository can be [protected](../../protected_branches.md) in multiple ways. You can:

- Limit who can push to the branch.
- Limit who can merge the branch.
- Require approval of all changes.
- Require external tests to pass.

The **Branch rules overview** page shows all branches with any configured protections,
and their protection methods:

![Example of a branch with configured protections](img/view_branch_protections_v15_10.png)

Prerequisites:

- You must have at least the Maintainer role for the project.

To view the **Branch rules overview** list:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Settings > Repository**.
1. Expand **Branch rules** to view all branches with protections.
   - To add protections to a new branch:
     1. Select **Add branch rule**.
     1. Select **Create protected branch**.
   - To view more information about protections on an existing branch:
     1. Identify the branch you want more information about.
     1. Select **View details** to see information about its:
        - [Branch protections](../../protected_branches.md).
        - [Approval rules](../../merge_requests/approvals/rules.md).
        - [Status checks](../../merge_requests/status_checks.md).

## Name your branch

Git enforces [branch name rules](https://git-scm.com/docs/git-check-ref-format)
to help ensure branch names remain compatible with other tools. GitLab
adds extra requirements for branch names, and provides benefits for well-structured branch names.

GitLab enforces these additional rules on all branches:

- No spaces are allowed in branch names.
- Branch names with 40 hexadecimal characters are prohibited, because they are similar to Git commit hashes.
- Branch names are case-sensitive.

Common software packages, like Docker, can enforce
[additional branch naming restrictions](../../../../administration/packages/container_registry.md#docker-connection-error).

For the best compatibility with other software packages, use only:

- Numbers
- Hyphens (`-`)
- Underscores (`_`)
- Lowercase letters from the ASCII standard table

You can use forward slashes (`/`) and emoji in branch names, but compatibility with other
software packages cannot be guaranteed.

Branch names with specific formatting offer extra benefits:

- Streamline your merge request workflow by
  [prefixing branch names with issue numbers](#prefix-branch-names-with-issue-numbers).
- Automate [branch protections](../../protected_branches.md) based on branch name.
- Test branch names with [push rules](../push_rules.md) before branches are pushed up to GitLab.
- Define which [CI/CD jobs](../../../../ci/jobs/index.md) to run on merge requests.

### Configure default pattern for branch names from issues

By default, GitLab uses the pattern `%{id}-%{title}` when creating a branch from
an issue, but you can change this pattern.

Prerequisites:

- You must have at least the Maintainer role for the project.

To change the default pattern for branches created from issues:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Settings > Repository**.
1. Expand **Branch defaults**.
1. Scroll to **Branch name template** and enter a value. The field supports these variables:
   - `%{id}`: The numeric ID of the issue.
   - `%{title}`: The title of the issue, modified to use only characters acceptable in Git branch names.
1. Select **Save changes**.

### Prefix branch names with issue numbers

To streamline the creation of merge requests, start your Git branch name with the
issue number, followed by a hyphen.
For example, to link a branch to issue `#123`, start the branch name with `123-`.

The issue and the branch must be in the same project.

GitLab uses the issue number to import data into the merge request:

- The issue is marked as related to the merge request. The issue and merge request
  display links to each other.
- The branch is connected to the issue.
- If your project is configured with a
  [default closing pattern](../../issues/managing_issues.md#default-closing-pattern),
  merging the merge request [also closes](../../issues/managing_issues.md#closing-issues-automatically)
  the related issue.
- Issue milestone and labels are copied to the merge request.

## Compare branches

To compare branches in a repository:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Compare revisions**.
1. Select the **Source** branch to search for your desired branch. Exact matches are
   shown first. You can refine your search with operators:
   - `^` matches the beginning of the branch name: `^feat` matches `feat/user-authentication`.
   - `$` matches the end of the branch name: `widget$` matches `feat/search-box-widget`.
   - `*` matches using a wildcard: `branch*cache*` matches `fix/branch-search-cache-expiration`.
   - You can combine operators: `^chore/*migration$` matches `chore/user-data-migration`.
1. Select the **Target** repository and branch. Exact matches are shown first.
1. Below **Show changes**, select the method to compare branches:
   <!-- vale gitlab.SubstitutionWarning = NO -->
   <!-- Disable Vale so it doesn't flag "since" -->
   - **Only incoming changes from source** (default) shows differences from the source branch since
     the latest common commit on both branches.
     It doesn't include unrelated changes made to the target branch after the source branch was created.
     This method uses the `git diff <from>...<to>`
     [Git command](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt-emgitdiffemltoptionsgtltcommitgtltcommitgt--ltpathgt82308203-1).
     To compare branches, this method uses the merge base instead of the actual commit, so
     changes from cherry-picked commits are shown as new changes.
   - **Include changes to target since source was created** shows all the differences between the two
     branches.
     This method uses the `git diff <from> <to>`
     [Git command](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt-emgitdiffemltoptionsgt--merge-baseltcommitgtltcommitgt--ltpathgt82308203).
   <!-- vale gitlab.SubstitutionWarning = YES -->
1. Select **Compare** to show the list of commits, and changed files.
1. Optional. To reverse the **Source** and **Target**, select **Swap revisions** (**{substitute}**).

## Delete merged branches

Merged branches can be deleted in bulk if they meet all of these criteria:

- They are not [protected branches](../../protected_branches.md).
- They have been merged into the project's default branch.

Prerequisites:

- You must have at least the Developer role for the project.

To do this:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Branches**.
1. In the upper right corner of the page, select **More** **{ellipsis_v}**.
1. Select **Delete merged branches**.
1. In the dialog, enter the word `delete` to confirm, then select **Delete merged branches**.

## Configure workflows for target branches **(PREMIUM ALL)**

> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127115) in GitLab 16.4 [with a flag](../../../../administration/feature_flags.md) named `target_branch_rules_flag`. Enabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136431) in GitLab 16.7.

Some projects use multiple long-term branches for development, like `develop` and `qa`.
In these projects, you might want to keep `main` as the default branch, but expect
merge requests to target `develop` or `qa` instead. Target branch workflows help ensure
merge requests target the appropriate development branch for your project.

When you create a merge request, the workflow checks the name of the branch. If the
branch name matches the workflow, the merge request targets the branch you specify. If the branch name does not match, the merge request targets the
default branch of the project.

Rules are processed on a "first-match" basis - if two rules match the same branch name, the top-most rule is applied.

Prerequisites:

- You must have at least the Maintainer role.

To create a target branch workflow:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Settings > Merge requests**.
1. Scroll down to **Merge request branch workflow**
1. Select **Add branch target**.
1. For **Branch name pattern**, provide a string or wild card to compare against branch names.
1. Select the **Target branch** to use when the branch name matches the **Branch name pattern**.
1. Select **Save**.

### Example

You could configure your project to have the following target branch workflows:

| Branch name pattern   | Target branch |
|-------------|---------------|
| `feature/*` | `develop`     |
| `bug/*`     | `develop`     |
| `release/*` | `main`        |

These target branches simplify the process of creating merge requests for a project that:

- Uses `main` to represent the deployed state of your application.
- Tracks current, unreleased development work in another long-running branch, like `develop`.

If your workflow initially places new features in `develop` instead of `main`, these target branches
ensure all branches matching either `feature/*` or `bug/*` do not target `main` by mistake.

When you're ready to release to `main`, create a branch named `release/*`, and
ensure this branch targets `main`.

## Delete a target branch workflow

When you remove a target branch workflow, existing merge requests remain unchanged.

Prerequisites:

- You must have at least the Maintainer role.

To do this:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Settings > Merge requests**.
1. Select **Delete** on the branch target you want to delete.

## Related topics

- [Protected branches](../../protected_branches.md)
- [Branches API](../../../../api/branches.md)
- [Protected Branches API](../../../../api/protected_branches.md)
- [Getting started with Git](../../../../topics/git/index.md)

## Troubleshooting

### Multiple branches containing the same commit

At a deeper technical level, Git branches aren't separate entities, but labels
attached to a set of commit SHAs. When GitLab determines whether or not a branch has been
merged, it checks the target branch for the existence of those commit SHAs.
This behavior can cause unexpected results when two merge requests contain the same
commits. In this example, branches `B` and `C` both start from the same commit (`3`)
on branch `A`:

```mermaid
gitGraph
    commit id:"a"
    branch "branch A"
    commit id:"b"
    commit id:"c" type: HIGHLIGHT
    branch "branch B"
    commit id:"d"
    checkout "branch A"
    branch "branch C"
    commit id:"e"
    checkout main
    merge "branch B" id:"merges commits b, c, d"
```

If you merge branch `B`, branch `A` also appears as merged (without any action from you)
because all commits from branch `A` now appear in the target branch `main`. Branch `C`
remains unmerged, because commit `5` wasn't part of branch `A` or `B`.

Merge request `A` remains merged, even if you attempt to push new commits
to its branch. If any changes in merge request `A` remain unmerged (because they
weren't part of merge request `A`), open a new merge request for them.

### Error: ambiguous `HEAD` branch exists

In versions of Git earlier than 2.16.0, you could create a branch named `HEAD`.
This branch named `HEAD` collides with the internal reference (also named `HEAD`)
Git uses to describe the active (checked out) branch. This naming collision can
prevent you from updating the default branch of your repository:

```plaintext
Error: Could not set the default branch. Do you have a branch named 'HEAD' in your repository?
```

To fix this problem:

1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Branches**.
1. Search for a branch named `HEAD`.
1. Make sure the branch has no uncommitted changes.
1. Select **Delete branch**, then **Yes, delete branch**.

Git versions [2.16.0 and later](https://github.com/git/git/commit/a625b092cc59940521789fe8a3ff69c8d6b14eb2),
prevent you from creating a branch with this name.

### Find all branches you've authored

To find all branches you've authored in a project, run this command in a Git repository:

```shell
git for-each-ref --format='%(refname:short) %(authoremail)'  | grep $(git config --get user.email)
```

To get a total of all branches in a project, sorted by author, run this command
in a Git repository:

```shell
git for-each-ref --format='%(authoremail)'  | sort | uniq -c | sort -g
```