/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/controldir.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-08 23:30:31 UTC
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170608233031-3qavls2o7a1pqllj
Update imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
"""
24
24
 
 
25
from __future__ import absolute_import
 
26
 
25
27
from .lazy_import import lazy_import
26
28
lazy_import(globals(), """
27
29
import textwrap
28
30
 
29
31
from breezy import (
30
 
    branch as _mod_branch,
 
32
    errors,
31
33
    hooks,
32
34
    revision as _mod_revision,
33
35
    transport as _mod_transport,
43
45
from breezy.i18n import gettext
44
46
""")
45
47
 
46
 
from . import (
47
 
    errors,
48
 
    registry,
49
 
    )
50
 
 
51
 
 
52
 
class MustHaveWorkingTree(errors.BzrError):
53
 
 
54
 
    _fmt = "Branching '%(url)s'(%(format)s) must create a working tree."
55
 
 
56
 
    def __init__(self, format, url):
57
 
        errors.BzrError.__init__(self, format=format, url=url)
58
 
 
59
 
 
60
 
class BranchReferenceLoop(errors.BzrError):
61
 
 
62
 
    _fmt = "Can not create branch reference that points at branch itself."
63
 
 
64
 
    def __init__(self, branch):
65
 
        errors.BzrError.__init__(self, branch=branch)
 
48
from . import registry
66
49
 
67
50
 
68
51
class ControlComponent(object):
127
110
        """
128
111
        return list(self.get_branches().values())
129
112
 
130
 
    def branch_names(self):
131
 
        """List all branch names in this control directory.
132
 
 
133
 
        :return: List of branch names
134
 
        """
135
 
        try:
136
 
            self.get_branch_reference()
137
 
        except (errors.NotBranchError, errors.NoRepositoryPresent):
138
 
            return []
139
 
        else:
140
 
            return [""]
141
 
 
142
113
    def get_branches(self):
143
114
        """Get all branches in this control directory, as a dictionary.
144
 
 
 
115
        
145
116
        :return: Dictionary mapping branch names to instances.
146
117
        """
147
118
        try:
148
 
            return {"": self.open_branch()}
 
119
           return { "": self.open_branch() }
149
120
        except (errors.NotBranchError, errors.NoRepositoryPresent):
150
 
            return {}
 
121
           return {}
151
122
 
152
123
    def is_control_filename(self, filename):
153
124
        """True if filename is the name of a path which is reserved for
162
133
        this in the future - for instance to make bzr talk with svn working
163
134
        trees.
164
135
        """
165
 
        return self._format.is_control_filename(filename)
 
136
        raise NotImplementedError(self.is_control_filename)
166
137
 
167
138
    def needs_format_conversion(self, format=None):
168
139
        """Return true if this controldir needs convert_format run on it.
204
175
    def destroy_branch(self, name=None):
205
176
        """Destroy a branch in this ControlDir.
206
177
 
207
 
        :param name: Name of the branch to destroy, None for the
 
178
        :param name: Name of the branch to destroy, None for the 
208
179
            user selected branch or "" for the active branch.
209
180
        :raise NotBranchError: When the branch does not exist
210
181
        """
211
182
        raise NotImplementedError(self.destroy_branch)
212
183
 
213
184
    def create_workingtree(self, revision_id=None, from_branch=None,
214
 
                           accelerator_tree=None, hardlink=False):
 
185
        accelerator_tree=None, hardlink=False):
215
186
        """Create a working tree at this ControlDir.
216
187
 
217
188
        :param revision_id: create it as of this revision id.
218
 
        :param from_branch: override controldir branch
 
189
        :param from_branch: override controldir branch 
219
190
            (for lightweight checkouts)
220
191
        :param accelerator_tree: A tree which can be used for retrieving file
221
192
            contents more quickly than the revision tree, i.e. a workingtree.
382
353
    def sprout(self, url, revision_id=None, force_new_repo=False,
383
354
               recurse='down', possible_transports=None,
384
355
               accelerator_tree=None, hardlink=False, stacked=False,
385
 
               source_branch=None, create_tree_if_local=True,
386
 
               lossy=False):
 
356
               source_branch=None, create_tree_if_local=True):
