~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-01 23:10:02 UTC
  • mto: This revision was merged to the branch mainline in revision 6338.
  • Revision ID: jelmer@samba.org-20111201231002-6u7hjlzddpjybfn3
Deprecate ``RevisionSpec.wants_revision_history`` and remove any uses of it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
objects returned.
26
26
"""
27
27
 
28
 
from __future__ import absolute_import
29
 
 
30
28
import sys
31
29
 
32
30
from bzrlib.lazy_import import lazy_import
48
46
    transport as _mod_transport,
49
47
    ui,
50
48
    urlutils,
51
 
    vf_search,
52
49
    win32utils,
53
50
    workingtree_3,
54
51
    workingtree_4,
203
200
                if (result_repo.user_url == result.user_url
204
201
                    and not require_stacking and
205
202
                    revision_id is not None):
206
 
                    fetch_spec = vf_search.PendingAncestryResult(
 
203
                    fetch_spec = graph.PendingAncestryResult(
207
204
                        [revision_id], local_repo)
208
205
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
209
206
                else:
355
352
            location of this control directory.
356
353
        :param create_tree_if_local: If true, a working-tree will be created
357
354
            when working locally.
358
 
        :return: The created control directory
359
355
        """
360
356
        operation = cleanup.OperationWithCleanups(self._sprout)
