/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 brzlib/controldir.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
The ControlDir class is the base for the control directory used
20
20
by all bzr and foreign formats. For the ".bzr" implementation,
21
 
see breezy.bzrdir.BzrDir.
 
21
see brzlib.bzrdir.BzrDir.
22
22
 
23
23
"""
24
24
 
25
 
from .lazy_import import lazy_import
 
25
from __future__ import absolute_import
 
26
 
 
27
from brzlib.lazy_import import lazy_import
26
28
lazy_import(globals(), """
27
29
import textwrap
28
30
 
29
 
from breezy import (
30
 
    branch as _mod_branch,
 
31
from brzlib import (
 
32
    errors,
31
33
    hooks,
32
34
    revision as _mod_revision,
33
35
    transport as _mod_transport,
35
37
    ui,
36
38
    urlutils,
37
39
    )
38
 
from breezy.transport import local
39
 
from breezy.push import (
 
40
from brzlib.transport import local
 
41
from brzlib.push import (
40
42
    PushResult,
41
43
    )
42
44
 
43
 
from breezy.i18n import gettext
 
45
from brzlib.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 brzlib import registry
66
49
 
67
50
 
68
51
class ControlComponent(object):
125
108
        """Return a sequence of all branches local to this control directory.
126
109
 
127
110
        """
128
 
        return list(self.get_branches().values())
 
111
        return self.get_branches().values()
129
112
 
130
113
    def get_branches(self):
131
114
        """Get all branches in this control directory, as a dictionary.
132
 
 
 
115
        
133
116
        :return: Dictionary mapping branch names to instances.
134
117
        """
135
118
        try:
136
 
            return {"": self.open_branch()}
 
119
           return { "": self.open_branch() }
137
120
        except (errors.NotBranchError, errors.NoRepositoryPresent):
138
 
            return {}
 
121
           return {}
139
122
 
140
123
    def is_control_filename(self, filename):
141
124
        """True if filename is the name of a path which is reserved for
150
133
        this in the future - for instance to make bzr talk with svn working
151
134
        trees.
152
135
        """
153
 
        return self._format.is_control_filename(filename)
 
136
        raise NotImplementedError(self.is_control_filename)
154
137
 
155
138
    def needs_format_conversion(self, format=None):
156
139
        """Return true if this controldir needs convert_format run on it.
192
175
    def destroy_branch(self, name=None):
193
176
        """Destroy a branch in this ControlDir.
194
177
 
195
 
        :param name: Name of the branch to destroy, None for the
 
178
        :param name: Name of the branch to destroy, None for the 
196
179
            user selected branch or "" for the active branch.
197
180
        :raise NotBranchError: When the branch does not exist
198
181
        """
199
182
        raise NotImplementedError(self.destroy_branch)
200
183
 
201
184
    def create_workingtree(self, revision_id=None, from_branch=None,
202
 
                           accelerator_tree=None, hardlink=False):
 
185
        accelerator_tree=None, hardlink=False):
203
186
        """Create a working tree at this ControlDir.
204
187
 
205
188
        :param revision_id: create it as of this revision id.
206
 
        :param from_branch: override controldir branch
 
189
        :param from_branch: override controldir branch 
207
190
            (for lightweight checkouts)
208
191
        :param accelerator_tree: A tree which can be used for retrieving file
209
192
            contents more quickly than the revision tree, i.e. a workingtree.
370
353
    def sprout(self, url, revision_id=None, force_new_repo=False,
371
354
               recurse='down', possible_transports=None,
372
355
               accelerator_tree=None, hardlink=False, stacked=False,
373
 
               source_branch=None, create_tree_if_local=True,
374
 
               lossy=False):
 
356
               source_branch=None, create_tree_if_local=True):
375
357
        """Create a copy of this controldir prepared for use as a new line of
376
358
        development.
377
359
 
397
379
        """
398
380
        raise NotImplementedError(self.sprout)
399
381
 
400
 
    def push_branch(self, source, revision_id=None, overwrite=False,
401
 
                    remember=False, create_prefix=False, lossy=False):
 
382
    def push_branch(self, source, revision_id=None, overwrite=False, 
 
383
        remember=False, create_prefix=False):
402
384
        """Push the source branch into this ControlDir."""
403
385
        br_to = None
404
386
        # If we can open a branch, use its direct repository, otherwise see
422
404
                # revision
423
405
                revision_id = source.last_revision()
424
406
            repository_to.fetch(source.repository, revision_id=revision_id)
425
 
            br_to = source.sprout(self, revision_id=revision_id, lossy=lossy)
 
407
            br_to = source.clone(self, revision_id=revision_id)
426
408
            if source.get_push_location() is None or remember:
427
409
                # FIXME: Should be done only if we succeed ? -- vila 2012-01-18
428
410
                source.set_push_location(br_to.base)
441
423
            try:
442
424
                tree_to = self.open_workingtree()
443
425
            except errors.NotLocalUrl:
444
 
                push_result.branch_push_result = source.push(
445
 
                    br_to, overwrite, stop_revision=revision_id, lossy=lossy)
 
426
                push_result.branch_push_result = source.push(br_to, 
 
427
                    overwrite, stop_revision=revision_id)
446
428
                push_result.workingtree_updated = False
447
429
            except errors.NoWorkingTree:
448
 
                push_result.branch_push_result = source.push(
449
 
                    br_to, overwrite, stop_revision=revision_id, lossy=lossy)
450
 
                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
451
433
            else:
452
 
                with tree_to.lock_write():
 
434
                tree_to.lock_write()
 
435
                try:
453
436
                    push_result.branch_push_result = source.push(
454
 
                        tree_to.branch, overwrite, stop_revision=revision_id,
455
 
                        lossy=lossy)
 
437
                        tree_to.branch, overwrite, stop_revision=revision_id)
