91
class ControlComponent(object):
92
"""Abstract base class for control directory components.
94
This provides interfaces that are common across bzrdirs,
95
repositories, branches, and workingtree control directories.
97
They all expose two urls and transports: the *user* URL is the
98
one that stops above the control directory (eg .bzr) and that
99
should normally be used in messages, and the *control* URL is
100
under that in eg .bzr/checkout and is used to read the control
103
This can be used as a mixin and is intended to fit with
108
def control_transport(self):
109
raise NotImplementedError
112
def control_url(self):
113
return self.control_transport.base
116
def user_transport(self):
117
raise NotImplementedError
121
return self.user_transport.base
124
class BzrDir(ControlComponent):
92
125
"""A .bzr control diretory.
94
127
BzrDir instances let you create or open any of the things that can be
261
294
# copied, and finally if we are copying up to a specific
262
295
# revision_id then we can use the pending-ancestry-result which
263
296
# does not require traversing all of history to describe it.
264
if (result_repo.bzrdir.root_transport.base ==
265
result.root_transport.base and not require_stacking and
297
if (result_repo.user_url == result.user_url
298
and not require_stacking and
266
299
revision_id is not None):
267
300
fetch_spec = graph.PendingAncestryResult(
268
301
[revision_id], local_repo)
466
499
except errors.NoRepositoryPresent:
467
500
repository = None
469
if ((found_bzrdir.root_transport.base !=
470
self.root_transport.base) and not repository.is_shared()):
502
if (found_bzrdir.user_url != self.user_url
503
and not repository.is_shared()):
471
504
# Don't look higher, can't use a higher shared repo.
472
505
repository = None
671
704
next_transport = found_bzrdir.root_transport.clone('..')
672
if (found_bzrdir.root_transport.base == next_transport.base):
705
if (found_bzrdir.user_url == next_transport.base):
673
706
# top of the file system
675
708
# find the next containing bzrdir
692
725
repository = found_bzrdir.open_repository()
693
726
except errors.NoRepositoryPresent:
694
727
return None, False
695
if found_bzrdir.root_transport.base == self.root_transport.base:
728
if found_bzrdir.user_url == self.user_url:
696
729
return repository, True
697
730
elif repository.is_shared():
698
731
return repository, True
704
737
raise errors.NoRepositoryPresent(self)
705
738
return found_repo
707
def get_branch_reference(self):
740
def get_branch_reference(self, name=None):
708
741
"""Return the referenced URL for the branch in this bzrdir.
743
:param name: Optional colocated branch name
710
744
:raises NotBranchError: If there is no Branch.
745
:raises NoColocatedBranchSupport: If a branch name was specified
746
but colocated branches are not supported.
711
747
:return: The URL the branch in this bzrdir references if it is a
712
748
reference branch, or None for regular branches.
751
raise errors.NoColocatedBranchSupport(self)
716
754
def get_branch_transport(self, branch_format, name=None):
814
852
:param _transport: the transport this dir is based at.
816
854
self._format = _format
855
# these are also under the more standard names of
856
# control_transport and user_transport
817
857
self.transport = _transport.clone('.bzr')
818
858
self.root_transport = _transport
819
859
self._mode_check_done = False
862
def user_transport(self):
863
return self.root_transport
866
def control_transport(self):
867
return self.transport
821
869
def is_control_filename(self, filename):
822
870
"""True if filename is the name of a path which is reserved for bzrdir's.
951
999
raise errors.NotBranchError(path=url)
952
1000
a_transport = new_t
954
def _get_tree_branch(self):
1002
def _get_tree_branch(self, name=None):
955
1003
"""Return the branch and tree, if any, for this bzrdir.
1005
:param name: Name of colocated branch to open.
957
1007
Return None for tree if not present or inaccessible.
958
1008
Raise NotBranchError if no branch is present.
959
1009
:return: (tree, branch)
962
1012
tree = self.open_workingtree()
963
1013
except (errors.NoWorkingTree, errors.NotLocalUrl):
965
branch = self.open_branch()
1015
branch = self.open_branch(name=name)
1017
if name is not None:
1018
branch = self.open_branch(name=name)
1020
branch = tree.branch
968
1021
return tree, branch
1330
1383
self.create_hook(hooks.HookPoint('pre_open',
1331
1384
"Invoked before attempting to open a BzrDir with the transport "
1332
1385
"that the open will use.", (1, 14), None))
1386
self.create_hook(hooks.HookPoint('post_repo_init',
1387
"Invoked after a repository has been initialized. "
1388
"post_repo_init is called with a "
1389
"bzrlib.bzrdir.RepoInitHookParams.",
1334
1392
# install the default hooks
1335
1393
BzrDir.hooks = BzrDirHooks()
1396
class RepoInitHookParams(object):
1397
"""Object holding parameters passed to *_repo_init hooks.
1399
There are 4 fields that hooks may wish to access:
1401
:ivar repository: Repository created
1402
:ivar format: Repository format
1403
:ivar bzrdir: The bzrdir for the repository
1404
:ivar shared: The repository is shared
1407
def __init__(self, repository, format, a_bzrdir, shared):
1408
"""Create a group of RepoInitHook parameters.
1410
:param repository: Repository created
1411
:param format: Repository format
1412
:param bzrdir: The bzrdir for the repository
1413
:param shared: The repository is shared
1415
self.repository = repository
1416
self.format = format
1417
self.bzrdir = a_bzrdir
1418
self.shared = shared
1420
def __eq__(self, other):
1421
return self.__dict__ == other.__dict__
1425
return "<%s for %s>" % (self.__class__.__name__,
1428
return "<%s for %s>" % (self.__class__.__name__,
1338
1432
class BzrDirPreSplitOut(BzrDir):
1339
1433
"""A common class for the all-in-one formats."""
1652
1746
def destroy_workingtree_metadata(self):
1653
1747
self.transport.delete_tree('checkout')
1655
def find_branch_format(self):
1749
def find_branch_format(self, name=None):
1656
1750
"""Find the branch 'format' for this bzrdir.
1658
1752
This might be a synthetic object for e.g. RemoteBranch and SVN.
1660
1754
from bzrlib.branch import BranchFormat
1661
return BranchFormat.find_format(self)
1755
return BranchFormat.find_format(self, name=name)
1663
1757
def _get_mkdir_mode(self):
1664
1758
"""Figure out the mode to use when creating a bzrdir subdir."""
1666
1760
lockable_files.TransportLock)
1667
1761
return temp_control._dir_mode
1669
def get_branch_reference(self):
1763
def get_branch_reference(self, name=None):
1670
1764
"""See BzrDir.get_branch_reference()."""
1671
1765
from bzrlib.branch import BranchFormat
1672
format = BranchFormat.find_format(self)
1673
return format.get_reference(self)
1766
format = BranchFormat.find_format(self, name=name)
1767
return format.get_reference(self, name=name)
1675
1769
def get_branch_transport(self, branch_format, name=None):
1676
1770
"""See BzrDir.get_branch_transport()."""
1770
1864
def open_branch(self, name=None, unsupported=False,
1771
1865
ignore_fallbacks=False):
1772
1866
"""See BzrDir.open_branch."""
1773
format = self.find_branch_format()
1867
format = self.find_branch_format(name=name)
1774
1868
self._check_supported(format, unsupported)
1775
1869
return format.open(self, name=name,
1776
1870
_found=True, ignore_fallbacks=ignore_fallbacks)
2651
2745
if isinstance(self.bzrdir.transport, local.LocalTransport):
2652
2746
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2653
2747
self._convert_to_weaves()
2654
return BzrDir.open(self.bzrdir.root_transport.base)
2748
return BzrDir.open(self.bzrdir.user_url)
2656
2750
self.pb.finished()
3032
3126
BzrDirMetaFormat1().get_format_string(),
3033
3127
mode=self.file_mode)
3034
3128
self.pb.finished()
3035
return BzrDir.open(self.bzrdir.root_transport.base)
3129
return BzrDir.open(self.bzrdir.user_url)
3037
3131
def make_lock(self, name):
3038
3132
"""Make a lock for the new control dir name."""
3620
3714
stack_on = urlutils.rebase_url(self._stack_on,
3621
3715
self._stack_on_pwd,
3622
branch.bzrdir.root_transport.base)
3623
3717
except errors.InvalidRebaseURLs:
3624
3718
stack_on = self._get_full_stack_on()