809
810
present within a BzrDir.
813
def _get_branch_path(self, name):
814
"""Obtain the branch path to use.
816
This uses the API specified branch name first, and then falls back to
817
the branch name specified in the URL. If neither of those is specified,
818
it uses the default branch.
820
:param name: Optional branch name to use
821
:return: Relative path to branch
825
return urlutils.join('branches', name.encode("utf-8"))
827
def _read_branch_list(self):
828
"""Read the branch list.
830
:return: List of utf-8 encoded branch names.
833
f = self.control_transport.get('branch-list')
834
except errors.NoSuchFile:
840
ret.append(name.rstrip("\n"))
845
def _write_branch_list(self, branches):
846
"""Write out the branch list.
848
:param branches: List of utf-8 branch names to write
850
self.transport.put_bytes('branch-list',
851
"".join([name+"\n" for name in branches]))
812
853
def __init__(self, _transport, _format):
813
854
super(BzrDirMeta1, self).__init__(_transport, _format)
814
self.control_files = lockable_files.LockableFiles(self.control_transport,
815
self._format._lock_file_name, self._format._lock_class)
855
self.control_files = lockable_files.LockableFiles(
856
self.control_transport, self._format._lock_file_name,
857
self._format._lock_class)
817
859
def can_convert_format(self):
818
860
"""See BzrDir.can_convert_format()."""
831
873
"""See BzrDir.create_branch."""
833
875
name = self._get_selected_branch()
876
path = self._get_branch_path(name)
835
raise errors.NoColocatedBranchSupport(self)
836
self.transport.delete_tree('branch')
878
self.control_files.lock_write()
880
branches = self._read_branch_list()
882
branches.remove(name.encode("utf-8"))
884
raise errors.NotBranchError(name)
885
self._write_branch_list(branches)
887
self.control_files.unlock()
888
self.transport.delete_tree(path)
838
890
def create_repository(self, shared=False):
839
891
"""See BzrDir.create_repository."""
895
947
"""See BzrDir.get_branch_transport()."""
897
949
name = self._get_selected_branch()
899
raise errors.NoColocatedBranchSupport(self)
950
path = self._get_branch_path(name)
900
951
# XXX: this shouldn't implicitly create the directory if it's just
901
952
# promising to get a transport -- mbp 20090727
902
953
if branch_format is None:
903
return self.transport.clone('branch')
954
return self.transport.clone(path)
905
956
branch_format.get_format_string()
906
957
except NotImplementedError:
907
958
raise errors.IncompatibleFormat(branch_format, self._format)
960
branches = self._read_branch_list()
961
utf8_name = name.encode("utf-8")
962
if not utf8_name in branches:
963
self.control_files.lock_write()
965
branches = self._read_branch_list()
966
dirname = urlutils.dirname(utf8_name)
967
if dirname != "" and dirname in branches:
968
raise errors.ParentBranchExists(name)
970
b.startswith(utf8_name+"/") for b in branches]
971
if any(child_branches):
972
raise errors.AlreadyBranchError(name)
973
branches.append(utf8_name)
974
self._write_branch_list(branches)
976
self.control_files.unlock()
977
branch_transport = self.transport.clone(path)
978
mode = self._get_mkdir_mode()
979
branch_transport.create_prefix(mode=mode)
909
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
981
self.transport.mkdir(path, mode=mode)
910
982
except errors.FileExists:
912
return self.transport.clone('branch')
984
return self.transport.clone(path)
914
986
def get_repository_transport(self, repository_format):
915
987
"""See BzrDir.get_repository_transport()."""
1012
1097
return config.TransportConfig(self.transport, 'control.conf')
1015
class BzrDirMeta1Colo(BzrDirMeta1):
1016
"""BzrDirMeta1 with support for colocated branches.
1018
This format is experimental, and will eventually be merged back into
1022
def _get_branch_path(self, name):
1023
"""Obtain the branch path to use.
1025
This uses the API specified branch name first, and then falls back to
1026
the branch name specified in the URL. If neither of those is specified,
1027
it uses the default branch.
1029
:param name: Optional branch name to use
1030
:return: Relative path to branch
1034
return urlutils.join('branches', name.encode("utf-8"))
1036
def _read_branch_list(self):
1037
"""Read the branch list.
1039
:return: List of utf-8 encoded branch names.
1042
f = self.control_transport.get('branch-list')
1043
except errors.NoSuchFile:
1049
ret.append(name.rstrip("\n"))
1054
def _write_branch_list(self, branches):
1055
"""Write out the branch list.
1057
:param branches: List of utf-8 branch names to write
1059
self.transport.put_bytes('branch-list',
1060
"".join([name+"\n" for name in branches]))
1062
def destroy_branch(self, name=None):
1063
"""See BzrDir.create_branch."""
1065
name = self._get_selected_branch()
1066
path = self._get_branch_path(name)
1068
self.control_files.lock_write()
1070
branches = self._read_branch_list()
1072
branches.remove(name.encode("utf-8"))
1074
raise errors.NotBranchError(name)
1075
self._write_branch_list(branches)
1077
self.control_files.unlock()
1078
self.transport.delete_tree(path)
1080
def get_branches(self):
1081
"""See ControlDir.get_branches."""
1084
ret[""] = self.open_branch(name="")
1085
except (errors.NotBranchError, errors.NoRepositoryPresent):
1088
for name in self._read_branch_list():
1089
ret[name] = self.open_branch(name=name.decode('utf-8'))
1093
def get_branch_transport(self, branch_format, name=None):
1094
"""See BzrDir.get_branch_transport()."""
1096
name = self._get_selected_branch()
1097
path = self._get_branch_path(name)
1098
# XXX: this shouldn't implicitly create the directory if it's just
1099
# promising to get a transport -- mbp 20090727
1100
if branch_format is None:
1101
return self.transport.clone(path)
1103
branch_format.get_format_string()
1104
except NotImplementedError:
1105
raise errors.IncompatibleFormat(branch_format, self._format)
1108
self.transport.mkdir('branches', mode=self._get_mkdir_mode())
1109
except errors.FileExists:
1111
branches = self._read_branch_list()
1112
utf8_name = name.encode("utf-8")
1113
if not utf8_name in branches:
1114
self.control_files.lock_write()
1116
branches = self._read_branch_list()
1117
branches.append(utf8_name)
1118
self._write_branch_list(branches)
1120
self.control_files.unlock()
1122
self.transport.mkdir(path, mode=self._get_mkdir_mode())
1123
except errors.FileExists:
1125
return self.transport.clone(path)
1128
1100
class BzrFormat(object):
1129
1101
"""Base class for all formats of things living in metadirs.
1924
1896
def convert(self, to_convert, pb):
1925
1897
"""See Converter.convert()."""
1926
to_convert.control_files.lock_write()
1928
branches = to_convert.list_branches()
1929
if len(branches) > 1:
1930
raise errors.BzrError("remove all but a single "
1931
"colocated branch when downgrading")
1933
to_convert.control_files.unlock()
1934
1898
to_convert.transport.put_bytes('branch-format',
1935
1899
self.target_format.as_string())
1936
1900
return BzrDir.open_from_transport(to_convert.root_transport)