changeset 4753:07efcce17d28

convert: add -r argument specifying latest revision to convert
author Brendan Cully <brendan@kublai.com>
date Sun, 01 Jul 2007 15:02:15 -0700
parents 20ec5cc02f18
children 7c8cd400e86a
files hgext/convert/__init__.py hgext/convert/common.py hgext/convert/cvs.py hgext/convert/git.py hgext/convert/hg.py
diffstat 5 files changed, 39 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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 <src>-hg will
     be created. If <mapfile> isn't given, it will be put in a default
     location (<dest>/.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]]'),
 }
--- 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()
--- 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:
--- 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):
--- 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: