#hgsvnsync.py
#
#Create a mercurial mirror of a branch in an svn repository
#This scripts requires that the commands svn and hg be present
#in the path.
#
#Usage:
#To create a new mirror
# python hgsvnsync.py init svn_url mirror_location
#
#To update the mirror
# python hgsvnsync.py update mirror_location
#
# Changes
# 23-Jan-2009 Updated to working version.
import commands
import re
import os
hgignore=
"""syntax: regexp
[.]svn/
[.]hgignore
[.]commitmessage"""def getRevisions(svn_url, frm=
1):
s = commands.getoutput(
'svn -r%s:HEAD log %s' % (frm, svn_url))
return re.findall(
'------------------------------------------------------------------------\n'+
'r(\d+) [|] \w+ [|] ', s)
def createFile(filename, content):
f = file(filename,
'w')
f.write(content)
f.close()
def init(svn_url, dest):
commands.getoutput(
'svn co -r1 %s %s' % (svn_url, dest))
commands.getoutput(
'hg init %s' % dest)
createFile(os.path.join(dest,
'.hgignore'), hgignore)
def parseLog(log):
(rev, commiter, date, lines) = re.search(
'------------------------------------------------------------------------\n'+
'r(\d+) [|] (\w+) [|] ([^(]+)[^|]+[|] (\d+) line[s]?\n', log).groups()
message =
"%s\n\nSvn Revision %s" % (
"\n".join(log.split(
'\n')[
3:(
3+int(lines))]),rev)
return (rev, commiter, date, message)
def parseInfo(info):
return dict(re.findall(
"(\w+): (.*)", info))
def commitRevs(svn_url, dest, frm):
revs = getRevisions(svn_url, frm)[
1:]
for rev
in revs:
print "Commiting revision %s" % rev
commands.getoutput(
'svn update -r%s %s' % (rev, dest))
logMsg = commands.getoutput(
'svn log -rCOMMITTED %s' % dest)
(rev, commiter, date, message) = parseLog(logMsg)
commitmessagepath = os.path.join(dest,
'.commitmessage')
createFile(commitmessagepath, message)
commands.getoutput(
"hg commit -A -l %s -d '%s' -u %s %s" %
(commitmessagepath, date, commiter, dest))
def main():
import sys
if sys.argv[
1]==
'init':
svn_url = sys.argv[
2]
dest = sys.argv[
3]
init(svn_url, dest)
commitRevs(svn_url, dest,
1)
elif sys.argv[
1]==
'update':
dest = sys.argv[
2]
info = parseInfo(commands.getoutput(
'svn info %s' % dest))
rev = info[
'Revision']
svn_url = info[
'URL']
commitRevs(svn_url, dest, rev)
if __name__ ==
'__main__':
main()