387
357
        """Create a copy of this controldir prepared for use as a new line of
388
358
        development.
389
359
 
409
379
        """
410
380
        raise NotImplementedError(self.sprout)
411
381
 
412
 
    def push_branch(self, source, revision_id=None, overwrite=False,
413
 
                    remember=False, create_prefix=False, lossy=False,
414
 
                    tag_selector=None):
 
382
    def push_branch(self, source, revision_id=None, overwrite=False, 
 
383
        remember=False, create_prefix=False):
415
384
        """Push the source branch into this ControlDir."""
416
385
        br_to = None
417
386
        # If we can open a branch, use its direct repository, otherwise see
435
404
                # revision
436
405
                revision_id = source.last_revision()
437
406
            repository_to.fetch(source.repository, revision_id=revision_id)
438
 
            br_to = source.sprout(
439
 
                self, revision_id=revision_id, lossy=lossy,
440
 
                tag_selector=tag_selector)
 
407
            br_to = source.clone(self, revision_id=revision_id)
441
408
            if source.get_push_location() is None or remember:
442
409
                # FIXME: Should be done only if we succeed ? -- vila 2012-01-18
443
410
                source.set_push_location(br_to.base)
456
423
            try:
457
424
                tree_to = self.open_workingtree()
458
425
            except errors.NotLocalUrl:
459
 
                push_result.branch_push_result = source.push(
460
 
                    br_to, overwrite, stop_revision=revision_id, lossy=lossy,
461
 
                    tag_selector=tag_selector)
 
426
                push_result.branch_push_result = source.push(br_to, 
 
427
                    overwrite, stop_revision=revision_id)
462
428
                push_result.workingtree_updated = False
463
429
            except errors.NoWorkingTree:
464
 
                push_result.branch_push_result = source.push(
465
 
                    br_to, overwrite, stop_revision=revision_id, lossy=lossy,
466
 
                    tag_selector=tag_selector)
467
 
                push_result.workingtree_updated = None  # Not applicable
 
430
                push_result.branch_push_result = source.push(br_to,
 
431
                    overwrite, stop_revision=revision_id)
 
432
                push_result.workingtree_updated = None # Not applicable
468
433
            else:
469
 
                with tree_to.lock_write():
 
434
                tree_to.lock_write()
 
435
                try:
470
436
                    push_result.branch_push_result = source.push(
471
 
                        tree_to.branch, overwrite, stop_revision=revision_id,
472
 
                        lossy=lossy, tag_selector=tag_selector)
 
437
                        tree_to.branch, overwrite, stop_revision=revision_id)
473
438
                    tree_to.update()
 
439
                finally:
 
440
                    tree_to.unlock()
474
441
                push_result.workingtree_updated = True
475
442
            push_result.old_revno = push_result.branch_push_result.old_revno
476
443
            push_result.old_revid = push_result.branch_push_result.old_revid
508
475
        raise NotImplementedError(self.check_conversion_target)
509
476
 
510
477
    def clone(self, url, revision_id=None, force_new_repo=False,
511
 
              preserve_stacking=False, tag_selector=None):
 
478
              preserve_stacking=False):
512
479
        """Clone this controldir and its contents to url verbatim.
513
480
 
514
481
        :param url: The url create the clone at.  If url's last component does
524
491
        return self.clone_on_transport(_mod_transport.get_transport(url),
525
492
                                       revision_id=revision_id,
526
493
                                       force_new_repo=force_new_repo,
527
 
                                       preserve_stacking=preserve_stacking,
528
 
                                       tag_selector=tag_selector)
 
494
                                       preserve_stacking=preserve_stacking)
529
495
 
530
496
    def clone_on_transport(self, transport, revision_id=None,
531
 
                           force_new_repo=False, preserve_stacking=False, stacked_on=None,
532
 
                           create_prefix=False, use_existing_dir=True, no_tree=False,
533
 
                           tag_selector=None):
 
497
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
498
        create_prefix=False, use_existing_dir=True, no_tree=False):
534
499
        """Clone this controldir and its contents to transport verbatim.
