[PATCH 4 of 6] convert: fix svn source getcommit()

Patrick Mezard pmezard at gmail.com
Tue Jan 1 17:03:14 CST 2008


# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1199228244 -3600
# Node ID 987216ee81437fa8f61bc7c1dd80203e1d8e1461
# Parent  43e851a9485190fa79b2a6d668214058111d2ac6
convert: fix svn source getcommit()

Converted revision heads were returned without any parents. It did not impact
the converter because such revisions were only retrieved for their branch
information.

diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -110,6 +110,8 @@ class svn_source(converter_source):
             raise NoRepo('Subversion python bindings could not be loaded')
 
         self.encoding = locale.getpreferredencoding()
+        # Map module to the last and last but one converted revision
+        # for that module.
         self.lastrevs = {}
 
         latest = None
@@ -164,9 +166,15 @@ class svn_source(converter_source):
         lastrevs = {}
         for revid in revmap.iterkeys():
             uuid, module, revnum = self.revsplit(revid)
-            lastrevnum = lastrevs.setdefault(module, revnum)
-            if revnum > lastrevnum:
-                lastrevs[module] = revnum
+            if module in lastrevs:
+                prevlastnum, lastnum = lastrevs[module]
+                if revnum > lastnum:
+                    lastrevs[module] = (lastnum, revnum)
+                elif revnum > prevlastnum and revnum < lastnum:
+                    lastrevs[module] = (revnum, lastnum)
+            else:
+                lastrevs[module] = (0, revnum)
+
         self.lastrevs = lastrevs
 
     def exists(self, path, optrev):
@@ -249,15 +257,7 @@ class svn_source(converter_source):
 
     def getcommit(self, rev):
         if rev not in self.commits:
-            uuid, module, revnum = self.revsplit(rev)
-            self.module = module
-            self.reparent(module)
-            stop = self.lastrevs.get(module, 0)
-            if stop > revnum:
-                raise util.Abort(
-                    _("subversion source cannot return converted "
-                      "revisions ancestors: %s") % rev)
-            self._fetch_revisions(from_revnum=revnum, to_revnum=stop)
+            self._fetch_revision(rev)                
         commit = self.commits[rev]
         # caller caches the result, so free it here to release memory
         del self.commits[rev]
@@ -564,6 +564,23 @@ class svn_source(converter_source):
                                 # copy from quux splort/quuxfile
 
         return (entries, copies)
+
+    def _fetch_revision(self, rev):
+        uuid, module, revnum = self.revsplit(rev)
+        self.module = module
+        self.reparent(module)
+        # We assume commits are requested from children to parents,
+        # so we try to fetch and cache ranges ending at revnum.
+        prevstop, stop = self.lastrevs.get(module, (0, 0))
+        if stop > revnum:
+            raise util.Abort(
+                _("subversion source cannot return converted "
+                  "revisions ancestors: %s") % rev)
+        # Fetch down to prevstop instead of stop because the cached 
+        # to_revnum revision parents are invalid
+        self._fetch_revisions(from_revnum=revnum, to_revnum=prevstop)
+        if prevstop != 0 and self.revid(prevstop) in self.commits:
+            del self.commits[self.revid(prevstop)]
 
     def _fetch_revisions(self, from_revnum, to_revnum):
         if from_revnum < to_revnum:


More information about the Mercurial-devel mailing list