[MERGE REQUEST] Couple of small fixes
Jelmer Vernooij
jelmer at samba.org
Fri Dec 9 01:21:30 GMT 2005
Hi Martin,
Please consider merging the following changes from my integration branch at
http://samba.org/~jelmer/bzr/foreignbranch.
1428 Jelmer Vernooij 2005-11-20
Use other registered branch types and add tests for foreign branches.
1427 Jelmer Vernooij 2005-11-20
Move use of Transport to BzrBranch
These changes are required for foreign Branch support and allow
viewing the history of foreign branches.
I am currently working on support for real checkouts in a branch that
contains this branch joined with Aaron's storage branch.
A diff of the changes in these revisions is attached.
Cheers, Jelmer
--
-------------- next part --------------
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py
+++ bzrlib/branch.py
@@ -92,6 +92,15 @@
self.unlock()
return decorated
+branch_types = []
+
+def register_branch_type(bt):
+ """Utility function to help register a branch type"""
+
+ branch_types.append(bt)
+
+ mutter('registered foreign branch type %s', bt.__name__)
+
######################################################################
# branch objects
@@ -114,14 +123,27 @@
return BzrBranch(get_transport(base), relax_version_check=True)
@staticmethod
- def open(base):
- """Open an existing branch, rooted at 'base' (url)"""
- t = get_transport(base)
- mutter("trying to open %r with transport %r", base, t)
- return BzrBranch(t)
+ def open(base,allowed_types=None):
+ """Open an existing branch, rooted at 'base' (url)
+
+ allowed_types
+ Branch types to allow (defaults to all branch types available)
+ """
+ if not allowed_types:
+ allowed_types = branch_types
+
+ for bt in allowed_types:
+ assert issubclass(bt, Branch)
+
+ try:
+ return bt.open(base)
+ except NotBranchError:
+ pass
+
+ raise NotBranchError(path=base)
@staticmethod
- def open_containing(url):
+ def open_containing(url,allowed_types=None):
"""Open an existing branch which contains url.
This probes for a branch at url, and searches upwards from there.
@@ -129,24 +151,28 @@
Basically we keep looking up until we find the control directory or
run into the root. If there isn't one, raises NotBranchError.
If there is one, it is returned, along with the unused portion of url.
- """
- t = get_transport(url)
- while True:
+
+ allowed_types
+ Branch types to allow (defaults to all branch types available)
+ """
+
+ if not allowed_types:
+ allowed_types = branch_types
+
+ for bt in allowed_types:
+ assert issubclass(bt, Branch)
+
try:
- return BzrBranch(t), t.relpath(url)
+ return bt.open_containing(url)
except NotBranchError:
pass
- new_t = t.clone('..')
- if new_t.base == t.base:
- # reached the root, whatever that may be
- raise NotBranchError(path=url)
- t = new_t
+
+ raise NotBranchError(path=url)
@staticmethod
def initialize(base):
"""Create a new branch, rooted at 'base' (url)"""
- t = get_transport(base)
- return BzrBranch(t, init=True)
+ return BzrBranch.initialize(base)
def setup_caching(self, cache_root):
"""Subclasses that care about caching should override this, and set
@@ -611,6 +637,35 @@
except UnlistableStore:
raise UnlistableBranch(from_store)
+ @staticmethod
+ def open(base):
+ """See Branch.open."""
+ t = get_transport(base)
+ mutter("trying to open %r with transport %r", base, t)
+ return BzrBranch(t)
+
+ @staticmethod
+ def open_containing(url):
+ """See Branch.open_containing."""
+ t = get_transport(url)
+ while True:
+ try:
+ return BzrBranch(t), t.relpath(url)
+ except NotBranchError:
+ pass
+ new_t = t.clone('..')
+ if new_t.base == t.base:
+ # reached the root, whatever that may be
+ raise NotBranchError(path=url)
+ t = new_t
+
+
+ @staticmethod
+ def initialize(base):
+ """See Branch.initialize."""
+ t = get_transport(base)
+ return BzrBranch(t,init=True)
+
def __init__(self, transport, init=False,
relax_version_check=False):
"""Create new branch object at a particular location.
@@ -1339,6 +1394,7 @@
self.revision_store.add(StringIO(gpg_strategy.sign(plaintext)),
revision_id, "sig")
+register_branch_type(BzrBranch)
class ScratchBranch(BzrBranch):
"""Special test class: a branch that cleans up after itself.
=== modified file 'bzrlib/selftest/testbranch.py'
--- bzrlib/selftest/testbranch.py
+++ bzrlib/selftest/testbranch.py
@@ -388,3 +388,64 @@
# TODO RBC 20051029 test getting a push location from a branch in a
# recursive section - that is, it appends the branch name.
+
+class TestForeignBranch(TestCaseInTempDir):
+ class FooError(Exception): pass
+ class FooBranch(Branch):
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def open(url):
+ if url == 'foo':
+ return TestForeignBranch.FooBranch()
+
+ if url == 'invalid':
+ raise TestForeignBranch.FooError
+
+ raise NotBranchError(path=url)
+
+ @staticmethod
+ def open_containing(base):
+ raise NotBranchError(path=base)
+
+ class BarBranch(Branch):
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def open(url):
+ if url == 'foo' or url == 'bar':
+ return TestForeignBranch.BarBranch()
+ raise NotBranchError(path=url)
+
+ @staticmethod
+ def open_containing(base):
+ raise NotBranchError(path=base)
+
+ def setUp(self):
+ super(TestForeignBranch, self).setUp()
+
+ from bzrlib.branch import register_branch_type
+ register_branch_type(self.FooBranch)
+ register_branch_type(self.BarBranch)
+
+ def test_open_allowed_types(self):
+ """test that the allowed_types argument to open() is honored"""
+ from bzrlib.branch import BzrBranch
+ self.assertRaises(NotBranchError, Branch.open, 'invalid', [BzrBranch])
+ self.assertRaises(NotBranchError, Branch.open, 'foo', [BzrBranch])
+ self.failUnless(isinstance(Branch.open('foo', [self.BarBranch]), self.BarBranch))
+
+ def test_non_exception_passthru(self):
+ """test that any non-NotBranchError exception gets thru"""
+ self.assertRaises(self.FooError, Branch.open, 'invalid', [self.FooBranch])
+ self.assertRaises(self.FooError, Branch.open, 'invalid')
+ self.assertRaises(NotBranchError, Branch.open, 'nonexisting')
+
+ def test_passthru(self):
+ """test that any successful branch url gets through
+ test that foreign branches get checked in the order they are registered"""
+ self.failUnless(isinstance(Branch.open('foo'), self.FooBranch))
+ self.failUnless(isinstance(Branch.open('bar'), self.BarBranch))
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051209/9c520e95/attachment.pgp
More information about the bazaar
mailing list