Rev 5189: (mbp) add ControlComponent base class and standard user_url etc in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Apr 28 09:23:38 BST 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5189 [merge]
revision-id: pqm at pqm.ubuntu.com-20100428082334-tmv91z1h0d99ls8s
parent: pqm at pqm.ubuntu.com-20100428043109-l9zglvkumb7q4x62
parent: mbp at sourcefrog.net-20100428070338-2af8y3takgfkrkyp
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2010-04-28 09:23:34 +0100
message:
  (mbp) add ControlComponent base class and standard user_url etc
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/check.py                check.py-20050309040759-f3a679400c06bcc1
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/info.py                 info.py-20050323235939-6bbfe7d9700b0b9b
  bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
  bzrlib/reconfigure.py          reconfigure.py-20070908040425-6ykgo7escxhyrg9p-1
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
  bzrlib/tests/per_branch/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
  bzrlib/tests/per_bzrdir/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
  bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/per_workingtree/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
  bzrlib/tests/test_foreign.py   test_foreign.py-20081125004048-ywb901edgp9lluxo-1
  bzrlib/upgrade.py              history2weaves.py-20050818063535-e7d319791c19a8b2
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
=== modified file 'NEWS'
--- a/NEWS	2010-04-27 18:09:12 +0000
+++ b/NEWS	2010-04-28 07:03:38 +0000
@@ -64,6 +64,14 @@
 API Changes
 ***********
 
+* `BzrDir`, `Branch`, `Repository` and `WorkingTree` now all support `user_url`,
+  `user_transport`, `control_url` and `control_transport` members pointing
+  respectively to the directory containing the ``.bzr`` control directory, 
+  and to the directory within ``.bzr`` used for the particular component.
+  All of them inherit from `ControlComponent` which provides default
+  implementations.
+  (Martin Pool)
+
 Internals
 *********
 

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2010-04-23 07:15:23 +0000
+++ b/bzrlib/branch.py	2010-04-28 07:03:38 +0000
@@ -63,23 +63,12 @@
 BZR_BRANCH_FORMAT_6 = "Bazaar Branch Format 6 (bzr 0.15)\n"
 
 
-# TODO: Maybe include checks for common corruption of newlines, etc?
-
-# TODO: Some operations like log might retrieve the same revisions
-# repeatedly to calculate deltas.  We could perhaps have a weakref
-# cache in memory to make this faster.  In general anything can be
-# cached in memory between lock and unlock operations. .. nb thats
-# what the transaction identity map provides
-
-
-######################################################################
-# branch objects
-
-class Branch(object):
+class Branch(bzrdir.ControlComponent):
     """Branch holding a history of revisions.
 
-    base
-        Base directory/url of the branch.
+    :ivar base:
+        Base directory/url of the branch; using control_url and
+        control_transport is more standardized.
 
     hooks: An instance of BranchHooks.
     """
@@ -87,6 +76,14 @@
     # - RBC 20060112
     base = None
 
+    @property
+    def control_transport(self):
+        return self._transport
+
+    @property
+    def user_transport(self):
+        return self.bzrdir.user_transport
+
     def __init__(self, *ignored, **ignored_too):
         self.tags = self._format.make_tags(self)
         self._revision_history_cache = None
@@ -107,7 +104,7 @@
         """Activate the branch/repository from url as a fallback repository."""
         repo = self._get_fallback_repository(url)
         if repo.has_same_location(self.repository):
-            raise errors.UnstackableLocationError(self.base, url)
+            raise errors.UnstackableLocationError(self.user_url, url)
         self.repository.add_fallback_repository(repo)
 
     def break_lock(self):
@@ -594,11 +591,11 @@
         :param other: The branch to bind to
         :type other: Branch
         """
-        raise errors.UpgradeRequired(self.base)
+        raise errors.UpgradeRequired(self.user_url)
 
     def set_append_revisions_only(self, enabled):
         if not self._format.supports_set_append_revisions_only():
-            raise errors.UpgradeRequired(self.base)
+            raise errors.UpgradeRequired(self.user_url)
         if enabled:
             value = 'True'
         else:
@@ -652,7 +649,7 @@
     def get_old_bound_location(self):
         """Return the URL of the branch we used to be bound to
         """
-        raise errors.UpgradeRequired(self.base)
+        raise errors.UpgradeRequired(self.user_url)
 
     def get_commit_builder(self, parents, config=None, timestamp=None,
                            timezone=None, committer=None, revprops=None,
@@ -736,7 +733,7 @@
             stacking.
         """
         if not self._format.supports_stacking():
