Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How safe are automatic merges in Mercurial?

In Mercurial there is the fetch extension that you can use to emulate something like svn update, i.e. to merge with incoming changes without even looking at them. But even if you don't use hg fetch, most of your merges will "miraculously" work without resulting in a conflict. This is great, but how safe is it to trust such merges to be valid merges of, say, Java code?

Are there any examples to demonstrate why or when these merges should be (or shouldn't be) trusted?

like image 492
Lóránt Pintér Avatar asked Feb 15 '11 12:02

Lóránt Pintér


2 Answers

Well, they are quite safe as long as you don't start reorganizing your code.

Consider the following example:

class A {

   public void methodA() {
     // do something here 
     // that should be great
   }

   public void methodB() {
     // And now I'll 
     // do something here
     // and it's gonna be good.
   }

   public void methodC() {
     // Finally, let's 
     // do something here
   }

}

Now, you start working and decide to add some instructions to methodC.
During this time, a co-worker decided that methodC, for whatever reason, should be placed on top of the class.

You will end up with two versions to merge.
Yours:

class A {

   public void methodA() {
     // do something here 
     // that should be great
   }

   public void methodB() {
     // And now I'll 
     // do something here
     // and it's gonna be good.
   }

   public void methodC() {
     // Finally, let's 
     // do something here
     // and here your marvelous changes
   }

}

And your co-worker ones:

class A {

   public void methodC() {
     // Finally, let's 
     // do something here
   }

   public void methodA() {
     // do something here 
     // that should be great
   }

   public void methodB() {
     // And now I'll 
     // do something here
     // and it's gonna be good.
   }

}

When the merge occurs, as the default context is three lines wide, the automatic merge might consider that a valid result would be this one:

class A {

   public void methodC() {
     // Finally, let's 
     // do something here
   }

   public void methodA() {
     // do something here 
     // that should be great
   }

   public void methodB() {
     // And now I'll 
     // do something here
     // and it's gonna be good.
   }

   public void methodC() {
     // Finally, let's 
     // do something here
     // and here your marvelous changes
   }

}

For that reason, if possible, I try to keep methods organized so that accessors are grouped, and untouched, privates are grouped by common logic, etc... But it is not always possible.

Hopefully this case is quite rare and if there are too many changes, mercurial will request you to merge the classes manually.

like image 64
gizmo Avatar answered Oct 06 '22 21:10

gizmo


I've been using Mercurial at work for several months now. The overall team is 50+ SW developers - divided down into sub-groups of 5-10 developers. We've yet to see a failed merge that was not the result of:

  1. a parent file being broken/corrupted going into the merge (ie: coding error)
  2. incorrect resolution of merge conflicts by developer

So, we've been perfectly happy with the merge results for standard text files (.c, .h, .pl, makefile, linkerfiles, etc..).

We have identified a case in which merging is a bad idea and can result in some issues, and this involves auto-generated code or models being stored as text files. Mercurial will not try to merge binary files, but it will happily merge models, auto-generated .c/.h files, and so on. You can specify merge strategies per directory or file type, but even with these settings in place, inappropriate merging can occur due to Mercurial's premerge. Outside of these cases, Hg merging has been very effective for us.

ps: if you are interested in the model/auto-gen case, find a suggestion here.

like image 44
dls Avatar answered Oct 06 '22 20:10

dls