361
357
        return operation.run(url, revision_id=revision_id,
787
783
    def __repr__(self):
788
784
        return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
785
 
790
 
    def update_feature_flags(self, updated_flags):
791
 
        """Update the features required by this bzrdir.
792
 
 
793
 
        :param updated_flags: Dictionary mapping feature names to necessities
794
 
            A necessity can be None to indicate the feature should be removed
795
 
        """
796
 
        self.control_files.lock_write()
797
 
        try:
798
 
            self._format._update_feature_flags(updated_flags)
799
 
            self.transport.put_bytes('branch-format', self._format.as_string())
800
 
        finally:
801
 
            self.control_files.unlock()
802
 
 
803
786
 
804
787
class BzrDirMeta1(BzrDir):
805
788
    """A .bzr meta version 1 control object.
810
793
    present within a BzrDir.
811
794
    """
812
795
 
813
 
    def _get_branch_path(self, name):
814
 
        """Obtain the branch path to use.
815
 
 
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.
819
 
 
820
 
        :param name: Optional branch name to use
821
 
        :return: Relative path to branch
822
 
        """
823
 
        if name == "":
824
 
            return 'branch'
825
 
        return urlutils.join('branches', name.encode("utf-8"))
826
 
 
827
 
    def _read_branch_list(self):
828
 
        """Read the branch list.
829
 
 
830
 
        :return: List of utf-8 encoded branch names.
831
 
        """
832
 
        try:
833
 
            f = self.control_transport.get('branch-list')
834
 
        except errors.NoSuchFile:
835
 
            return []
836
 
 
837
 
        ret = []
838
 
        try:
839
 
            for name in f:
840
 
                ret.append(name.rstrip("\n"))
841
 
        finally:
842
 
            f.close()
843
 
        return ret
844
 
 
845
 
    def _write_branch_list(self, branches):
846
 
        """Write out the branch list.
847
 
 
848
 
        :param branches: List of utf-8 branch names to write
849
 
        """
850
 
        self.transport.put_bytes('branch-list',
851
 
            "".join([name+"\n" for name in branches]))
852
 
 
853
 
    def __init__(self, _transport, _format):
854
 
        super(BzrDirMeta1, self).__init__(_transport, _format)
855
 
        self.control_files = lockable_files.LockableFiles(
856
 
            self.control_transport, self._format._lock_file_name,
857
 
            self._format._lock_class)
858
 
 
859
796
    def can_convert_format(self):
860
797
        """See BzrDir.can_convert_format()."""
861
798
        return True
862
799
 
863
800
    def create_branch(self, name=None, repository=None,
864
801
            append_revisions_only=None):
865
 
        """See ControlDir.create_branch."""
 
802
        """See BzrDir.create_branch."""
866
803
        if name is None:
867
804
            name = self._get_selected_branch()
868
805
        return self._format.get_branch_format().initialize(self, name=name,
870
807
                append_revisions_only=append_revisions_only)
871
808
 
872
809
    def destroy_branch(self, name=None):
873
 
        """See ControlDir.destroy_branch."""
874
 
        if name is None:
875
 
            name = self._get_selected_branch()
876
 
        path = self._get_branch_path(name)
877
 
        if name != "":
878
 
            self.control_files.lock_write()
879
 
            try:
880
 
                branches = self._read_branch_list()
881
 
                try:
882
 
                    branches.remove(name.encode("utf-8"))
883
 
                except ValueError:
884
 
                    raise errors.NotBranchError(name)
885
 
                self._write_branch_list(branches)
886
 
            finally:
887
 
                self.control_files.unlock()
888
 
        try:
889
 
            self.transport.delete_tree(path)
890
 
        except errors.NoSuchFile:
891
 
            raise errors.NotBranchError(path=urlutils.join(self.transport.base,
892
 
                path), bzrdir=self)
 
810
        """See BzrDir.create_branch."""
 
811
        if name is not None:
 
812
            raise errors.NoColocatedBranchSupport(self)
 
813
        self.transport.delete_tree('branch')
893
814
 
894
815
    def create_repository(self, shared=False):
895
816
        """See BzrDir.create_repository."""
928
849
 
929
850
        This might be a synthetic object for e.g. RemoteBranch and SVN.
930
851
        """
931
 
        from bzrlib.branch import BranchFormatMetadir
932
 
        return BranchFormatMetadir.find_format(self, name=name)
 
852
        from bzrlib.branch import BranchFormat
 
853
        return BranchFormat.find_format(self, name=name)
933
854
 
934
855
    def _get_mkdir_mode(self):
935
856
        """Figure out the mode to use when creating a bzrdir subdir."""
939
860
 
940
861
    def get_branch_reference(self, name=None):
941
862
        """See BzrDir.get_branch_reference()."""
942
 
        from bzrlib.branch import BranchFormatMetadir
943
 
        format = BranchFormatMetadir.find_format(self, name=name)
 
863
        from bzrlib.branch import BranchFormat
 
864
        format = BranchFormat.find_format(self, name=name)
944
865
        return format.get_reference(self, name=name)
945
866
 
946
 
    def set_branch_reference(self, target_branch, name=None):
947
 
        format = _mod_branch.BranchReferenceFormat()
948
 
        return format.initialize(self, target_branch=target_branch, name=name)
949
 
 
950
867
    def get_branch_transport(self, branch_format, name=None):
951
868
        """See BzrDir.get_branch_transport()."""
952
 
        if name is None:
953
 
            name = self._get_selected_branch()
954
 
        path = self._get_branch_path(name)
 
869
        if name is not None:
 
870
            raise errors.NoColocatedBranchSupport(self)
955
871
        # XXX: this shouldn't implicitly create the directory if it's just
956
872
        # promising to get a transport -- mbp 20090727
957
873
        if branch_format is None:
958
 
            return self.transport.clone(path)
 
874
            return self.transport.clone('branch')
959
875
        try:
960
876
            branch_format.get_format_string()
961
877
        except NotImplementedError:
962
878
            raise errors.IncompatibleFormat(branch_format, self._format)
963
 
        if name != "":
964
 
            branches = self._read_branch_list()
965
 
            utf8_name = name.encode("utf-8")
966
 
            if not utf8_name in branches:
967
 
                self.control_files.lock_write()
968
 
                try:
969
 
                    branches = self._read_branch_list()
970
 
                    dirname = urlutils.dirname(utf8_name)
971
 
                    if dirname != "" and dirname in branches:
972
 
                        raise errors.ParentBranchExists(name)
973
 
                    child_branches = [
974
 
                        b.startswith(utf8_name+"/") for b in branches]
975
 
                    if any(child_branches):
976
 
                        raise errors.AlreadyBranchError(name)
977
 
                    branches.append(utf8_name)
978
 
                    self._write_branch_list(branches)
979
 
                finally:
980
 
                    self.control_files.unlock()
981
 
        branch_transport = self.transport.clone(path)
982
 
        mode = self._get_mkdir_mode()
983
 
        branch_transport.create_prefix(mode=mode)
984
879
        try:
985
 
            self.transport.mkdir(path, mode=mode)
 
880
            self.transport.mkdir('branch', mode=self._get_mkdir_mode())
986
881
        except errors.FileExists:
987
882
            pass
988
 
        return self.transport.clone(path)
 
883
        return self.transport.clone('branch')
989
884
 
990
885
    def get_repository_transport(self, repository_format):
991
886
        """See BzrDir.get_repository_transport()."""
1015
910
            pass
1016
911
        return self.transport.clone('checkout')
1017
912
 
1018
 
    def get_branches(self):
1019
 
        """See ControlDir.get_branches."""
1020
 
        ret = {}
1021
 
        try:
1022
 
            ret[""] = self.open_branch(name="")
1023
 
        except (errors.NotBranchError, errors.NoRepositoryPresent):
1024
 
            pass
1025
 
 
1026
 
        for name in self._read_branch_list():
1027
 
            ret[name] = self.open_branch(name=name.decode('utf-8'))
1028
 
 
1029
 
        return ret
1030
 
 
1031
913
    def has_workingtree(self):
1032
914
        """Tell if this bzrdir contains a working tree.
1033
915
 
1034
916
        Note: if you're going to open the working tree, you should just go
1035
917
        ahead and try, and not ask permission first.
1036
918
        """
1037
 
        from bzrlib.workingtree import WorkingTreeFormatMetaDir
 
919
        from bzrlib.workingtree import WorkingTreeFormat
1038
920
        try:
1039
 
            WorkingTreeFormatMetaDir.find_format_string(self)
 
921
            WorkingTreeFormat.find_format_string(self)
1040
922
        except errors.NoWorkingTree:
1041
923
            return False
1042
924
        return True
1083
965
 
1084
966
    def open_repository(self, unsupported=False):
1085
967
        """See BzrDir.open_repository."""
1086
 
        from bzrlib.repository import RepositoryFormatMetaDir
1087
 
        format = RepositoryFormatMetaDir.find_format(self)
 
968
        from bzrlib.repository import RepositoryFormat
 
969
        format = RepositoryFormat.find_format(self)
1088
970
        format.check_support_status(unsupported)
1089
971
        return format.open(self, _found=True)
1090
972
 
1091
973
    def open_workingtree(self, unsupported=False,
1092
974
            recommend_upgrade=True):
1093
975
        """See BzrDir.open_workingtree."""
1094
 
        from bzrlib.workingtree import WorkingTreeFormatMetaDir
1095
 
        format = WorkingTreeFormatMetaDir.find_format(self)
 
976
        from bzrlib.workingtree import WorkingTreeFormat
 
977
        format = WorkingTreeFormat.find_format(self)
1096
978
        format.check_support_status(unsupported, recommend_upgrade,
1097
979
            basedir=self.root_transport.base)
1098
980
        return format.open(self, _found=True)
1101
983
        return config.TransportConfig(self.transport, 'control.conf')
1102
984
 
1103
985
 
1104
 
class BzrFormat(object):
1105
 
    """Base class for all formats of things living in metadirs.
1106
 
 
1107
 
    This class manages the format string that is stored in the 'format'
1108
 
    or 'branch-format' file.
1109
 
 
1110
 
    All classes for (branch-, repository-, workingtree-) formats that
1111
 
    live in meta directories and have their own 'format' file
1112
 
    (i.e. different from .bzr/branch-format) derive from this class,
1113
 
    as well as the relevant base class for their kind
1114
 
    (BranchFormat, WorkingTreeFormat, RepositoryFormat).
1115
 
 
1116
 
    Each format is identified by a "format" or "branch-format" file with a
1117
 
    single line containing the base format name and then an optional list of
1118
 
    feature flags.
1119
 
 
1120
 
    Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1121
 
    will render them inaccessible to older versions of bzr.
1122
 
 
1123
 
    :ivar features: Dictionary mapping feature names to their necessity
 
986
class BzrDirMeta1Colo(BzrDirMeta1):
 
987
    """BzrDirMeta1 with support for colocated branches.
 
988
 
 
989
    This format is experimental, and will eventually be merged back into
 
990
    BzrDirMeta1.
1124
991
    """
1125
992
 
1126
 
    _present_features = set()
1127
 
 
1128
 
    def __init__(self):
1129
 
        self.features = {}
1130
 
 
1131
 
    @classmethod
1132
 
    def register_feature(cls, name):
1133
 
        """Register a feature as being present.
1134
 
 
1135
 
        :param name: Name of the feature
1136
 
        """
1137
 
        if " " in name:
1138
 
            raise ValueError("spaces are not allowed in feature names")
1139
 
        if name in cls._present_features:
1140
 
            raise errors.FeatureAlreadyRegistered(name)
1141
 
        cls._present_features.add(name)
1142
 
 
1143
 
    @classmethod
1144
 
    def unregister_feature(cls, name):
1145
 
        """Unregister a feature."""
1146
 
        cls._present_features.remove(name)
1147
 
 
1148
 
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1149
 
            basedir=None):