-            raise errors.UnstackableBranchFormat(self._format, self.base)
+            raise errors.UnstackableBranchFormat(self._format, self.user_url)
         # XXX: Changing from one fallback repository to another does not check
         # that all the data you need is present in the new fallback.
         # Possibly it should.
@@ -893,7 +890,7 @@
 
     def unbind(self):
         """Older format branches cannot bind or unbind."""
-        raise errors.UpgradeRequired(self.base)
+        raise errors.UpgradeRequired(self.user_url)
 
     def last_revision(self):
         """Return last revision id, or NULL_REVISION."""
@@ -1059,7 +1056,7 @@
         try:
             return urlutils.join(self.base[:-1], parent)
         except errors.InvalidURLJoin, e:
-            raise errors.InaccessibleParent(parent, self.base)
+            raise errors.InaccessibleParent(parent, self.user_url)
 
     def _get_parent_location(self):
         raise NotImplementedError(self._get_parent_location)
@@ -1564,7 +1561,7 @@
             elsewhere)
         :return: a branch in this format
         """
-        mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
+        mutter('creating branch %r in %s', self, a_bzrdir.user_url)
         branch_transport = a_bzrdir.get_branch_transport(self, name=name)
         lock_map = {
             'metadir': ('lock', lockdir.LockDir),
@@ -1957,8 +1954,8 @@
             if format.__class__ != self.__class__:
                 raise AssertionError("wrong format %r found for %r" %
                     (format, self))
+        transport = a_bzrdir.get_branch_transport(None, name=name)
         try:
-            transport = a_bzrdir.get_branch_transport(None, name=name)
             control_files = lockable_files.LockableFiles(transport, 'lock',
                                                          lockdir.LockDir)
             return self._branch_class()(_format=self,
@@ -2162,10 +2159,10 @@
             # this format does not implement branch itself, thus the implicit
             # creation contract must see it as uninitializable
             raise errors.UninitializableFormat(self)
-        mutter('creating branch reference in %s', a_bzrdir.transport.base)
+        mutter('creating branch reference in %s', a_bzrdir.user_url)
         branch_transport = a_bzrdir.get_branch_transport(self, name=name)
         branch_transport.put_bytes('location',
-            target_branch.bzrdir.root_transport.base)
+            target_branch.bzrdir.user_url)
         branch_transport.put_bytes('format', self.get_format_string())
         branch = self.open(
             a_bzrdir, name, _found=True,
@@ -2293,9 +2290,10 @@
 
     def __str__(self):
         if self.name is None:
-            return '%s(%r)' % (self.__class__.__name__, self.base)
+            return '%s(%s)' % (self.__class__.__name__, self.user_url)
         else:
-            return '%s(%r,%r)' % (self.__class__.__name__, self.base, self.name)
+            return '%s(%s,%s)' % (self.__class__.__name__, self.user_url,
+                self.name)
 
     __repr__ = __str__
 
@@ -2516,7 +2514,7 @@
         return result
 
     def get_stacked_on_url(self):
-        raise errors.UnstackableBranchFormat(self._format, self.base)
+        raise errors.UnstackableBranchFormat(self._format, self.user_url)
 
     def set_push_location(self, location):
         """See Branch.set_push_location."""
@@ -2712,7 +2710,7 @@
         if _mod_revision.is_null(last_revision):
             return
         if last_revision not in self._lefthand_history(revision_id):
-            raise errors.AppendRevisionsOnlyViolation(self.base)
+            raise errors.AppendRevisionsOnlyViolation(self.user_url)
 
     def _gen_revision_history(self):
         """Generate the revision history from last revision
@@ -2818,7 +2816,7 @@
         if branch_location is None:
             return Branch.reference_parent(self, file_id, path,
                                            possible_transports)
