Here's a chunk of commit messages from our repo. It's mercurial but I believe in this context git will be relevant as well:

Viktor Bubnidze TEST: chat send url fix changeset
Kate Gunicky    PROJ-15754: [work-space] Chat Section CSS issues
Vadym Malan     Merge 
Vadym Malan     TEST: char send url test
Ron Cosby       Merge
Ron Cosby       Merge
Ron Cosby       Merge
Ron Cosby       Merge
Ron Cosby       PROJ-15711: Fix the jsdoc template 
Anna  Flint     Merge

See what's going on - each time user updates while goint to push and found that repo is outdated just merges. This creates informational noise and makes log reading less comfortable. Also, merges to my understanding are not completely cheap in terms of disk space.

My question is - what can be done to encourage contributors to use rebase whenever it is possible. For instance, it's relatively easy to introduce hooks that forbids merge commmits at all. In fact, there are already lot of restrictions in our project - like commit message naming etc. I'm not sure that being restrictive is the best thing to do in this particular case.

People are choosing merges because it is the cheapest strategy for syncing. If some other strategy will work for them and be more pleasant - they'll just switch to it.

The thing is I can not come up with any elegant "kind" solution for this. To be completely honest with you, the tempation to play as a dictator is quite strong. But I just want to learn somthing new. Something, well, more peaceful.

  • 1
    possible duplicate of Why squash git commits for pull requests? – gbjbaanb Jul 23 '15 at 7:33
  • @gbjbaanb it is definitely not - it's not about "why", it's not about squashing (though rebase can be collapsed) – shabunc Jul 23 '15 at 14:16
  • @gbjbaanb the reasons why we should rebase are not relevant. Please, re-read the question. – shabunc Jul 23 '15 at 14:31
  • 1
    FWIW "↑↑↑" is useless - until the question is closed, that duplicate banner is visible only to the asker. No one else can see what these arrows are really pointing to. Try opening your question in logged out / incognito mode to see how it looks to other readers – gnat Jul 23 '15 at 14:57

Ask for meaningful commit messages

The problem does not come from using merge commits instead of rebase in this particular case. It is the lack of meaningful commit messages. For example, without seeing your repository, this could very well be a merge commit:

 Ron Cosby       PROJ-15711: Fix the jsdoc template

But contrary to the other commits, this one has a clear meaning. Similarly, imagine you have:

 Vadym Malan     Rebase

This rebase commit is the same kind of noise as current merge commits (edit: assuming this was obtained by collapsing commits and changing the message, of course). Granted, the tool design is such that merge commits have automatic messages and rebase do not, but that is in no way an argument to force people to use rebase, because rebasing does not automatically prevent you from having noise in your history.

It is easier to commit merges without thinking about a message, because there is a default message for merges. For example, originally, git would not even fire the editor for merge messages, which was recognized as being a design error:

[...] my main issue is that git makes it way too easy to have bad merge messages.

(Linus Torvalds)

This has been fixed, but still, the default message should not be used. Note also that the default message in git at least indicates which branches are being merged, which could provide more informations than simply "Merge".

Also, merges to my understanding are not completely cheap in terms of disk space.

No, they are as cheap as regular commits, don't worry. To be more precise, even if they take more space, this is not important. You don't decide to rebase instead of doing a merge commit because it could save you a couple of bytes.

How is it relevant to your question?

You said:

People are choosing merges because it is the cheapest strategy for syncing. If some other strategy will work for them and be more pleasant - they'll just switch to it.

Imagine you tell your team:

"Team, from now on we want to have descriptive commit messages. Yes, Ron, that includes merge commits. You better follow this policy, or else* ..."

(* this part is optional)

Then, your merge-oriented people will:

  • see it as a burden and decide to rebase instead;
  • or, they are okay with the new policy and will write good commit messages.

You win in both cases.

  • Sorry, but I have to downvote beause it's irrelevant. First, you won't see Rebase message because it's not like Merge message, which is automated. To see rebase message one must 1) user rebase with --collapsed 2) Edit for some reason existing commit message. > No, they are as cheap as regular commits, don't worry. Merges consist of data about chnges in your files and files that we changed in repo while you were in branch. – shabunc Jul 23 '15 at 14:19
  • @shabunc See edits – coredump Jul 23 '15 at 20:54

One way of 'hiding' the merge change sets is to use Mercurial Queues. It is an extension currently being distributed along with Mercurial.

In short, they are mutable change sets, known as patches in a patch-queue. Instead of having to merge, your users can rebase and then apply the patch or patches they want to push on top of the tip of the rebase, finalise the patch(es) and push.

You still will have to educate your users to use the patch queue properly.

Maybe there is a different reason for your users to merge...

A distributed version control system like Mercurial implies merging, that is the whole idea of it. People can work disconnected and at a later stage merge their work into the main branch. Mercurial makes merging easy, so I'm not surprised that your users use it - it is the path of lest resistance.

Merging is also (almost) impossible to prevent. Say, all of your users have a commit hook installed that checks upstream before committing. Then your users have to rebase before they can commit and thus prevent merges. If two users rebase first and then commit at the same time (which is allowed by the commit hook) one of them will still have to merge.

To prevent this, a number of the teams at my current work-place use commit & push tokens. Only the person who owns the token, is allowed to commit and then push. This prevents merging (at least most of the time).

On one of my previous work-places, they used a gatekeeper. The central repository was always closed. Only when your code was reviewed and approved (this involved an official document that required signatures of multiple people), the gatekeeper allowed you to commit and push. This was a very elaborate process.

You see, there are several ways of preventing merging ;-)

  • Downvoted. First, you are just restating something that already was stated in question - yes, it is the path of less resistance, there's no doubt about it. Second, your assumptions about two users rebasing at the same time, so one had to merge is just not true. – shabunc Jul 23 '15 at 14:30
  • @shabunc It works as follows: Both user rebase around the same time. They then commit their changes and push them to the central repository. Who comes in first can push, the second one will have to rebase again (because upstraeam has changed) and then merge. – NZD Jul 23 '15 at 19:23
  • each time users changes need to be synched with latest state of repo merge or rebase is inevitable. If user A had rebased first and user B has exactly this two options - either again to rebase or to merge. Or you are talking about users working in same branch? – shabunc Jul 23 '15 at 20:21
  • @shabunc. Mercurial case: If user A and user B both have uncommited changes and want to commit, they pull first (rebase) and then commit their changes on top of the latest tip. Then you end up with two users of which one has to merge because they both have committed their changes and made them permanent. The first one to push, will have his changes in the repository. The second one would create on push another head and must merge. If they would have communicated their intentions, one user could have waited until the other user had completed his pull/commit/push cycle, before doing the same. – NZD Jul 24 '15 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.