Develop branch is behind after merging into master using Gitlab MR

Viewed 578

I have merged some changes from develop into master using GitLab merge request and I squashed the commits. After merging, I compared the two branches and it shows the wrong diffs. I expected no diffs since they are the same after merging. I checked the commit graph and I see that the develop and master branch are now disconnected.

Graph after merge: enter image description here

Why is the master branch ahead of the develop after merge? Is this expected behavior? I am using Gitlab 12.9. I want to retain the develop branch for future development but I want to avoid unnecessary diffs to show up.

1 Answers

Essentially, git only has one way of tracking history: every commit has zero or more parents. By tracking backwards from a commit to its parents, and their parents, git can determine what commits are in that commit's history.

When you merge two branches, say develop into master, you have three choices:

  1. If all the commits on master already exist on develop, you can just move the branch pointer of master to match develop, without creating any new commits. This is a "fast-forward merge".
  2. You can create a new commit which has both develop and master as its parents. All the commits that are in develop's history are now in master's history as well.
  3. You can "squash" all the differences between the two branches into one commit, with only master as its parent. All the changes from develop will now be on master, but none of the commits that made up those changes are in master's history.

When you next ask to merge the same branches, git will look for commits which exist on develop but don't exist on master. If you took option 3, all those commits you squashed the changes from are still in that category.

The lesson is to only use squash merges on branches you're going to throw away afterwards. For instance, each task you work on can be in a new branch; you start it from the current state of develop (or master, or main, or wherever), squash merge it, and then delete the branch. The next task starts again from develop/master/main, not from the old task branch, so the old commits that you squashed away don't matter any more.

Alternatively (and my personal preference), don't use squash merges. Make each commit meaningful, use git rebase -i and git commit --amend to tidy up stupid mistakes you don't want in your history (being careful to only rewrite history that you haven't shared with other users, or other branches), and then use a fast-forward merge or a merge commit.

Related