-        branch_location = urlutils.join(self.base, branch_location)
+        branch_location = urlutils.join(self.user_url, branch_location)
         return Branch.open(branch_location,
                            possible_transports=possible_transports)
 
@@ -2939,7 +2937,7 @@
     """
 
     def get_stacked_on_url(self):
-        raise errors.UnstackableBranchFormat(self._format, self.base)
+        raise errors.UnstackableBranchFormat(self._format, self.user_url)
 
 
 ######################################################################
@@ -3032,7 +3030,7 @@
         :param verbose: Requests more detailed display of what was checked,
             if any.
         """
-        note('checked branch %s format %s', self.branch.base,
+        note('checked branch %s format %s', self.branch.user_url,
             self.branch._format)
         for error in self.errors:
             note('found error:%s', error)
@@ -3367,7 +3365,7 @@
         if local and not bound_location:
             raise errors.LocalRequiresBoundBranch()
         master_branch = None
-        if not local and bound_location and self.source.base != bound_location:
+        if not local and bound_location and self.source.user_url != bound_location:
             # not pulling from master, so we need to update master.
             master_branch = self.target.get_master_branch(possible_transports)
             master_branch.lock_write()

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2010-04-23 11:11:22 +0000
+++ b/bzrlib/builtins.py	2010-04-28 07:03:38 +0000
@@ -504,9 +504,7 @@
                 if (working.has_changes()):
                     raise errors.UncommittedChanges(working)
 
-            working_path = working.bzrdir.root_transport.base
-            branch_path = working.branch.bzrdir.root_transport.base
-            if working_path != branch_path:
+            if working.user_url != working.branch.user_url:
                 raise errors.BzrCommandError("You cannot remove the working tree"
                                              " from a lightweight checkout")
 

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2010-04-22 17:08:27 +0000
+++ b/bzrlib/bzrdir.py	2010-04-28 07:03:38 +0000
@@ -86,9 +86,42 @@
     registry,
     symbol_versioning,
     )
-
-
-class BzrDir(object):
+    
+    
+class ControlComponent(object):
+    """Abstract base class for control directory components.
+    
+    This provides interfaces that are common across bzrdirs, 
+    repositories, branches, and workingtree control directories.
+    
+    They all expose two urls and transports: the *user* URL is the 
+    one that stops above the control directory (eg .bzr) and that 
+    should normally be used in messages, and the *control* URL is
+    under that in eg .bzr/checkout and is used to read the control
+    files.
+    
+    This can be used as a mixin and is intended to fit with 
+    foreign formats.
+    """
+    
+    @property
+    def control_transport(self):
+        raise NotImplementedError
+   
+    @property
+    def control_url(self):
+        return self.control_transport.base
+    
+    @property
+    def user_transport(self):
+        raise NotImplementedError
+        
+    @property
+    def user_url(self):
+        return self.user_transport.base
+    
+
+class BzrDir(ControlComponent):
     """A .bzr control diretory.
 
     BzrDir instances let you create or open any of the things that can be
@@ -261,8 +294,8 @@
                 # copied, and finally if we are copying up to a specific
                 # revision_id then we can use the pending-ancestry-result which
                 # does not require traversing all of history to describe it.
-                if (result_repo.bzrdir.root_transport.base ==
-                    result.root_transport.base and not require_stacking and
+                if (result_repo.user_url == result.user_url
+                    and not require_stacking and
                     revision_id is not None):
                     fetch_spec = graph.PendingAncestryResult(
                         [revision_id], local_repo)
@@ -458,7 +491,7 @@
             stop = False
             stack_on = config.get_default_stack_on()
             if stack_on is not None:
-                stack_on_pwd = found_bzrdir.root_transport.base
+                stack_on_pwd = found_bzrdir.user_url
                 stop = True
             # does it have a repository ?
             try:
@@ -466,8 +499,8 @@
             except errors.NoRepositoryPresent:
                 repository = None
             else:
-                if ((found_bzrdir.root_transport.base !=
-                     self.root_transport.base) and not repository.is_shared()):
+                if (found_bzrdir.user_url != self.user_url 
+                    and not repository.is_shared()):
                     # Don't look higher, can't use a higher shared repo.
                     repository = None
                     stop = True
@@ -669,7 +702,7 @@
             if stop:
                 return result
             next_transport = found_bzrdir.root_transport.clone('..')
-            if (found_bzrdir.root_transport.base == next_transport.base):
+            if (found_bzrdir.user_url == next_transport.base):
                 # top of the file system
                 return None
             # find the next containing bzrdir
@@ -692,7 +725,7 @@
                 repository = found_bzrdir.open_repository()
             except errors.NoRepositoryPresent:
                 return None, False
-            if found_bzrdir.root_transport.base == self.root_transport.base:
+            if found_bzrdir.user_url == self.user_url:
                 return repository, True
             elif repository.is_shared():
                 return repository, True
@@ -814,9 +847,19 @@
         :param _transport: the transport this dir is based at.
         """
         self._format = _format
