gitgitlabmerge-conflict-resolution

Merge from feature to dev Includes commits from dev to feature


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:

Commits Graph:

enter image description here

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.

  1. Is there something I did wrong with the merge, or is it just a normal git workflow?
  2. How do I maintain so that my branch for features (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.


Solution

  • 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:

    1. 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:

    1. You have, or can temporarily get, access to directly push the target branch.
    2. Your Merge Request (aka Pull Request) tool allows an option to perform a fast-forward merge. (GitLab does have this option.)

    (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