Vendor Branches: Mercurial Part 2
Once we got used to using Mercurial and its Queue extension as I described previously in Vendor Branches: Mercurial, we found that updating to a new vendor version of OfBiz was typically quick and painless.
Some of the steps below could be skipped, but I tend to include them so it’s easy to go back one step if something major goes wrong along the way. Also, I use Linux, so the command line examples given below are Linux commands. You’ll have to translate them if you use a different operating system.
We have a separate Mercurial repository which contains only vendor code, which we call vendor-trunk. We update this when we decide it’s time to update our copy of the vendor’s code from their subversion repository, and that’s what I’ll describe below. However there are tools to directly import subversion commits into a mercurial repository, and you may prefer to use them.
I first clone the vendor-trunk repository. Then if something goes wrong, I can delete the damaged vendor-trunk repository, and recreate it from the clone.
hg clone vendor-trunk vendor-trunk-old
Now export the vendor’s code into a new folder called vendor-exp.
svn export http://svn.apache.org/repos/asf/ofbiz/trunk vendor-exp
Clean out the old contents of the vendor-trunk repository, keeping only the hidden ones (.hg and perhaps .hgignore and .hgtags). Then copy in the new vendor code.
cd vendor-trunk
rm -r *
cp -r ../vendor-exp/* .
cp ../vendor-exp/.* .
Now we ask Mercurial to sort out what’s new and what isn’t, and tag the result with the vendor’s revision number. Mercurial tries to detect renamed files. If you care much about that, you can add options to affect how it checks for renamed files. I’m happy with the default settings.
hg commit --addremove --message "Vendor update REV xxxxxx"
hg tag REV_xxxxxx
Finally comes the important part; fetching the vendor’s version into our customised repository.
After ensuring there are no patches applied in our development repository (though Mercurial will complain if we forget) we pull the changes from our vendor repository (vendor-trunk) into a copy of our customised code base (bonsaierp), after moving into the bonsaierp repository. We merge the changes, commit the merge, then apply all patches to check that all still apply cleanly.
cd bonsaierp
hg qpop -a
hg pull ../vendor-trunk
hg merge
hg commit
hg qpush -a
If there are any conflicts, the merge can invoke your favourite diff tool for you to fix the problem. We use meld, but there are plenty of others around.
If the qpush reports either failure or fuzziness, it indicates that a vendor file we have a patch for has changed, in which case we ensure the patch can be applied correctly. We then qrefresh that patch before another hg qpush -a until all patches apply cleanly. Then it’s just a matter of committing patch changes in the patch repository, running our unit tests, and we are up and running with a new vendor version.
Although this all sounds long winded, it is significantly less work than any of the other systems we have tried. In the days when we used subversion with a vendor branch, it could easily take 2 days to update to new vendor code and be confident it had been correctly applied. With our current system, it typically takes about 30 to 60 minutes. One particularly tricky update, with many conflicts, took about 5 hours.
An added benefit is that when we next update after a patch we submitted upstream has been accepted, all we need do is remove that patch from mercurial (hg qdelete patch-name).
Previous: Vendor Branches: Mercurial