456
438
                    tree_to.update()
 
439
                finally:
 
440
                    tree_to.unlock()
457
441
                push_result.workingtree_updated = True
458
442
            push_result.old_revno = push_result.branch_push_result.old_revno
459
443
            push_result.old_revid = push_result.branch_push_result.old_revid
510
494
                                       preserve_stacking=preserve_stacking)
511
495
 
512
496
    def clone_on_transport(self, transport, revision_id=None,
513
 
                           force_new_repo=False, preserve_stacking=False, stacked_on=None,
514
 
                           create_prefix=False, use_existing_dir=True, no_tree=False):
 
497
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
498
        create_prefix=False, use_existing_dir=True, no_tree=False):
515
499
        """Clone this controldir and its contents to transport verbatim.
516
500
 
517
501
        :param transport: The transport for the location to produce the clone
531
515
        raise NotImplementedError(self.clone_on_transport)
532
516
 
533
517
    @classmethod
534
 
    def find_controldirs(klass, transport, evaluate=None, list_current=None):
 
518
    def find_bzrdirs(klass, transport, evaluate=None, list_current=None):
535
519
        """Find control dirs recursively from current location.
536
520
 
537
521
        This is intended primarily as a building block for more sophisticated
559
543
            recurse = True
560
544
            try:
561
545
                controldir = klass.open_from_transport(current_transport)
562
 
            except (errors.NotBranchError, errors.PermissionDenied,
563
 
                    errors.UnknownFormatError):
 
546
            except (errors.NotBranchError, errors.PermissionDenied):
564
547
                pass
565
548
            else:
566
549
                recurse, value = evaluate(controldir)
593
576
                return False, ([], repository)
594
577
            return True, (controldir.list_branches(), None)
595
578
        ret = []
596
 
        for branches, repo in klass.find_controldirs(
 
579
        for branches, repo in klass.find_bzrdirs(
597
580
                transport, evaluate=evaluate):
598
581
            if repo is not None:
599
582
                ret.extend(repo.find_branches())
685
668
        if not isinstance(t, local.LocalTransport):
686
669
            raise errors.NotLocalUrl(base)
687
670
        controldir = klass.create_branch_and_repo(base,
688
 
                                                  force_new_repo=True,
689
 
                                                  format=format).controldir
 
671
                                               force_new_repo=True,
 
672
                                               format=format).bzrdir