+        # these are also under the more standard names of 
+        # control_transport and user_transport
         self.transport = _transport.clone('.bzr')
         self.root_transport = _transport
         self._mode_check_done = False
+        
+    @property 
+    def user_transport(self):
+        return self.root_transport
+        
+    @property
+    def control_transport(self):
+        return self.transport
 
     def is_control_filename(self, filename):
         """True if filename is the name of a path which is reserved for bzrdir's.
@@ -2692,7 +2735,7 @@
             if isinstance(self.bzrdir.transport, local.LocalTransport):
                 self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
             self._convert_to_weaves()
-            return BzrDir.open(self.bzrdir.root_transport.base)
+            return BzrDir.open(self.bzrdir.user_url)
         finally:
             self.pb.finished()
 
@@ -2945,7 +2988,7 @@
         try:
             ui.ui_factory.note('starting upgrade from format 5 to 6')
             self._convert_to_prefixed()
-            return BzrDir.open(self.bzrdir.root_transport.base)
+            return BzrDir.open(self.bzrdir.user_url)
         finally:
             pb.finished()
 
@@ -3073,7 +3116,7 @@
             BzrDirMetaFormat1().get_format_string(),
             mode=self.file_mode)
         self.pb.finished()
-        return BzrDir.open(self.bzrdir.root_transport.base)
+        return BzrDir.open(self.bzrdir.user_url)
 
     def make_lock(self, name):
         """Make a lock for the new control dir name."""
@@ -3660,7 +3703,7 @@
             try:
                 stack_on = urlutils.rebase_url(self._stack_on,
                     self._stack_on_pwd,
-                    branch.bzrdir.root_transport.base)
+                    branch.user_url)
             except errors.InvalidRebaseURLs:
                 stack_on = self._get_full_stack_on()
         try:

=== modified file 'bzrlib/check.py'
--- a/bzrlib/check.py	2009-09-18 01:06:10 +0000
+++ b/bzrlib/check.py	2010-04-23 00:44:15 +0000
@@ -192,8 +192,8 @@
 
     def _report_repo_results(self, verbose):
         note('checked repository %s format %s',
-             self.repository.bzrdir.root_transport,
-             self.repository._format)
+            self.repository.user_url,
+            self.repository._format)
         note('%6d revisions', self.checked_rev_cnt)
         note('%6d file-ids', len(self.checked_weaves))
         if verbose:
@@ -451,7 +451,7 @@
             if do_repo or do_branch or do_tree:
                 if do_repo:
                     note("Checking repository at '%s'."
-                         % (repo.bzrdir.root_transport.base,))
+                         % (repo.user_url,))
                 result = repo.check(None, callback_refs=needed_refs,
                     check_repo=do_repo)
                 result.report_results(verbose)

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2010-03-24 14:15:01 +0000
+++ b/bzrlib/errors.py	2010-04-21 11:27:04 +0000
@@ -2176,7 +2176,7 @@
 
     def __init__(self, repo):
         BzrError.__init__(self)
-        self.repo_path = repo.bzrdir.root_transport.base
+        self.repo_path = repo.user_url
 
 
 class InconsistentDelta(BzrError):
@@ -2754,7 +2754,7 @@
 
     def __init__(self, bzrdir):
         import bzrlib.urlutils as urlutils
-        display_url = urlutils.unescape_for_display(bzrdir.root_transport.base,
+        display_url = urlutils.unescape_for_display(bzrdir.user_url,
                                                     'ascii')
         BzrError.__init__(self, bzrdir=bzrdir, display_url=display_url)
 
@@ -2835,7 +2835,7 @@
             more = ' ' + more
         import bzrlib.urlutils as urlutils
         display_url = urlutils.unescape_for_display(
-            tree.bzrdir.root_transport.base, 'ascii')
+            tree.user_url, 'ascii')
         BzrError.__init__(self, tree=tree, display_url=display_url, more=more)
 
 

=== modified file 'bzrlib/info.py'
--- a/bzrlib/info.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/info.py	2010-04-21 09:57:18 +0000
@@ -80,9 +80,9 @@
 
 def gather_location_info(repository, branch=None, working=None):
     locs = {}
-    repository_path = repository.bzrdir.root_transport.base
+    repository_path = repository.user_url
     if branch is not None:
-        branch_path = branch.bzrdir.root_transport.base
+        branch_path = branch.user_url
         master_path = branch.get_bound_location()
         if master_path is None:
             master_path = branch_path
@@ -90,7 +90,7 @@
         branch_path = None
         master_path = None
     if working:
-        working_path = working.bzrdir.root_transport.base
+        working_path = working.user_url
         if working_path != branch_path:
             locs['light checkout root'] = working_path
         if master_path != branch_path:
@@ -420,8 +420,8 @@
         if branch is None and tree is not None:
             phrase = "branchless tree"
         else:
-            if (tree is not None and tree.bzrdir.root_transport.base !=
-                branch.bzrdir.root_transport.base):
+            if (tree is not None and tree.user_url !=
+                branch.user_url):
                 independence = ''
                 phrase = "Lightweight checkout"
             elif branch.get_bound_location() is not None:
@@ -446,8 +446,7 @@
     """
     candidates  = []
     if (branch is not None and tree is not None and
-        branch.bzrdir.root_transport.base !=
-        tree.bzrdir.root_transport.base):
+        branch.user_url != tree.user_url):
         branch = None
         repository = None
     non_aliases = set(bzrdir.format_registry.keys())