1150
 
        for name, necessity in self.features.iteritems():
1151
 
            if name in self._present_features:
1152
 
                continue
1153
 
            if necessity == "optional":
1154
 
                mutter("ignoring optional missing feature %s", name)
1155
 
                continue
1156
 
            elif necessity == "required":
1157
 
                raise errors.MissingFeature(name)
1158
 
            else:
1159
 
                mutter("treating unknown necessity as require for %s",
1160
 
                       name)
1161
 
                raise errors.MissingFeature(name)
1162
 
 
1163
 
    @classmethod
1164
 
    def get_format_string(cls):
1165
 
        """Return the ASCII format string that identifies this format."""
1166
 
        raise NotImplementedError(cls.get_format_string)
1167
 
 
1168
 
    @classmethod
1169
 
    def from_string(cls, text):
1170
 
        format_string = cls.get_format_string()
1171
 
        if not text.startswith(format_string):
1172
 
            raise AssertionError("Invalid format header %r for %r" % (text, cls))
1173
 
        lines = text[len(format_string):].splitlines()
1174
 
        ret = cls()
1175
 
        for lineno, line in enumerate(lines):
1176
 
            try:
1177
 
                (necessity, feature) = line.split(" ", 1)
1178
 
            except ValueError:
1179
 
                raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1180
 
                    line=line, text=text)