535
500
 
536
501
        :param transport: The transport for the location to produce the clone
550
515
        raise NotImplementedError(self.clone_on_transport)
551
516
 
552
517
    @classmethod
553
 
    def find_controldirs(klass, transport, evaluate=None, list_current=None):
 
518
    def find_bzrdirs(klass, transport, evaluate=None, list_current=None):
554
519
        """Find control dirs recursively from current location.
555
520
 
556
521
        This is intended primarily as a building block for more sophisticated
578
543
            recurse = True
579
544
            try:
580
545
                controldir = klass.open_from_transport(current_transport)
581
 
            except (errors.NotBranchError, errors.PermissionDenied,
582
 
                    errors.UnknownFormatError):
 
546
            except (errors.NotBranchError, errors.PermissionDenied):
583
547
                pass
584
548
            else:
585
549
                recurse, value = evaluate(controldir)
612
576
                return False, ([], repository)
613
577
            return True, (controldir.list_branches(), None)
614
578
        ret = []
615
 
        for branches, repo in klass.find_controldirs(
 
579
        for branches, repo in klass.find_bzrdirs(
616
580
                transport, evaluate=evaluate):
617
581
            if repo is not None:
618
582
                ret.extend(repo.find_branches())
704
668
        if not isinstance(t, local.LocalTransport):
705
669
            raise errors.NotLocalUrl(base)
706
670
        controldir = klass.create_branch_and_repo(base,
707
 
                                                  force_new_repo=True,
708
 
                                                  format=format).controldir
 
671
                                               force_new_repo=True,
 
672
                                               format=format).bzrdir
709
673
        return controldir.create_workingtree()
710
674
 
711
675
    @classmethod
722
686
        """
723
687
        t = _mod_transport.get_transport(base, possible_transports)
724
688
        return klass.open_from_transport(t, probers=probers,
725
 
                                         _unsupported=_unsupported)
 
689
                _unsupported=_unsupported)
726
690
 
727
691
    @classmethod
728
692
    def open_from_transport(klass, transport, _unsupported=False,
737
701
        # Keep initial base since 'transport' may be modified while following
738
702
        # the redirections.
739
703
        base = transport.base
740
 
 
741
704
        def find_format(transport):
742
705
            return transport, ControlDirFormat.find_format(transport,
743
 
                                                           probers=probers)
 
706
                probers=probers)
744
707
 
745
708
        def redirected(transport, e, redirection_notice):
746
709
            redirected_transport = transport._redirected_to(e.source, e.target)
747
710
            if redirected_transport is None:
748
711
                raise errors.NotBranchError(base)
749
712
            trace.note(gettext('{0} is{1} redirected to {2}').format(
750
 
                transport.base, e.permanently, redirected_transport.base))
 
713
                 transport.base, e.permanently, redirected_transport.base))
751
714
            return redirected_transport
752
715
 
753
716
        try:
791
754
            try:
792
755
                result = klass.open_from_transport(a_transport)
793
756
                return result, urlutils.unescape(a_transport.relpath(url))
794
 
            except errors.NotBranchError:
 
757
            except errors.NotBranchError as e:
795
758
                pass
796
759
            except errors.PermissionDenied:
797
760
                pass
798
761
            try:
799
762
                new_t = a_transport.clone('..')
800
 
            except urlutils.InvalidURLJoin:
 
763
            except errors.InvalidURLJoin:
801
764
                # reached the root, whatever that may be
802
765
                raise errors.NotBranchError(path=url)
803
766
            if new_t.base == a_transport.base:
806
769
            a_transport = new_t