=== modified file 'bzrlib/reconcile.py'
--- a/bzrlib/reconcile.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/reconcile.py	2010-04-23 00:44:15 +0000
@@ -97,7 +97,7 @@
     def _reconcile_repository(self):
         self.repo = self.bzrdir.find_repository()
         ui.ui_factory.note('Reconciling repository %s' %
-            self.repo.bzrdir.root_transport.base)
+            self.repo.user_url)
         self.pb.update("Reconciling repository", 0, 1)
         repo_reconciler = self.repo.reconcile(thorough=True)
         self.inconsistent_parents = repo_reconciler.inconsistent_parents

=== modified file 'bzrlib/reconfigure.py'
--- a/bzrlib/reconfigure.py	2010-03-25 09:39:03 +0000
+++ b/bzrlib/reconfigure.py	2010-04-23 00:44:15 +0000
@@ -82,14 +82,13 @@
             self.repository = None
             self.local_repository = None
         else:
-            if (self.repository.bzrdir.root_transport.base ==
-                self.bzrdir.root_transport.base):
+            if (self.repository.user_url == self.bzrdir.user_url):
                 self.local_repository = self.repository
             else:
                 self.local_repository = None
         try:
             branch = self.bzrdir.open_branch()
-            if branch.bzrdir.root_transport.base == bzrdir.root_transport.base:
+            if branch.user_url == bzrdir.user_url:
                 self.local_branch = branch
                 self.referenced_branch = None
             else:
@@ -217,8 +216,8 @@
             if not want_reference:
                 self._create_repository = True
         else:
-            if want_reference and (self.repository.bzrdir.root_transport.base
-                                   == self.bzrdir.root_transport.base):
+            if want_reference and (
+                self.repository.user_url == self.bzrdir.user_url):
                 if not self.repository.is_shared():
                     self._destroy_repository = True
         if self.referenced_branch is None:
@@ -344,7 +343,7 @@
             if self._create_reference:
                 reference_branch.repository.fetch(self.repository)
             elif self.local_branch is not None and not self._destroy_branch:
