2

Let's say that I want to do a non-fast-forward merge (a "real merge" and definitely not a rebase) of a branch featureBranch into a branch master. For the sake of simplicity please assume that there are no remote repositories (there is only 1 local repository), and this is the output of git checkout featureBranch && git log:

Switched to branch 'featureBranch'
commit 486b01a6db4597a8f02c9f23a16ddaa2d0e18392
Author: xxx <xxx@xxx.com>
Date:   Mon Sep 28 21:02:00 2015 +0100

    C

commit 39fde8a6ccd27ad8e5b815f5462ae6267df2e213
Author: xxx <xxx@xxx.com>
Date:   Mon Sep 28 21:00:34 2015 +0100

    A

And this is the output of git checkout master && git log:

Switched to branch 'master'
commit 903ad86a4395f004dd2f28009b11f93d4c056d0b
Author: xxx <xxx@xxx.com>
Date:   Mon Sep 28 21:00:54 2015 +0100

    B

commit 39fde8a6ccd27ad8e5b815f5462ae6267df2e213
Author: xxx <xxx@xxx.com>
Date:   Mon Sep 28 21:00:34 2015 +0100

    A

Is the right way of carrying out the merge like this:

git checkout master && git merge featureBranch

or like that:

git checkout featureBranch && git merge master

Please note this is not a duplicate of this SO question, which is about a fast-forward merge.

Community
  • 1
  • 1
Adam Kurkiewicz
  • 1,526
  • 1
  • 15
  • 34

3 Answers3

1

The correct way is to:

git checkout master
git merge featureBranch

The reason is that the order of parent commits in merge is important, and master should always be the first of the two. This makes sure that behaviour of git log --first-parent is as expected. More detail in this blog post: http://devblog.nestoria.com/post/98892582763/maintaining-a-consistent-linear-history-for-git

The method proposed by marcolz would break the log, as it creates 2 merge commits, the first of which has the last commit of feature branch on the first place (it should be on the second).

Jonathan's answer is essentially correct, but lacks the detail in the blog post.

Adam Kurkiewicz
  • 1,526
  • 1
  • 15
  • 34
  • Yes, that's ok for small non-conflicting merges. We tend to have several feature branches being developed on in parallel. That means that when some of the branches are merged to master in the mean time, the chances of your merge to master going ok will be dminishing. There is no such thing as linear history then. Then you'd merge master back into your dev branch now and then to resolve conflicts in your dev branch on the go, so the final merge to master will be easy. A linear history would not add much clarity in this case either. – marcolz Dec 10 '15 at 07:55
  • You could use a merge --squash for the final merge to master to keep linear history on master in the case you're describing (a long living branch). – Adam Kurkiewicz Dec 11 '15 at 12:28
  • 1
    As nearly as I can tell, the *only* difference between merging one way and merging the other is which sequence the parent commits are listed within the commit object? Which means by that way that it doesn't just break `git log --first-parent` but also `master~5`, `HEAD^^^`, etc. – Wildcard Mar 16 '16 at 11:54
0

It is most common to merge into the branch you are currently on.

So:

git checkout master
git merge featureBranch

Don't forget about the reflog...if you ever merge and realize you have made a mistake (before pushing) you can reset your branch to it's previous point. See Undo a Git merge that hasn't been pushed yet

Community
  • 1
  • 1
Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • I keep thinking this is a correct answer, but I think I'd need a better proof. I think I vaguely remember seeing on git mailing list a specific reason, something regarding merging master into a different branch breaking some behaviour of git log... "It is most common" is not a very thoughtful justification. – Adam Kurkiewicz Nov 09 '15 at 01:51
  • @AdamKurkiewicz "breaking some behavior of git log" perhaps they are referring to the merge-commits that can be created when using "git merge". Using a merge approach to integrating your work into master certainly can create a "spider web" of commits which can be difficult to manage. I would still assert that what I have in my answer is the "most standard" way, but you may want to take a look at the "rebase" command – Jonathan.Brink Nov 09 '15 at 12:02
  • 1
    I've recalled what it is that breaks if merges are in the wrong direcrion. It's git log --first-parent. Have a look at my answer! – Adam Kurkiewicz Dec 09 '15 at 20:27
0

It is good practice to merge the branch you want to merge into into your feature branch first, so as to resolve possible conflicts in your feature branch.

git checkout featureBranch && git merge master

When conflicts are resolved, you can then safely do:

git checkout master && git merge featureBranch

To force a non-ff merge, you could pass --no-ff

marcolz
  • 2,880
  • 2
  • 23
  • 28
  • My best guess is that this is bad advise. I think I vaguely remember seeing on git mailing list a specific reason, something regarding merging master into a different branch breaking some behaviour of git log... – Adam Kurkiewicz Nov 09 '15 at 01:52
  • Well, in this particular case it is not needed as the branches are only 1 commit long (short), but if you have a long living parallel featureBranch, in order to keep up with changes committed to master, you either need to use the method I described, or keep rebasing featureBranch on master. If you do not care about the history of your featureBranch (like you say it is local only), that would be preferred. In that case you can skip the merging of master into featureBranch. If other people have featureBranch cloned as well, that will be a problem of course. – marcolz Nov 09 '15 at 09:10
  • I've done some more digging, and I digged out a very useful blog post, which explains why `git checkout master && git merge featureBranch` is the right way to go. Check up my answer! – Adam Kurkiewicz Dec 09 '15 at 20:29