working a lot these days on the exciting OpenSim project i end up generating a number of patches. even though i do have commit rights for the OpenSim subversion repository i tend to really use the distributed version control tool mercurial and work against the OpenSim mercurial repository as that allows me to very quickly set up a clone of the OpenSim source tree, work on a particular feature there, then draw a patch set, apply that to the subversion tree, and get rid of the cloned tree. mercurial’s clone function is particularly nice in that it uses hard links wherever possible.
so, what i’ve done is the following:
% hg clone http://opensimulator.org/hg/opensim-trunk/ opensim
that clones the opensimulator.org tree via HTTP to my local /proj tree. next, i create a local clone:
% hg clone opensim opensim-http
(i’m currently overhauling the HTTP server code inside OpenSim); do whatever i feel urged to do inside that tree. when i’m ready to commit a patch i update the opensim-http tree to the latest version:
% cd opensim-http
% hg pull http://opensimulator.org/hg/opensim-trunk/
% hg merge
% hg ci
those steps will ensure that i’m at the latest and greatest OpenSim level now. next, i need to prepare a patch set against the latest subversion release. if you look at the output of hg log…
changeset: 4634:111496b95f43
parent: 4631:10ade1d4f3de
parent: 4633:076831c7c06b
user: Dr Scofield <hud@zurich.ibm.com>
date: Wed Jul 09 13:58:52 2008 +0200
summary: sync/opensim
changeset: 4633:076831c7c06b
parent: 4629:cc11643a0520
user: mw
date: Wed Jul 09 11:01:26 2008 +0000
summary: [svn 5396] corrected the params types on IClientAPI.SendParcelMediaCommand. the command parameter should be set to the the ParcelMediaCommandEnum value. While flags seems to need to be set to (uint)(1<<[value of the command enum])
…you can see that some of the summary fields of the mercurial changesets contain an [svn NUMBER] part, which, by happy coincidence1, indicates the corresponding subversion release number.
so all we need to do now is create a diff against mercurial changeset 4633:076831c7c06b and apply that to our subversion tree (or submit it to [OpenSim’s mantis][os-mantis]):
% hg diff -r 076831c7c06b > /tmp/opensim-another.patch
needless to say, but after doing this a couple of times you start wondering whether that process could be wrapped in a script…
…and it turns out, that, yes, we can do that:
[python]
#!/usr/bin/python
from mercurial import ui, hg, cmdutil, node
from optparse import OptionParser
import re
if __name__ == '__main__':
parser = OptionParser(usage = 'usage %prog [options] mapping')
parser.add_option("-v", "--verbose", action = 'store_true', dest = "verbose", help = "verbose")
(options, args) = parser.parse_args()
# setup mercurial stuff
ui = ui.ui()
repo = hg.repository(ui, ".")
# get revision range
revs = cmdutil.revrange(repo, ['-1:0'])
reSubversion = re.compile(r'^\[svn\s+(?P<svn>\d+)\]', re.IGNORECASE)
for r in revs:
cx = repo.changectx(r)
match = reSubversion.match(cx.description())
if match:
if options.verbose: print 'last SVN release %d with hg release %s' % (int(match.group('svn')),
node.short(cx.node()))
print node.short(cx.node())
break
[/python]
save it in ~/bin/hgsvn, stir2, then apply as follows:
% hg diff -r $(hgsvn) > /tmp/opensim-yet-another.patch
voila.