690
673
        return controldir.create_workingtree()
691
674
 
692
675
    @classmethod
703
686
        """
704
687
        t = _mod_transport.get_transport(base, possible_transports)
705
688
        return klass.open_from_transport(t, probers=probers,
706
 
                                         _unsupported=_unsupported)
 
689
                _unsupported=_unsupported)
707
690
 
708
691
    @classmethod
709
692
    def open_from_transport(klass, transport, _unsupported=False,
718
701
        # Keep initial base since 'transport' may be modified while following
719
702
        # the redirections.
720
703
        base = transport.base
721
 
 
722
704
        def find_format(transport):
723
705
            return transport, ControlDirFormat.find_format(transport,
724
 
                                                           probers=probers)
 
706
                probers=probers)
725
707
 
726
708
        def redirected(transport, e, redirection_notice):
727
709
            redirected_transport = transport._redirected_to(e.source, e.target)
728
710
            if redirected_transport is None:
729
711
                raise errors.NotBranchError(base)
730
712
            trace.note(gettext('{0} is{1} redirected to {2}').format(
731
 
                transport.base, e.permanently, redirected_transport.base))
 
713
                 transport.base, e.permanently, redirected_transport.base))
732
714
            return redirected_transport
733
715
 
734
716
        try:
772
754
            try:
773
755
                result = klass.open_from_transport(a_transport)
774
756
                return result, urlutils.unescape(a_transport.relpath(url))
775
 
            except errors.NotBranchError:
 
757
            except errors.NotBranchError, e:
776
758
                pass
777
759
            except errors.PermissionDenied:
778
760
                pass
779
761
            try:
780
762
                new_t = a_transport.clone('..')
781
 
            except urlutils.InvalidURLJoin:
 
763
            except errors.InvalidURLJoin:
782
764
                # reached the root, whatever that may be
783
765
                raise errors.NotBranchError(path=url)
784
766
            if new_t.base == a_transport.base:
800
782
 
801
783
    @classmethod
802
784
    def open_containing_tree_or_branch(klass, location,
803
 
                                       possible_transports=None):
 
785
            possible_transports=None):
804
786
        """Return the branch and working tree contained by a location.
805
787
 
806
788
        Returns (tree, branch, relpath).
810
792
        relpath is the portion of the path that is contained by the branch.
811
793
        """
812
794
        controldir, relpath = klass.open_containing(location,
813
 
                                                    possible_transports=possible_transports)
 
795
            possible_transports=possible_transports)
814
796
        tree, branch = controldir._get_tree_branch()
815
797
        return tree, branch, relpath
816
798
 
850
832
        """
851
833
        if klass is not ControlDir:
852
834
            raise AssertionError("ControlDir.create always creates the"
853
 
                                 "default format, not one of %r" % klass)
 
835
                "default format, not one of %r" % klass)
854
836
        t = _mod_transport.get_transport(base, possible_transports)
855
837
        t.ensure_base()
856
838
        if format is None:
863
845
 
864
846
    def __init__(self):
865
847
        """Create the default hooks."""
866
 
        hooks.Hooks.__init__(self, "breezy.controldir", "ControlDir.hooks")
 
848
        hooks.Hooks.__init__(self, "brzlib.controldir", "ControlDir.hooks")
867
849
        self.add_hook('pre_open',
868
 
                      "Invoked before attempting to open a ControlDir with the transport "
869
 
                      "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))
870
852
        self.add_hook('post_repo_init',
871
 
                      "Invoked after a repository has been initialized. "
872
 
                      "post_repo_init is called with a "
873
 
                      "breezy.controldir.RepoInitHookParams.",
874
 
                      (2, 2))
875
 
 
 
853
            "Invoked after a repository has been initialized. "
 
854
            "post_repo_init is called with a "
 
855
            "brzlib.controldir.RepoInitHookParams.",
 
856
            (2, 2))
876
857
 
877
858
# install the default hooks
878
859
ControlDir.hooks = ControlDirHooks()
897
878
        return True
