Friday, November 15, 2013

Using DeltaWalker with Mercurial for diffs

I bought a bundle of apps with a deal, and got DeltaWalker as part of the bundle. It's a reasonably decent diff tool, with the ability to do folder merging as well (rsync anybody ;) ). In terms of interface it's not bad, nice layout, colours, etc. I haven't used it much because most of my diff work is handled by my JetBrains tools as I'm developing.

For my current project I'm doing a reasonably complicated merge between two feature branches to bring them into alignment. I'm not a fan of Feature Branches as they impede Continuous Integration (FeatureToggles are a better approach), and the fact that my merge is complicated is living proof as to why they should be avoided. However due to particular circumstances a Feature Branch was unavoidable.

With part of the codebase there's not a 1-1 mapping of files. For example a class that was an inner class in Branch A is now in it's own Java file in Branch B. So it turned out to be easier to see what changed in Branch A in a file and port the concepts/semantics of the changes across to Branch B instead of just relying on a syntactical/textual merge. This worked really well because even though the implementation had diverged quite significantly, the interfaces were reasonably unchanged so my Branch A Tests changes merged to Branch B very easily, which would help inform me if I stuffed up the merge of a file. Another win for TDD.

Mercurial's diff commands were powerful enough to show me the changes for a file between the last merge point from Branch A to Branch B to the head of Branch A. However since I like my graphical diff tools, I wanted to try out DeltaWalker to see how good it was.

DELTAWALKER DOCUMENTATION SUCKS - It doesn't actually tell you HOW to integrate with your SCM tools. This is the WORST form of marketing and almost made me toss the tool. Fortunately I was able to figure it out.

When you select Hg in the DeltaWalker and point it to your Hgrc file it updates the file for you. Would be nice if it explains that it does that! I found out about it because I version control my Hg config (with Mercurial of course), and running a diff on the file, for another update I made caused me to see the changes.

[extdiff]
cmd.dw = /Applications/DeltaWalker.app/Contents/MacOS/hg

[merge-tools]
dw.executable = /Applications/DeltaWalker.app/Contents/MacOS/hg
dw.args = $local $other $base -merged=$output
So one can then use Hg's extdiff functionality to load up the diffs.
$ hg dw -r $lastmerge:$branch_head file
It actually works well, but they guys behind the product need to update their docs!!

Finding the last merge point between branches in Mercurial

When merging between my development and release branches, I like to know what the last merge point was between the two so that I can do tasks like compile Release Notes or see if some code needs to be merged (based on tags).

I developed a little Hg alias that finds the last merge node between two branches.

lastmerge = !hg log -r "children(ancestor($1, $2)) and merge() and ::$2"

$ hg lastmerge BRANCH_1 BRANCH_2
In the example above, BRANCH_1 and BRANCH_2 are bookmarks. The alias makes use of Hg Revsets to find the latest merge node from BRANCH_1 into BRANCH_2