807
770
 
808
771
    @classmethod
809
 
    def open_tree_or_branch(klass, location, name=None):
 
772
    def open_tree_or_branch(klass, location):
810
773
        """Return the branch and working tree at a location.
811
774
 
812
775
        If there is no tree at the location, tree will be None.
815
778
        :return: (tree, branch)
816
779
        """
817
780
        controldir = klass.open(location)
818
 
        return controldir._get_tree_branch(name=name)
 
781
        return controldir._get_tree_branch()
819
782
 
820
783
    @classmethod
821
784
    def open_containing_tree_or_branch(klass, location,
822
 
                                       possible_transports=None):
 
785
            possible_transports=None):
823
786
        """Return the branch and working tree contained by a location.
824
787
 
825
788
        Returns (tree, branch, relpath).
829
792
        relpath is the portion of the path that is contained by the branch.
830
793
        """
831
794
        controldir, relpath = klass.open_containing(location,
832
 
                                                    possible_transports=possible_transports)
 
795
            possible_transports=possible_transports)
833
796
        tree, branch = controldir._get_tree_branch()
834
797
        return tree, branch, relpath
835
798
 
869
832
        """
870
833
        if klass is not ControlDir:
871
834
            raise AssertionError("ControlDir.create always creates the"
872
 
                                 "default format, not one of %r" % klass)
 
835
                "default format, not one of %r" % klass)
873
836
        t = _mod_transport.get_transport(base, possible_transports)
874
837
        t.ensure_base()
875
838
        if format is None:
884
847
        """Create the default hooks."""
885
848
        hooks.Hooks.__init__(self, "breezy.controldir", "ControlDir.hooks")
886
849
        self.add_hook('pre_open',
887
 
                      "Invoked before attempting to open a ControlDir with the transport "
888
 
                      "that the open will use.", (1, 14))
 
850
            "Invoked before attempting to open a ControlDir with the transport "
 
851
            "that the open will use.", (1, 14))
889
852
        self.add_hook('post_repo_init',
890
 
                      "Invoked after a repository has been initialized. "
891
 
                      "post_repo_init is called with a "
892
 
                      "breezy.controldir.RepoInitHookParams.",
893
 
                      (2, 2))
894
 
 
 
853
            "Invoked after a repository has been initialized. "
 
854
            "post_repo_init is called with a "
 
855
            "breezy.controldir.RepoInitHookParams.",
 
856
            (2, 2))
895
857
 
896
858
# install the default hooks
897
859
ControlDir.hooks = ControlDirHooks()
916
878
        return True
917
879
 
918
880
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
919
 
                             basedir=None):
 
881
        basedir=None):
920
882
        """Give an error or warning on old formats.
921
883
 
922
884
        :param allow_unsupported: If true, allow opening
976
938
            registry._LazyObjectGetter(module_name, member_name))
977
939
 
978
940
    def _get_extra(self):
979
 
        """Return getters for extra formats, not usable in meta directories."""
980
 
        return [getter.get_obj for getter in self._extra_formats]
981
 
 
982
 
    def _get_all_lazy(self):
983
 
        """Return getters for all formats, even those not usable in metadirs."""
984
 
        result = [self._dict[name].get_obj for name in self.keys()]
985
 
        result.extend(self._get_extra())
 
941
        """Return all "extra" formats, not usable in meta directories."""
 
942
        result = []
 
943
        for getter in self._extra_formats:
 
944
            f = getter.get_obj()
 
945
            if callable(f):
 
946
                f = f()
 
947
            result.append(f)
986
948
        return result
987
949
 
988
950
    def _get_all(self):
989
 
        """Return all formats, even those not usable in metadirs."""
 
951
        """Return all formats, even those not usable in metadirs.
 
952
        """
990
953
        result = []
991
 
        for getter in self._get_all_lazy():
992
 
            fmt = getter()
 
954
        for name in self.keys():
 
955
            fmt = self.get(name)