898
879
 
899
880
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
900
 
                             basedir=None):
 
881
        basedir=None):
901
882
        """Give an error or warning on old formats.
902
883
 
903
884
        :param allow_unsupported: If true, allow opening
957
938
            registry._LazyObjectGetter(module_name, member_name))
958
939
 
959
940
    def _get_extra(self):
960
 
        """Return getters for extra formats, not usable in meta directories."""
961
 
        return [getter.get_obj for getter in self._extra_formats]
962
 
 
963
 
    def _get_all_lazy(self):
964
 
        """Return getters for all formats, even those not usable in metadirs."""
965
 
        result = [self._dict[name].get_obj for name in self.keys()]
966
 
        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)
967
948
        return result
968
949
 
969
950
    def _get_all(self):
970
 
        """Return all formats, even those not usable in metadirs."""
 
951
        """Return all formats, even those not usable in metadirs.
 
952
        """
971
953
        result = []
972
 
        for getter in self._get_all_lazy():
973
 
            fmt = getter()
 
954
        for name in self.keys():
 
955
            fmt = self.get(name)
974
956
            if callable(fmt):
975
957
                fmt = fmt()
976
958
            result.append(fmt)
977
 
        return result
 
959
        return result + self._get_extra()
978
960
 
979
961
    def _get_all_modules(self):
980
962
        """Return a set of the modules providing objects."""
998
980
 
999
981
    def step(self, message):
1000
982
        """Update the pb by a step."""
1001
 
        self.count += 1
 
983
        self.count +=1
1002
984
        self.pb.update(message, self.count, self.total)
1003
985
 
1004
986
 
1026
1008
    _default_format = None
1027
1009
    """The default format used for new control directories."""
1028
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
 
1029
1017
    _probers = []
1030
1018
    """The registered format probers, e.g. BzrProber.
1031
1019
 
1054
1042
    def get_converter(self, format=None):
1055
1043
        """Return the converter to use to convert controldirs needing converts.
1056
1044
 
1057
 
        This returns a breezy.controldir.Converter object.
 
1045
        This returns a brzlib.controldir.Converter object.
1058
1046
 
1059
1047
        This should return the best upgrader to step this format towards the
1060
1048
        current default format. In the case of plugins we can/should provide
1080
1068
        return self.is_supported()
1081
1069
 
1082
1070
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1083
 
                             basedir=None):
 
1071
        basedir=None):
1084
1072
        """Give an error or warning on old formats.
1085
1073
 
1086
1074
        :param allow_unsupported: If true, allow opening
1100
1088
 
1101
1089
    def same_model(self, target_format):
