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)
377
344
bzrdir = BzrDir.open_from_transport(current_transport)
378
except (errors.NotBranchError, errors.PermissionDenied):
345
except errors.NotBranchError:
381
348
recurse, value = evaluate(bzrdir)
384
351
subdirs = list_current(current_transport)
385
except (errors.NoSuchFile, errors.PermissionDenied):
352
except errors.NoSuchFile:
388
355
for subdir in sorted(subdirs, reverse=True):
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
704
671
next_transport = found_bzrdir.root_transport.clone('..')
705
if (found_bzrdir.user_url == next_transport.base):
672
if (found_bzrdir.root_transport.base == next_transport.base):
706
673
# top of the file system
708
675
# find the next containing bzrdir
725
692
repository = found_bzrdir.open_repository()
726
693
except errors.NoRepositoryPresent:
727
694
return None, False
728
if found_bzrdir.user_url == self.user_url:
695
if found_bzrdir.root_transport.base == self.root_transport.base:
729
696
return repository, True
730
697
elif repository.is_shared():
731
698
return repository, True
737
704
raise errors.NoRepositoryPresent(self)
738
705
return found_repo
740
def get_branch_reference(self, name=None):
707
def get_branch_reference(self):
741
708
"""Return the referenced URL for the branch in this bzrdir.
743
:param name: Optional colocated branch name
744
710
:raises NotBranchError: If there is no Branch.
745
:raises NoColocatedBranchSupport: If a branch name was specified
746
but colocated branches are not supported.
747
711
:return: The URL the branch in this bzrdir references if it is a
748
712
reference branch, or None for regular branches.
751
raise errors.NoColocatedBranchSupport(self)
754
716
def get_branch_transport(self, branch_format, name=None):
852
814
:param _transport: the transport this dir is based at.
854
816
self._format = _format
855
# these are also under the more standard names of
856
# control_transport and user_transport
857
817
self.transport = _transport.clone('.bzr')
858
818
self.root_transport = _transport
859
819
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
821
def is_control_filename(self, filename):
870
822
"""True if filename is the name of a path which is reserved for bzrdir's.
999
951
raise errors.NotBranchError(path=url)
1000
952
a_transport = new_t
1002
def _get_tree_branch(self, name=None):
954
def _get_tree_branch(self):
1003
955
"""Return the branch and tree, if any, for this bzrdir.
1005
:param name: Name of colocated branch to open.
1007
957
Return None for tree if not present or inaccessible.
1008
958
Raise NotBranchError if no branch is present.
1009
959
:return: (tree, branch)
1012
962
tree = self.open_workingtree()
1013
963
except (errors.NoWorkingTree, errors.NotLocalUrl):
1015
branch = self.open_branch(name=name)
965
branch = self.open_branch()
1017
if name is not None:
1018
branch = self.open_branch(name=name)
1020
branch = tree.branch
1021
968
return tree, branch
1244
1191
repository_policy = result.determine_repository_policy(
1245
1192
force_new_repo, stacked_branch_url, require_stacking=stacked)
1246
1193
result_repo, is_new_repo = repository_policy.acquire_repository()
1247
is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
1248
if is_new_repo and revision_id is not None and not is_stacked:
1194
if is_new_repo and revision_id is not None and not stacked:
1249
1195
fetch_spec = graph.PendingAncestryResult(
1250
1196
[revision_id], source_repository)
1384
1330
self.create_hook(hooks.HookPoint('pre_open',
1385
1331
"Invoked before attempting to open a BzrDir with the transport "
1386
1332
"that the open will use.", (1, 14), None))
1387
self.create_hook(hooks.HookPoint('post_repo_init',
1388
"Invoked after a repository has been initialized. "
1389
"post_repo_init is called with a "
1390
"bzrlib.bzrdir.RepoInitHookParams.",
1393
1334
# install the default hooks
1394
1335
BzrDir.hooks = BzrDirHooks()
1397
class RepoInitHookParams(object):
1398
"""Object holding parameters passed to *_repo_init hooks.
1400
There are 4 fields that hooks may wish to access:
1402
:ivar repository: Repository created
1403
:ivar format: Repository format
1404
:ivar bzrdir: The bzrdir for the repository
1405
:ivar shared: The repository is shared
1408
def __init__(self, repository, format, a_bzrdir, shared):
1409
"""Create a group of RepoInitHook parameters.
1411
:param repository: Repository created
1412
:param format: Repository format
1413
:param bzrdir: The bzrdir for the repository
1414
:param shared: The repository is shared
1416
self.repository = repository
1417
self.format = format
1418
self.bzrdir = a_bzrdir
1419
self.shared = shared
1421
def __eq__(self, other):
1422
return self.__dict__ == other.__dict__
1426
return "<%s for %s>" % (self.__class__.__name__,
1429
return "<%s for %s>" % (self.__class__.__name__,
1433
1338
class BzrDirPreSplitOut(BzrDir):
1434
1339
"""A common class for the all-in-one formats."""
1747
1652
def destroy_workingtree_metadata(self):
1748
1653
self.transport.delete_tree('checkout')
1750
def find_branch_format(self, name=None):
1655
def find_branch_format(self):
1751
1656
"""Find the branch 'format' for this bzrdir.
1753
1658
This might be a synthetic object for e.g. RemoteBranch and SVN.
1755
1660
from bzrlib.branch import BranchFormat
1756
return BranchFormat.find_format(self, name=name)
1661
return BranchFormat.find_format(self)
1758
1663
def _get_mkdir_mode(self):
1759
1664
"""Figure out the mode to use when creating a bzrdir subdir."""
1761
1666
lockable_files.TransportLock)
1762
1667
return temp_control._dir_mode
1764
def get_branch_reference(self, name=None):
1669
def get_branch_reference(self):
1765
1670
"""See BzrDir.get_branch_reference()."""
1766
1671
from bzrlib.branch import BranchFormat
1767
format = BranchFormat.find_format(self, name=name)
1768
return format.get_reference(self, name=name)
1672
format = BranchFormat.find_format(self)
1673
return format.get_reference(self)
1770
1675
def get_branch_transport(self, branch_format, name=None):
1771
1676
"""See BzrDir.get_branch_transport()."""
1865
1770
def open_branch(self, name=None, unsupported=False,
1866
1771
ignore_fallbacks=False):
1867
1772
"""See BzrDir.open_branch."""
1868
format = self.find_branch_format(name=name)
1773
format = self.find_branch_format()
1869
1774
self._check_supported(format, unsupported)
1870
1775
return format.open(self, name=name,
1871
1776
_found=True, ignore_fallbacks=ignore_fallbacks)
2745
2651
if isinstance(self.bzrdir.transport, local.LocalTransport):
2746
2652
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2747
2653
self._convert_to_weaves()
2748
return BzrDir.open(self.bzrdir.user_url)
2654
return BzrDir.open(self.bzrdir.root_transport.base)
2750
2656
self.pb.finished()
2873
2779
self.revisions[rev_id] = rev
2875
2781
def _load_old_inventory(self, rev_id):
2876
f = self.branch.repository.inventory_store.get(rev_id)
2878
old_inv_xml = f.read()
2782
old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2881
2783
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2882
2784
inv.revision_id = rev_id
2883
2785
rev = self.revisions[rev_id]
2961
2863
ie.revision = previous_ie.revision
2963
2865
if ie.has_text():
2964
f = self.branch.repository._text_store.get(ie.text_id)
2966
file_lines = f.readlines()
2866
text = self.branch.repository._text_store.get(ie.text_id)
2867
file_lines = text.readlines()
2969
2868
w.add_lines(rev_id, previous_revisions, file_lines)
2970
2869
self.text_count += 1
3133
3032
BzrDirMetaFormat1().get_format_string(),
3134
3033
mode=self.file_mode)
3135
3034
self.pb.finished()
3136
return BzrDir.open(self.bzrdir.user_url)
3035
return BzrDir.open(self.bzrdir.root_transport.base)
3138
3037
def make_lock(self, name):
3139
3038
"""Make a lock for the new control dir name."""
3252
3151
# XXX: It's a bit ugly that the network name is here, because we'd
3253
3152
# like to believe that format objects are stateless or at least
3254
3153
# immutable, However, we do at least avoid mutating the name after
3255
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
3154
# it's returned. See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
3256
3155
self._network_name = None
3258
3157
def __repr__(self):
3721
3620
stack_on = urlutils.rebase_url(self._stack_on,
3722
3621
self._stack_on_pwd,
3622
branch.bzrdir.root_transport.base)
3724
3623
except errors.InvalidRebaseURLs:
3725
3624
stack_on = self._get_full_stack_on()