993
956
            if callable(fmt):
994
957
                fmt = fmt()
995
958
            result.append(fmt)
996
 
        return result
 
959
        return result + self._get_extra()
997
960
 
998
961
    def _get_all_modules(self):
999
962
        """Return a set of the modules providing objects."""
1017
980
 
1018
981
    def step(self, message):
1019
982
        """Update the pb by a step."""
1020
 
        self.count += 1
 
983
        self.count +=1
1021
984
        self.pb.update(message, self.count, self.total)
1022
985
 
1023
986
 
1045
1008
    _default_format = None
1046
1009
    """The default format used for new control directories."""
1047
1010
 
 
1011
    _server_probers = []
 
1012
    """The registered server format probers, e.g. RemoteBzrProber.
 
1013
 
 
1014
    This is a list of Prober-derived classes.
 
1015
    """
 
1016
 
1048
1017
    _probers = []
1049
1018
    """The registered format probers, e.g. BzrProber.
1050
1019
 
1099
1068
        return self.is_supported()
1100
1069
 
1101
1070
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1102
 
                             basedir=None):
 
1071
        basedir=None):
1103
1072
        """Give an error or warning on old formats.
1104
1073
 
1105
1074
        :param allow_unsupported: If true, allow opening
1119
1088
 
1120
1089
    def same_model(self, target_format):
1121
1090
        return (self.repository_format.rich_root_data ==
1122
 
                target_format.rich_root_data)
 
1091
            target_format.rich_root_data)
 
1092
 
 
1093
    @classmethod
 
1094
    def register_format(klass, format):
 
1095
        """Register a format that does not use '.bzr' for its control dir.
 
1096
 
 
1097
        """
 
1098
        raise errors.BzrError("ControlDirFormat.register_format() has been "
 
1099
            "removed in Bazaar 2.4. Please upgrade your plugins.")
1123
1100
 
1124
1101
    @classmethod
1125
1102
    def register_prober(klass, prober):
1135
1112
        """
1136
1113
        klass._probers.remove(prober)
1137
1114
 
 
1115
    @classmethod
 
1116
    def register_server_prober(klass, prober):
 
1117
        """Register a control format prober for client-server environments.
 
1118
 
 
1119
        These probers will be used before ones registered with
 
1120
        register_prober.  This gives implementations that decide to the
 
1121
        chance to grab it before anything looks at the contents of the format
 
1122
        file.
 
1123
        """
 
1124
        klass._server_probers.append(prober)
 
1125
 
1138
1126
    def __str__(self):
1139
1127
        # Trim the newline
1140
1128
        return self.get_format_description().rstrip()
1141
1129
 
1142
1130
    @classmethod
1143
1131
    def all_probers(klass):
1144
 
        return klass._probers
 
1132
        return klass._server_probers + klass._probers
1145
1133
 
1146
1134
    @classmethod
1147
1135
    def known_formats(klass):
1148
1136
        """Return all the known formats.
1149
1137
        """
1150
 
        result = []
 
1138
        result = set()
1151
1139
        for prober_kls in klass.all_probers():
1152
 
            result.extend(prober_kls.known_formats())
 
1140
            result.update(prober_kls.known_formats())
1153
1141
        return result
1154
1142
 
1155
1143
    @classmethod
1156
1144
    def find_format(klass, transport, probers=None):
1157
1145
        """Return the format present at transport."""
1158
1146
        if probers is None:
1159
 
            probers = sorted(
1160
 
                klass.all_probers(),
1161
 
                key=lambda prober: prober.priority(transport))
 
1147
            probers = klass.all_probers()
1162
1148
        for prober_kls in probers:
1163
1149
            prober = prober_kls()
1164
1150
            try:
1186
1172
        raise NotImplementedError(self.initialize_on_transport)
1187
1173
 
1188
1174
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1189
 
                                   create_prefix=False, force_new_repo=False, stacked_on=None,
1190
 
                                   stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1191
 
                                   shared_repo=False, vfs_only=False):
 
1175
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
1176
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
1177
        shared_repo=False, vfs_only=False):
1192
1178
        """Create this format on transport.
