changeset 748:e1e2af66953d

svnmeta: store subdir in a file, and verify it when loading.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Fri, 12 Nov 2010 19:22:20 +0100
parents 34b25f6bc4ef
children ec52205e5ed1
files hgsubversion/svncommands.py hgsubversion/svnmeta.py hgsubversion/svnrepo.py hgsubversion/wrappers.py tests/test_rebuildmeta.py
diffstat 5 files changed, 41 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/svncommands.py
+++ b/hgsubversion/svncommands.py
@@ -113,6 +113,10 @@ def rebuildmeta(ui, repo, args, **opts):
 
     numrevs = len(repo)
 
+    subdirfile = open(os.path.join(svnmetadir, 'subdir'), 'w')
+    subdirfile.write(subdir.strip('/'))
+    subdirfile.close()
+
     # ctx.children() visits all revisions in the repository after ctx. Calling
     # it would make us use O(revisions^2) time, so we perform an extra traversal
     # of the repository instead. During this traversal, we find all converted
--- a/hgsubversion/svnmeta.py
+++ b/hgsubversion/svnmeta.py
@@ -32,7 +32,7 @@ def pickle_atomic(data, file_path, dir=N
 
 class SVNMeta(object):
 
-    def __init__(self, repo, uuid=None, subdir=''):
+    def __init__(self, repo, uuid=None, subdir=None):
         """path is the path to the target hg repo.
 
         subdir is the subdirectory of the edits *on the svn server*.
@@ -45,7 +45,7 @@ class SVNMeta(object):
         if not os.path.isdir(self.meta_data_dir):
             os.makedirs(self.meta_data_dir)
         self.uuid = uuid
-        # TODO: validate subdir too
+        self.subdir = subdir
         self.revmap = maps.RevMap(repo)
 
         author_host = self.ui.config('hgsubversion', 'defaulthost', uuid)
@@ -56,12 +56,6 @@ class SVNMeta(object):
         branchmap = self.ui.config('hgsubversion', 'branchmap')
         tagmap = self.ui.config('hgsubversion', 'tagmap')
 
-        # FIXME: test that this hasn't changed! defer & compare?
-        if subdir:
-            # strip leading and trailing slashes
-            # collapse all repeated slashes to a single one
-            subdir = '/'.join(p for p in subdir.split('/') if p)
-        self.subdir = subdir
         self.branches = {}
         if os.path.exists(self.branch_info_file):
             f = open(self.branch_info_file)
@@ -126,6 +120,38 @@ class SVNMeta(object):
             self._editor = editor.HgEditor(self)
         return self._editor
 
+    def _get_subdir(self):
+        return self.__subdir
+
+    def _set_subdir(self, subdir):
+        if subdir:
+            subdir = '/'.join(p for p in subdir.split('/') if p)
+
+        subdirfile = os.path.join(self.meta_data_dir, 'subdir')
+
+        if os.path.isfile(subdirfile):
+            stored_subdir = open(subdirfile).read()
+            assert stored_subdir is not None
+            if subdir is None:
+                self.__subdir = stored_subdir
+            elif subdir != stored_subdir:
+                raise hgutil.Abort('unable to work on a different path in the '
+                                   'repository')
+            else:
+                self.__subdir = subdir
+        elif subdir is not None:
+            f = open(subdirfile, 'w')
+            f.write(subdir)
+            f.close()
+            self.__subdir = subdir
+        else:
+            raise hgutil.Abort("hgsubversion metadata unavailable; "
+                               "please run 'hg svn rebuildmeta'")
+
+    subdir = property(_get_subdir, _set_subdir, None,
+                    'Error-checked sub-directory of source Subversion '
+                    'repository.')
+
     def _get_uuid(self):
         return self.__uuid
 
--- a/hgsubversion/svnrepo.py
+++ b/hgsubversion/svnrepo.py
@@ -66,7 +66,7 @@ def generate_repo_class(ui, repo):
         def findoutgoing(self, remote, base=None, heads=None, force=False):
             return wrappers.outgoing(repo, remote, heads, force)
 
-        def svnmeta(self, uuid=None, subdir=''):
+        def svnmeta(self, uuid=None, subdir=None):
             return svnmeta.SVNMeta(self, uuid, subdir)
 
     repo.__class__ = svnlocalrepo
--- a/hgsubversion/wrappers.py
+++ b/hgsubversion/wrappers.py
@@ -127,7 +127,7 @@ def push(repo, dest, force, revs):
     # TODO: do credentials specified in the URL still work?
     svnurl = repo.ui.expandpath(dest.svnurl)
     svn = dest.svn
-    meta = repo.svnmeta(svn.uuid)
+    meta = repo.svnmeta(svn.uuid, svn.subdir)
 
     # Strategy:
     # 1. Find all outgoing commits from this head
--- a/tests/test_rebuildmeta.py
+++ b/tests/test_rebuildmeta.py
@@ -44,7 +44,7 @@ def _do_case(self, name, stupid, single)
     self.assertTrue(os.path.isdir(os.path.join(src.path, 'svn')),
                     'no .hg/svn directory in the destination!')
     dest = hg.repository(u, os.path.dirname(dest.path))
-    for tf in ('rev_map', 'uuid', 'tagmap', 'layout', ):
+    for tf in ('rev_map', 'uuid', 'tagmap', 'layout', 'subdir', ):
         stf = os.path.join(src.path, 'svn', tf)
         self.assertTrue(os.path.isfile(stf), '%r is missing!' % stf)
         dtf = os.path.join(dest.path, 'svn', tf)