1102
1090
        return (self.repository_format.rich_root_data ==
1103
 
                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.")
1104
1100
 
1105
1101
    @classmethod
1106
1102
    def register_prober(klass, prober):
1116
1112
        """
1117
1113
        klass._probers.remove(prober)
1118
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
 
1119
1126
    def __str__(self):
1120
1127
        # Trim the newline
1121
1128
        return self.get_format_description().rstrip()
1122
1129
 
1123
1130
    @classmethod
1124
1131
    def all_probers(klass):
1125
 
        return klass._probers
 
1132
        return klass._server_probers + klass._probers
1126
1133
 
1127
1134
    @classmethod
1128
1135
    def known_formats(klass):
1129
1136
        """Return all the known formats.
1130
1137
        """
1131
 
        result = []
 
1138
        result = set()
1132
1139
        for prober_kls in klass.all_probers():
1133
 
            result.extend(prober_kls.known_formats())
 
1140
            result.update(prober_kls.known_formats())
1134
1141
        return result
1135
1142
 
1136
1143
    @classmethod
1137
1144
    def find_format(klass, transport, probers=None):
1138
1145
        """Return the format present at transport."""
1139
1146
        if probers is None:
1140
 
            probers = sorted(
1141
 
                klass.all_probers(),
1142
 
                key=lambda prober: prober.priority(transport))
 
1147
            probers = klass.all_probers()
1143
1148
        for prober_kls in probers:
1144
1149
            prober = prober_kls()
1145
1150
            try:
1167
1172
        raise NotImplementedError(self.initialize_on_transport)
1168
1173
 
1169
1174
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1170
 
                                   create_prefix=False, force_new_repo=False, stacked_on=None,
1171
 
                                   stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1172
 
                                   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):
1173
1178
        """Create this format on transport.
1174
1179
 
1175
1180
        The directory to initialize will be created.
1230
1235
        """
1231
1236
        raise NotImplementedError(self.supports_transport)
1232
1237
 
1233
 
    @classmethod
1234
 
    def is_control_filename(klass, filename):
1235
 
        """True if filename is the name of a path which is reserved for
1236
 
        controldirs.
1237
 
 
1238
 
        :param filename: A filename within the root transport of this
1239
 
            controldir.
1240
 
 
1241
 
        This is true IF and ONLY IF the filename is part of the namespace reserved
1242
 
        for bzr control dirs. Currently this is the '.bzr' directory in the root
1243
 
        of the root_transport. it is expected that plugins will need to extend
1244
 
        this in the future - for instance to make bzr talk with svn working
1245
 
        trees.
1246
 
        """
1247
 
        raise NotImplementedError(self.is_control_filename)
1248
 
 
1249
1238
 
1250
1239
class Prober(object):
1251
1240
    """Abstract class that can be used to detect a particular kind of
1255
1244
    transport, but it may be extended in the future to e.g. avoid
1256
1245
    multiple levels of probing for Subversion repositories.
1257
1246
 
1258
 
    See BzrProber and RemoteBzrProber in breezy.bzrdir for the
 
1247
    See BzrProber and RemoteBzrProber in brzlib.bzrdir for the
1259
1248
    probers that detect .bzr/ directories and Bazaar smart servers,
1260
1249
    respectively.
1261
1250
 
1262
 
    Probers should be registered using the register_prober methods on
1263
 
    ControlDirFormat.
 
1251
    Probers should be registered using the register_server_prober or
 
1252
    register_prober methods on ControlDirFormat.
1264
1253
    """
1265
1254
 
1266
1255
    def probe_transport(self, transport):
1284
1273
        """
1285
1274
        raise NotImplementedError(klass.known_formats)
1286
1275
 
1287
 
    @classmethod
1288
 
    def priority(klass, transport):
1289
 
        """Priority of this prober.
1290
 
 
1291
 
        A lower value means the prober gets checked first.
1292
 
 
1293
 
        Other conventions:
1294
 
 
1295
 
        -10: This is a "server" prober
1296
 
        0: No priority set
1297
 
        10: This is a regular file-based prober
1298
 
        100: This is a prober for an unsupported format
1299
 
        """
1300
 
        return 0
1301
 
 
1302
1276
 
1303
1277
class ControlDirFormatInfo(object):
1304
1278
 
1318
1292
 
1319
1293
    def __init__(self):
1320
1294
        """Create a ControlDirFormatRegistry."""
 
1295
        self._aliases = set()
1321
1296
        self._registration_order = list()
1322
1297
        super(ControlDirFormatRegistry, self).__init__()
1323
1298
 
 
1299
    def aliases(self):
 
1300
        """Return a set of the format names which are aliases."""
 
1301
        return frozenset(self._aliases)
 
1302
 
1324
1303
    def register(self, key, factory, help, native=True, deprecated=False,
1325
 
                 hidden=False, experimental=False):
 
1304
                 hidden=False, experimental=False, alias=False):
1326
1305
        """Register a ControlDirFormat factory.
1327
1306
 
1328
1307
        The factory must be a callable that takes one parameter: the key.
1332
1311
        supplied directly.
1333
1312
        """
