Branches
DETAILS: Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated
A branch is a version of a project's working tree. Branches are the foundation of development in a project. When you create a new project, GitLab creates a default branch for your repository. Default branch settings are configured in a project, subgroup, group, or instance.
As your project grows, your team creates more branches. 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.
The development workflow for branches is:
- Create a branch and add commits to it. To streamline this process, you should follow branch naming patterns.
- When the work is ready for review, create a merge request to propose merging the changes in your branch.
- Preview the changes with a review app.
- Request a review.
- After your merge request is approved, merge your branch to the origin branch. The merge method determines how merge requests are handled in your project.
- After the contents of your branch are merged, delete the merged branch.
Create a branch
Prerequisites:
- You must have at least the Developer role for the project.
To create a new branch from the GitLab UI:
- On the left sidebar, select Search or go to and find your project.
- Select Code > Branches.
- In the upper-right corner, select New branch.
- Enter a Branch name.
- In Create from, select the base of your branch: an existing branch, an existing tag, or a commit SHA.
- Select Create branch.
In a blank project
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
must be set to
Partially protected
orNot protected
for you to push a commit to the default branch.
To add a default branch to a blank project:
- On the left sidebar, select Search or go to and find your project.
- Scroll to The repository for this project is empty and select the type of file you want to add.
- In the Web IDE, make any desired changes to this file, then select Create commit.
- Enter a commit message, and select Commit.
GitLab creates a default branch and adds your file to it.
From an issue
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, including variables.
Prerequisites:
- You must have at least the Developer role for the project.
To create a branch from an issue:
- On the left sidebar, select Search or go to and find your project.
- Select Plan > Issues and find your issue.
- Below the issue description, find the Create merge request dropdown list, and select {chevron-down} to display the dropdown list.
- Select Create branch. A default Branch name is provided, based on the default pattern for this project. If desired, enter a different Branch name.
- Select Create branch to create the branch based on your project's default branch.
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:
- Apply enhanced security and protection to your project's default branch.
- Configure protected branches to:
- Limit who can push and merge to a branch.
- Manage if users can force push to the branch.
- Manage if changes to files listed in the
CODEOWNERS
file can be pushed directly to the branch.
- Configure approval rules to manage review requirements and implement security-related approvals.
- Integrate with third-party status checks to ensure the contents of your branch meets your defined quality standards.
You can manage your branches:
- With the GitLab user interface.
- With Git on the command line.
- With the Branches API.
View all branches
To view and manage your branches in the GitLab user interface:
- On the left sidebar, select Search or go to and find your project.
- Select Code > Branches.
On this page, you can:
-
See all branches, or filter to see only active or stale branches.
A branch is considered active if a commit has been made to it in the last three months. Otherwise it is considered stale.
-
Create new branches.
-
Delete merged branches.
-
See merge request links that point to the default branch. Branches with merge requests that do not point to the default branch show the New button instead.
-
See latest pipeline status on the branch.
View branch rules
- Introduced in GitLab 15.1 with a flag named
branch_rules
. Disabled by default.- Enabled on GitLab.com in GitLab 15.10.
- Enabled on self-managed in GitLab 15.11.
- Generally available in GitLab 16.1. Feature flag
branch_rules
removed.
The Branch rules overview page shows all branches with any configured protections, and their protection methods:
Prerequisites:
- You must have at least the Maintainer role for the project.
To view the Branch rules overview list:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Repository.
- Expand Branch rules to view all branches with protections.
- To add protections to a new branch:
- Select Add branch rule.
- Select Create protected branch.
- To view more information about protections on an existing branch:
- Identify the branch you want more information about.
- Select View details to see information about its:
- To add protections to a new branch:
Create a branch rule
- Introduced in GitLab 16.8 with a flag named
add_branch_rules
. Disabled by default.- Feature flag
add_branch_rules
renamed toedit_branch_rules
in GitLab 16.11. Disabled by default.- All branches and All protected branches options introduced in GitLab 17.0.
FLAG: The availability of this feature is controlled by a feature flag. For more information, see the history. This feature is available for testing, but not ready for production use.
Prerequisites:
- You must have at least the Maintainer role for the project.
To create a branch rule:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Repository.
- Expand Branch rules.
- Then:
- To enter a specific branch name or pattern:
- In the Add branch rule dropdown list, select Branch name or pattern.
- On the dialog, from the Create branch rule dropdown list, select a branch name or create a wildcard by typing
*
.
- To protect all branches in the project:
- In the Add branch rule dropdown list, select All branches.
- On the rule's details page, under Merge request approvals, enter the required number of approvals for the rule.
- To protect all branches in the project that are already specified as protected:
- In the Add branch rule dropdown list, select All protected branches.
- On the rule's details page, under Merge request approvals, enter the required number of approvals for the rule.
- To enter a specific branch name or pattern:
Edit a branch rule
- Introduced in GitLab 16.8 with a flag named
add_branch_rules
. Disabled by default.- Feature flag
add_branch_rules
renamed toedit_branch_rules
in GitLab 16.11. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, an administrator can enable the feature flag named edit_branch_rules
.
On GitLab.com and GitLab Dedicated, this feature is not available.
This feature is not ready for production use.
Prerequisites:
- You must have at least the Maintainer role for the project.
To edit a branch rule:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Repository.
- Expand Branch rules.
- Next to a rule you want to edit, select View details.
- In the upper-right corner, select Edit.
- Edit the information as needed.
- Select Update.
Delete a branch rule
- Introduced in GitLab 16.8 with a flag named
add_branch_rules
. Disabled by default.- Feature flag
add_branch_rules
renamed toedit_branch_rules
in GitLab 16.11. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, an administrator can enable the feature flag named edit_branch_rules
.
On GitLab.com and GitLab Dedicated, this feature is not available.
This feature is not ready for production use.
Prerequisites:
- You must have at least the Maintainer role for the project.
To delete a branch rule:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Repository.
- Expand Branch rules.
- Next to a rule you want to delete, select View details.
- In the upper-right corner, select Delete rule.
- On the confirmation dialog, select Delete branch rule.
Name your branch
Git enforces branch name rules 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.
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.
- Automate branch protections based on branch name.
- Test branch names with push rules before branches are pushed up to GitLab.
- Define which CI/CD jobs 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:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Repository.
- Expand Branch defaults.
- 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.
-
- 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, merging the merge request also closes the related issue.
- If the merge request is in the same project, and not a fork, the issue milestone and labels are copied to the merge request.
Compare branches
To compare branches in a repository:
- On the left sidebar, select Search or go to and find your project.
- Select Code > Compare revisions.
- 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
matchesfeat/user-authentication
. -
$
matches the end of the branch name:widget$
matchesfeat/search-box-widget
. -
*
matches using a wildcard:branch*cache*
matchesfix/branch-search-cache-expiration
. - You can combine operators:
^chore/*migration$
matcheschore/user-data-migration
.
-
- Select the Target repository and branch. Exact matches are shown first.
- Below Show changes, select the method to compare branches:
-
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. 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.
-
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
- Select Compare to show the list of commits, and changed files.
- 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.
- 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:
- On the left sidebar, select Search or go to and find your project.
- Select Code > Branches.
- In the upper right corner of the page, select More {ellipsis_v}.
- Select Delete merged branches.
- In the dialog, enter the word
delete
to confirm, then select Delete merged branches.
Configure workflows for target branches
DETAILS: Tier: Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated
- Introduced in GitLab 16.4 with a flag named
target_branch_rules_flag
. Enabled by default.- Feature flag removed 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:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Merge requests.
- Scroll down to Merge request branch workflow
- Select Add branch target.
- For Branch name pattern, provide a string or wild card to compare against branch names.
- Select the Target branch to use when the branch name matches the Branch name pattern.
- 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:
- On the left sidebar, select Search or go to and find your project.
- Select Settings > Merge requests.
- Select Delete on the branch target you want to delete.
Related topics
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
:
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: Diagram of multiple branches with the same commit
accDescr: Branches A and B contain the same commit, but branch B also contains other commits. Merging branch B makes branch A appear as merged, because all its commits are merged.
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.
HEAD
branch exists
Error: ambiguous 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:
Error: Could not set the default branch. Do you have a branch named 'HEAD' in your repository?
To fix this problem:
- On the left sidebar, select Search or go to and find your project.
- Select Code > Branches.
- Search for a branch named
HEAD
. - Make sure the branch has no uncommitted changes.
- Select Delete branch, then Yes, delete branch.
Git versions 2.16.0 and later, 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:
git for-each-ref --format='%(authoremail) %(refname:short)' | 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:
git for-each-ref --format='%(authoremail)' | sort | uniq -c | sort -g