38

I have a branch called master and another called dev. Usually, I do tests and improvements on dev; when done, I merge it into master, tag it, and release new version of the application.

Now, I face a decision to make in regard to merging:

  1. merge master into dev
  2. merge dev into master

but I am not really sure how the two are different... Any explanation would be welcome.

Sebastian Nielsen
  • 3,835
  • 5
  • 27
  • 43
sop
  • 3,445
  • 8
  • 41
  • 84
  • 2
    Merging one branch into another is not a symmetric operation; merging `master` into `dev` is different from merging `dev` into `master`. Follow this example and the difference should become clear: http://stackoverflow.com/questions/25933056/how-can-i-do-a-bugfix-on-master-and-integrate-it-into-my-less-stable-branches/25934341#25934341 – jub0bs Oct 15 '14 at 13:48
  • 2
    With `merge master`, you advance the `dev` branch. – raina77ow Oct 15 '14 at 13:49
  • master branch in GIT is a generic name which means that this is a MAIN branch that is used as a TRUNK in SVN, you can mark your Dev like your master branch but not vice versa, each time you need to start new development iteration you to need create new branch using master and when you finish this iteration you also need to merge or rebase your changes into master branch, you Dev is just one of the iterations in your development cycle – Anonymous Oct 15 '14 at 14:16

2 Answers2

56

TL;DR

The main difference lies in where the master and dev branches end up pointing. enter image description here

Full explanation

Merging one branch into another is not a symmetric operation:

  • merging dev into master, and
  • merging master into dev,

are, in general, not equivalent. Here is an illustrative example that explains the difference between the two. Let's assume your repo looks as follows:

enter image description here

If you merge dev into master

If master is checked out (git checkout master),

enter image description here

and you then merge dev (git merge dev), you will end up in the following situation:

enter image description here

The master branch now points to the new merge commit (F), whereas dev still points to the same commit (E) as it did before the merge.

If you merge master into dev

If, on the other hand, dev is checked out (git checkout dev),

enter image description here

and you then merge master (git merge master), you will end up in the following situation:

enter image description here

The dev branch now points to the new merge commit (F', whereas master still points to the same commit as it did before the merge (D).

Putting it all together

enter image description here

jub0bs
  • 60,866
  • 25
  • 183
  • 186
  • 8
    So by "not symmetric" you just mean that the branch pointers point to different commits after the merge? Because imho the commits F and F' should be the same (content-wise, not necessarily SHA-1-wise). – musiKk Oct 15 '14 at 14:25
  • 4
    @musiKk Yes that's what I mean. I use different names for `F` and `F'` because `F'` is `F`'s evil twin from a parallel universe, and would have a different SHA1 from `F`'s. – jub0bs Oct 15 '14 at 14:35
  • 2
    Alright! Btw what do you use do draw the slick images? They look suspiciously like the images from Pro Git... – musiKk Oct 15 '14 at 14:41
  • @musiKk Nah! I wrote a [little LaTeX package](https://github.com/Jubobs/gitdags) for that, and I drew inspiration from the style of the diagrams in the Pro Git book. – jub0bs Oct 15 '14 at 14:43
  • 1
    @Jubobs - I realize you hedge your addendum slightly, but you might want to explicitly point out the parents are reversed in the two scenarios. – Andrew C Oct 15 '14 at 14:57
  • @AndrewC Do you mean the way that parents of the merge commits are numbered? – jub0bs Oct 15 '14 at 15:00
  • @AndrewC Yes, you're right. We're getting into the weeds, though. I think I should just delete my *addendum*... – jub0bs Oct 15 '14 at 15:04
  • Personally I think it would be worth noting - it's a constant source of confusion in my organization. It changes how the merge bubbles look in gitk for instance. So when you try to follow the branch history instead of following left-most in gitk as you go down you have to keep taking the right hand path which is unexpected. – Andrew C Oct 15 '14 at 15:10
  • @AndrewC I agree that it's interesting, but I'm not sure this is the right place to discuss it. My addendum already goes beyond what the OP asked for. In another post, perhaps. – jub0bs Oct 15 '14 at 15:13
  • 1
    I'd like to add that picking a proper "first parent" (the branch which receives the merge) is a question of policy in some projects: some branch might be "blessed" to only receive merges (say, of feature branches) and not be merged to other branches. Git does even support the `--first-parent` command-line option in its `git log` command (and its friends); reading up on it in the `git log` manual page could shed quite some light on your question, @sop. – kostix Oct 15 '14 at 15:33
  • @kostix True. I touch on that in this other answer of mine: http://stackoverflow.com/questions/25933056/how-can-i-do-a-bugfix-on-master-and-integrate-it-into-my-less-stable-branches/25934341#25934341, but perhaps I should also mention it here... – jub0bs Oct 15 '14 at 15:35
  • It should have a TL;DR, I thought the it would be more different. – Jp_ Feb 02 '18 at 22:38
  • @Jubobs I know the question is too old. But I have a problem that relates to this question. According to your answer, two approached's pointers are different, but is there any difference between their's source code? I think they are the same, is it right? – Ken Block Feb 26 '18 at 15:50
  • @KenBlock I will add an answer. – dawid Jun 06 '19 at 03:04
-1

Personally, I don't think that the accepted answer is sufficient for the layman (and if you've been searching for this answer, you are a Git layman!!).

@jub0bs correctly describes the technical difference between the two. But there's no direction in his answer as to which you "should" use, or why.

There will always be exceptions of course, but in the general case you'll (ahem) always want to merge DEV into MASTER (scenario b in jub0bs answer).

Why?

To understand why, you need to dig a little deeper than the high-level timeline graph that jub0bs has the conversation at. Because at the end of both commits, when you look in your OS directory, you won't be able to tell the difference. The naive developer will therefore tell you that it doesn't matter which way round you merge the commits.

To see the difference, you need to look at the diff-tools (which should hopefully be built into your git-client (be that SmartGit, GitKraken, or whatever).

Let's imagine this file on MASTER branch:

filename: my_code.txt
some (code) { includes := feature1 + feature2 + feature3; }

And on DEV branch we have a bug-fix that was included :

filename: my_code.txt
some (code) { includes := feature1 + feature2 + bug-fix; }

After the merge-commit (regardless of which way around you do it), you'll have:

filename: my_code.txt
some (code) { includes := feature1 + feature2 + bug-fix + feature3; }

You'll only see the difference in your Git-client.

If you merge MASTER into DEV (as per scenario c) your Git-client will tell you that bug-fix was always there as part of the main history of the file, and that at some point someone came along to wedge-in feature3 (almost as an after-thought). But any half-decent coder would tell you that logically, this is an incorrect interpretation of history!

What you really want to do is merge DEV into MASTER. In this scenario, the history will tell you that feature1, feature2 and feature3 were always in-scope and planned as the main development trunk of the overall project. bug-fix on the other hand, was only added as a necessary correction (after-thought or distraction) along the way.

cartbeforehorse
  • 3,045
  • 1
  • 34
  • 49