1334
1313
        registry.Registry.register(self, key, factory, help,
1335
 
                                   ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1314
            ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1315
        if alias:
 
1316
            self._aliases.add(key)
1336
1317
        self._registration_order.append(key)
1337
1318
 
1338
 
    def register_alias(self, key, target, hidden=False):
1339
 
        """Register a format alias.
1340
 
 
1341
 
        :param key: Alias name
1342
 
        :param target: Target format
1343
 
        :param hidden: Whether the alias is hidden
1344
 
        """
1345
 
        info = self.get_info(target)
1346
 
        registry.Registry.register_alias(self, key, target,
1347
 
                                         ControlDirFormatInfo(
1348
 
                                             native=info.native, deprecated=info.deprecated,
1349
 
                                             hidden=hidden, experimental=info.experimental))
1350
 
 
1351
1319
    def register_lazy(self, key, module_name, member_name, help, native=True,
1352
 
                      deprecated=False, hidden=False, experimental=False):
 
1320
        deprecated=False, hidden=False, experimental=False, alias=False):
1353
1321
        registry.Registry.register_lazy(self, key, module_name, member_name,
1354
 
                                        help, ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1322
            help, ControlDirFormatInfo(native, deprecated, hidden, experimental))
 
1323
        if alias:
 
1324
            self._aliases.add(key)
1355
1325
        self._registration_order.append(key)
1356
1326
 
1357
1327
    def set_default(self, key):
1359
1329
 
1360
1330
        This method must be called once and only once.
1361
1331
        """
1362
 
        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')
1363
1335
 
1364
1336
    def set_default_repository(self, key):
1365
1337
        """Set the FormatRegistry default and Repository default.
1372
1344
        self.set_default(key)
1373
1345
        format = self.get('default')()
1374
1346
 
1375
 
    def make_controldir(self, key):
 
1347
    def make_bzrdir(self, key):
1376
1348
        return self.get(key)()
1377
1349
 
1378
1350
    def help_topic(self, topic):
1393
1365
            if info.native:
1394
1366
                help = '(native) ' + help
1395
1367
            return ':%s:\n%s\n\n' % (key,
1396
 
                                     textwrap.fill(help, initial_indent='    ',
1397
 
                                                   subsequent_indent='    ',
1398
 
                                                   break_long_words=False))
 
1368
                textwrap.fill(help, initial_indent='    ',
 
1369
                    subsequent_indent='    ',
 
1370
                    break_long_words=False))
1399
1371
        if default_realkey is not None:
1400
1372
            output += wrapped(default_realkey, '(default) %s' % default_help,
1401
1373
                              self.get_info('default'))
1430
1402
            other_output += \
1431
1403
                "\nNo deprecated formats are available.\n\n"
1432
1404
        other_output += \
1433
 
            "\nSee :doc:`formats-help` for more about storage formats."
 
1405
                "\nSee :doc:`formats-help` for more about storage formats."
1434
1406
 
1435
1407
        if topic == 'other-formats':
1436
1408
            return other_output
1459
1431
        """
1460
1432
        self.repository = repository
1461
1433
        self.format = format
1462
 
        self.controldir = controldir
 
1434
        self.bzrdir = controldir
1463
1435
        self.shared = shared
1464
1436
 
1465
1437
    def __eq__(self, other):
1468
1440
    def __repr__(self):
1469
1441
        if self.repository:
1470
1442
            return "<%s for %s>" % (self.__class__.__name__,
1471
 
                                    self.repository)
 
1443
                self.repository)
1472
1444
        else:
1473
1445
            return "<%s for %s>" % (self.__class__.__name__,
1474
 
                                    self.controldir)
1475
 
 
1476
 
 
1477
 
def is_control_filename(filename):
1478
 
    """Check if filename is used for control directories."""
1479
 
    # TODO(jelmer): Instead, have a function that returns all control
1480
 
    # filenames.
1481
 
    for key, format in format_registry.items():
1482
 
        if format().is_control_filename(filename):
1483
 
            return True
1484
 
    else:
1485
 
        return False
1486
 
 
1487
 
 
1488
 
class RepositoryAcquisitionPolicy(object):
1489
 
    """Abstract base class for repository acquisition policies.
1490
 
 
1491
 
    A repository acquisition policy decides how a ControlDir acquires a repository
1492
 
    for a branch that is being created.  The most basic policy decision is
1493
 
    whether to create a new repository or use an existing one.
