changeset 301:79440ed81011

Allow specifying a revision to stop at using the -H flag. This is useful for converting repositories which have been deleted or renamed, such as llvm-gcc-4-2 in the LLVM repositories which was renamed to llvm-gcc-4.2 shortly after its creation. Also, consolidate the two places in svn_swig_wrapper.py where a default chunk size is specified to one, single variable declaration.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Fri, 27 Mar 2009 03:21:45 +0100
parents 4aba7542f6a9
children 827d4702a3b3
files __init__.py fetch_command.py svnwrap/svn_swig_wrapper.py
diffstat 3 files changed, 44 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/__init__.py
+++ b/__init__.py
@@ -84,7 +84,8 @@ cmdtable = {
          ),
     "svnclone":
         (svn_fetch,
-         [('S', 'skipto-rev', '0', 'skip commits before this revision.'),
+         [('S', 'skipto-rev', 0, 'skip commits before this revision.'),
+          ('H', 'head', 0, 'skip revisions after this one.'),
           ('', 'stupid', False, 'be stupid and use diffy replay.'),
           ('T', 'tag-locations', 'tags', 'Relative path to Subversion tags.'),
           ('A', 'authors', '', 'username mapping filename'),
--- a/fetch_command.py
+++ b/fetch_command.py
@@ -21,7 +21,8 @@ def print_your_svn_is_old_message(ui): #
               "as good a job. You should really upgrade your server.\n")
 
 
-def fetch_revisions(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
+def fetch_revisions(ui, svn_url, hg_repo_path, skipto_rev=0, head=0,
+                    stupid=None,
                     tag_locations='tags',
                     authors=None,
                     filemap=None,
@@ -65,12 +66,23 @@ def fetch_revisions(ui, svn_url, hg_repo
         initializing_repo = True
         start = skipto_rev
 
+    if head <= 0:
+        stop = svn.last_changed_rev
+    else:
+        stop = head
+
     if initializing_repo and start > 0:
         raise merc_util.Abort('Revision skipping at repository initialization '
                               'remains unimplemented.')
 
+    if start >= stop:
+        ui.status('No new revisions beyond %d.\n' % stop)
+        return
+    else:
+        ui.status('Pulling revisions %d through %d.\n' % (start, stop))
+
     # start converting revisions
-    for r in svn.revisions(start=start):
+    for r in svn.revisions(start=start, stop=head):
         valid = True
         hg_editor.update_branch_tag_map_for_rev(r)
         for p in r.paths:
@@ -86,7 +98,7 @@ def fetch_revisions(ui, svn_url, hg_repo
                     util.describe_revision(ui, r)
                     if have_replay:
                         try:
-                            replay_convert_rev(hg_editor, svn, r)
+                            replay_convert_rev(hg_editor, svn, r, skipto_rev)
                         except svnwrap.SubversionRepoCanNotReplay, e: #pragma: no cover
                             ui.status('%s\n' % e.message)
                             print_your_svn_is_old_message(ui)
@@ -109,9 +121,9 @@ def cleanup_file_handles(svn, count):
     if count % 50 == 0:
         svn.init_ra_and_client()
 
-def replay_convert_rev(hg_editor, svn, r):
+def replay_convert_rev(hg_editor, svn, r, skipto_rev):
     hg_editor.set_current_rev(r)
-    svn.get_replay(r.revnum, hg_editor)
+    svn.get_replay(r.revnum, hg_editor, skipto_rev)
     i = 1
     if hg_editor.missing_plaintexts:
         hg_editor.ui.debug('Fetching %s files that could not use replay.\n' %
--- a/svnwrap/svn_swig_wrapper.py
+++ b/svnwrap/svn_swig_wrapper.py
@@ -29,6 +29,9 @@ class SubversionRepoCanNotDiff(Exception
     """Exception raised when the svn API diff3() command cannot be used
     """
 
+'''Default chunk size used in fetch_history_at_paths() and revisions().'''
+_chunk_size = 1000
+
 def optrev(revnum):
     optrev = core.svn_opt_revision_t()
     optrev.kind = core.svn_opt_revision_number
@@ -145,7 +148,7 @@ class SubversionRepo(object):
     This uses the SWIG Python bindings, and will only work on svn >= 1.4.
     It takes a required param, the URL.
     """
-    def __init__(self, url='', username=''):
+    def __init__(self, url='', username='', head=None):
         self.svn_url = url
         self.uname = username
         self.auth_baton_pool = core.Pool()
@@ -207,6 +210,26 @@ class SubversionRepo(object):
         return 0
     START = property(START)
 
+    def last_changed_rev(self):
+        try:
+            holder = []
+            ra.get_log(self.ra, [''],
+                       self.HEAD, 1,
+                       1, #limit of how many log messages to load
+                       True, # don't need to know changed paths
+                       True, # stop on copies
+                       lambda paths, revnum, author, date, message, pool:
+                           holder.append(revnum),
+                       self.pool)
+
+            return holder[-1]
+        except core.SubversionException, e:
+            if e.apr_err not in [core.SVN_ERR_FS_NOT_FOUND]:
+                raise
+            else:
+                return self.HEAD
+    last_changed_rev = property(last_changed_rev)
+
     def branches(self):
         """Get the branches defined in this repo assuming a standard layout.
 
@@ -302,7 +325,7 @@ class SubversionRepo(object):
         folders, props, junk = r
         return folders
 
-    def revisions(self, start=None, chunk_size=1000):
+    def revisions(self, start=None, stop=None, chunk_size=_chunk_size):
         """Load the history of this repo.
 
         This is LAZY. It returns a generator, and fetches a small number