810
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]))
813
853
def __init__(self, _transport, _format):
814
854
super(BzrDirMeta1, self).__init__(_transport, _format)
815
self.control_files = lockable_files.LockableFiles(self.control_transport,
816
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)
818
859
def can_convert_format(self):
819
860
"""See BzrDir.can_convert_format()."""
832
873
"""See BzrDir.create_branch."""
834
875
name = self._get_selected_branch()
876
path = self._get_branch_path(name)
836
raise errors.NoColocatedBranchSupport(self)
837
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)
839
890
def create_repository(self, shared=False):
840
891
"""See BzrDir.create_repository."""
896
947
"""See BzrDir.get_branch_transport()."""
898
949
name = self._get_selected_branch()
900
raise errors.NoColocatedBranchSupport(self)
950
path = self._get_branch_path(name)
901
951
# XXX: this shouldn't implicitly create the directory if it's just
902
952
# promising to get a transport -- mbp 20090727
903
953
if branch_format is None:
904
return self.transport.clone('branch')
954
return self.transport.clone(path)
906
956
branch_format.get_format_string()
907
957
except NotImplementedError:
908
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)
910
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
981
self.transport.mkdir(path, mode=mode)
911
982
except errors.FileExists:
913
return self.transport.clone('branch')
984
return self.transport.clone(path)
915
986
def get_repository_transport(self, repository_format):
916
987
"""See BzrDir.get_repository_transport()."""
1013
1097
return config.TransportConfig(self.transport, 'control.conf')
1016
class BzrDirMeta1Colo(BzrDirMeta1):
1017
"""BzrDirMeta1 with support for colocated branches.
1019
This format is experimental, and will eventually be merged back into
1023
def _get_branch_path(self, name):
1024
"""Obtain the branch path to use.
1026
This uses the API specified branch name first, and then falls back to
1027
the branch name specified in the URL. If neither of those is specified,
1028
it uses the default branch.
1030
:param name: Optional branch name to use
1031
:return: Relative path to branch
1035
return urlutils.join('branches', name.encode("utf-8"))
1037
def _read_branch_list(self):
1038
"""Read the branch list.
1040
:return: List of utf-8 encoded branch names.
1043
f = self.control_transport.get('branch-list')
1044
except errors.NoSuchFile:
1050
ret.append(name.rstrip("\n"))
1055
def _write_branch_list(self, branches):
1056
"""Write out the branch list.
1058
:param branches: List of utf-8 branch names to write
1060
self.transport.put_bytes('branch-list',
1061
"".join([name+"\n" for name in branches]))
1063
def destroy_branch(self, name=None):
1064
"""See BzrDir.create_branch."""
1066
name = self._get_selected_branch()
1067
path = self._get_branch_path(name)
1069
self.control_files.lock_write()
1071
branches = self._read_branch_list()
1073
branches.remove(name.encode("utf-8"))
1075
raise errors.NotBranchError(name)
1076
self._write_branch_list(branches)
1078
self.control_files.unlock()
1079
self.transport.delete_tree(path)
1081
def get_branches(self):
1082
"""See ControlDir.get_branches."""
1085
ret[""] = self.open_branch(name="")
1086
except (errors.NotBranchError, errors.NoRepositoryPresent):
1089
for name in self._read_branch_list():
1090
ret[name] = self.open_branch(name=name.decode('utf-8'))
1094
def get_branch_transport(self, branch_format, name=None):
1095
"""See BzrDir.get_branch_transport()."""
1097
name = self._get_selected_branch()
1098
path = self._get_branch_path(name)
1099
# XXX: this shouldn't implicitly create the directory if it's just
1100
# promising to get a transport -- mbp 20090727
1101
if branch_format is None:
1102
return self.transport.clone(path)
1104
branch_format.get_format_string()
1105
except NotImplementedError:
1106
raise errors.IncompatibleFormat(branch_format, self._format)
1108
branches = self._read_branch_list()
1109
utf8_name = name.encode("utf-8")
1110
if not utf8_name in branches:
1111
self.control_files.lock_write()
1113
branches = self._read_branch_list()
1114
dirname = urlutils.dirname(utf8_name)
1115
if dirname != "" and dirname in branches:
1116
raise errors.ParentBranchExists(name)
1118
b.startswith(utf8_name+"/") for b in branches]
1119
if any(child_branches):
1120
raise errors.AlreadyBranchError(name)
1121
branches.append(utf8_name)
1122
self._write_branch_list(branches)
1124
self.control_files.unlock()
1125
branch_transport = self.transport.clone(path)
1126
branch_transport.create_prefix()
1128
self.transport.mkdir('.', mode=self._get_mkdir_mode())
1129
except errors.FileExists:
1131
return branch_transport
1134
1100
class BzrFormat(object):
1135
1101
"""Base class for all formats of things living in metadirs.
1930
1896
def convert(self, to_convert, pb):
1931
1897
"""See Converter.convert()."""
1932
to_convert.control_files.lock_write()
1934
branches = to_convert.list_branches()
1935
if len(branches) > 1:
1936
raise errors.BzrError("remove all but a single "
1937
"colocated branch when downgrading")
1939
to_convert.control_files.unlock()
1940
1898
to_convert.transport.put_bytes('branch-format',
1941
1899
self.target_format.as_string())
1942
1900
return BzrDir.open_from_transport(to_convert.root_transport)