1181
 
            ret.features[feature] = necessity
1182
 
        return ret
1183
 
 
1184
 
    def as_string(self):
1185
 
        """Return the string representation of this format.
1186
 
        """
1187
 
        lines = [self.get_format_string()]
1188
 
        lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1189
 
            self.features.iteritems()])
1190
 
        return "".join(lines)
1191
 
 
1192
 
    @classmethod
1193
 
    def _find_format(klass, registry, kind, format_string):
1194
 
        try:
1195
 
            first_line = format_string[:format_string.index("\n")+1]
1196
 
        except ValueError:
1197
 
            first_line = format_string
1198
 
        try:
1199
 
            cls = registry.get(first_line)
1200
 
        except KeyError:
1201
 
            raise errors.UnknownFormatError(format=first_line, kind=kind)
1202
 
        return cls.from_string(format_string)
1203
 
 
1204
 
    def network_name(self):
1205
 
        """A simple byte string uniquely identifying this format for RPC calls.
1206
 
 
1207
 
        Metadir branch formats use their format string.
1208
 
        """
1209
 
        return self.as_string()
1210
 
 
1211
 
    def __eq__(self, other):
1212
 
        return (self.__class__ is other.__class__ and
1213
 
                self.features == other.features)
1214
 
 
1215
 
    def _update_feature_flags(self, updated_flags):
1216
 
        """Update the feature flags in this format.
1217
 
 
1218
 
        :param updated_flags: Updated feature flags
1219
 
        """
1220
 
        for name, necessity in updated_flags.iteritems():
1221
 
            if necessity is None:
1222
 
                try:
1223
 
                    del self.features[name]
1224
 
                except KeyError:
1225
 
                    pass
1226
 
            else:
1227
 
                self.features[name] = necessity
 
993
    def __init__(self, _transport, _format):
 
994
        super(BzrDirMeta1Colo, self).__init__(_transport, _format)
 
995
        self.control_files = lockable_files.LockableFiles(self.control_transport,
 
996
            self._format._lock_file_name, self._format._lock_class)
 