-                up = self.local_branch.bzrdir.root_transport.clone('..')
+                up = self.local_branch.user_transport.clone('..')
                 up_bzrdir = bzrdir.BzrDir.open_containing_from_transport(up)[0]
                 new_repo = up_bzrdir.find_repository()
                 new_repo.fetch(self.repository)

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2010-04-20 04:16:50 +0000
+++ b/bzrlib/remote.py	2010-04-28 07:03:38 +0000
@@ -643,7 +643,8 @@
         return self._custom_format._serializer
 
 
-class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
+class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
+    bzrdir.ControlComponent):
     """Repository accessed over rpc.
 
     For the moment most operations are performed using local transport-backed
@@ -692,6 +693,17 @@
         # Additional places to query for data.
         self._fallback_repositories = []
 
+    @property
+    def user_transport(self):
+        return self.bzrdir.user_transport
+
+    @property
+    def control_transport(self):
+        # XXX: Normally you shouldn't directly get at the remote repository
+        # transport, but I'm not sure it's worth making this method
+        # optional -- mbp 2010-04-21
+        return self.bzrdir.get_repository_transport(None)
+        
     def __str__(self):
         return "%s(%s)" % (self.__class__.__name__, self.base)
 
@@ -1234,9 +1246,9 @@
         # _real_branch had its get_stacked_on_url method called), then the
         # repository to be added may already be in the _real_repositories list.
         if self._real_repository is not None:
-            fallback_locations = [repo.bzrdir.root_transport.base for repo in
+            fallback_locations = [repo.user_url for repo in
                 self._real_repository._fallback_repositories]
-            if repository.bzrdir.root_transport.base not in fallback_locations:
+            if repository.user_url not in fallback_locations:
                 self._real_repository.add_fallback_repository(repository)
 
     def _check_fallback_repository(self, repository):
@@ -2181,7 +2193,8 @@
             self._real_branch = None
         # Fill out expected attributes of branch for bzrlib API users.
         self._clear_cached_state()
-        self.base = self.bzrdir.root_transport.base
+        # TODO: deprecate self.base in favor of user_url
+        self.base = self.bzrdir.user_url
         self._name = name
         self._control_files = None
         self._lock_mode = None

=== modified file 'bzrlib/repofmt/weaverepo.py'
--- a/bzrlib/repofmt/weaverepo.py	2010-04-26 13:51:08 +0000
+++ b/bzrlib/repofmt/weaverepo.py	2010-04-28 07:03:38 +0000
@@ -177,7 +177,7 @@
         :param new_value: True to restore the default, False to disable making
                           working trees.
         """
-        raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
+        raise errors.RepositoryUpgradeRequired(self.user_url)
 
     def make_working_trees(self):
         """Returns the policy for making working trees on new branches."""

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2010-04-22 17:08:27 +0000
+++ b/bzrlib/repository.py	2010-04-28 07:03:38 +0000
@@ -864,7 +864,7 @@
 # Repositories
 
 
-class Repository(_RelockDebugMixin):
+class Repository(_RelockDebugMixin, bzrdir.ControlComponent):
     """Repository holding history for one or more branches.
 
     The repository holds and retrieves historical information including
@@ -1291,11 +1291,10 @@
 
         :param _format: The format of the repository on disk.
         :param a_bzrdir: The BzrDir of the repository.
-
-        In the future we will have a single api for all stores for
-        getting file texts, inventories and revisions, then
-        this construct will accept instances of those things.
         """
+        # In the future we will have a single api for all stores for
+        # getting file texts, inventories and revisions, then
+        # this construct will accept instances of those things.
         super(Repository, self).__init__()
         self._format = _format
         # the following are part of the public API for Repository:
@@ -1316,6 +1315,14 @@
         # rather copying them?
         self._safe_to_return_from_cache = False
 