1193
1179
 
1194
1180
        The directory to initialize will be created.
1249
1235
        """
1250
1236
        raise NotImplementedError(self.supports_transport)
1251
1237
 
1252
 
    @classmethod
1253
 
    def is_control_filename(klass, filename):
1254
 
        """True if filename is the name of a path which is reserved for
1255
 
        controldirs.
1256
 
 
1257
 
        :param filename: A filename within the root transport of this
1258
 
            controldir.
1259
 
 
1260
 
        This is true IF and ONLY IF the filename is part of the namespace reserved
1261
 
        for bzr control dirs. Currently this is the '.bzr' directory in the root
1262
 
        of the root_transport. it is expected that plugins will need to extend
1263
 
        this in the future - for instance to make bzr talk with svn working
1264
 
        trees.
1265
 
        """
1266
 
        raise NotImplementedError(self.is_control_filename)
1267
 
 
1268
1238
 
1269
1239
class Prober(object):
1270
1240
    """Abstract class that can be used to detect a particular kind of
1278
1248
    probers that detect .bzr/ directories and Bazaar smart servers,
1279
1249
    respectively.
1280
1250
 
1281
 
    Probers should be registered using the register_prober methods on
1282
 
    ControlDirFormat.
 
1251
    Probers should be registered using the register_server_prober or
 
1252
    register_prober methods on ControlDirFormat.
1283
1253
    """
1284
1254
 
1285
1255
    def probe_transport(self, transport):
1303
1273
        """
1304
1274
        raise NotImplementedError(klass.known_formats)
1305
1275
 
1306
 
    @classmethod
1307
 
    def priority(klass, transport):
1308
 
        """Priority of this prober.
1309
 
 
1310
 
        A lower value means the prober gets checked first.
1311
 
 
1312
 
        Other conventions:
1313
 
 
1314
 
        -10: This is a "server" prober
1315
 
        0: No priority set
1316
 
        10: This is a regular file-based prober
1317
 
        100: This is a prober for an unsupported format
1318
 
        """
1319
 
        return 0
1320
 
 
1321
1276
 
1322
1277
class ControlDirFormatInfo(object):
1323
1278
 
1337
1292
 
1338
1293
    def __init__(self):
1339
1294
        """Create a ControlDirFormatRegistry."""
 
1295
        self._aliases = set()
1340
1296
        self._registration_order = list()
1341
1297
        super(ControlDirFormatRegistry, self).__init__()
1342
1298
 
 
1299
    def aliases(self):
 
1300
        """Return a set of the format names which are aliases."""
 
1301
        return frozenset(self._aliases)
 
1302
 
1343
1303
    def register(self, key, factory, help, native=True, deprecated=False,
1344
 
                 hidden=False, experimental=False):
 
1304
                 hidden=False, experimental=False, alias=False):
1345
1305
        """Register a ControlDirFormat factory.
1346
1306
 
1347
1307
        The factory must be a callable that takes one parameter: the key.
1351
1311
        supplied directly.
1352
1312
        """
1353
1313
        registry.Registry.register(self, key, factory, help,
1354
 
                                   ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1314
            ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1315
        if alias:
 
1316
            self._aliases.add(key)
1355
1317
        self._registration_order.append(key)
1356
1318
 
1357
 
    def register_alias(self, key, target, hidden=False):
1358
 
        """Register a format alias.
1359
 
 
1360
 
        :param key: Alias name
1361
 
        :param target: Target format
1362
 
        :param hidden: Whether the alias is hidden
1363
 
        """
1364
 
        info = self.get_info(target)
1365
 
        registry.Registry.register_alias(self, key, target,
1366
 
                                         ControlDirFormatInfo(
1367
 
                                             native=info.native, deprecated=info.deprecated,
1368
 
                                             hidden=hidden, experimental=info.experimental))
1369
 
 
1370
1319
    def register_lazy(self, key, module_name, member_name, help, native=True,
1371
 
                      deprecated=False, hidden=False, experimental=False):
 
1320
        deprecated=False, hidden=False, experimental=False, alias=False):
