781
807
present within a BzrDir.
810
def _get_branch_path(self, name):
811
"""Obtain the branch path to use.
813
This uses the API specified branch name first, and then falls back to
814
the branch name specified in the URL. If neither of those is specified,
815
it uses the default branch.
817
:param name: Optional branch name to use
818
:return: Relative path to branch
822
return urlutils.join('branches', name.encode("utf-8"))
824
def _read_branch_list(self):
825
"""Read the branch list.
827
:return: List of utf-8 encoded branch names.
830
f = self.control_transport.get('branch-list')
831
except errors.NoSuchFile:
837
ret.append(name.rstrip("\n"))
842
def _write_branch_list(self, branches):
843
"""Write out the branch list.
845
:param branches: List of utf-8 branch names to write
847
self.transport.put_bytes('branch-list',
848
"".join([name+"\n" for name in branches]))
850
def __init__(self, _transport, _format):
851
super(BzrDirMeta1, self).__init__(_transport, _format)
852
self.control_files = lockable_files.LockableFiles(
853
self.control_transport, self._format._lock_file_name,
854
self._format._lock_class)
784
856
def can_convert_format(self):
785
857
"""See BzrDir.can_convert_format()."""
788
860
def create_branch(self, name=None, repository=None,
789
861
append_revisions_only=None):
790
"""See BzrDir.create_branch."""
862
"""See ControlDir.create_branch."""
864
name = self._get_selected_branch()
791
865
return self._format.get_branch_format().initialize(self, name=name,
792
866
repository=repository,
793
867
append_revisions_only=append_revisions_only)
795
869
def destroy_branch(self, name=None):
796
"""See BzrDir.create_branch."""
798
raise errors.NoColocatedBranchSupport(self)
799
self.transport.delete_tree('branch')
870
"""See ControlDir.destroy_branch."""
872
name = self._get_selected_branch()
873
path = self._get_branch_path(name)
875
self.control_files.lock_write()
877
branches = self._read_branch_list()
879
branches.remove(name.encode("utf-8"))
881
raise errors.NotBranchError(name)
882
self._write_branch_list(branches)
884
self.control_files.unlock()
886
self.transport.delete_tree(path)
887
except errors.NoSuchFile:
888
raise errors.NotBranchError(path=urlutils.join(self.transport.base,
801
891
def create_repository(self, shared=False):
802
892
"""See BzrDir.create_repository."""
844
937
def get_branch_reference(self, name=None):
845
938
"""See BzrDir.get_branch_reference()."""
846
from bzrlib.branch import BranchFormat
847
format = BranchFormat.find_format(self, name=name)
939
from bzrlib.branch import BranchFormatMetadir
940
format = BranchFormatMetadir.find_format(self, name=name)
848
941
return format.get_reference(self, name=name)
943
def set_branch_reference(self, target_branch, name=None):
944
format = _mod_branch.BranchReferenceFormat()
945
return format.initialize(self, target_branch=target_branch, name=name)
850
947
def get_branch_transport(self, branch_format, name=None):
851
948
"""See BzrDir.get_branch_transport()."""
853
raise errors.NoColocatedBranchSupport(self)
950
name = self._get_selected_branch()
951
path = self._get_branch_path(name)
854
952
# XXX: this shouldn't implicitly create the directory if it's just
855
953
# promising to get a transport -- mbp 20090727
856
954
if branch_format is None:
857
return self.transport.clone('branch')
955
return self.transport.clone(path)
859
957
branch_format.get_format_string()
860
958
except NotImplementedError:
861
959
raise errors.IncompatibleFormat(branch_format, self._format)
961
branches = self._read_branch_list()
962
utf8_name = name.encode("utf-8")
963
if not utf8_name in branches:
964
self.control_files.lock_write()
966
branches = self._read_branch_list()
967
dirname = urlutils.dirname(utf8_name)
968
if dirname != "" and dirname in branches:
969
raise errors.ParentBranchExists(name)
971
b.startswith(utf8_name+"/") for b in branches]
972
if any(child_branches):
973
raise errors.AlreadyBranchError(name)
974
branches.append(utf8_name)
975
self._write_branch_list(branches)
977
self.control_files.unlock()
978
branch_transport = self.transport.clone(path)
979
mode = self._get_mkdir_mode()
980
branch_transport.create_prefix(mode=mode)
863
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
982
self.transport.mkdir(path, mode=mode)
864
983
except errors.FileExists:
866
return self.transport.clone('branch')
985
return self.transport.clone(path)
868
987
def get_repository_transport(self, repository_format):
869
988
"""See BzrDir.get_repository_transport()."""
938
1070
def open_branch(self, name=None, unsupported=False,
939
ignore_fallbacks=False):
940
"""See BzrDir.open_branch."""
1071
ignore_fallbacks=False, possible_transports=None):
1072
"""See ControlDir.open_branch."""
1074
name = self._get_selected_branch()
941
1075
format = self.find_branch_format(name=name)
942
1076
format.check_support_status(unsupported)
943
1077
return format.open(self, name=name,
944
_found=True, ignore_fallbacks=ignore_fallbacks)
1078
_found=True, ignore_fallbacks=ignore_fallbacks,
1079
possible_transports=possible_transports)
946
1081
def open_repository(self, unsupported=False):
947
1082
"""See BzrDir.open_repository."""
948
from bzrlib.repository import RepositoryFormat
949
format = RepositoryFormat.find_format(self)
1083
from bzrlib.repository import RepositoryFormatMetaDir
1084
format = RepositoryFormatMetaDir.find_format(self)
950
1085
format.check_support_status(unsupported)
951
1086
return format.open(self, _found=True)
953
1088
def open_workingtree(self, unsupported=False,
954
1089
recommend_upgrade=True):
955
1090
"""See BzrDir.open_workingtree."""
956
from bzrlib.workingtree import WorkingTreeFormat
957
format = WorkingTreeFormat.find_format(self)
1091
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1092
format = WorkingTreeFormatMetaDir.find_format(self)
958
1093
format.check_support_status(unsupported, recommend_upgrade,
959
1094
basedir=self.root_transport.base)
960
1095
return format.open(self, _found=True)
963
1098
return config.TransportConfig(self.transport, 'control.conf')
966
class BzrDirMeta1Colo(BzrDirMeta1):
967
"""BzrDirMeta1 with support for colocated branches.
969
This format is experimental, and will eventually be merged back into
1101
class BzrFormat(object):
1102
"""Base class for all formats of things living in metadirs.
1104
This class manages the format string that is stored in the 'format'
1105
or 'branch-format' file.
1107
All classes for (branch-, repository-, workingtree-) formats that
1108
live in meta directories and have their own 'format' file
1109
(i.e. different from .bzr/branch-format) derive from this class,
1110
as well as the relevant base class for their kind
1111
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1113
Each format is identified by a "format" or "branch-format" file with a
1114
single line containing the base format name and then an optional list of
1117
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1118
will render them inaccessible to older versions of bzr.
1120
:ivar features: Dictionary mapping feature names to their necessity
973
def __init__(self, _transport, _format):
974
super(BzrDirMeta1Colo, self).__init__(_transport, _format)
975
self.control_files = lockable_files.LockableFiles(_transport,
976
self._format._lock_file_name, self._format._lock_class)
978
def _get_branch_path(self, name):
979
"""Obtain the branch path to use.
981
This uses the API specified branch name first, and then falls back to
982
the branch name specified in the URL. If neither of those is specified,
983
it uses the default branch.
985
:param name: Optional branch name to use
986
:return: Relative path to branch, branch name
989
name = self._get_selected_branch()
991
return 'branch', None
992
return urlutils.join('branches', name), name
994
def _read_branch_list(self):
995
"""Read the branch list.
997
:return: List of utf-8 encoded branch names.
1000
f = self.control_transport.get('branch-list')
1001
except errors.NoSuchFile:
1007
ret.append(name.rstrip("\n"))
1012
def _write_branch_list(self, branches):
1013
"""Write out the branch list.
1015
:param branches: List of utf-8 branch names to write
1017
self.transport.put_bytes('branch-list',
1018
"".join([name+"\n" for name in branches]))
1020
def destroy_branch(self, name=None):
1021
"""See BzrDir.create_branch."""
1022
path, name = self._get_branch_path(name)
1023
if name is not None:
1024
self.control_files.lock_write()
1026
branches = self._read_branch_list()
1028
branches.remove(name)
1030
raise errors.NotBranchError(name)
1031
self._write_branch_list(name)
1033
self.control_files.unlock()
1034
self.transport.delete_tree(path)
1036
def list_branches(self):
1037
"""See ControlDir.list_branches."""
1041
ret.append(self.open_branch())
1042
except (errors.NotBranchError, errors.NoRepositoryPresent):
1045
# colocated branches
1046
ret.extend([self.open_branch(name) for name in
1047
self._read_branch_list()])
1051
def get_branch_transport(self, branch_format, name=None):
1052
"""See BzrDir.get_branch_transport()."""
1053
path, name = self._get_branch_path(name)
1054
# XXX: this shouldn't implicitly create the directory if it's just
1055
# promising to get a transport -- mbp 20090727
1056
if branch_format is None:
1057
return self.transport.clone(path)
1059
branch_format.get_format_string()
1060
except NotImplementedError:
1061
raise errors.IncompatibleFormat(branch_format, self._format)
1062
if name is not None:
1064
self.transport.mkdir('branches', mode=self._get_mkdir_mode())
1065
except errors.FileExists:
1067
branches = self._read_branch_list()
1068
if not name in branches:
1069
self.control_files.lock_write()
1071
branches = self._read_branch_list()
1072
branches.append(name)
1073
self._write_branch_list(branches)
1075
self.control_files.unlock()
1077
self.transport.mkdir(path, mode=self._get_mkdir_mode())
1078
except errors.FileExists:
1080
return self.transport.clone(path)
1123
_present_features = set()
1129
def register_feature(cls, name):
1130
"""Register a feature as being present.
1132
:param name: Name of the feature
1135
raise ValueError("spaces are not allowed in feature names")
1136
if name in cls._present_features:
1137
raise errors.FeatureAlreadyRegistered(name)
1138
cls._present_features.add(name)
1141
def unregister_feature(cls, name):
1142
"""Unregister a feature."""
1143
cls._present_features.remove(name)
1145
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1147
for name, necessity in self.features.iteritems():
1148
if name in self._present_features:
1150
if necessity == "optional":
1151
mutter("ignoring optional missing feature %s", name)
1153
elif necessity == "required":
1154
raise errors.MissingFeature(name)
1156
mutter("treating unknown necessity as require for %s",
1158
raise errors.MissingFeature(name)
1161
def get_format_string(cls):
1162
"""Return the ASCII format string that identifies this format."""
1163
raise NotImplementedError(cls.get_format_string)
1166
def from_string(cls, text):
1167
format_string = cls.get_format_string()
1168
if not text.startswith(format_string):
1169
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1170
lines = text[len(format_string):].splitlines()
1172
for lineno, line in enumerate(lines):
1174
(necessity, feature) = line.split(" ", 1)
1176
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1177
line=line, text=text)
1178
ret.features[feature] = necessity
1181
def as_string(self):
1182
"""Return the string representation of this format.
1184
lines = [self.get_format_string()]
1185
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1186
self.features.iteritems()])
1187
return "".join(lines)
1190
def _find_format(klass, registry, kind, format_string):
1192
first_line = format_string[:format_string.index("\n")+1]
1194
first_line = format_string
1196
cls = registry.get(first_line)
1198
raise errors.UnknownFormatError(format=first_line, kind=kind)
1199
return cls.from_string(format_string)
1201
def network_name(self):
1202
"""A simple byte string uniquely identifying this format for RPC calls.
1204
Metadir branch formats use their format string.
1206
return self.as_string()
1208
def __eq__(self, other):
1209
return (self.__class__ is other.__class__ and
1210
self.features == other.features)
1212
def _update_feature_flags(self, updated_flags):
1213
"""Update the feature flags in this format.
1215
:param updated_flags: Updated feature flags
1217
for name, necessity in updated_flags.iteritems():
1218
if necessity is None:
1220
del self.features[name]
1224
self.features[name] = necessity
1083
1227
class BzrProber(controldir.Prober):
1862
2005
require_stacking)
1863
2006
self._bzrdir = bzrdir
1865
def acquire_repository(self, make_working_trees=None, shared=False):
2008
def acquire_repository(self, make_working_trees=None, shared=False,
2009
possible_transports=None):
1866
2010
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
1868
2012
Creates the desired repository in the bzrdir we already have.
2014
if possible_transports is None:
2015
possible_transports = []
2017
possible_transports = list(possible_transports)
2018
possible_transports.append(self._bzrdir.root_transport)
1870
2019
stack_on = self._get_full_stack_on()
1872
2021
format = self._bzrdir._format
1873
2022
format.require_stacking(stack_on=stack_on,
1874
possible_transports=[self._bzrdir.root_transport])
2023
possible_transports=possible_transports)
1875
2024
if not self._require_stacking:
1876
2025
# We have picked up automatic stacking somewhere.
1877
2026
note(gettext('Using default stacking branch {0} at {1}').format(
1878
2027
self._stack_on, self._stack_on_pwd))
1879
2028
repository = self._bzrdir.create_repository(shared=shared)
1880
2029
self._add_fallback(repository,
1881
possible_transports=[self._bzrdir.transport])
2030
possible_transports=possible_transports)
1882
2031
if make_working_trees is not None:
1883
2032
repository.set_make_working_trees(make_working_trees)
1884
2033
return repository, True
1959
2114
register_metadir(controldir.format_registry, 'knit',
1960
2115
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
1961
2116
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
1962
branch_format='bzrlib.branch.BzrBranchFormat5',
2117
branch_format='bzrlib.branchfmt.fullhistory.BzrBranchFormat5',
1963
2118
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
1965
2120
deprecated=True)
1966
2121
register_metadir(controldir.format_registry, 'dirstate',
1967
2122
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
1968
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
1969
'above when accessed over the network.',
1970
branch_format='bzrlib.branch.BzrBranchFormat5',
2123
help='Format using dirstate for working trees. '
2124
'Compatible with bzr 0.8 and '
2125
'above when accessed over the network. Introduced in bzr 0.15.',
2126
branch_format='bzrlib.branchfmt.fullhistory.BzrBranchFormat5',
1971
2127
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
1973
2129
deprecated=True)
1974
2130
register_metadir(controldir.format_registry, 'dirstate-tags',
1975
2131
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
1976
help='New in 0.15: Fast local operations and improved scaling for '
1977
'network operations. Additionally adds support for tags.'
1978
' Incompatible with bzr < 0.15.',
2132
help='Variant of dirstate with support for tags. '
2133
'Introduced in bzr 0.15.',
1979
2134
branch_format='bzrlib.branch.BzrBranchFormat6',
1980
2135
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
1982
2137
deprecated=True)
1983
2138
register_metadir(controldir.format_registry, 'rich-root',
1984
2139
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
1985
help='New in 1.0. Better handling of tree roots. Incompatible with'
2140
help='Variant of dirstate with better handling of tree roots. '
2141
'Introduced in bzr 1.0',
1987
2142
branch_format='bzrlib.branch.BzrBranchFormat6',
1988
2143
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
1990
2145
deprecated=True)
1991
2146
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
1992
2147
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
1993
help='New in 0.15: Fast local operations and improved scaling for '
1994
'network operations. Additionally adds support for versioning nested '
1995
'bzr branches. Incompatible with bzr < 0.15.',
2148
help='Variant of dirstate with support for nested trees. '
2149
'Introduced in 0.15.',
1996
2150
branch_format='bzrlib.branch.BzrBranchFormat6',
1997
2151
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
1998
2152
experimental=True,
2001
2155
register_metadir(controldir.format_registry, 'pack-0.92',
2002
2156
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2003
help='New in 0.92: Pack-based format with data compatible with '
2004
'dirstate-tags format repositories. Interoperates with '
2005
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2157
help='Pack-based format used in 1.x series. Introduced in 0.92. '
2158
'Interoperates with bzr repositories before 0.92 but cannot be '
2159
'read by bzr < 0.92. '
2007
2161
branch_format='bzrlib.branch.BzrBranchFormat6',
2008
2162
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2010
2165
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2011
2166
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2012
help='New in 0.92: Pack-based format with data compatible with '
2013
'dirstate-with-subtree format repositories. Interoperates with '
2167
help='Pack-based format used in 1.x series, with subtree support. '
2168
'Introduced in 0.92. Interoperates with '
2014
2169
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2016
2171
branch_format='bzrlib.branch.BzrBranchFormat6',
2017
2172
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2019
2175
experimental=True,
2021
2177
register_metadir(controldir.format_registry, 'rich-root-pack',
2022
2178
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2023
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2024
'(needed for bzr-svn and bzr-git).',
2179
help='A variant of pack-0.92 that supports rich-root data '
2180
'(needed for bzr-svn and bzr-git). Introduced in 1.0.',
2025
2181
branch_format='bzrlib.branch.BzrBranchFormat6',
2026
2182
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2029
2186
register_metadir(controldir.format_registry, '1.6',
2030
2187
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',