Rev 490: Allow only opening branches that actually exist. in file:///data/jelmer/bzr-svn/0.4/

Jelmer Vernooij jelmer at samba.org
Thu Jul 12 09:28:23 BST 2007


At file:///data/jelmer/bzr-svn/0.4/

------------------------------------------------------------
revno: 490
revision-id: jelmer at samba.org-20070624175251-v165quq77m6ey7ej
parent: jelmer at samba.org-20070624140849-6ijkriw19gdih4jz
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: main
timestamp: Sun 2007-06-24 19:52:51 +0200
message:
  Allow only opening branches that actually exist.
  Remove more uses of self.scheme in repositories.
modified:
  branch.py                      svnbranch.py-20051017135706-11c749eb0dab04a7
  fetch.py                       fetch.py-20060625004942-x2lfaib8ra707a8p-1
  format.py                      format.py-20060406233823-b6fa009fe35dfde7
  repository.py                  repository.py-20060306123302-1f8c5069b3fe0265
  tests/test_branch.py           test_branch.py-20060508162215-74ffeb5d608f8e20
  transport.py                   transport.py-20060406231150-b3472d06b3a0818d
=== modified file 'branch.py'
--- a/branch.py	2007-06-24 14:08:49 +0000
+++ b/branch.py	2007-06-24 17:52:51 +0000
@@ -17,12 +17,14 @@
 
 from bzrlib.branch import Branch, BranchFormat, BranchCheckResult, PullResult
 from bzrlib.bzrdir import BzrDir
-from bzrlib.errors import NoSuchFile, DivergedBranches, NoSuchRevision
+from bzrlib.errors import (NoSuchFile, DivergedBranches, NoSuchRevision, 
+                           NotBranchError)
 from bzrlib.inventory import (Inventory)
 from bzrlib.trace import mutter
 from bzrlib.workingtree import WorkingTree
 
 import svn.client, svn.core
+from svn.core import SubversionException
 
 from commit import push
 from format import get_rich_root_format
@@ -48,7 +50,7 @@
 
 class SvnBranch(Branch):
     """Maps to a Branch in a Subversion repository """
-    def __init__(self, base, repository, branch_path):
+    def __init__(self, base, repository, branch_path, revnum=None):
         """Instantiate a new SvnBranch.
 
         :param repos: SvnRepository this branch is part of.
@@ -64,6 +66,20 @@
         self._format = SvnBranchFormat()
         self._revision_history = None
         self.scheme = BranchingScheme.guess_scheme(branch_path)
+        self.revnum = revnum
+        try:
+            if self.repository.transport.check_path(self.branch_path.strip("/"), self.get_revnum()) != \
+                    svn.core.svn_node_dir:
+                raise NotBranchError(self.base)
+        except SubversionException, (_, num):
+            if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
+                raise NotBranchError(self.base)
+            raise
+
+    def get_revnum(self):
+        if self.revnum is None:
+            return self.repository._latest_revnum
+        return self.revnum
 
     def check(self):
         """See Branch.Check.