1372
1321
        registry.Registry.register_lazy(self, key, module_name, member_name,
1373
 
                                        help, ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1322
            help, ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1323
        if alias:
 
1324
            self._aliases.add(key)
1374
1325
        self._registration_order.append(key)
1375
1326
 
1376
1327
    def set_default(self, key):
1378
1329
 
1379
1330
        This method must be called once and only once.
1380
1331
        """
1381
 
        self.register_alias('default', key)
 
1332
        registry.Registry.register(self, 'default', self.get(key),
 
1333
            self.get_help(key), info=self.get_info(key))
 
1334
        self._aliases.add('default')
1382
1335
 
1383
1336
    def set_default_repository(self, key):
1384
1337
        """Set the FormatRegistry default and Repository default.
1391
1344
        self.set_default(key)
1392
1345
        format = self.get('default')()
1393
1346
 
1394
 
    def make_controldir(self, key):
 
1347
    def make_bzrdir(self, key):
1395
1348
        return self.get(key)()
1396
1349
 
1397
1350
    def help_topic(self, topic):
1412
1365
            if info.native:
1413
1366
                help = '(native) ' + help
1414
1367
            return ':%s:\n%s\n\n' % (key,
1415
 
                                     textwrap.fill(help, initial_indent='    ',
1416
 
                                                   subsequent_indent='    ',
1417
 
                                                   break_long_words=False))
 
1368
                textwrap.fill(help, initial_indent='    ',
 
1369
                    subsequent_indent='    ',
 
1370
                    break_long_words=False))
1418
1371
        if default_realkey is not None:
1419
1372
            output += wrapped(default_realkey, '(default) %s' % default_help,
1420
1373
                              self.get_info('default'))
1449
1402
            other_output += \
1450
1403
                "\nNo deprecated formats are available.\n\n"
1451
1404
        other_output += \
1452
 
            "\nSee :doc:`formats-help` for more about storage formats."
 
1405
                "\nSee :doc:`formats-help` for more about storage formats."
1453
1406
 
1454
1407
        if topic == 'other-formats':
1455
1408
            return other_output
1478
1431
        """
1479
1432
        self.repository = repository
1480
1433
        self.format = format
1481
 
        self.controldir = controldir
 
1434
        self.bzrdir = controldir
1482
1435
        self.shared = shared
1483
1436
 
1484
1437
    def __eq__(self, other):
1487
1440
    def __repr__(self):
1488
1441
        if self.repository:
1489
1442
            return "<%s for %s>" % (self.__class__.__name__,
1490
 
                                    self.repository)
 
1443
                self.repository)
1491
1444
        else:
1492
1445
            return "<%s for %s>" % (self.__class__.__name__,
1493
 
                                    self.controldir)
1494
 
 
1495
 
 
1496
 
def is_control_filename(filename):
1497
 
    """Check if filename is used for control directories."""
1498
 
    # TODO(jelmer): Instead, have a function that returns all control
1499
 
    # filenames.
1500
 
    for key, format in format_registry.items():
1501
 
        if format().is_control_filename(filename):
1502
 
            return True
1503
 
    else:
1504
 
        return False
1505
 
 
1506
 
 
1507
 
class RepositoryAcquisitionPolicy(object):
1508
 
    """Abstract base class for repository acquisition policies.
1509
 
 
1510
 
    A repository acquisition policy decides how a ControlDir acquires a repository
1511
 
    for a branch that is being created.  The most basic policy decision is
1512
 
    whether to create a new repository or use an existing one.
1513
 
    """
1514
 
 
1515
 
    def __init__(self, stack_on, stack_on_pwd, require_stacking):
1516
 
        """Constructor.
