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):
125
92
"""A .bzr control diretory.
127
94
BzrDir instances let you create or open any of the things that can be
294
261
# copied, and finally if we are copying up to a specific
295
262
# revision_id then we can use the pending-ancestry-result which
296
263
# does not require traversing all of history to describe it.
297
if (result_repo.user_url == result.user_url
298
and not require_stacking and
264
if (result_repo.bzrdir.root_transport.base ==
265
result.root_transport.base and not require_stacking and
299
266
revision_id is not None):
300
267
fetch_spec = graph.PendingAncestryResult(
301
268
[revision_id], local_repo)
499
466
except errors.NoRepositoryPresent:
500
467
repository = None
502
if (found_bzrdir.user_url != self.user_url
503
and not repository.is_shared()):
469
if ((found_bzrdir.root_transport.base !=
470
self.root_transport.base) and not repository.is_shared()):
504
471
# Don't look higher, can't use a higher shared repo.
505
472
repository = None
635
602
# already exists, but it should instead either remove it or make
636
603
# a new backup directory.
605
# FIXME: bug 262450 -- the backup directory should have the same
606
# permissions as the .bzr directory (probably a bug in copy_tree)
638
607
old_path = self.root_transport.abspath('.bzr')
639
608
new_path = self.root_transport.abspath(backup_dir)
640
609
ui.ui_factory.note('making backup of %s\n to %s' % (old_path, new_path,))
704
673
next_transport = found_bzrdir.root_transport.clone('..')
705
if (found_bzrdir.user_url == next_transport.base):
674
if (found_bzrdir.root_transport.base == next_transport.base):
706
675
# top of the file system
708
677
# find the next containing bzrdir
725
694
repository = found_bzrdir.open_repository()
726
695
except errors.NoRepositoryPresent:
727
696
return None, False
728
if found_bzrdir.user_url == self.user_url:
697
if found_bzrdir.root_transport.base == self.root_transport.base:
729
698
return repository, True
730
699
elif repository.is_shared():
731
700
return repository, True
737
706
raise errors.NoRepositoryPresent(self)
738
707
return found_repo
740
def get_branch_reference(self, name=None):
709
def get_branch_reference(self):
741
710
"""Return the referenced URL for the branch in this bzrdir.
743
:param name: Optional colocated branch name
744
712
:raises NotBranchError: If there is no Branch.
745
:raises NoColocatedBranchSupport: If a branch name was specified
746
but colocated branches are not supported.
747
713
:return: The URL the branch in this bzrdir references if it is a
748
714
reference branch, or None for regular branches.
751
raise errors.NoColocatedBranchSupport(self)
754
def get_branch_transport(self, branch_format, name=None):
718
def get_branch_transport(self, branch_format):
755
719
"""Get the transport for use by branch format in this BzrDir.
757
721
Note that bzr dirs that do not support format strings will raise
852
816
:param _transport: the transport this dir is based at.
854
818
self._format = _format
855
# these are also under the more standard names of
856
# control_transport and user_transport
857
819
self.transport = _transport.clone('.bzr')
858
820
self.root_transport = _transport
859
821
self._mode_check_done = False
862
def user_transport(self):
863
return self.root_transport
866
def control_transport(self):
867
return self.transport
869
823
def is_control_filename(self, filename):
870
824
"""True if filename is the name of a path which is reserved for bzrdir's.
999
953
raise errors.NotBranchError(path=url)
1000
954
a_transport = new_t
1002
def _get_tree_branch(self, name=None):
956
def _get_tree_branch(self):
1003
957
"""Return the branch and tree, if any, for this bzrdir.
1005
:param name: Name of colocated branch to open.
1007
959
Return None for tree if not present or inaccessible.
1008
960
Raise NotBranchError if no branch is present.
1009
961
:return: (tree, branch)
1012
964
tree = self.open_workingtree()
1013
965
except (errors.NoWorkingTree, errors.NotLocalUrl):
1015
branch = self.open_branch(name=name)
967
branch = self.open_branch()
1017
if name is not None:
1018
branch = self.open_branch(name=name)
1020
branch = tree.branch
1021
970
return tree, branch
1383
1332
self.create_hook(hooks.HookPoint('pre_open',
1384
1333
"Invoked before attempting to open a BzrDir with the transport "
1385
1334
"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.",
1392
1336
# install the default hooks
1393
1337
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__,
1432
1340
class BzrDirPreSplitOut(BzrDir):
1433
1341
"""A common class for the all-in-one formats."""
1476
1384
def create_branch(self, name=None):
1477
1385
"""See BzrDir.create_branch."""
1478
return self._format.get_branch_format().initialize(self, name=name)
1386
if name is not None:
1387
raise errors.NoColocatedBranchSupport(self)
1388
return self._format.get_branch_format().initialize(self)
1480
1390
def destroy_branch(self, name=None):
1481
1391
"""See BzrDir.destroy_branch."""
1539
1449
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1542
def get_branch_transport(self, branch_format, name=None):
1452
def get_branch_transport(self, branch_format):
1543
1453
"""See BzrDir.get_branch_transport()."""
1544
if name is not None:
1545
raise errors.NoColocatedBranchSupport(self)
1546
1454
if branch_format is None:
1547
1455
return self.transport
1584
1492
def open_branch(self, name=None, unsupported=False,
1585
1493
ignore_fallbacks=False):
1586
1494
"""See BzrDir.open_branch."""
1495
if name is not None:
1496
raise errors.NoColocatedBranchSupport(self)
1587
1497
from bzrlib.branch import BzrBranchFormat4
1588
1498
format = BzrBranchFormat4()
1589
1499
self._check_supported(format, unsupported)
1590
return format.open(self, name, _found=True)
1500
return format.open(self, _found=True)
1592
1502
def sprout(self, url, revision_id=None, force_new_repo=False,
1593
1503
possible_transports=None, accelerator_tree=None,
1713
1623
def create_branch(self, name=None):
1714
1624
"""See BzrDir.create_branch."""
1715
return self._format.get_branch_format().initialize(self, name=name)
1625
if name is not None:
1626
raise errors.NoColocatedBranchSupport(self)
1627
return self._format.get_branch_format().initialize(self)
1717
1629
def destroy_branch(self, name=None):
1718
1630
"""See BzrDir.create_branch."""
1746
1658
def destroy_workingtree_metadata(self):
1747
1659
self.transport.delete_tree('checkout')
1749
def find_branch_format(self, name=None):
1661
def find_branch_format(self):
1750
1662
"""Find the branch 'format' for this bzrdir.
1752
1664
This might be a synthetic object for e.g. RemoteBranch and SVN.
1754
1666
from bzrlib.branch import BranchFormat
1755
return BranchFormat.find_format(self, name=name)
1667
return BranchFormat.find_format(self)
1757
1669
def _get_mkdir_mode(self):
1758
1670
"""Figure out the mode to use when creating a bzrdir subdir."""
1760
1672
lockable_files.TransportLock)
1761
1673
return temp_control._dir_mode
1763
def get_branch_reference(self, name=None):
1675
def get_branch_reference(self):
1764
1676
"""See BzrDir.get_branch_reference()."""
1765
1677
from bzrlib.branch import BranchFormat
1766
format = BranchFormat.find_format(self, name=name)
1767
return format.get_reference(self, name=name)
1678
format = BranchFormat.find_format(self)
1679
return format.get_reference(self)
1769
def get_branch_transport(self, branch_format, name=None):
1681
def get_branch_transport(self, branch_format):
1770
1682
"""See BzrDir.get_branch_transport()."""
1771
if name is not None:
1772
raise errors.NoColocatedBranchSupport(self)
1773
1683
# XXX: this shouldn't implicitly create the directory if it's just
1774
1684
# promising to get a transport -- mbp 20090727
1775
1685
if branch_format is None:
1864
1774
def open_branch(self, name=None, unsupported=False,
1865
1775
ignore_fallbacks=False):
1866
1776
"""See BzrDir.open_branch."""
1867
format = self.find_branch_format(name=name)
1777
if name is not None:
1778
raise errors.NoColocatedBranchSupport(self)
1779
format = self.find_branch_format()
1868
1780
self._check_supported(format, unsupported)
1869
return format.open(self, name=name,
1870
_found=True, ignore_fallbacks=ignore_fallbacks)
1781
return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1872
1783
def open_repository(self, unsupported=False):
1873
1784
"""See BzrDir.open_repository."""
2745
2656
if isinstance(self.bzrdir.transport, local.LocalTransport):
2746
2657
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2747
2658
self._convert_to_weaves()
2748
return BzrDir.open(self.bzrdir.user_url)
2659
return BzrDir.open(self.bzrdir.root_transport.base)
2750
2661
self.pb.finished()
3126
3037
BzrDirMetaFormat1().get_format_string(),
3127
3038
mode=self.file_mode)
3128
3039
self.pb.finished()
3129
return BzrDir.open(self.bzrdir.user_url)
3040
return BzrDir.open(self.bzrdir.root_transport.base)
3131
3042
def make_lock(self, name):
3132
3043
"""Make a lock for the new control dir name."""
3714
3625
stack_on = urlutils.rebase_url(self._stack_on,
3715
3626
self._stack_on_pwd,
3627
branch.bzrdir.root_transport.base)
3717
3628
except errors.InvalidRebaseURLs:
3718
3629
stack_on = self._get_full_stack_on()