1494
 
    """
1495
 
 
1496
 
    def __init__(self, stack_on, stack_on_pwd, require_stacking):
1497
 
        """Constructor.
1498
 
 
1499
 
        :param stack_on: A location to stack on
1500
 
        :param stack_on_pwd: If stack_on is relative, the location it is
1501
 
            relative to.
1502
 
        :param require_stacking: If True, it is a failure to not stack.
1503
 
        """
1504
 
        self._stack_on = stack_on
1505
 
        self._stack_on_pwd = stack_on_pwd
1506
 
        self._require_stacking = require_stacking
1507
 
 
1508
 
    def configure_branch(self, branch):
1509
 
        """Apply any configuration data from this policy to the branch.
1510
 
 
1511
 
        Default implementation sets repository stacking.
1512
 
        """
1513
 
        if self._stack_on is None:
1514
 
            return
1515
 
        if self._stack_on_pwd is None:
1516
 
            stack_on = self._stack_on
1517
 
        else:
1518
 
            try:
1519
 
                stack_on = urlutils.rebase_url(self._stack_on,
1520
 
                                               self._stack_on_pwd,
1521
 
                                               branch.user_url)
1522
 
            except urlutils.InvalidRebaseURLs:
1523
 
                stack_on = self._get_full_stack_on()
1524
 
        try:
1525
 
            branch.set_stacked_on_url(stack_on)
1526
 
        except (_mod_branch.UnstackableBranchFormat,
1527
 
                errors.UnstackableRepositoryFormat):
1528
 
            if self._require_stacking:
1529
 
                raise
1530
 
 
1531
 
    def requires_stacking(self):
1532
 
        """Return True if this policy requires stacking."""
1533
 
        return self._stack_on is not None and self._require_stacking
1534
 
 
1535
 
    def _get_full_stack_on(self):
1536
 
        """Get a fully-qualified URL for the stack_on location."""
1537
 
        if self._stack_on is None:
1538
 
            return None
1539
 
        if self._stack_on_pwd is None:
1540
 
            return self._stack_on
1541
 
        else:
1542
 
            return urlutils.join(self._stack_on_pwd, self._stack_on)
1543
 
 
1544
 
    def _add_fallback(self, repository, possible_transports=None):
1545
 
        """Add a fallback to the supplied repository, if stacking is set."""
1546
 
        stack_on = self._get_full_stack_on()
1547
 
        if stack_on is None:
1548
 
            return
1549
 
        try:
1550
 
            stacked_dir = ControlDir.open(
1551
 
                stack_on, possible_transports=possible_transports)
1552
 
        except errors.JailBreak:
1553
 
            # We keep the stacking details, but we are in the server code so
1554
 
            # actually stacking is not needed.
1555
 
            return
1556
 
        try:
1557
 
            stacked_repo = stacked_dir.open_branch().repository
1558
 
        except errors.NotBranchError:
1559
 
            stacked_repo = stacked_dir.open_repository()
1560
 
        try:
1561
 
            repository.add_fallback_repository(stacked_repo)
1562
 
        except errors.UnstackableRepositoryFormat:
1563
 
            if self._require_stacking:
1564
 
                raise
1565
 
        else:
1566
 
            self._require_stacking = True
1567
 
 
1568
 
    def acquire_repository(self, make_working_trees=None, shared=False,
1569
 
                           possible_transports=None):
1570
 
        """Acquire a repository for this controlrdir.
1571
 
 
1572
 
        Implementations may create a new repository or use a pre-exising
1573
 
        repository.
1574
 
 
1575
 
        :param make_working_trees: If creating a repository, set
1576
 
            make_working_trees to this value (if non-None)
1577
 
        :param shared: If creating a repository, make it shared if True
1578
 
        :return: A repository, is_new_flag (True if the repository was
1579
 
            created).
1580
 
        """
1581
 
        raise NotImplementedError(
1582
 
            RepositoryAcquisitionPolicy.acquire_repository)
 
1446
                self.bzrdir)
1583
1447
 
1584
1448
 
1585
1449
# Please register new formats after old formats so that formats