784
786
def __repr__(self):
785
787
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
def update_feature_flags(self, updated_flags):
790
"""Update the features required by this bzrdir.
792
:param updated_flags: Dictionary mapping feature names to necessities
793
A necessity can be None to indicate the feature should be removed
795
self.control_files.lock_write()
797
self._format._update_feature_flags(updated_flags)
798
self.transport.put_bytes('branch-format', self._format.as_string())
800
self.control_files.unlock()
788
803
class BzrDirMeta1(BzrDir):
789
804
"""A .bzr meta version 1 control object.
862
884
def get_branch_reference(self, name=None):
863
885
"""See BzrDir.get_branch_reference()."""
864
from bzrlib.branch import BranchFormat
865
format = BranchFormat.find_format(self, name=name)
886
from bzrlib.branch import BranchFormatMetadir
887
format = BranchFormatMetadir.find_format(self, name=name)
866
888
return format.get_reference(self, name=name)
890
def set_branch_reference(self, target_branch, name=None):
891
format = _mod_branch.BranchReferenceFormat()
892
return format.initialize(self, target_branch=target_branch, name=name)
868
894
def get_branch_transport(self, branch_format, name=None):
869
895
"""See BzrDir.get_branch_transport()."""
897
name = self._get_selected_branch()
871
899
raise errors.NoColocatedBranchSupport(self)
872
900
# XXX: this shouldn't implicitly create the directory if it's just
873
901
# promising to get a transport -- mbp 20090727
967
995
def open_repository(self, unsupported=False):
968
996
"""See BzrDir.open_repository."""
969
from bzrlib.repository import RepositoryFormat
970
format = RepositoryFormat.find_format(self)
997
from bzrlib.repository import RepositoryFormatMetaDir
998
format = RepositoryFormatMetaDir.find_format(self)
971
999
format.check_support_status(unsupported)
972
1000
return format.open(self, _found=True)
974
1002
def open_workingtree(self, unsupported=False,
975
1003
recommend_upgrade=True):
976
1004
"""See BzrDir.open_workingtree."""
977
from bzrlib.workingtree import WorkingTreeFormat
978
format = WorkingTreeFormat.find_format(self)
1005
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1006
format = WorkingTreeFormatMetaDir.find_format(self)
979
1007
format.check_support_status(unsupported, recommend_upgrade,
980
1008
basedir=self.root_transport.base)
981
1009
return format.open(self, _found=True)
1054
1077
self.control_files.unlock()
1055
1078
self.transport.delete_tree(path)
1057
def list_branches(self):
1058
"""See ControlDir.list_branches."""
1080
def get_branches(self):
1081
"""See ControlDir.get_branches."""
1062
ret.append(self.open_branch())
1084
ret[""] = self.open_branch(name="")
1063
1085
except (errors.NotBranchError, errors.NoRepositoryPresent):
1066
# colocated branches
1067
ret.extend([self.open_branch(name.decode("utf-8")) for name in
1068
self._read_branch_list()])
1088
for name in self._read_branch_list():
1089
ret[name] = self.open_branch(name=name.decode('utf-8'))
1072
1093
def get_branch_transport(self, branch_format, name=None):
1073
1094
"""See BzrDir.get_branch_transport()."""
1096
name = self._get_selected_branch()
1074
1097
path = self._get_branch_path(name)
1075
1098
# XXX: this shouldn't implicitly create the directory if it's just
1076
1099
# promising to get a transport -- mbp 20090727
1102
1125
return self.transport.clone(path)
1128
class BzrFormat(object):
1129
"""Base class for all formats of things living in metadirs.
1131
This class manages the format string that is stored in the 'format'
1132
or 'branch-format' file.
1134
All classes for (branch-, repository-, workingtree-) formats that
1135
live in meta directories and have their own 'format' file
1136
(i.e. different from .bzr/branch-format) derive from this class,
1137
as well as the relevant base class for their kind
1138
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1140
Each format is identified by a "format" or "branch-format" file with a
1141
single line containing the base format name and then an optional list of
1144
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1145
will render them inaccessible to older versions of bzr.
1147
:ivar features: Dictionary mapping feature names to their necessity
1150
_present_features = set()
1156
def register_feature(cls, name):
1157
"""Register a feature as being present.
1159
:param name: Name of the feature
1162
raise ValueError("spaces are not allowed in feature names")
1163
if name in cls._present_features:
1164
raise errors.FeatureAlreadyRegistered(name)
1165
cls._present_features.add(name)
1168
def unregister_feature(cls, name):
1169
"""Unregister a feature."""
1170
cls._present_features.remove(name)
1172
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1174
for name, necessity in self.features.iteritems():
1175
if name in self._present_features:
1177
if necessity == "optional":
1178
mutter("ignoring optional missing feature %s", name)
1180
elif necessity == "required":
1181
raise errors.MissingFeature(name)
1183
mutter("treating unknown necessity as require for %s",
1185
raise errors.MissingFeature(name)
1188
def get_format_string(cls):
1189
"""Return the ASCII format string that identifies this format."""
1190
raise NotImplementedError(cls.get_format_string)
1193
def from_string(cls, text):
1194
format_string = cls.get_format_string()
1195
if not text.startswith(format_string):
1196
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1197
lines = text[len(format_string):].splitlines()
1199
for lineno, line in enumerate(lines):
1201
(necessity, feature) = line.split(" ", 1)
1203
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1204
line=line, text=text)
1205
ret.features[feature] = necessity
1208
def as_string(self):
1209
"""Return the string representation of this format.
1211
lines = [self.get_format_string()]
1212
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1213
self.features.iteritems()])
1214
return "".join(lines)
1217
def _find_format(klass, registry, kind, format_string):
1219
first_line = format_string[:format_string.index("\n")+1]
1221
first_line = format_string
1223
cls = registry.get(first_line)
1225
raise errors.UnknownFormatError(format=first_line, kind=kind)
1226
return cls.from_string(format_string)
1228
def network_name(self):
1229
"""A simple byte string uniquely identifying this format for RPC calls.
1231
Metadir branch formats use their format string.
1233
return self.as_string()
1235
def __eq__(self, other):
1236
return (self.__class__ is other.__class__ and
1237
self.features == other.features)
1239
def _update_feature_flags(self, updated_flags):
1240
"""Update the feature flags in this format.
1242
:param updated_flags: Updated feature flags
1244
for name, necessity in updated_flags.iteritems():
1245
if necessity is None:
1247
del self.features[name]
1251
self.features[name] = necessity
1105
1254
class BzrProber(controldir.Prober):
1106
1255
"""Prober for formats that use a .bzr/ control directory."""
1326
1475
# mode from the root directory
1327
1476
temp_control = lockable_files.LockableFiles(transport,
1328
1477
'', lockable_files.TransportLock)
1329
temp_control._transport.mkdir('.bzr',
1330
# FIXME: RBC 20060121 don't peek under
1332
mode=temp_control._dir_mode)
1479
temp_control._transport.mkdir('.bzr',
1480
# FIXME: RBC 20060121 don't peek under
1482
mode=temp_control._dir_mode)
1483
except errors.FileExists:
1484
raise errors.AlreadyControlDirError(transport.base)
1333
1485
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1334
1486
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1335
1487
file_mode = temp_control._file_mode
1389
1541
compatible with whatever sub formats are supported by self.
1544
other_format.features = dict(self.features)
1393
1546
def supports_transport(self, transport):
1394
1547
# bzr formats can be opened over all known transports
1550
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1552
controldir.ControlDirFormat.check_support_status(self,
1553
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1555
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1556
recommend_upgrade=recommend_upgrade, basedir=basedir)
1398
1559
class BzrDirMetaFormat1(BzrDirFormat):
1399
1560
"""Bzr meta control format 1