+    @property
+    def user_transport(self):
+        return self.bzrdir.user_transport
+
+    @property
+    def control_transport(self):
+        return self._transport
+
     def __repr__(self):
         if self._fallback_repositories:
             return '%s(%r, fallback_repositories=%r)' % (
@@ -1469,7 +1476,7 @@
 
         # now gather global repository information
         # XXX: This is available for many repos regardless of listability.
-        if self.bzrdir.root_transport.listable():
+        if self.user_transport.listable():
             # XXX: do we want to __define len__() ?
             # Maybe the versionedfiles object should provide a different
             # method to get the number of keys.
@@ -1507,7 +1514,7 @@
 
         ret = []
         for branches, repository in bzrdir.BzrDir.find_bzrdirs(
-                self.bzrdir.root_transport, evaluate=Evaluator()):
+                self.user_transport, evaluate=Evaluator()):
             if branches is not None:
                 ret.extend(branches)
             if not using and repository is not None:

=== modified file 'bzrlib/smart/bzrdir.py'
--- a/bzrlib/smart/bzrdir.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/smart/bzrdir.py	2010-04-23 00:44:15 +0000
@@ -110,7 +110,7 @@
         """Get the relative path for repository from current_transport."""
         # the relpath of the bzrdir in the found repository gives us the
         # path segments to pop-out.
