What is the purpose of separately merging commit in git?

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 merger, itโ€™s clear to me that this is useful: it keeps a history of how things were combined separately from any other changes. But when merging is trivial (for example, when two branches do not affect shared files) , what is the purpose of a separate merge commit?

You can avoid this commit with git merge --no-commit . Then you can add a โ€œrealโ€ change to this commit. This way you avoid the seemingly useless extra fixation. But the manual page warns about this:

You should refrain from abusing this option in order to sneak significant changes to the merge commit. Minor fixes, such as release / version name bumping, would be acceptable.

Why is this?

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

 o---ooo---o--- master \ \ \ \ ooXoXoXo--- my-feature o---ooo---o--- master \ \ \ \ ooo---o---o--- my-feature 

Why does the former prefer the latter?

PS: Suppose my function is a public branch that other people use, so rebase will not be an option.

+8
git merge
source share
2 answers

I think there are several reasons why individual merge commits are a good idea, but it all comes down to the basic rule: each commit should contain changes that belong to each other.

Possible situations where you will benefit from a separate merger:

  • You are trying to figure out which commit introduced an error. If you do not separate the merge from the normal commits, it is difficult to determine if the merge caused this error or the actual changes from this commit.
  • You want to revert the changes made by the commit. What should happen when you return a commit, which is a merge, and also contains the changes yourself? Do you want to return only changes, or just a merger, or both? If only one of them, how to separate them?

As an added benefit, you get a story that is easier to understand. (You could get a story that is even easier to understand if you used rebase , but you said it was not possible).

+2
source share

At my workstation, the โ€œcentralโ€ repository is an SVN server. I am using git through git-svn.

SVN (obviously) does not perform fast merges. Therefore, in order to be able to replicate my local history to the server, I do all the merges that become externally visible explicit.

The reason why you would prefer this template in the general case (clarification: "why do you want an explicit merge union for the main combination of two branches, for example, reuniting a multi-year branch of a side function, even if the two do not conflict?") that it makes the repository better reflect the real series of operations performed, i.e. abstraction for a story better reflects the reality of that story.

When you move forward, information about when the integration occurs is lost - in history there is no sense in saying โ€œhere, when X became Yโ€ with the corresponding message.

This is the same reason some people use merges, preferring to repack even for their local branches - reloading is a form of rewriting a story, a white lie on paper.

To your other question - โ€œwhy should there be only small changes in the command commitโ€, the answer is that the merger can have a large spread in relation to all parents. So, if you added significant work there, it is very difficult to figure out if the problem was an integration problem or one of the new changes that you added. If you place the commit either on one of the parents or after the merger, the halving is simplified, the cherry change can be transferred, you can cancel the merger without losing functions, etc.

+2
source share

All Articles