1517
 
 
1518
 
        :param stack_on: A location to stack on
1519
 
        :param stack_on_pwd: If stack_on is relative, the location it is
1520
 
            relative to.
1521
 
        :param require_stacking: If True, it is a failure to not stack.
1522
 
        """
1523
 
        self._stack_on = stack_on
1524
 
        self._stack_on_pwd = stack_on_pwd
1525
 
        self._require_stacking = require_stacking
1526
 
 
1527
 
    def configure_branch(self, branch):
1528
 
        """Apply any configuration data from this policy to the branch.
1529
 
 
1530
 
        Default implementation sets repository stacking.
1531
 
        """
1532
 
        if self._stack_on is None:
1533
 
            return
1534
 
        if self._stack_on_pwd is None:
1535
 
            stack_on = self._stack_on
1536
 
        else:
1537
 
            try:
1538
 
                stack_on = urlutils.rebase_url(self._stack_on,
1539
 
                                               self._stack_on_pwd,
1540
 
                                               branch.user_url)
1541
 
            except urlutils.InvalidRebaseURLs:
1542
 
                stack_on = self._get_full_stack_on()
1543
 
        try:
1544
 
            branch.set_stacked_on_url(stack_on)
1545
 
        except (_mod_branch.UnstackableBranchFormat,
1546
 
                errors.UnstackableRepositoryFormat):
1547
 
            if self._require_stacking:
1548
 
                raise
1549
 
 
1550
 
    def requires_stacking(self):
1551
 
        """Return True if this policy requires stacking."""
1552
 
        return self._stack_on is not None and self._require_stacking
1553
 
 
1554
 
    def _get_full_stack_on(self):
1555
 
        """Get a fully-qualified URL for the stack_on location."""
1556
 
        if self._stack_on is None:
1557
 
            return None
1558
 
        if self._stack_on_pwd is None:
1559
 
            return self._stack_on
1560
 
        else:
1561
 
            return urlutils.join(self._stack_on_pwd, self._stack_on)
1562
 
 
1563
 
    def _add_fallback(self, repository, possible_transports=None):
1564
 
        """Add a fallback to the supplied repository, if stacking is set."""
1565
 
        stack_on = self._get_full_stack_on()
1566
 
        if stack_on is None:
1567
 
            return
1568
 
        try:
1569
 
            stacked_dir = ControlDir.open(
1570
 
                stack_on, possible_transports=possible_transports)
1571
 
        except errors.JailBreak:
1572
 
            # We keep the stacking details, but we are in the server code so
1573
 
            # actually stacking is not needed.
1574
 
            return
1575
 
        try:
1576
 
            stacked_repo = stacked_dir.open_branch().repository
1577
 
        except errors.NotBranchError:
1578
 
            stacked_repo = stacked_dir.open_repository()
1579
 
        try:
1580
 
            repository.add_fallback_repository(stacked_repo)
1581
 
        except errors.UnstackableRepositoryFormat:
1582
 
            if self._require_stacking:
1583
 
                raise
1584
 
        else:
1585
 
            self._require_stacking = True
1586
 
 
1587
 
    def acquire_repository(self, make_working_trees=None, shared=False,
1588
 
                           possible_transports=None):
1589
 
        """Acquire a repository for this controlrdir.
1590
 
 
1591
 
        Implementations may create a new repository or use a pre-exising
1592
 
        repository.
1593
 
 
1594
 
        :param make_working_trees: If creating a repository, set
1595
 
            make_working_trees to this value (if non-None)
1596
 
        :param shared: If creating a repository, make it shared if True
1597
 
        :return: A repository, is_new_flag (True if the repository was
1598
 
            created).
1599
 
        """
1600
 
        raise NotImplementedError(
1601
 
            RepositoryAcquisitionPolicy.acquire_repository)
 
1446
                self.bzrdir)
1602
1447
 
1603
1448
 
1604
1449
# Please register new formats after old formats so that formats