997
 
 
998
    def _get_branch_path(self, name):
 
999
        """Obtain the branch path to use.
 
1000
 
 
1001
        This uses the API specified branch name first, and then falls back to
 
1002
        the branch name specified in the URL. If neither of those is specified,
 
1003
        it uses the default branch.
 
1004
 
 
1005
        :param name: Optional branch name to use
 
1006
        :return: Relative path to branch
 
1007
        """
 
1008
        if name is None:
 
1009
            return 'branch'
 
1010
        return urlutils.join('branches', name.encode("utf-8"))
 
1011
 
 
1012
    def _read_branch_list(self):
 
1013
        """Read the branch list.
 
1014
 
 
1015
        :return: List of utf-8 encoded branch names.
 
1016
        """
 
1017
        try:
 
1018
            f = self.control_transport.get('branch-list')
 
1019
        except errors.NoSuchFile:
 
1020
            return []
 
1021
 
 
1022
        ret = []
 
1023
        try:
 
1024
            for name in f:
 
1025
                ret.append(name.rstrip("\n"))
 
1026
        finally:
 
1027
            f.close()
 
1028
        return ret
 
1029
 
 
1030
    def _write_branch_list(self, branches):
 
1031
        """Write out the branch list.
 
1032
 
 
1033
        :param branches: List of utf-8 branch names to write
 
1034
        """
 
1035
        self.transport.put_bytes('branch-list',
 
1036
            "".join([name+"\n" for name in branches]))
 
1037
 
 
1038
    def destroy_branch(self, name=None):
 
1039
        """See BzrDir.create_branch."""
 
1040
        if name is None:
 
1041
            name = self._get_selected_branch()
 
1042
        path = self._get_branch_path(name)
 
1043
        if name is not None:
 
1044
            self.control_files.lock_write()
 
1045
            try:
 
1046
                branches = self._read_branch_list()
 
1047
                try:
 
1048
                    branches.remove(name.encode("utf-8"))
 
1049
                except ValueError:
 
1050
                    raise errors.NotBranchError(name)
 
1051
                self._write_branch_list(branches)
 
1052
            finally:
 
1053
                self.control_files.unlock()
 
1054
        self.transport.delete_tree(path)
 
1055
 
 
1056
    def list_branches(self):
 
1057
        """See ControlDir.list_branches."""
 
1058
        ret = []
 
1059
        # Default branch
 
1060
        try:
 
1061
            ret.append(self.open_branch())
 
1062
        except (errors.NotBranchError, errors.NoRepositoryPresent):
 
1063
            pass
 
1064
 
 
1065
        # colocated branches
 
1066
        ret.extend([self.open_branch(name.decode("utf-8")) for name in
 
1067
                    self._read_branch_list()])
 
1068
 
 
1069
        return ret
 
1070
 
 
1071
    def get_branch_transport(self, branch_format, name=None):
 
1072
        """See BzrDir.get_branch_transport()."""
 
1073
        path = self._get_branch_path(name)
 
1074
        # XXX: this shouldn't implicitly create the directory if it's just
 
1075
        # promising to get a transport -- mbp 20090727
 
1076
        if branch_format is None:
 
1077
            return self.transport.clone(path)
 
1078
        try:
 
1079
            branch_format.get_format_string()
 
1080
        except NotImplementedError:
 
1081
            raise errors.IncompatibleFormat(branch_format, self._format)
 
1082
        if name is not None:
 
1083
            try:
 
1084
                self.transport.mkdir('branches', mode=self._get_mkdir_mode())
 
1085
            except errors.FileExists:
 
1086
                pass
 
1087
            branches = self._read_branch_list()
 
1088
            utf8_name = name.encode("utf-8")
 
1089
            if not utf8_name in branches:
 
1090
                self.control_files.lock_write()
 
1091
                try:
 
1092
                    branches = self._read_branch_list()
 
1093
                    branches.append(utf8_name)
 
1094
                    self._write_branch_list(branches)
 
1095
                finally:
 
1096
                    self.control_files.unlock()
 
1097
        try:
 
1098
            self.transport.mkdir(path, mode=self._get_mkdir_mode())
 
1099
        except errors.FileExists:
 
