Finding Merges in the Wrong Direction

Jensen, Aaron ajensen at webmd.net
Mon Nov 11 15:55:43 CST 2013


We have three major releases a year, with co-responding branches: e.g. 2013A, 2013B, and 2013C. When we create each branch, it is started from default. Changes in each branch should only be merged *forward*, e.g. 2013A -> 2013B -> 2013C -> default.  We have a push hook on the server that checks if a pushed merge is in the wrong direction, i.e. default -> 2013C, 2013C -> 2013B, etc.

We also have team-specific branches, some of which are working on features for a release, and others which are working on the next release, e.g. default.  While a team is working on a release, they merge to/from the release branch.  When the team is ready to work on the next release, they start to merge to/from the default branch.

The other day we had a situation where a new developer merged default into his team branch before the team was ready to move on to the next release, then merged the team branch into a previous release, i.e. default -> TeamBranch -> 2013B.  Unfortunately, our hook didn't take this situation into account.

Essentially, this is what happened:

2013B       A---o---o---o---o---B---o
           /     \             /     \
Team      /       o---o---o---C---o---o
         /                   /         \  
Default D---o---o---o---o---o---o---o---o

A = Creation of 2013B branch
B = Merge into release branch
C = The bad merge.  We want to detect and prevent these whenever we merge into a release branch.
D = The first common ancestor of the release branch and default.

So, I've re-written our hook to check that when a change is merged into a release branch, it doesn't merge anything backward.  For each merge into a release branch, I check that there aren't any ancestor merges from a forward branch.  Here's the revset query I'm using:

	> hg log -r "limit(descendants(p1(first(branch('2013B')))) and reverse(p2(ancestors(branch('2013B'))) and branch('default')),1)"

This works.  However, we have a large repository (111,000+ changesets,) and the check takes 30 to 40 seconds. I wanted to know if there is a quicker/faster/more efficient way of writing my revset query, or another approach I'm not seeing.





More information about the Mercurial mailing list