doc/user/project/repository/branches/_index.md
{{< details >}}
{{< /details >}}
Branches keep your team's development work organized and separated. When multiple people work on different features simultaneously, branches prevent changes from conflicting with each other. Each branch acts as an isolated workspace where you implement new features, fix bugs, or experiment with ideas.
With branches, your team can:
The development workflow for branches is:
To view and manage your branches in the GitLab user interface:
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.
See merge request links that point to the default branch.
Branches with merge requests that do not point to the default branch display the {{< icon name="merge-request" >}} New merge request button.
See latest pipeline status on the branch.
Prerequisites:
To create a new branch from the GitLab UI:
A blank project does not contain a branch, but you can add one.
Prerequisites:
Partially protected or Not protected for you to push a commit
to the default branch.To add a default branch to a blank project:
GitLab creates a default branch and adds your file to it.
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:
To create a branch from an issue:
For information about creating branches in empty repositories, see empty repository behavior.
If the name of the created branch is prefixed with the issue number, GitLab cross-links the issue and related merge request.
Prerequisites:
To create a branch directly from a task:
For information about creating branches in empty repositories, see empty repository behavior.
If the name of the created branch is prefixed with the task number, GitLab cross-links the issue and related merge request.
If your Git repository is empty, GitLab:
README.md file to it..gitlab-ci.yml file.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:
Branch names with specific formatting provide:
Common software packages, like Docker, can enforce additional branch naming restrictions.
For the best compatibility with other software packages, use only:
-)_)While Git technically allows many characters in branch names, certain characters can cause issues with GitLab Runner and other tools and are not recommended:
~, ^, :, ?, *, [, \, ', "..@{//. or .lock suffix- or .For maximum compatibility with GitLab Runner and other tools, use only alphanumeric characters, hyphens, and underscores.
By default, GitLab uses the pattern %{id}-%{title} when creating a branch from
an issue, but you can change this pattern.
Prerequisites:
To change the default pattern for branches created from issues:
%{id}: The numeric ID of the issue.%{title}: The title of the issue, modified to use only characters acceptable in Git branch names.To streamline the creation of merge requests, start your Git branch name with the
issue or task number, followed by a hyphen. For example, to link a branch to issue #123,
start the branch name with 123-.
The branch must be in the same project as the issue or task.
GitLab uses this number to import data into the merge request:
GitLab provides multiple methods to protect individual branches. These methods ensure your branches receive oversight and quality checks from their creation to their deletion. To view and edit branch protections, see branch rules.
{{< history >}}
{{< /history >}}
You can download the comparison between branches as a diff or patch file for use outside of GitLab.
To download the branch comparison as a diff, add format=diff to the compare URL:
If the URL has no query parameters, append ?format=diff:
https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?format=diff
If the URL already has query parameters, append &format=diff:
https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?from_project_id=2&format=diff
To download and apply the diff:
curl "https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?format=diff" | git apply
To download the branch comparison as a patch file, add format=patch to the compare URL:
If the URL has no query parameters, append ?format=patch:
https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?format=patch
If the URL already has query parameters, append &format=patch:
https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?from_project_id=2&format=patch
To download and apply the patch using git am:
# Download and preview the patch
curl "https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?format=patch" > changes.patch
git apply --check changes.patch
# Apply the patch
git am changes.patch
You can also download and apply the patch in a single command:
curl "https://gitlab.example.com/my-group/my-project/-/compare/main...feature-branch?format=patch" | git am
Merged branches can be deleted in bulk if they meet all of these criteria:
Prerequisites:
To do this:
delete to confirm, then select Delete merged branches.[!note] Deleting a branch does not completely erase all related data. Some information persists to maintain project history and to support recovery processes. For more information, see handle sensitive information.
{{< details >}}
{{< /details >}}
{{< history >}}
target_branch_rules_flag. Enabled by default.{{< /history >}}
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:
To create a target branch workflow:
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:
main to represent the deployed state of your application.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.
When you remove a target branch workflow, existing merge requests remain unchanged.
Prerequisites:
To do this:
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 existsIn 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:
HEAD.Git versions 2.16.0 and later, prevent you from creating a branch with this name.
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
Failed to create branch 4:Deadline ExceededThis error is caused by a timeout in Gitaly. It occurs when creating a branch take longer to complete than the configured timeout period.
To resolve this issue, choose one of the following: