2008-06-03

Merging with Mercurial and Meld

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 @@
conflicts_or_success
fi

if [ -n "$MELD" ]; then
+ cp "$BACKUP" "$LOCAL"
cp "$BACKUP" "$CHGTEST"
# 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
fi


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).

Thoughts?

(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.)

JS 1.8 syntax checking in Komodo

I've been using JavaScript 1.8 expression closures lately, but ActiveState Komodo's JS syntax checker, which is just SpiderMonkey 1.7, doesn't recognize them, so it treats them as a syntax error and stops checking the file:



Fortunately, the fix turns out to be pretty simple. Komodo ships with SpiderMonkey 1.7 as an executable, so I first built SpiderMonkey 1.8 (on Linux) using the SpiderMonkey build instructions:

cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -l mozilla/js/src mozilla/js/src/config mozilla/js/src/editline mozilla/js/src/fdlibm
cd mozilla/js/src
BUILD_OPT=1 make -f Makefile.ref

Then I backed up Komodo's version and replaced it with the one I built:

cp Linux_All_OPT.OBJ/js ~/Applications/Komodo-IDE-4/lib/mozilla/js18
cd ~/Applications/Komodo-IDE-4/lib/mozilla
mv js js17
ln -s js18 js

Voila! Syntax checking works for expression closures:



In theory I might have just horked some part of Komodo that depends on JS 1.7, although the New in JavaScript 1.8 doc doesn't mention breaking changes between the two versions, and so far Komodo seems to be working fine.

If it does create problems, however, then a more contained fix, as ActiveState's Todd Whiteman points out on the Komodo Discuss mailing list, would be to update koXPCShellLinter.py's jsInterp variable to point to the 1.8 executable.