[PATCH 6 of 6] convert: pass startrev to sources as an optimization hint
Patrick Mezard
pmezard at gmail.com
Tue Jan 1 17:03:16 CST 2008
# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1199228284 -3600
# Node ID 8ea6e30f0970063b3c4eb2d6d3e91215a16b6214
# Parent 788a3da824f18f7669aee3c65cd4fc0132a3d97e
convert: pass startrev to sources as an optimization hint
diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -40,9 +40,14 @@ class converter_source(object):
class converter_source(object):
"""Conversion source interface"""
- def __init__(self, ui, path=None, rev=None):
+ def __init__(self, ui, path=None, rev=None, startrev=None):
"""Initialize conversion source (or raise NoRepo("message")
- exception if path is not a valid repository)"""
+ exception if path is not a valid repository)
+
+ If startrev is not None, the conversion operates on startrev descendants.
+ It can be used to optimize revisions retrieval but must not change
+ the source output.
+ """
self.ui = ui
self.path = path
self.rev = rev
diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -31,12 +31,12 @@ sink_converters = [
('svn', svn_sink),
]
-def convertsource(ui, path, type, rev):
+def convertsource(ui, path, type, rev, startrev):
exceptions = []
for name, source in source_converters:
try:
if not type or name == type:
- return source(ui, path, rev)
+ return source(ui, path, rev, startrev)
except NoRepo, inst:
exceptions.append(inst)
if not ui.quiet:
@@ -287,16 +287,16 @@ def convert(ui, src, dest=None, revmapfi
destc = convertsink(ui, dest, opts.get('dest_type'))
try:
+ startrev = opts.get('startrev')
srcc = convertsource(ui, src, opts.get('source_type'),
- opts.get('rev'))
+ opts.get('rev'), startrev)
except Exception:
for path in destc.created:
shutil.rmtree(path, True)
raise
- if opts.get('startrev'):
- srcc = revstart.startrev_source(ui, srcc,
- opts.get('startrev'))
+ if startrev:
+ srcc = revstart.startrev_source(ui, srcc, startrev)
fmap = opts.get('filemap')
if fmap:
diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py
--- a/hgext/convert/cvs.py
+++ b/hgext/convert/cvs.py
@@ -7,8 +7,9 @@ from common import NoRepo, commit, conve
from common import NoRepo, commit, converter_source, checktool
class convert_cvs(converter_source):
- def __init__(self, ui, path, rev=None):
- super(convert_cvs, self).__init__(ui, path, rev=rev)
+ def __init__(self, ui, path, rev=None, startrev=None):
+ super(convert_cvs, self).__init__(ui, path, rev=rev,
+ startrev=startrev)
cvs = os.path.join(path, "CVS")
if not os.path.exists(cvs):
diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py
--- a/hgext/convert/darcs.py
+++ b/hgext/convert/darcs.py
@@ -18,8 +18,8 @@ except ImportError:
class darcs_source(converter_source, commandline):
- def __init__(self, ui, path, rev=None):
- converter_source.__init__(self, ui, path, rev=rev)
+ def __init__(self, ui, path, rev=None, startrev=None):
+ converter_source.__init__(self, ui, path, rev=rev, startrev=startrev)
commandline.__init__(self, ui, 'darcs')
# check for _darcs, ElementTree, _darcs/inventory so that we can
diff --git a/hgext/convert/git.py b/hgext/convert/git.py
--- a/hgext/convert/git.py
+++ b/hgext/convert/git.py
@@ -24,8 +24,9 @@ class convert_git(converter_source):
def gitcmd(self, s):
return util.popen('GIT_DIR=%s %s' % (self.path, s))
- def __init__(self, ui, path, rev=None):
- super(convert_git, self).__init__(ui, path, rev=rev)
+ def __init__(self, ui, path, rev=None, startrev=None):
+ super(convert_git, self).__init__(ui, path, rev=rev,
+ startrev=startrev)
if os.path.isdir(path + "/.git"):
path += "/.git"
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -185,8 +185,8 @@ class mercurial_sink(converter_sink):
self.filemapmode = active
class mercurial_source(converter_source):
- def __init__(self, ui, path, rev=None):
- converter_source.__init__(self, ui, path, rev)
+ def __init__(self, ui, path, rev=None, startrev=None):
+ converter_source.__init__(self, ui, path, rev, startrev=startrev)
self.saverev = ui.configbool('convert', 'hg.saverev', True)
try:
self.repo = hg.repository(self.ui, path)
diff --git a/hgext/convert/revstart.py b/hgext/convert/revstart.py
--- a/hgext/convert/revstart.py
+++ b/hgext/convert/revstart.py
@@ -17,7 +17,7 @@ class startrev_source(converter_source):
before any operations making use of source revisions.
"""
def __init__(self, ui, baseconverter, startrev):
- super(startrev_source, self).__init__(ui)
+ super(startrev_source, self).__init__(ui, startrev=startrev)
self.startrev = startrev
self.built = False
self.commits = {}
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -101,8 +101,9 @@ def debugsvnlog(ui, **opts):
# SVN conversion code stolen from bzr-svn and tailor
class svn_source(converter_source):
- def __init__(self, ui, url, rev=None):
- super(svn_source, self).__init__(ui, url, rev=rev)
+ def __init__(self, ui, url, rev=None, startrev=None):
+ super(svn_source, self).__init__(ui, url, rev=rev,
+ startrev=startrev)
try:
SubversionException
@@ -113,6 +114,9 @@ class svn_source(converter_source):
# Map module to the last and last but one converted revision
# for that module.
self.lastrevs = {}
+ # Map module to the module converted revision preceding the start
+ # revision and the start revision
+ self.startrevs = {}
latest = None
try:
@@ -143,6 +147,10 @@ class svn_source(converter_source):
if rev:
latest = self.revnum(self.getrevid(rev))
+ self.startrev = 0
+ if startrev:
+ self.startrev = self.revnum(self.getrevid(startrev))
+
try:
self.get_blacklist()
except IOError, e:
@@ -161,6 +169,7 @@ class svn_source(converter_source):
def setrevmap(self, revmap):
lastrevs = {}
+ startrevs = {}
for revid in revmap.iterkeys():
uuid, module, revnum = self.revsplit(revid)
if module in lastrevs:
@@ -171,8 +180,14 @@ class svn_source(converter_source):
lastrevs[module] = (revnum, lastnum)
else:
lastrevs[module] = (0, revnum)
+
+ if self.startrev > 0:
+ prev, start = startrevs.setdefault(module, (0, self.startrev))
+ if prev < revnum < start:
+ startrevs[module] = (revnum, start)
self.lastrevs = lastrevs
+ self.startrevs = startrevs
def exists(self, path, optrev):
try:
@@ -586,8 +601,14 @@ class svn_source(converter_source):
self.reparent(module)
# We assume commits are requested from children to parents,
# so we try to fetch and cache ranges ending at revnum.
+ # 1- Try to cache down to module last converted revisions
prevstop, stop = self.lastrevs.get(module, (0, 0))
if stop > revnum:
+ # 2- Then try down to the module converted revision just
+ # lower than the start revision
+ prevstop, stop = self.startrevs.get(module, (0, 0))
+ if stop > revnum:
+ # 3- Fetch all revisions for this module
prevstop, stop = 0, 0
# Fetch down to prevstop instead of stop because the cached
# to_revnum revision parents are invalid
More information about the Mercurial-devel
mailing list