@@ -90,7 +106,8 @@
         :return: Revision number on the branch. 
         :raises NoSuchRevision: If the revision id was not found.
         """
-        (bp, revnum, scheme) = self.repository.lookup_revision_id(revid)
+        (bp, revnum, scheme) = self.repository.lookup_revision_id(revid, 
+                                                             scheme=self.scheme)
         assert bp.strip("/") == self.branch_path.strip("/"), \
                 "Got %r, expected %r" % (bp, self.branch_path)
         return revnum
@@ -187,7 +204,7 @@
 
     def revision_history(self):
         if self._revision_history is None:
-            self._generate_revision_history(self.repository._latest_revnum)
+            self._generate_revision_history(self.get_revnum())
         return self._revision_history
 
     def last_revision(self):
@@ -195,7 +212,7 @@
         # on large branches.
         if self._revision_history is None:
             for (branch, rev) in self.repository.follow_branch(
-                self.branch_path, self.repository._latest_revnum, self.scheme):
+                self.branch_path, self.get_revnum(), self.scheme):
                 return self.repository.generate_revision_id(rev, branch, 
                                                             self.scheme)
             return None

=== modified file 'fetch.py'
--- a/fetch.py	2007-06-24 14:08:49 +0000
+++ b/fetch.py	2007-06-24 17:52:51 +0000
@@ -326,18 +326,13 @@
         return None
 
     def _find_all(self):
-        needed = []
         parents = {}
-        for (branch, revnum) in self.source.follow_history(
-                                                self.source._latest_revnum, 
-                                                self.source.scheme):
-            revid = self.source.generate_revision_id(revnum, branch, 
-                                               self.source.scheme)
+        needed = filter(lambda x: not self.target.has_revision(x), 
+                        self.source.all_revision_ids())
+        for revid in needed:
+            (branch, revnum, scheme) = self.source.lookup_revision_id(revid)
             parents[revid] = self.source._mainline_revision_parent(branch, 
-                                               revnum, self.source.scheme)
-
-            if not self.target.has_revision(revid):
-                needed.append(revid)
+                                               revnum, scheme)
         return (needed, parents)
 
     def _find_until(self, revision_id):
@@ -370,8 +365,6 @@
         # Loop over all the revnums until revision_id
         # (or youngest_revnum) and call self.target.add_revision() 
         # or self.target.add_inventory() each time
-        needed = []
-        parents = {}
         self.target.lock_read()
         try:
             if revision_id is None:

=== modified file 'format.py'
--- a/format.py	2007-06-16 23:43:38 +0000
+++ b/format.py	2007-06-24 17:52:51 +0000
@@ -138,7 +138,8 @@
         repos = self.find_repository()
 
         if self.branch_path != "":
-            self.root_transport.mkdir(".")
+            repos.transport.mkdir(self.branch_path)
+            repos._latest_revnum = repos.transport.get_latest_revnum()
         else:
             # TODO: Check if there are any revisions in this repository yet
             pass
@@ -149,11 +150,6 @@
     def open_branch(self, unsupported=True):
         """See BzrDir.open_branch()."""
         from branch import SvnBranch
-
-        if not self.scheme.is_branch(self.branch_path) and \
-           not self.scheme.is_tag(self.branch_path):
-            raise NotBranchError(path=self.root_transport.base)
-
         repos = self.find_repository()
         branch = SvnBranch(self.root_transport.base, repos, self.branch_path)
         branch.bzrdir = self

=== modified file 'repository.py'
--- a/repository.py	2007-06-24 14:08:49 +0000
+++ b/repository.py	2007-06-24 17:52:51 +0000
@@ -234,10 +234,12 @@
         return self.fileid_map.apply_changes(uuid, revnum, branch, changes, 
                                              renames, scheme)
 
-    def all_revision_ids(self):
+    def all_revision_ids(self, scheme=None):
+        if scheme is None:
+            scheme = self.scheme
         for (bp, rev) in self.follow_history(
-                self.transport.get_latest_revnum(), self.scheme):
-            yield self.generate_revision_id(rev, bp, str(self.scheme))
+                self.transport.get_latest_revnum(), scheme):
+            yield self.generate_revision_id(rev, bp, str(scheme))
 
     def get_inventory_weave(self):
         raise NotImplementedError(self.get_inventory_weave)
@@ -289,7 +291,7 @@
             return False
 
         try:
-            return (svn.core.svn_node_none != self.transport.check_path(path.encode('utf8'), revnum))
+            return (svn.core.svn_node_none != self.transport.check_path(path, revnum))
         except SubversionException, (_, num):
             if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
                 return False
@@ -463,20 +465,22 @@
 
         return revid
 
-    def lookup_revision_id(self, revid):
+    def lookup_revision_id(self, revid, scheme=None):
         """Parse an existing Subversion-based revision id.
 
         :param revid: The revision id.
