Question

This may be a fairly simple problem with how I'm using git or how I'm integrating it with Visual Studio 2012. I have (or thought I had) two major branches: master and develop.

I rarely touch the master branch, I mostly make commits to the develop branch and when I reach a milestone I merge the develop branch with the master branch. If I'm introducing a new feature, I make a new branch feat/SomeFeature off from the develop branch. When that feature is done, I merge that with the develop branch and then merge that with the master branch.

Switching branches does exactly what I expect it to do, I see the old untouched versions of the code. However, when I open the repo in a branch visualisation program it appears that all my commits are all along one branch:

enter image description here

I was expecting to see loops and merges, like in this screenshot: enter image description here

Why do my branches appear different? Why do all my commits appear along one branch?

Was it helpful?

Solution

What's going on

It's hard to know exactly what's going on without more information, but you are probably getting fast-forward merges. Basically, if Git can flatten a merge it defaults to doing so. Your workflow of working primarily in develop and merging that repeatedly into master predisposes you to fast-forward merges.

(Note that there is nothing inherently wrong with fast-forward merging. Some developers love this flow and go out of their way to only use this merge strategy by rebaseing their work before merging. Other developers, myself included, like to see "merge bubbles" for feature merges.)

As an example, consider the following commit graph:

[master]   A---B---C
                    \
[develop]            D---E---F

master contains commits A, B and C. develop contains commits A, B, C, D, E, and F.

At this point, if you merge develop into master Git will default to a fast-forward merge, resulting in

[master] [develop] A---B---C---D---E---F

This happens because the merge would logically result in the same commits existing in both trees: You are merging commits D, E and F onto a branch that already contains A, B and C.

If the previous graph looked different, for example

[master]   A---B---C---G
                    \
[develop]            D---E---F

something different would happen. You would end up with something like this:

[master]   A---B---C---G-------H
                    \         /
[develop]            D---E---F

In this case you get a new commit H, which is called a merge commit.

Keeping merge bubbles

You can force the latter behaviour using the --no-ff flag to git merge. (There is also a --ff-only flag to force the opposite behaviour.) From the first example a git checkout master && git merge --no-ff develop would result in something like this

[master]   A---B---C-----------G
                    \         /
[develop]            D---E---F

Note the new merge commit G.

Visual Studio

This is all from the perspective of Git on the command-line, but I note that you are using Visual Studio. I am not sure how to trigger the --no-ff option to merge from VS, assuming you are performing your merges from that tool. Sadly, many graphical Git clients hide very useful options like this flag.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top