1100
            pass
 
1101
        return self.transport.clone(path)
1228
1102
 
1229
1103
 
1230
1104
class BzrProber(controldir.Prober):
1251
1125
        except errors.NoSuchFile:
1252
1126
            raise errors.NotBranchError(path=transport.base)
1253
1127
        try:
1254
 
            first_line = format_string[:format_string.index("\n")+1]
1255
 
        except ValueError:
1256
 
            first_line = format_string
1257
 
        try:
1258
 
            cls = klass.formats.get(first_line)
 
1128
            return klass.formats.get(format_string)
1259
1129
        except KeyError:
1260
 
            raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1261
 
        return cls.from_string(format_string)
 
1130
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1262
1131
 
1263
1132
    @classmethod
1264
1133
    def known_formats(cls):
1307
1176
        return set([RemoteBzrDirFormat()])
1308
1177
 
1309
1178
 
1310
 
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
 
1179
class BzrDirFormat(controldir.ControlDirFormat):
1311
1180
    """ControlDirFormat base class for .bzr/ directories.
1312
1181
 
1313
1182
    Formats are placed in a dict by their format string for reference
1324
1193
    # _lock_class must be set in subclasses to the lock type, typ.
1325
1194
    # TransportLock or LockDir
1326
1195
 
 
1196
    @classmethod
 
1197
    def get_format_string(cls):
 
1198
        """Return the ASCII format string that identifies this format."""
 
1199
        raise NotImplementedError(cls.get_format_string)
 
1200
 
1327
1201
    def initialize_on_transport(self, transport):
1328
1202
        """Initialize a new bzrdir in the base directory of a Transport."""
1329
1203
        try:
1451
1325
        # mode from the root directory
1452
1326
        temp_control = lockable_files.LockableFiles(transport,
1453
1327
                            '', lockable_files.TransportLock)
1454
 
        try:
1455
 
            temp_control._transport.mkdir('.bzr',
1456
 
                # FIXME: RBC 20060121 don't peek under
1457
 
                # the covers
1458
 
                mode=temp_control._dir_mode)
1459
 
        except errors.FileExists:
1460
 
            raise errors.AlreadyControlDirError(transport.base)
 
1328
        temp_control._transport.mkdir('.bzr',
 
1329
                                      # FIXME: RBC 20060121 don't peek under
 
1330
                                      # the covers
 
1331
                                      mode=temp_control._dir_mode)
1461
1332
        if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1462
1333
            win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1463
1334
        file_mode = temp_control._file_mode
1467
1338
                       "This is a Bazaar control directory.\n"
1468
1339
                       "Do not change any files in this directory.\n"
1469
1340
                       "See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1470
 
                      ('branch-format', self.as_string()),
 
1341
                      ('branch-format', self.get_format_string()),
1471
1342
                      ]
1472
1343
        # NB: no need to escape relative paths that are url safe.
1473
1344
        control_files = lockable_files.LockableFiles(bzrdir_transport,
1517
1388
            compatible with whatever sub formats are supported by self.
1518
1389
        :return: None.
1519
1390
        """
1520
 
        other_format.features = dict(self.features)
1521
1391
 
1522
1392
    def supports_transport(self, transport):
1523
1393
        # bzr formats can be opened over all known transports
1524
1394
        return True
1525
1395
 
1526
 
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1527
 
            basedir=None):
1528
 
        controldir.ControlDirFormat.check_support_status(self,
1529
 
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1530
 
            basedir=basedir)
1531
 
        BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1532
 
            recommend_upgrade=recommend_upgrade, basedir=basedir)
1533
 
 
1534
1396
 
