# HG changeset patch # User Brendan Cully # Date 1183327335 25200 # Node ID 07efcce17d28305556014ea2ea0a361ab380d978 # Parent 20ec5cc02f1878e6dbb52d2c49b7ad39029a7a3b convert: add -r argument specifying latest revision to convert diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py --- a/hgext/convert/__init__.py +++ b/hgext/convert/__init__.py @@ -17,12 +17,15 @@ commands.norepo += " convert" converters = [convert_cvs, convert_git, convert_mercurial] -def converter(ui, path): +def converter(ui, path, rev=None): if not os.path.isdir(path): raise util.Abort("%s: not a directory" % path) for c in converters: try: - return c(ui, path) + if rev: + return c(ui, path, rev=rev) + else: + return c(ui, path) except NoRepo: pass raise util.Abort("%s: unknown repository type" % path) @@ -248,6 +251,10 @@ def _convert(ui, src, dest=None, mapfile Accepted destination formats: - Mercurial + If no revision is given, all revisions will be converted. Otherwise, + convert will only import up to the named revision (given in a format + understood by the source). + If destination isn't given, a new Mercurial repo named -hg will be created. If isn't given, it will be put in a default location (/.hg/shamap by default) @@ -267,7 +274,7 @@ def _convert(ui, src, dest=None, mapfile srcauthor=whatever string you want ''' - srcc = converter(ui, src) + srcc = converter(ui, src, rev=opts.get('rev')) if not hasattr(srcc, "getcommit"): raise util.Abort("%s: can't read from this repo type" % src) @@ -313,6 +320,7 @@ cmdtable = { "convert": (_convert, [('A', 'authors', '', 'username mapping filename'), + ('r', 'rev', '', 'import up to target revision REV'), ('', 'datesort', None, 'try to sort changesets by date')], 'hg convert [OPTION]... SOURCE [DEST [MAPFILE]]'), } diff --git a/hgext/convert/common.py b/hgext/convert/common.py --- a/hgext/convert/common.py +++ b/hgext/convert/common.py @@ -12,7 +12,7 @@ class commit(object): class converter_source(object): """Conversion source interface""" - def __init__(self, ui, path): + def __init__(self, ui, path, rev=None): """Initialize conversion source (or raise NoRepo("message") exception if path is not a valid repository)""" raise NotImplementedError() diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py --- a/hgext/convert/cvs.py +++ b/hgext/convert/cvs.py @@ -6,9 +6,10 @@ from mercurial import util from common import NoRepo, commit, converter_source class convert_cvs(converter_source): - def __init__(self, ui, path): + def __init__(self, ui, path, rev=None): self.path = path self.ui = ui + self.rev = rev cvs = os.path.join(path, "CVS") if not os.path.exists(cvs): raise NoRepo("couldn't open CVS repo %s" % path) @@ -29,15 +30,32 @@ class convert_cvs(converter_source): if self.changeset: return + maxrev = 0 + cmd = 'cvsps -A -u --cvs-direct -q' + if self.rev: + # TODO: handle tags + try: + # patchset number? + maxrev = int(self.rev) + except ValueError: + try: + # date + util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S']) + cmd = "%s -d '1970/01/01 00:00:01' -d '%s'" % (cmd, self.rev) + except util.Abort: + raise util.Abort('revision %s is not a patchset number or date' % self.rev) + d = os.getcwd() try: os.chdir(self.path) id = None state = 0 - for l in os.popen("cvsps -A -u --cvs-direct -q"): + for l in os.popen(cmd): if state == 0: # header if l.startswith("PatchSet"): id = l[9:-2] + if maxrev and int(id) > maxrev: + state = 3 elif l.startswith("Date"): date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"]) date = util.datestr(date) @@ -85,6 +103,8 @@ class convert_cvs(converter_source): rev = l[colon+1:-2] rev = rev.split("->")[1] files[file] = rev + elif state == 3: + continue self.heads = self.lastbranch.values() finally: diff --git a/hgext/convert/git.py b/hgext/convert/git.py --- a/hgext/convert/git.py +++ b/hgext/convert/git.py @@ -5,7 +5,7 @@ import os from common import NoRepo, commit, converter_source class convert_git(converter_source): - def __init__(self, ui, path): + def __init__(self, ui, path, rev=None): if os.path.isdir(path + "/.git"): path += "/.git" if not os.path.exists(path + "/objects"): @@ -13,10 +13,12 @@ class convert_git(converter_source): self.path = path self.ui = ui + self.rev = rev self.encoding = 'utf-8' def getheads(self): - fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path) + rev = self.rev or 'HEAD' + fh = os.popen("GIT_DIR=%s git-rev-parse --verify %s" % (self.path, rev)) return [fh.read()[:-1]] def catfile(self, rev, type): diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py --- a/hgext/convert/hg.py +++ b/hgext/convert/hg.py @@ -6,7 +6,7 @@ from mercurial import hg from common import NoRepo, converter_sink class convert_mercurial(converter_sink): - def __init__(self, ui, path): + def __init__(self, ui, path, rev=None): self.path = path self.ui = ui try: