changeset 1347:759cafce6bec stable 1.8.3

editor: cope with slightly out-of-order editor drives As of Subversion 1.8, ra_serf replaces ra_neon as the only http remote access method. ra_serf does lots of clever network things, but as a side effect violates some of the legacy editor API. It turns out we were only barely using those guarantees, so it was straightforward to relax our constraints and work with serf. Prior to this change, attempting to use ra_serf would almost certainly result in an exception due to an out-of-order editor drive. See https://svn.apache.org/repos/asf/subversion/trunk/notes/api-errata/1.7/ra001.txt for more details of the Subversion change.
author Augie Fackler <raf@durin42.com>
date Sat, 26 Sep 2015 10:49:57 -0400
parents 2fdf16f2d4dd
children 17876c2c9ce5
files hgsubversion/editor.py
diffstat 1 files changed, 7 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/editor.py
+++ b/hgsubversion/editor.py
@@ -199,8 +199,8 @@ class HgEditor(svnwrap.Editor):
         self._openpaths = {}
         self._deleted = set()
         self._getctx = hgutil.lrucachefunc(self.repo.changectx)
-        # A stack of opened directory (baton, path) pairs.
-        self._opendirs = []
+        # A map from directory baton to path
+        self._opendirs = {}
         self._missing = set()
 
     def _openfile(self, path, data, isexec, islink, copypath, create=False):
@@ -220,16 +220,13 @@ class HgEditor(svnwrap.Editor):
     def _opendir(self, path):
         self._filecounter += 1
         baton = 'f%d-%s' % (self._filecounter, path)
-        self._opendirs.append((baton, path))
+        self._opendirs[baton] = path
         return baton
 
     def _checkparentdir(self, baton):
-        if not self._opendirs:
+        if not self._opendirs or baton not in self._opendirs:
             raise EditingError('trying to operate on an already closed '
                 'directory: %s' % baton)
-        if self._opendirs[-1][0] != baton:
-            raise EditingError('can only operate on the most recently '
-                'opened directory: %s != %s' % (self._opendirs[-1][0], baton))
 
     def _deletefile(self, path):
         if self.meta.is_path_valid(path):
@@ -532,7 +529,7 @@ class HgEditor(svnwrap.Editor):
         self._checkparentdir(dir_baton)
         if len(self._opendirs) == 1:
             return
-        path = self._opendirs[-1][1]
+        path = self._opendirs[dir_baton]
         if name == 'svn:externals':
             self.current.externals[path] = value
 
@@ -556,7 +553,7 @@ class HgEditor(svnwrap.Editor):
     @svnwrap.ieditor
     def close_directory(self, dir_baton, dir_pool=None):
         self._checkparentdir(dir_baton)
-        self._opendirs.pop()
+        del self._opendirs[dir_baton]
 
     @svnwrap.ieditor
     def apply_textdelta(self, file_baton, base_checksum, pool=None):
@@ -620,7 +617,7 @@ class HgEditor(svnwrap.Editor):
 
         if self._opendirs:
             raise EditingError('directory %s was not closed'
-                % self._opendirs[-1][1])
+                % self._opendirs.keys()[-1])
 
         # Resolve by changelog entries to avoid extra reads
         nodes = {}