1535
1397
class BzrDirMetaFormat1(BzrDirFormat):
1536
1398
    """Bzr meta control format 1
1549
1411
 
1550
1412
    fixed_components = False
1551
1413
 
1552
 
    colocated_branches = True
 
1414
    colocated_branches = False
1553
1415
 
1554
1416
    def __init__(self):
1555
 
        BzrDirFormat.__init__(self)
1556
1417
        self._workingtree_format = None
1557
1418
        self._branch_format = None
1558
1419
        self._repository_format = None
1564
1425
            return False
1565
1426
        if other.workingtree_format != self.workingtree_format:
1566
1427
            return False
1567
 
        if other.features != self.features:
1568
 
            return False
1569
1428
        return True
1570
1429
 
1571
1430
    def __ne__(self, other):
1682
1541
            return ConvertMetaToColo(format)
1683
1542
        if (type(self) is BzrDirMetaFormat1Colo and
1684
1543
            type(format) is BzrDirMetaFormat1):
1685
 
            return ConvertMetaToColo(format)
 
1544
            return ConvertMetaRemoveColo(format)
1686
1545
        if not isinstance(self, format.__class__):
1687
1546
            # converting away from metadir is not implemented
1688
1547
            raise NotImplementedError(self.get_converter)
1697
1556
        """See BzrDirFormat.get_format_description()."""
1698
1557
        return "Meta directory format 1"
1699
1558
 
 
1559
    def network_name(self):
 
1560
        return self.get_format_string()
 
1561
 
1700
1562
    def _open(self, transport):
1701
1563
        """See BzrDirFormat._open."""
1702
1564
        # Create a new format instance because otherwise initialisation of new
1731
1593
            compatible with whatever sub formats are supported by self.
1732
1594
        :return: None.
1733
1595
        """
1734
 
        super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1735
1596
        if getattr(self, '_repository_format', None) is not None:
1736
1597
            other_format.repository_format = self.repository_format
1737
1598
        if self._branch_format is not None:
1750
1611
    def __set_workingtree_format(self, wt_format):
1751
1612
        self._workingtree_format = wt_format
1752
1613
 
1753
 
    def __repr__(self):
1754
 
        return "<%r>" % (self.__class__.__name__,)
1755
 
 
1756
1614
    workingtree_format = property(__get_workingtree_format,
1757
1615
                                  __set_workingtree_format)
1758
1616
 
1784
1642
        # problems.
1785
1643
        format = BzrDirMetaFormat1Colo()
1786
1644
        self._supply_sub_formats_to(format)
1787
 
        return BzrDirMeta1(transport, format)
 
1645
        return BzrDirMeta1Colo(transport, format)
1788
1646
 
1789
1647
 
1790
1648
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1882
1740
    def convert(self, to_convert, pb):
1883
1741
        """See Converter.convert()."""
1884
1742
        to_convert.transport.put_bytes('branch-format',
1885
 
            self.target_format.as_string())
 
1743
            self.target_format.get_format_string())
1886
1744
        return BzrDir.open_from_transport(to_convert.root_transport)
1887
1745
 
1888
1746
 
1889
 
class ConvertMetaToColo(controldir.Converter):
1890
 
    """Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
 
1747
class ConvertMetaRemoveColo(controldir.Converter):
 
1748
    """Remove colocated branch support from a bzrdir."""
1891
1749
 
1892
1750
    def __init__(self, target_format):
1893
 
        """Create a converter that converts a 'development-colo' metadir
1894
 
        to a '2a' metadir.
 
1751
        """Create a converter.that downgrades a colocated branch metadir
 
1752
        to a regular metadir.
1895
1753
 
1896
1754
        :param target_format: The final metadir format that is desired.
1897
1755
        """
1899
1757
 
1900
1758
    def convert(self, to_convert, pb):
1901
1759
        """See Converter.convert()."""
 
1760
        to_convert.control_files.lock_write()
 
1761
        try:
 
1762
            branches = to_convert.list_branches()
 
1763
            if len(branches) > 1:
 
1764
                raise errors.BzrError("remove all but a single "
 
1765
                    "colocated branch when downgrading")
 
1766
        finally:
 
1767
            to_convert.control_files.unlock()
1902
1768
        to_convert.transport.put_bytes('branch-format',
1903
 
            self.target_format.as_string())
 
1769
            self.target_format.get_format_string())
1904
1770
        return BzrDir.open_from_transport(to_convert.root_transport)
1905
1771
 
1906
1772
 
1999
1865
        :return: A repository, is_new_flag (True if the repository was
2000
1866
            created).
2001
1867
        """
2002
 
        raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
 
1868
        raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2003
1869
 
2004
1870
 
2005
1871
class CreateRepository(RepositoryAcquisitionPolicy):