Merging with Mercurial and Meld

[Update: see Merging with Mercurial 1.0 and Meld for more up-to-date info on the experience with Mercurial 1.0, which comes with Ubuntu 8.10.]

When confronted with a merge conflict, Mercurial 0.9.5 (the version that comes with Ubuntu 8.04) uses its hgmerge script to call meld in a way that displays your version of the file on the left, the other version on the right, and hg's attempt to merge them in the middle, with conflict markers where it was unable to do so.

Here's meld handling the Merging conflicting changes example from the hg book:

You're supposed to fix the one in the middle, resolving the conflicts between the ones on either side, and then save the middle one (which will get saved to your working directory, from where you can commit your merge).

The following patch hacks hgmerge to display the base version (the one from which your version and the other version originated) on the left, the other version on the right, and your version in the middle.

--- hgmerge.orig        2008-06-01 13:51:10.000000000 -0700
+++ hgmerge 2008-06-01 14:35:46.000000000 -0700
@@ -158,13 +158,12 @@

if [ -n "$MELD" ]; then
+ cp "$BACKUP" "$LOCAL"
# protect our feet - meld allows us to save to the left file
- cp "$BACKUP" "$LOCAL.tmp.$RAND"
- # Meld doesn't have automatic merging, so to reduce intervention
- # use the file with conflicts
+ cp "$BASE" "$LOCAL.tmp.$RAND"
$MELD "$LOCAL.tmp.$RAND" "$LOCAL" "$OTHER" || failure
# Also it doesn't return good error code
$TEST "$LOCAL" -nt "$CHGTEST" && conflicts_or_success || ask_if_merged

Here again you're supposed to fix and save the file in the middle, which gets saved to your working directory.

Here's what the example looks like using the hacked version of hgmerge:

After trying both versions of the script on several test and real merges (a few of which I screwed up), it's still not clear to me which approach is better (or if there's something better still). David Baron pointed out in a conversation that it can be useful to see the base version, but it's also useful to distinguish between your version and the version that ultimately results from the merge (which is presumably why kdiff3, which is shown in the book, displays all four: base, yours, other, and final).


(Note: Devmo's Mercurial basics says to use Mercurial version 1.0 or later, although I hear that doesn't even include hgmerge, leaving configuration of a merge tool entirely up to each user, so the question is even more significant there.)


Daniel E said...

It isn't open source, but Scooter Software's new version of Beyond Compare, currently in beta, supports Linux as a target platform and it has a really great 3-way diff/merge. It uses the four pane view.
Yours | Base | Theirs

Which is the most intuitive one I've seen.

BC3 is amazing and one of the reasons I keep Parallels on my Mac. I use it to compare my local sandbox to a deployed version of it on a Linux server using the SFTP functionality. I've always felt it was one of the most appropriately named products. :)

Please don't hate me for advertising on your blog. :) I only mentioned it because I felt it relevant to your post.

weblog said...

1.0 doesn't include hgmerge because it has a much improved merge tool detection algorithm. You can still configure it to launch Meld, though, if you want (it might even find Meld all by itself).

Anonymous said...

You say that the user is supposed to "fix the one in the middle", but on current Mercurial versions, that's the base file, not the output file.

You don't show the (all important) file name extensions in your screen shot, but it looks like somehow your configuration differs from the Mercurial standard.

Your instructions don't agree with what Mercurial actually does. Since your page comes up pretty high when searching for "mercurial" and "meld", it would be good if the instructions on it were clear and applicable to the latest version of Mercurial.

Myk said...

Anonymous: actually, if you look at the tab above the three files in the screenshot, you'll see that it does list the full names of the three files, including their extensions.

You're right that Mercurial 1.0, which Ubuntu 8.10 ships, behaves differently than Mercurial 0.9.5, which Ubuntu 8.04 ships and which I used in this post, so I've written another post on my experience using the newer version of Mercurial.

Check that one out for more up-to-date information. I've updated this post to point to that one at the top.