I’m heavily involved in the Enterprise Web Library open-source project, and the other contributors and I sometimes run into situations in which we need to merge two complex branches together. This happens mainly because we don’t always have the time to promptly review and merge each other’s changes; sometimes a contributor will write some code that won’t make it into our canonical repo for several months. But anyway, when merging, we try to always avoid “criss-cross” merges (i.e. merges in which the two branches being merged have multiple Greatest Common Ancestors) since these can result in changes being accidentally undone and other bad things.

After toiling away for the better part of a week, I’ve created a Mercurial revsets alias called nextMerge that takes in two branch heads (merge destination and merge source) and gives you the next ancestor of source that you should merge into destination. It will just return source itself if there is no criss-crossing. If there is criss-crossing, it will tell you to first merge each parent of a merge changeset that would cause a criss-cross, and then it will tell you to actually do the criss-cross merge, but at this point it will be what I call a “no-op” merge, meaning that it should not change destination in any way since all you’re doing is merging in a merge changeset whose parents (i.e. the actual code changes) have already been merged. This no-op merge reduces the number of Greatest Common Ancestors for the original desired merge, and when we get down to just a single GCA, we can safely proceed with the original merge.

Complicated explanation, I know. Drop me a line if you want to know more. But to use nextMerge, just drop the code below into your Mercurial configuration file:

Happy merging!