I am experiencing an issue while merging branches in GitLab. I want to merge changes from the release-8
branch into dev
, but after completing the merge, the commit history shows that changes from dev
were also merged into release-8
.
Scenario:
dev
contains commits A--B--C
release-8
branch is made from master
D--E
in release-8
fix/feature-B
branch is made from master
F
in fix/feature-B
and merge it to dev
(so dev
should be A--B--C--F
)release-8
into dev
with some conflict and resolving it in GitLab UIrelease-8
to dev
and not the other way around).Commits Graph:
What I expect is that dev
contains commits A--B--C--F--D--E
and 'release-8' still D--E
. But what I got is that release-8
contains F
too.
release-8
) is not merged with any branch from fix (fix/feature-B
) or contains any changes from not related commit?The merge that includes F
is only happening when there is a conflict on merge, and GitLab UI somehow name the commit message to be "Merge branch 'dev' into release-8" so maybe there is something I need to figure out.
Edit:
What I expect is something like what it looks on the commit graph I provide. But what is actually happening is, because of my merge (release-8
into dev
) is having a conflict, F is commited to release-8
first, and then merged to dev
. So there is unwanted and unrelated F
commits in branch release-8
.
To restate the relevant problem:
However, after completing the merge, the commit history shows "Merge branch 'dev' into release-8"...
This is happening because you are resolving merge conflicts using the GitLab UI. Behind the scenes GitLab resolves conflicts in the UI as defined here. The key point of that documentation is:
- Finally, we write that index as a merge commit to the source branch.
If you don't want to have that merge commit on your source branch, then you'll need to resolve the conflicts a different way, such as locally on your machine with rebase, or using a first-parent merge as described below.
An alternative to rebase to avoid the extra merge commit:
To resolve merge conflicts, you need to use either merge or rebase. For personal feature branches that are linear, I almost always prefer to use rebase. But if the feature branch is not linear (meaning it already contains new merge commits), and if some of the merge commits already have resolved conficts, then you may prefer to use merge to resolve conflicts. (Unless you're willing to squash and lose your commit history.) You also must use merge to resolve conflicts if both the source and target branches are long-lived shared branches in your workflow. Since your source branch is called release-8
, perhaps it is also a shared branch so rebase would not be an option.
There is a way to use merge to resolve conflicts without having that extra merge commit in your source branch, if one of the following statements is true:
(For the following examples I will assume your remote is origin
, your source branch is release-8
, and your target branch is dev
.)
For both #1 and #2, you would start with:
# update all of your remote origin branches
git fetch
# checkout dev and reset it to origin/dev in case you have an old copy
git switch -C dev origin/dev
# Merge in your branch
git merge origin/release-8
# Resolve conflicts and stage the changes
# Complete the merge
git merge --continue
Now for #1, it's simply: git push
If you don't have permission to directly push and must use a Merge Request (or Pull Request if not GitLab), then for #2:
# Make a temporary branch from your newly updated dev branch
git switch -c merge-release-8-into-dev dev
# Push the temp branch
git push origin merge-release-8-into-dev
# Create a Merge Request from merge-release-8-into-dev into dev
# Complete the Merge Request with fast-forward merge