-        relpath = repository.bzrdir.root_transport.relpath(
+        relpath = repository.user_transport.relpath(
             current_transport.base)
         if len(relpath):
             segments = ['..'] * len(relpath.split('/'))

=== modified file 'bzrlib/tests/per_branch/test_branch.py'
--- a/bzrlib/tests/per_branch/test_branch.py	2010-03-02 22:25:58 +0000
+++ b/bzrlib/tests/per_branch/test_branch.py	2010-04-21 04:12:25 +0000
@@ -988,3 +988,16 @@
         merger.do_merge()
         self.assertEqual('../branch/reference',
                          tree.branch.get_reference_info('file-id')[1])
+
+
+class TestBranchControlComponent(per_branch.TestCaseWithBranch):
+    """Branch implementations adequately implement ControlComponent."""
+    
+    def test_urls(self):
+        br = self.make_branch('branch')
+        self.assertIsInstance(br.user_url, str)
+        self.assertEqual(br.user_url, br.user_transport.base)
+        # for all current bzrdir implementations the user dir must be 
+        # above the control dir but we might need to relax that?
+        self.assertEqual(br.control_url.find(br.user_url), 0)
+        self.assertEqual(br.control_url, br.control_transport.base)

=== modified file 'bzrlib/tests/per_bzrdir/test_bzrdir.py'
--- a/bzrlib/tests/per_bzrdir/test_bzrdir.py	2010-04-11 19:40:23 +0000
+++ b/bzrlib/tests/per_bzrdir/test_bzrdir.py	2010-04-21 04:02:42 +0000
@@ -1971,3 +1971,15 @@
         self.assertRaises(errors.NoRepositoryPresent,
                           made_control.find_repository)
 
+
+class TestBzrDirControlComponent(TestCaseWithBzrDir):
+    """BzrDir implementations adequately implement ControlComponent."""
+    
+    def test_urls(self):
+        bd = self.make_bzrdir('bd')
+        self.assertIsInstance(bd.user_url, str)
+        self.assertEqual(bd.user_url, bd.user_transport.base)
+        # for all current bzrdir implementations the user dir must be 
+        # above the control dir but we might need to relax that?
+        self.assertEqual(bd.control_url.find(bd.user_url), 0)
+        self.assertEqual(bd.control_url, bd.control_transport.base)

=== modified file 'bzrlib/tests/per_repository/test_repository.py'
--- a/bzrlib/tests/per_repository/test_repository.py	2010-04-10 01:22:00 +0000
+++ b/bzrlib/tests/per_repository/test_repository.py	2010-04-21 04:53:33 +0000
@@ -1342,3 +1342,18 @@
         fileobj = StringIO()
         wt.branch.repository.create_bundle(
             'rev1', _mod_revision.NULL_REVISION, fileobj)
+
+
+
+
+class TestRepositoryControlComponent(per_repository.TestCaseWithRepository):
+    """Repository implementations adequately implement ControlComponent."""
+    
+    def test_urls(self):
+        repo = self.make_repository('repo')
+        self.assertIsInstance(repo.user_url, str)
+        self.assertEqual(repo.user_url, repo.user_transport.base)
+        # for all current bzrdir implementations the user dir must be 
+        # above the control dir but we might need to relax that?
+        self.assertEqual(repo.control_url.find(repo.user_url), 0)
+        self.assertEqual(repo.control_url, repo.control_transport.base)

=== modified file 'bzrlib/tests/per_workingtree/test_workingtree.py'
--- a/bzrlib/tests/per_workingtree/test_workingtree.py	2010-03-02 22:25:58 +0000
+++ b/bzrlib/tests/per_workingtree/test_workingtree.py	2010-04-21 09:41:26 +0000
@@ -1091,3 +1091,16 @@
         # We should display the relative path
         self.assertEqual('subdir/m\xb5', e.filename)
         self.assertEqual(osutils._fs_enc, e.fs_encoding)
+
+
+class TestControlComponent(TestCaseWithWorkingTree):
+    """WorkingTree implementations adequately implement ControlComponent."""
+    
+    def test_urls(self):
+        wt = self.make_branch_and_tree('wt')
+        self.assertIsInstance(wt.user_url, str)
+        self.assertEqual(wt.user_url, wt.user_transport.base)
+        # for all current bzrdir implementations the user dir must be 
+        # above the control dir but we might need to relax that?
+        self.assertEqual(wt.control_url.find(wt.user_url), 0)
+        self.assertEqual(wt.control_url, wt.control_transport.base)

=== modified file 'bzrlib/tests/test_foreign.py'
--- a/bzrlib/tests/test_foreign.py	2010-03-02 22:25:58 +0000
+++ b/bzrlib/tests/test_foreign.py	2010-04-23 00:44:15 +0000
@@ -90,6 +90,7 @@
         self._format = _format
         self._base = a_bzrdir.transport.base
         self._ignore_fallbacks = False
+        self.bzrdir = a_bzrdir
         foreign.ForeignBranch.__init__(self, 
             DummyForeignVcsMapping(DummyForeignVcs()))
         branch.BzrBranch6.__init__(self, _format, _control_files, a_bzrdir, 

=== modified file 'bzrlib/upgrade.py'
--- a/bzrlib/upgrade.py	2010-03-25 07:34:15 +0000
+++ b/bzrlib/upgrade.py	2010-04-21 11:27:04 +0000
@@ -47,11 +47,10 @@
     def convert(self):
         try:
             branch = self.bzrdir.open_branch()
-            if branch.bzrdir.root_transport.base != \
-                self.bzrdir.root_transport.base:
+            if branch.user_url != self.bzrdir.user_url:
                 ui.ui_factory.note("This is a checkout. The branch (%s) needs to be "
                              "upgraded separately." %
-                             branch.bzrdir.root_transport.base)
+                             branch.user_url)
             del branch
         except (errors.NotBranchError, errors.IncompatibleRepositories):
             # might not be a format we can open without upgrading; see e.g.

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2010-04-08 06:05:44 +0000
+++ b/bzrlib/workingtree.py	2010-04-27 04:30:01 +0000
@@ -29,12 +29,6 @@
 WorkingTree.open(dir).
 """
 
-# TODO: Give the workingtree sole responsibility for the working inventory;
-# remove the variable and references to it from the branch.  This may require
-# updating the commit code so as to update the inventory within the working
-# copy, and making sure there's only one WorkingTree for any directory on disk.
-# At the moment they may alias the inventory and have old copies of it in
-# memory.  (Now done? -- mbp 20060309)
 
 from cStringIO import StringIO
 import os
@@ -174,7 +168,8 @@
         return ''
 
 
-class WorkingTree(bzrlib.mutabletree.MutableTree):
+class WorkingTree(bzrlib.mutabletree.MutableTree,
+    bzrdir.ControlComponent):
     """Working copy tree.
 
     The inventory is held in the `Branch` working-inventory, and the
@@ -253,6 +248,14 @@
         self._rules_searcher = None
         self.views = self._make_views()
 
+    @property
+    def user_transport(self):
+        return self.bzrdir.user_transport
+
+    @property
+    def control_transport(self):
+        return self._transport
+
     def _detect_case_handling(self):
         wt_trans = self.bzrdir.get_workingtree_transport(None)
         try:




More information about the bazaar-commits mailing list