+        :param scheme: Optional branching scheme to use when searching for 
+                       revisions
         :raises: NoSuchRevision
         :return: Tuple with branch path, revision number and scheme.
         """
 
         # Try a simple parse
         try:
-            (uuid, branch_path, revnum, scheme) = parse_svn_revision_id(revid)
+            (uuid, branch_path, revnum, schemen) = parse_svn_revision_id(revid)
             assert isinstance(branch_path, str)
             if uuid == self.uuid:
-                return (branch_path, revnum, self.get_scheme(scheme))
+                return (branch_path, revnum, self.get_scheme(schemen))
             # If the UUID doesn't match, this may still be a valid revision
             # id; a revision from another SVN repository may be pushed into 
             # this one.
@@ -493,11 +497,13 @@
                 return (branch_path, min_revnum, self.get_scheme(scheme))
         except NoSuchRevision:
             # If there is no entry in the map, walk over all branches:
-            for (branch, revno, exists) in self.find_branches(self.scheme):
+            if scheme is None:
+                scheme = self.scheme # FIXME
+            for (branch, revno, exists) in self.find_branches(scheme):
                 # Look at their bzr:revision-id-vX
                 revids = []
                 for line in self.branchprop_list.get_property(branch, revno, 
-                        SVN_PROP_BZR_REVISION_ID+str(self.scheme), "").splitlines():
+                        SVN_PROP_BZR_REVISION_ID+str(scheme), "").splitlines():
                     try:
                         revids.append(parse_revid_property(line))
                     except errors.InvalidPropertyValue, e:
@@ -507,7 +513,7 @@
                 # add them
                 for (entry_revno, entry_revid) in revids:
                     self.revmap.insert_revid(entry_revid, branch, 0, revno, 
-                            str(self.scheme), entry_revno)
+                            str(scheme), entry_revno)
 
                 if revid in revids:
                     break
@@ -518,7 +524,8 @@
         # Find the branch property between min_revnum and max_revnum that 
         # added revid
         i = min_revnum
-        for (bp, rev) in self.follow_branch(branch_path, max_revnum, self.get_scheme(scheme)):
+        for (bp, rev) in self.follow_branch(branch_path, max_revnum, 
+                                            self.get_scheme(scheme)):
             try:
                 (entry_revno, entry_revid) = parse_revid_property(
                  self.branchprop_list.get_property_diff(bp, rev, 
@@ -564,6 +571,7 @@
         :param revnum: Revision number up to which to search.
         :return: iterator over branches in the range 0..revnum
         """
+        assert scheme is not None
 
         while revnum >= 0:
             yielded_paths = []
@@ -712,7 +720,7 @@
             return {}
 
         if revision_id is None:
-            return self._full_revision_graph(self.scheme)
+            return self._full_revision_graph(self.scheme) # FIXME
 
         (path, revnum, scheme) = self.lookup_revision_id(revision_id)
 

=== modified file 'tests/test_branch.py'
--- a/tests/test_branch.py	2007-06-24 14:08:49 +0000
+++ b/tests/test_branch.py	2007-06-24 17:52:51 +0000
@@ -18,7 +18,7 @@
 
 from bzrlib.branch import Branch
 from bzrlib.bzrdir import BzrDir
-from bzrlib.errors import NoSuchFile, NoSuchRevision
+from bzrlib.errors import NoSuchFile, NoSuchRevision, NotBranchError
 from bzrlib.repository import Repository
 from bzrlib.trace import mutter
 
@@ -38,6 +38,10 @@
         branch.revision_history()
         self.assertEqual(branch.generate_revision_id(0), branch.last_revision())
 
+    def test_open_nonexistant(self):
+        repos_url = self.make_client("a", "dc")
+        self.assertRaises(NotBranchError, Branch.open, repos_url + "/trunk")
+
     def test_last_rev_rev_info(self):
         repos_url = self.make_client("a", "dc")
         branch = Branch.open(repos_url)
@@ -228,7 +232,7 @@
     def test_get_nick_path(self):
         repos_url = self.make_client('a', 'dc')
 
-        self.build_tree({'dc/trunk': "data"})
+        self.build_tree({'dc/trunk': None})
         self.client_add("dc/trunk")
         self.client_commit("dc", "My Message")
 

=== modified file 'transport.py'
--- a/transport.py	2007-05-27 19:33:30 +0000
+++ b/transport.py	2007-06-24 17:52:51 +0000
@@ -243,7 +243,7 @@
     def check_path(self, path, revnum, *args, **kwargs):
         assert len(path) == 0 or path[0] != "/"
         mutter("svn check_path -r%d %s" % (revnum, path))
-        return svn.ra.check_path(self._ra, path, revnum, *args, **kwargs)
+        return svn.ra.check_path(self._ra, path.encode('utf-8'), revnum, *args, **kwargs)
 
     @need_lock
     @convert_svn_error




More information about the bazaar-commits mailing list