Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of a separate merge commit in git?

Tags:

git

merge

When you merge two branches together, git creates a separate commit with a message like Merge branch 'master' into my-branch. For a non-trivial merge it is clear to me that this is useful: It keeps the history of how things were merged separate from any other changes. But when the merge is trivial (for example when the two branches don't affect any files in common), what is the purpose of the separate merge commit?

You can avoid that commit with git merge --no-commit. You could then add a "real" change on this commit too. That way you avoid a seemingly useless extra commit. But the man page warns about this:

You should refrain from abusing this option to sneak substantial changes into a merge commit. Small fixups like bumping release/version name would be acceptable.

Why is that?

With commits with real changes in them marked as o and merge-only commits as X, this is the difference between these two situations:

o---o-o-o---o--- master
 \   \   \   \
  o-o-X-o-X-o-X-o--- my-feature


o---o-o-o---o--- master
 \   \   \   \
  o-o-o---o---o--- my-feature

Why is the first one preferred over the second one?

PS: Assume my-feature is a public branch that other people also use, so rebase would not be an option.

like image 578
Wouter Coekaerts Avatar asked Feb 15 '12 21:02

Wouter Coekaerts


1 Answers

I think there are several reasons why having separate merge commits is a good idea, but it all comes down to the basic rule, that every commit should contain changes that belong together.

Possible situations where you will benefit from having separate merge commits:

  1. You're trying to find out which commit introduced a bug. If you don't separate merging and normal commits, it's hard to figure out whether the merge caused that bug, or the actual changes from that commit.
  2. You want to revert a change made by a commit. What should happen when you're reverting a commit that is a merge and also contains changes on its own? Do you want to revert just the changes, or just the merge, or both? If only one of them, how to separate them?

As added benefit, you get history that's easier to understand. (You could get history that's even easier to understand if you used rebase, but you said that's not possible.)

like image 98
svick Avatar answered Oct 06 '22 01:10

svick