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
749
def get_branch_transport(self, branch_format, name=None):
718
def get_branch_transport(self, branch_format):
750
719
"""Get the transport for use by branch format in this BzrDir.
752
721
Note that bzr dirs that do not support format strings will raise
847
816
:param _transport: the transport this dir is based at.
849
818
self._format = _format
850
# these are also under the more standard names of
851
# control_transport and user_transport
852
819
self.transport = _transport.clone('.bzr')
853
820
self.root_transport = _transport
854
821
self._mode_check_done = False
857
def user_transport(self):
858
return self.root_transport
861
def control_transport(self):
862
return self.transport
864
823
def is_control_filename(self, filename):
865
824
"""True if filename is the name of a path which is reserved for bzrdir's.
1373
1332
self.create_hook(hooks.HookPoint('pre_open',
1374
1333
"Invoked before attempting to open a BzrDir with the transport "
1375
1334
"that the open will use.", (1, 14), None))
1376
self.create_hook(hooks.HookPoint('post_repo_init',
1377
"Invoked after a repository has been initialized. "
1378
"post_repo_init is called with a "
1379
"bzrlib.bzrdir.RepoInitHookParams.",
1382
1336
# install the default hooks
1383
1337
BzrDir.hooks = BzrDirHooks()
1386
class RepoInitHookParams(object):
1387
"""Object holding parameters passed to *_repo_init hooks.
1389
There are 4 fields that hooks may wish to access:
1391
:ivar repository: Repository created
1392
:ivar format: Repository format
1393
:ivar bzrdir: The bzrdir for the repository
1394
:ivar shared: The repository is shared
1397
def __init__(self, repository, format, a_bzrdir, shared):
1398
"""Create a group of RepoInitHook parameters.
1400
:param repository: Repository created
1401
:param format: Repository format
1402
:param bzrdir: The bzrdir for the repository
1403
:param shared: The repository is shared
1405
self.repository = repository
1406
self.format = format
1407
self.bzrdir = a_bzrdir
1408
self.shared = shared
1410
def __eq__(self, other):
1411
return self.__dict__ == other.__dict__
1415
return "<%s for %s>" % (self.__class__.__name__,
1418
return "<%s for %s>" % (self.__class__.__name__,
1422
1340
class BzrDirPreSplitOut(BzrDir):
1423
1341
"""A common class for the all-in-one formats."""
1466
1384
def create_branch(self, name=None):
1467
1385
"""See BzrDir.create_branch."""
1468
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)
1470
1390
def destroy_branch(self, name=None):
1471
1391
"""See BzrDir.destroy_branch."""
1529
1449
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1532
def get_branch_transport(self, branch_format, name=None):
1452
def get_branch_transport(self, branch_format):
1533
1453
"""See BzrDir.get_branch_transport()."""
1534
if name is not None:
1535
raise errors.NoColocatedBranchSupport(self)
1536
1454
if branch_format is None:
1537
1455
return self.transport
1574
1492
def open_branch(self, name=None, unsupported=False,
1575
1493
ignore_fallbacks=False):
1576
1494
"""See BzrDir.open_branch."""
1495
if name is not None:
1496
raise errors.NoColocatedBranchSupport(self)
1577
1497
from bzrlib.branch import BzrBranchFormat4
1578
1498
format = BzrBranchFormat4()
1579
1499
self._check_supported(format, unsupported)
1580
return format.open(self, name, _found=True)
1500
return format.open(self, _found=True)
1582
1502
def sprout(self, url, revision_id=None, force_new_repo=False,
1583
1503
possible_transports=None, accelerator_tree=None,
1703
1623
def create_branch(self, name=None):
1704
1624
"""See BzrDir.create_branch."""
1705
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)
1707
1629
def destroy_branch(self, name=None):
1708
1630
"""See BzrDir.create_branch."""
1756
1678
format = BranchFormat.find_format(self)
1757
1679
return format.get_reference(self)
1759
def get_branch_transport(self, branch_format, name=None):
1681
def get_branch_transport(self, branch_format):
1760
1682
"""See BzrDir.get_branch_transport()."""
1761
if name is not None:
1762
raise errors.NoColocatedBranchSupport(self)
1763
1683
# XXX: this shouldn't implicitly create the directory if it's just
1764
1684
# promising to get a transport -- mbp 20090727
1765
1685
if branch_format is None:
1854
1774
def open_branch(self, name=None, unsupported=False,
1855
1775
ignore_fallbacks=False):
1856
1776
"""See BzrDir.open_branch."""
1777
if name is not None:
1778
raise errors.NoColocatedBranchSupport(self)
1857
1779
format = self.find_branch_format()
1858
1780
self._check_supported(format, unsupported)
1859
return format.open(self, name=name,
1860
_found=True, ignore_fallbacks=ignore_fallbacks)
1781
return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1862
1783
def open_repository(self, unsupported=False):
1863
1784
"""See BzrDir.open_repository."""
1895
1816
Once a format is deprecated, just deprecate the initialize and open
1896
1817
methods on the format class. Do not deprecate the object, as the
1897
1818
object will be created every system load.
1899
:cvar colocated_branches: Whether this formats supports colocated branches.
1902
1821
_default_format = None
2735
2654
if isinstance(self.bzrdir.transport, local.LocalTransport):
2736
2655
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2737
2656
self._convert_to_weaves()
2738
return BzrDir.open(self.bzrdir.user_url)
2657
return BzrDir.open(self.bzrdir.root_transport.base)
2740
2659
self.pb.finished()
3116
3035
BzrDirMetaFormat1().get_format_string(),
3117
3036
mode=self.file_mode)
3118
3037
self.pb.finished()
3119
return BzrDir.open(self.bzrdir.user_url)
3038
return BzrDir.open(self.bzrdir.root_transport.base)
3121
3040
def make_lock(self, name):
3122
3041
"""Make a lock for the new control dir name."""
3704
3623
stack_on = urlutils.rebase_url(self._stack_on,
3705
3624
self._stack_on_pwd,
3625
branch.bzrdir.root_transport.base)
3707
3626
except errors.InvalidRebaseURLs:
3708
3627
stack_on = self._get_full_stack_on()