~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

(jelmer) Fix bug #1010339,
 use encoding_type='exact' for bzr testament (John A Meinel)

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,
58
55
    do_catching_redirections,
59
56
    local,
60
57
    )
61
 
from bzrlib.i18n import gettext
62
58
""")
63
59
 
64
60
from bzrlib.trace import (
69
65
from bzrlib import (
70
66
    config,
71
67
    controldir,
 
68
    hooks,
72
69
    registry,
73
70
    )
74
71
from bzrlib.symbol_versioning import (
77
74
    )
78
75
 
79
76
 
 
77
def extract_format_string(text):
 
78
    """Read a format string from a file.
 
79
 
 
80
    The first line is returned. The other lines can contain
 
81
    optional features. An exception is raised when a
 
82
    required feature is present.
 
83
    """
 
84
    lines = text.splitlines(True)
 
85
    try:
 
86
        firstline = lines.pop(0)
 
87
    except IndexError:
 
88
        raise errors.UnknownFormatError(format=text, kind='')
 
89
    for lineno, line in enumerate(lines):
 
90
        try:
 
91
            (necessity, feature) = line.split(" ", 1)
 
92
        except ValueError:
 
93
            raise errors.ParseFormatError(lineno=lineno+2,
 
94
                line=line, text=text)
 
95
        else:
 
96
            if necessity == "optional":
 
97
                mutter("Ignoring optional feature %s", feature)
 
98
            else:
 
99
                raise errors.MissingFeature(feature)
 
100
    return firstline
 
101
 
 
102
 
80
103
class BzrDir(controldir.ControlDir):
81
104
    """A .bzr control diretory.
82
105
 
203
226
                if (result_repo.user_url == result.user_url
204
227
                    and not require_stacking and
205
228
                    revision_id is not None):
206
 
                    fetch_spec = vf_search.PendingAncestryResult(
 
229
                    fetch_spec = graph.PendingAncestryResult(
207
230
                        [revision_id], local_repo)
208
231
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
209
232
                else:
224
247
            # the tree and fail.
225
248
            result.root_transport.local_abspath('.')
226
249
            if result_repo is None or result_repo.make_working_trees():
227
 
                self.open_workingtree().clone(result, revision_id=revision_id)
 
250
                self.open_workingtree().clone(result)
228
251
        except (errors.NoWorkingTree, errors.NotLocalUrl):
229
252
            pass
230
253
        return result
235
258
        t = _mod_transport.get_transport(url)
236
259
        t.ensure_base()
237
260
 
 
261
    @staticmethod
 
262
    def find_bzrdirs(transport, evaluate=None, list_current=None):
 
263
        """Find bzrdirs recursively from current location.
 
264
 
 
265
        This is intended primarily as a building block for more sophisticated
 
266
        functionality, like finding trees under a directory, or finding
 
267
        branches that use a given repository.
 
268
 
 
269
        :param evaluate: An optional callable that yields recurse, value,
 
270
            where recurse controls whether this bzrdir is recursed into
 
271
            and value is the value to yield.  By default, all bzrdirs
 
272
            are recursed into, and the return value is the bzrdir.
 
273
        :param list_current: if supplied, use this function to list the current
 
274
            directory, instead of Transport.list_dir
 
275
        :return: a generator of found bzrdirs, or whatever evaluate returns.
 
276
        """
 
277
        if list_current is None:
 
278
            def list_current(transport):
 
279
                return transport.list_dir('')
 
280
        if evaluate is None:
 
281
            def evaluate(bzrdir):
 
282
                return True, bzrdir
 
283
 
 
284
        pending = [transport]
 
285
        while len(pending) > 0:
 
286
            current_transport = pending.pop()
 
287
            recurse = True
 
288
            try:
 
289
                bzrdir = BzrDir.open_from_transport(current_transport)
 
290
            except (errors.NotBranchError, errors.PermissionDenied):
 
291
                pass
 
292
            else:
 
293
                recurse, value = evaluate(bzrdir)
 
294
                yield value
 
295
            try:
 
296
                subdirs = list_current(current_transport)
 
297
            except (errors.NoSuchFile, errors.PermissionDenied):
 
298
                continue
 
299
            if recurse:
 
300
                for subdir in sorted(subdirs, reverse=True):
 
301
                    pending.append(current_transport.clone(subdir))
 
302
 
 
303
    @staticmethod
 
304
    def find_branches(transport):
 
305
        """Find all branches under a transport.
 
306
 
 
307
        This will find all branches below the transport, including branches
 
308
        inside other branches.  Where possible, it will use
 
309
        Repository.find_branches.
 
310
 
 
311
        To list all the branches that use a particular Repository, see
 
312
        Repository.find_branches
 
313
        """
 
314
        def evaluate(bzrdir):
 
315
            try:
 
316
                repository = bzrdir.open_repository()
 
317
            except errors.NoRepositoryPresent:
 
318
                pass
 
319
            else:
 
320
                return False, ([], repository)
 
321
            return True, (bzrdir.list_branches(), None)
 
322
        ret = []
 
323
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
324
                                                  evaluate=evaluate):
 
325
            if repo is not None:
 
326
                ret.extend(repo.find_branches())
 
327
            if branches is not None:
 
328
                ret.extend(branches)
 
329
        return ret
 
330
 
 
331
    @staticmethod
 
332
    def create_branch_and_repo(base, force_new_repo=False, format=None):
 
333
        """Create a new BzrDir, Branch and Repository at the url 'base'.
 
334
 
 
335
        This will use the current default BzrDirFormat unless one is
 
336
        specified, and use whatever
 
337
        repository format that that uses via bzrdir.create_branch and
 
338
        create_repository. If a shared repository is available that is used
 
339
        preferentially.
 
340
 
 
341
        The created Branch object is returned.
 
342
 
 
343
        :param base: The URL to create the branch at.
 
344
        :param force_new_repo: If True a new repository is always created.
 
345
        :param format: If supplied, the format of branch to create.  If not
 
346
            supplied, the default is used.
 
347
        """
 
348
        bzrdir = BzrDir.create(base, format)
 
349
        bzrdir._find_or_create_repository(force_new_repo)
 
350
        return bzrdir.create_branch()
 
351
 
238
352
    def determine_repository_policy(self, force_new_repo=False, stack_on=None,
239
353
                                    stack_on_pwd=None, require_stacking=False):
240
354
        """Return an object representing a policy to use.
355
469
            location of this control directory.
356
470
        :param create_tree_if_local: If true, a working-tree will be created
357
471
            when working locally.
358
 
        :return: The created control directory
359
472
        """
360
473
        operation = cleanup.OperationWithCleanups(self._sprout)
361
474
        return operation.run(url, revision_id=revision_id,
374
487
        if revision_id is not None:
375
488
            fetch_spec_factory.add_revision_ids([revision_id])
376
489
            fetch_spec_factory.source_branch_stop_revision_id = revision_id
377
 
        if possible_transports is None:
378
 
            possible_transports = []
379
 
        else:
380
 
            possible_transports = list(possible_transports) + [
381
 
                self.root_transport]
382
490
        target_transport = _mod_transport.get_transport(url,
383
491
            possible_transports)
384
492
        target_transport.ensure_base()
385
493
        cloning_format = self.cloning_metadir(stacked)
386
494
        # Create/update the result branch
387
 
        try:
388
 
            result = controldir.ControlDir.open_from_transport(target_transport)
389
 
        except errors.NotBranchError:
390
 
            result = cloning_format.initialize_on_transport(target_transport)
 
495
        result = cloning_format.initialize_on_transport(target_transport)
391
496
        source_branch, source_repository = self._find_source_repo(
392
497
            add_cleanup, source_branch)
393
498
        fetch_spec_factory.source_branch = source_branch
399
504
            stacked_branch_url = None
400
505
        repository_policy = result.determine_repository_policy(
401
506
            force_new_repo, stacked_branch_url, require_stacking=stacked)
402
 
        result_repo, is_new_repo = repository_policy.acquire_repository(
403
 
            possible_transports=possible_transports)
 
507
        result_repo, is_new_repo = repository_policy.acquire_repository()
404
508
        add_cleanup(result_repo.lock_write().unlock)
405
509
        fetch_spec_factory.source_repo = source_repository
406
510
        fetch_spec_factory.target_repo = result_repo
427
531
        mutter("created new branch %r" % (result_branch,))
428
532
 
429
533
        # Create/update the result working tree
430
 
        if (create_tree_if_local and not result.has_workingtree() and
 
534
        if (create_tree_if_local and
431
535
            isinstance(target_transport, local.LocalTransport) and
432
536
            (result_repo is None or result_repo.make_working_trees())):
433
537
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
465
569
                    stacked=stacked)
466
570
        return result
467
571
 
 
572
 
 
573
 
 
574
    @staticmethod
 
575
    def create_branch_convenience(base, force_new_repo=False,
 
576
                                  force_new_tree=None, format=None,
 
577
                                  possible_transports=None):
 
578
        """Create a new BzrDir, Branch and Repository at the url 'base'.
 
579
 
 
580
        This is a convenience function - it will use an existing repository
 
581
        if possible, can be told explicitly whether to create a working tree or
 
582
        not.
 
583
 
 
584
        This will use the current default BzrDirFormat unless one is
 
585
        specified, and use whatever
 
586
        repository format that that uses via bzrdir.create_branch and
 
587
        create_repository. If a shared repository is available that is used
 
588
        preferentially. Whatever repository is used, its tree creation policy
 
589
        is followed.
 
590
 
 
591
        The created Branch object is returned.
 
592
        If a working tree cannot be made due to base not being a file:// url,
 
593
        no error is raised unless force_new_tree is True, in which case no
 
594
        data is created on disk and NotLocalUrl is raised.
 
595
 
 
596
        :param base: The URL to create the branch at.
 
597
        :param force_new_repo: If True a new repository is always created.
 
598
        :param force_new_tree: If True or False force creation of a tree or
 
599
                               prevent such creation respectively.
 
600
        :param format: Override for the bzrdir format to create.
 
601
        :param possible_transports: An optional reusable transports list.
 
602
        """
 
603
        if force_new_tree:
 
604
            # check for non local urls
 
605
            t = _mod_transport.get_transport(base, possible_transports)
 
606
            if not isinstance(t, local.LocalTransport):
 
607
                raise errors.NotLocalUrl(base)
 
608
        bzrdir = BzrDir.create(base, format, possible_transports)
 
609
        repo = bzrdir._find_or_create_repository(force_new_repo)
 
610
        result = bzrdir.create_branch()
 
611
        if force_new_tree or (repo.make_working_trees() and
 
612
                              force_new_tree is None):
 
613
            try:
 
614
                bzrdir.create_workingtree()
 
615
            except errors.NotLocalUrl:
 
616
                pass
 
617
        return result
 
618
 
 
619
    @staticmethod
 
620
    def create_standalone_workingtree(base, format=None):
 
621
        """Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
 
622
 
 
623
        'base' must be a local path or a file:// url.
 
624
 
 
625
        This will use the current default BzrDirFormat unless one is
 
626
        specified, and use whatever
 
627
        repository format that that uses for bzrdirformat.create_workingtree,
 
628
        create_branch and create_repository.
 
629
 
 
630
        :param format: Override for the bzrdir format to create.
 
631
        :return: The WorkingTree object.
 
632
        """
 
633
        t = _mod_transport.get_transport(base)
 
634
        if not isinstance(t, local.LocalTransport):
 
635
            raise errors.NotLocalUrl(base)
 
636
        bzrdir = BzrDir.create_branch_and_repo(base,
 
637
                                               force_new_repo=True,
 
638
                                               format=format).bzrdir
 
639
        return bzrdir.create_workingtree()
 
640
 
468
641
    @deprecated_method(deprecated_in((2, 3, 0)))
469
642
    def generate_backup_name(self, base):
470
643
        return self._available_backup_name(base)
487
660
            old_path = self.root_transport.abspath('.bzr')
488
661
            backup_dir = self._available_backup_name('backup.bzr')
489
662
            new_path = self.root_transport.abspath(backup_dir)
490
 
            ui.ui_factory.note(gettext('making backup of {0}\n  to {1}').format(
491
 
                urlutils.unescape_for_display(old_path, 'utf-8'),
492
 
                urlutils.unescape_for_display(new_path, 'utf-8')))
 
663
            ui.ui_factory.note('making backup of %s\n  to %s'
 
664
                               % (old_path, new_path,))
493
665
            self.root_transport.copy_tree('.bzr', backup_dir)
494
666
            return (old_path, new_path)
495
667
        finally:
510
682
            try:
511
683
                to_path = '.bzr.retired.%d' % i
512
684
                self.root_transport.rename('.bzr', to_path)
513
 
                note(gettext("renamed {0} to {1}").format(
514
 
                    self.root_transport.abspath('.bzr'), to_path))
 
685
                note("renamed %s to %s"
 
686
                    % (self.root_transport.abspath('.bzr'), to_path))
515
687
                return
516
688
            except (errors.TransportError, IOError, errors.PathError):
517
689
                i += 1
544
716
                return None
545
717
            # find the next containing bzrdir
546
718
            try:
547
 
                found_bzrdir = self.open_containing_from_transport(
 
719
                found_bzrdir = BzrDir.open_containing_from_transport(
548
720
                    next_transport)[0]
549
721
            except errors.NotBranchError:
550
722
                return None
667
839
        # add new tests for it to the appropriate place.
668
840
        return filename == '.bzr' or filename.startswith('.bzr/')
669
841
 
 
842
    @staticmethod
 
843
    def open_unsupported(base):
 
844
        """Open a branch which is not supported."""
 
845
        return BzrDir.open(base, _unsupported=True)
 
846
 
 
847
    @staticmethod
 
848
    def open(base, _unsupported=False, possible_transports=None):
 
849
        """Open an existing bzrdir, rooted at 'base' (url).
 
850
 
 
851
        :param _unsupported: a private parameter to the BzrDir class.
 
852
        """
 
853
        t = _mod_transport.get_transport(base, possible_transports)
 
854
        return BzrDir.open_from_transport(t, _unsupported=_unsupported)
 
855
 
 
856
    @staticmethod
 
857
    def open_from_transport(transport, _unsupported=False,
 
858
                            _server_formats=True):
 
859
        """Open a bzrdir within a particular directory.
 
860
 
 
861
        :param transport: Transport containing the bzrdir.
 
862
        :param _unsupported: private.
 
863
        """
 
864
        for hook in BzrDir.hooks['pre_open']:
 
865
            hook(transport)
 
866
        # Keep initial base since 'transport' may be modified while following
 
867
        # the redirections.
 
868
        base = transport.base
 
869
        def find_format(transport):
 
870
            return transport, controldir.ControlDirFormat.find_format(
 
871
                transport, _server_formats=_server_formats)
 
872
 
 
873
        def redirected(transport, e, redirection_notice):
 
874
            redirected_transport = transport._redirected_to(e.source, e.target)
 
875
            if redirected_transport is None:
 
876
                raise errors.NotBranchError(base)
 
877
            note('%s is%s redirected to %s',
 
878
                 transport.base, e.permanently, redirected_transport.base)
 
879
            return redirected_transport
 
880
 
 
881
        try:
 
882
            transport, format = do_catching_redirections(find_format,
 
883
                                                         transport,
 
884
                                                         redirected)
 
885
        except errors.TooManyRedirections:
 
886
            raise errors.NotBranchError(base)
 
887
 
 
888
        format.check_support_status(_unsupported)
 
889
        return format.open(transport, _found=True)
 
890
 
 
891
    @staticmethod
 
892
    def open_containing(url, possible_transports=None):
 
893
        """Open an existing branch which contains url.
 
894
 
 
895
        :param url: url to search from.
 
896
 
 
897
        See open_containing_from_transport for more detail.
 
898
        """
 
899
        transport = _mod_transport.get_transport(url, possible_transports)
 
900
        return BzrDir.open_containing_from_transport(transport)
 
901
 
 
902
    @staticmethod
 
903
    def open_containing_from_transport(a_transport):
 
904
        """Open an existing branch which contains a_transport.base.
 
905
 
 
906
        This probes for a branch at a_transport, and searches upwards from there.
 
907
 
 
908
        Basically we keep looking up until we find the control directory or
 
909
        run into the root.  If there isn't one, raises NotBranchError.
 
910
        If there is one and it is either an unrecognised format or an unsupported
 
911
        format, UnknownFormatError or UnsupportedFormatError are raised.
 
912
        If there is one, it is returned, along with the unused portion of url.
 
913
 
 
914
        :return: The BzrDir that contains the path, and a Unicode path
 
915
                for the rest of the URL.
 
916
        """
 
917
        # this gets the normalised url back. I.e. '.' -> the full path.
 
918
        url = a_transport.base
 
919
        while True:
 
920
            try:
 
921
                result = BzrDir.open_from_transport(a_transport)
 
922
                return result, urlutils.unescape(a_transport.relpath(url))
 
923
            except errors.NotBranchError, e:
 
924
                pass
 
925
            try:
 
926
                new_t = a_transport.clone('..')
 
927
            except errors.InvalidURLJoin:
 
928
                # reached the root, whatever that may be
 
929
                raise errors.NotBranchError(path=url)
 
930
            if new_t.base == a_transport.base:
 
931
                # reached the root, whatever that may be
 
932
                raise errors.NotBranchError(path=url)
 
933
            a_transport = new_t
 
934
 
 
935
    @classmethod
 
936
    def open_tree_or_branch(klass, location):
 
937
        """Return the branch and working tree at a location.
 
938
 
 
939
        If there is no tree at the location, tree will be None.
 
940
        If there is no branch at the location, an exception will be
 
941
        raised
 
942
        :return: (tree, branch)
 
943
        """
 
944
        bzrdir = klass.open(location)
 
945
        return bzrdir._get_tree_branch()
 
946
 
 
947
    @classmethod
 
948
    def open_containing_tree_or_branch(klass, location):
 
949
        """Return the branch and working tree contained by a location.
 
950
 
 
951
        Returns (tree, branch, relpath).
 
952
        If there is no tree at containing the location, tree will be None.
 
953
        If there is no branch containing the location, an exception will be
 
954
        raised
 
955
        relpath is the portion of the path that is contained by the branch.
 
956
        """
 
957
        bzrdir, relpath = klass.open_containing(location)
 
958
        tree, branch = bzrdir._get_tree_branch()
 
959
        return tree, branch, relpath
 
960
 
 
961
    @classmethod
 
962
    def open_containing_tree_branch_or_repository(klass, location):
 
963
        """Return the working tree, branch and repo contained by a location.
 
964
 
 
965
        Returns (tree, branch, repository, relpath).
 
966
        If there is no tree containing the location, tree will be None.
 
967
        If there is no branch containing the location, branch will be None.
 
968
        If there is no repository containing the location, repository will be
 
969
        None.
 
970
        relpath is the portion of the path that is contained by the innermost
 
971
        BzrDir.
 
972
 
 
973
        If no tree, branch or repository is found, a NotBranchError is raised.
 
974
        """
 
975
        bzrdir, relpath = klass.open_containing(location)
 
976
        try:
 
977
            tree, branch = bzrdir._get_tree_branch()
 
978
        except errors.NotBranchError:
 
979
            try:
 
980
                repo = bzrdir.find_repository()
 
981
                return None, None, repo, relpath
 
982
            except (errors.NoRepositoryPresent):
 
983
                raise errors.NotBranchError(location)
 
984
        return tree, branch, branch.repository, relpath
 
985
 
670
986
    def _cloning_metadir(self):
671
987
        """Produce a metadir suitable for cloning with.
672
988
 
712
1028
 
713
1029
        :require_stacking: If True, non-stackable formats will be upgraded
714
1030
            to similar stackable formats.
715
 
        :returns: a ControlDirFormat with all component formats either set
 
1031
        :returns: a BzrDirFormat with all component formats either set
716
1032
            appropriately or set to None if that component should not be
717
1033
            created.
718
1034
        """
730
1046
            format.require_stacking()
731
1047
        return format
732
1048
 
 
1049
    @classmethod
 
1050
    def create(cls, base, format=None, possible_transports=None):
 
1051
        """Create a new BzrDir at the url 'base'.
 
1052
 
 
1053
        :param format: If supplied, the format of branch to create.  If not
 
1054
            supplied, the default is used.
 
1055
        :param possible_transports: If supplied, a list of transports that
 
1056
            can be reused to share a remote connection.
 
1057
        """
 
1058
        if cls is not BzrDir:
 
1059
            raise AssertionError("BzrDir.create always creates the"
 
1060
                "default format, not one of %r" % cls)
 
1061
        t = _mod_transport.get_transport(base, possible_transports)
 
1062
        t.ensure_base()
 
1063
        if format is None:
 
1064
            format = controldir.ControlDirFormat.get_default_format()
 
1065
        return format.initialize_on_transport(t)
 
1066
 
733
1067
    def get_branch_transport(self, branch_format, name=None):
734
1068
        """Get the transport for use by branch format in this BzrDir.
735
1069
 
769
1103
        """
770
1104
        raise NotImplementedError(self.get_workingtree_transport)
771
1105
 
772
 
    @classmethod
773
 
    def create(cls, base, format=None, possible_transports=None):
774
 
        """Create a new BzrDir at the url 'base'.
775
 
 
776
 
        :param format: If supplied, the format of branch to create.  If not
777
 
            supplied, the default is used.
778
 
        :param possible_transports: If supplied, a list of transports that
779
 
            can be reused to share a remote connection.
 
1106
 
 
1107
class BzrDirHooks(hooks.Hooks):
 
1108
    """Hooks for BzrDir operations."""
 
1109
 
 
1110
    def __init__(self):
 
1111
        """Create the default hooks."""
 
1112
        hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
 
1113
        self.add_hook('pre_open',
 
1114
            "Invoked before attempting to open a BzrDir with the transport "
 
1115
            "that the open will use.", (1, 14))
 
1116
        self.add_hook('post_repo_init',
 
1117
            "Invoked after a repository has been initialized. "
 
1118
            "post_repo_init is called with a "
 
1119
            "bzrlib.bzrdir.RepoInitHookParams.",
 
1120
            (2, 2))
 
1121
 
 
1122
# install the default hooks
 
1123
BzrDir.hooks = BzrDirHooks()
 
1124
 
 
1125
 
 
1126
class RepoInitHookParams(object):
 
1127
    """Object holding parameters passed to `*_repo_init` hooks.
 
1128
 
 
1129
    There are 4 fields that hooks may wish to access:
 
1130
 
 
1131
    :ivar repository: Repository created
 
1132
    :ivar format: Repository format
 
1133
    :ivar bzrdir: The bzrdir for the repository
 
1134
    :ivar shared: The repository is shared
 
1135
    """
 
1136
 
 
1137
    def __init__(self, repository, format, a_bzrdir, shared):
 
1138
        """Create a group of RepoInitHook parameters.
 
1139
 
 
1140
        :param repository: Repository created
 
1141
        :param format: Repository format
 
1142
        :param bzrdir: The bzrdir for the repository
 
1143
        :param shared: The repository is shared
780
1144
        """
781
 
        if cls is not BzrDir:
782
 
            raise AssertionError("BzrDir.create always creates the "
783
 
                "default format, not one of %r" % cls)
784
 
        return controldir.ControlDir.create(base, format=format,
785
 
                possible_transports=possible_transports)
 
1145
        self.repository = repository
 
1146
        self.format = format
 
1147
        self.bzrdir = a_bzrdir
 
1148
        self.shared = shared
 
1149
 
 
1150
    def __eq__(self, other):
 
1151
        return self.__dict__ == other.__dict__
786
1152
 
787
1153
    def __repr__(self):
788
 
        return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
 
 
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()
 
1154
        if self.repository:
 
1155
            return "<%s for %s>" % (self.__class__.__name__,
 
1156
                self.repository)
 
1157
        else:
 
1158
            return "<%s for %s>" % (self.__class__.__name__,
 
1159
                self.bzrdir)
802
1160
 
803
1161
 
804
1162
class BzrDirMeta1(BzrDir):
810
1168
    present within a BzrDir.
811
1169
    """
812
1170
 
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
1171
    def can_convert_format(self):
860
1172
        """See BzrDir.can_convert_format()."""
861
1173
        return True
862
1174
 
863
 
    def create_branch(self, name=None, repository=None,
864
 
            append_revisions_only=None):
865
 
        """See ControlDir.create_branch."""
866
 
        if name is None:
867
 
            name = self._get_selected_branch()
 
1175
    def create_branch(self, name=None, repository=None):
 
1176
        """See BzrDir.create_branch."""
868
1177
        return self._format.get_branch_format().initialize(self, name=name,
869
 
                repository=repository,
870
 
                append_revisions_only=append_revisions_only)
 
1178
                repository=repository)
871
1179
 
872
1180
    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)
 
1181
        """See BzrDir.create_branch."""
 
1182
        if name is not None:
 
1183
            raise errors.NoColocatedBranchSupport(self)
 
1184
        self.transport.delete_tree('branch')
893
1185
 
894
1186
    def create_repository(self, shared=False):
895
1187
        """See BzrDir.create_repository."""
897
1189
 
898
1190
    def destroy_repository(self):
899
1191
        """See BzrDir.destroy_repository."""
900
 
        try:
901
 
            self.transport.delete_tree('repository')
902
 
        except errors.NoSuchFile:
903
 
            raise errors.NoRepositoryPresent(self)
 
1192
        self.transport.delete_tree('repository')
904
1193
 
905
1194
    def create_workingtree(self, revision_id=None, from_branch=None,
906
1195
                           accelerator_tree=None, hardlink=False):
928
1217
 
929
1218
        This might be a synthetic object for e.g. RemoteBranch and SVN.
930
1219
        """
931
 
        from bzrlib.branch import BranchFormatMetadir
932
 
        return BranchFormatMetadir.find_format(self, name=name)
 
1220
        from bzrlib.branch import BranchFormat
 
1221
        return BranchFormat.find_format(self, name=name)
933
1222
 
934
1223
    def _get_mkdir_mode(self):
935
1224
        """Figure out the mode to use when creating a bzrdir subdir."""
939
1228
 
940
1229
    def get_branch_reference(self, name=None):
941
1230
        """See BzrDir.get_branch_reference()."""
942
 
        from bzrlib.branch import BranchFormatMetadir
943
 
        format = BranchFormatMetadir.find_format(self, name=name)
 
1231
        from bzrlib.branch import BranchFormat
 
1232
        format = BranchFormat.find_format(self, name=name)
944
1233
        return format.get_reference(self, name=name)
945
1234
 
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
1235
    def get_branch_transport(self, branch_format, name=None):
951
1236
        """See BzrDir.get_branch_transport()."""
952
 
        if name is None:
953
 
            name = self._get_selected_branch()
954
 
        path = self._get_branch_path(name)
 
1237
        if name is not None:
 
1238
            raise errors.NoColocatedBranchSupport(self)
955
1239
        # XXX: this shouldn't implicitly create the directory if it's just
956
1240
        # promising to get a transport -- mbp 20090727
957
1241
        if branch_format is None:
958
 
            return self.transport.clone(path)
 
1242
            return self.transport.clone('branch')
959
1243
        try:
960
1244
            branch_format.get_format_string()
961
1245
        except NotImplementedError:
962
1246
            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
1247
        try:
985
 
            self.transport.mkdir(path, mode=mode)
 
1248
            self.transport.mkdir('branch', mode=self._get_mkdir_mode())
986
1249
        except errors.FileExists:
987
1250
            pass
988
 
        return self.transport.clone(path)
 
1251
        return self.transport.clone('branch')
989
1252
 
990
1253
    def get_repository_transport(self, repository_format):
991
1254
        """See BzrDir.get_repository_transport()."""
1015
1278
            pass
1016
1279
        return self.transport.clone('checkout')
1017
1280
 
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
1281
    def has_workingtree(self):
1032
1282
        """Tell if this bzrdir contains a working tree.
1033
1283
 
1034
1284
        Note: if you're going to open the working tree, you should just go
1035
1285
        ahead and try, and not ask permission first.
1036
1286
        """
1037
 
        from bzrlib.workingtree import WorkingTreeFormatMetaDir
 
1287
        from bzrlib.workingtree import WorkingTreeFormat
1038
1288
        try:
1039
 
            WorkingTreeFormatMetaDir.find_format_string(self)
 
1289
            WorkingTreeFormat.find_format_string(self)
1040
1290
        except errors.NoWorkingTree:
1041
1291
            return False
1042
1292
        return True
1043
1293
 
1044
1294
    def needs_format_conversion(self, format):
1045
1295
        """See BzrDir.needs_format_conversion()."""
1046
 
        if (not isinstance(self._format, format.__class__) or
1047
 
            self._format.get_format_string() != format.get_format_string()):
 
1296
        if not isinstance(self._format, format.__class__):
1048
1297
            # it is not a meta dir format, conversion is needed.
1049
1298
            return True
1050
1299
        # we might want to push this down to the repository?
1071
1320
        return False
1072
1321
 
1073
1322
    def open_branch(self, name=None, unsupported=False,
1074
 
                    ignore_fallbacks=False, possible_transports=None):
1075
 
        """See ControlDir.open_branch."""
1076
 
        if name is None:
1077
 
            name = self._get_selected_branch()
 
1323
                    ignore_fallbacks=False):
 
1324
        """See BzrDir.open_branch."""
1078
1325
        format = self.find_branch_format(name=name)
1079
1326
        format.check_support_status(unsupported)
1080
1327
        return format.open(self, name=name,
1081
 
            _found=True, ignore_fallbacks=ignore_fallbacks,
1082
 
            possible_transports=possible_transports)
 
1328
            _found=True, ignore_fallbacks=ignore_fallbacks)
1083
1329
 
1084
1330
    def open_repository(self, unsupported=False):
1085
1331
        """See BzrDir.open_repository."""
1086
 
        from bzrlib.repository import RepositoryFormatMetaDir
1087
 
        format = RepositoryFormatMetaDir.find_format(self)
 
1332
        from bzrlib.repository import RepositoryFormat
 
1333
        format = RepositoryFormat.find_format(self)
1088
1334
        format.check_support_status(unsupported)
1089
1335
        return format.open(self, _found=True)
1090
1336
 
1091
1337
    def open_workingtree(self, unsupported=False,
1092
1338
            recommend_upgrade=True):
1093
1339
        """See BzrDir.open_workingtree."""
1094
 
        from bzrlib.workingtree import WorkingTreeFormatMetaDir
1095
 
        format = WorkingTreeFormatMetaDir.find_format(self)
 
1340
        from bzrlib.workingtree import WorkingTreeFormat
 
1341
        format = WorkingTreeFormat.find_format(self)
1096
1342
        format.check_support_status(unsupported, recommend_upgrade,
1097
1343
            basedir=self.root_transport.base)
1098
1344
        return format.open(self, _found=True)
1101
1347
        return config.TransportConfig(self.transport, 'control.conf')
1102
1348
 
1103
1349
 
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
1124
 
    """
1125
 
 
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
1228
 
 
1229
 
 
1230
1350
class BzrProber(controldir.Prober):
1231
1351
    """Prober for formats that use a .bzr/ control directory."""
1232
1352
 
1250
1370
            format_string = transport.get_bytes(".bzr/branch-format")
1251
1371
        except errors.NoSuchFile:
1252
1372
            raise errors.NotBranchError(path=transport.base)
1253
 
        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)
 
1373
        format_string = extract_format_string(format_string)
 
1374
        try:
 
1375
            return klass.formats.get(format_string)
1259
1376
        except KeyError:
1260
 
            raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1261
 
        return cls.from_string(format_string)
 
1377
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1262
1378
 
1263
1379
    @classmethod
1264
1380
    def known_formats(cls):
1307
1423
        return set([RemoteBzrDirFormat()])
1308
1424
 
1309
1425
 
1310
 
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
 
1426
class BzrDirFormat(controldir.ControlDirFormat):
1311
1427
    """ControlDirFormat base class for .bzr/ directories.
1312
1428
 
1313
1429
    Formats are placed in a dict by their format string for reference
1324
1440
    # _lock_class must be set in subclasses to the lock type, typ.
1325
1441
    # TransportLock or LockDir
1326
1442
 
 
1443
    @classmethod
 
1444
    def get_format_string(cls):
 
1445
        """Return the ASCII format string that identifies this format."""
 
1446
        raise NotImplementedError(cls.get_format_string)
 
1447
 
1327
1448
    def initialize_on_transport(self, transport):
1328
1449
        """Initialize a new bzrdir in the base directory of a Transport."""
1329
1450
        try:
1451
1572
        # mode from the root directory
1452
1573
        temp_control = lockable_files.LockableFiles(transport,
1453
1574
                            '', 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)
 
1575
        temp_control._transport.mkdir('.bzr',
 
1576
                                      # FIXME: RBC 20060121 don't peek under
 
1577
                                      # the covers
 
1578
                                      mode=temp_control._dir_mode)
1461
1579
        if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1462
1580
            win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1463
1581
        file_mode = temp_control._file_mode
1467
1585
                       "This is a Bazaar control directory.\n"
1468
1586
                       "Do not change any files in this directory.\n"
1469
1587
                       "See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1470
 
                      ('branch-format', self.as_string()),
 
1588
                      ('branch-format', self.get_format_string()),
1471
1589
                      ]
1472
1590
        # NB: no need to escape relative paths that are url safe.
1473
1591
        control_files = lockable_files.LockableFiles(bzrdir_transport,
1517
1635
            compatible with whatever sub formats are supported by self.
1518
1636
        :return: None.
1519
1637
        """
1520
 
        other_format.features = dict(self.features)
1521
 
 
1522
 
    def supports_transport(self, transport):
1523
 
        # bzr formats can be opened over all known transports
1524
 
        return True
1525
 
 
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
1638
 
1534
1639
 
1535
1640
class BzrDirMetaFormat1(BzrDirFormat):
1549
1654
 
1550
1655
    fixed_components = False
1551
1656
 
1552
 
    colocated_branches = True
1553
 
 
1554
1657
    def __init__(self):
1555
 
        BzrDirFormat.__init__(self)
1556
1658
        self._workingtree_format = None
1557
1659
        self._branch_format = None
1558
1660
        self._repository_format = None
1564
1666
            return False
1565
1667
        if other.workingtree_format != self.workingtree_format:
1566
1668
            return False
1567
 
        if other.features != self.features:
1568
 
            return False
1569
1669
        return True
1570
1670
 
1571
1671
    def __ne__(self, other):
1649
1749
                    new_repo_format = None
1650
1750
            if new_repo_format is not None:
1651
1751
                self.repository_format = new_repo_format
1652
 
                note(gettext('Source repository format does not support stacking,'
1653
 
                     ' using format:\n  %s'),
 
1752
                note('Source repository format does not support stacking,'
 
1753
                     ' using format:\n  %s',
1654
1754
                     new_repo_format.get_format_description())
1655
1755
 
1656
1756
        if not self.get_branch_format().supports_stacking():
1669
1769
            if new_branch_format is not None:
1670
1770
                # Does support stacking, use its format.
1671
1771
                self.set_branch_format(new_branch_format)
1672
 
                note(gettext('Source branch format does not support stacking,'
1673
 
                     ' using format:\n  %s'),
 
1772
                note('Source branch format does not support stacking,'
 
1773
                     ' using format:\n  %s',
1674
1774
                     new_branch_format.get_format_description())
1675
1775
 
1676
1776
    def get_converter(self, format=None):
1677
1777
        """See BzrDirFormat.get_converter()."""
1678
1778
        if format is None:
1679
1779
            format = BzrDirFormat.get_default_format()
1680
 
        if (type(self) is BzrDirMetaFormat1 and
1681
 
            type(format) is BzrDirMetaFormat1Colo):
1682
 
            return ConvertMetaToColo(format)
1683
 
        if (type(self) is BzrDirMetaFormat1Colo and
1684
 
            type(format) is BzrDirMetaFormat1):
1685
 
            return ConvertMetaToColo(format)
1686
1780
        if not isinstance(self, format.__class__):
1687
1781
            # converting away from metadir is not implemented
1688
1782
            raise NotImplementedError(self.get_converter)
1697
1791
        """See BzrDirFormat.get_format_description()."""
1698
1792
        return "Meta directory format 1"
1699
1793
 
 
1794
    def network_name(self):
 
1795
        return self.get_format_string()
 
1796
 
1700
1797
    def _open(self, transport):
1701
1798
        """See BzrDirFormat._open."""
1702
1799
        # Create a new format instance because otherwise initialisation of new
1731
1828
            compatible with whatever sub formats are supported by self.
1732
1829
        :return: None.
1733
1830
        """
1734
 
        super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1735
1831
        if getattr(self, '_repository_format', None) is not None:
1736
1832
            other_format.repository_format = self.repository_format
1737
1833
        if self._branch_format is not None:
1750
1846
    def __set_workingtree_format(self, wt_format):
1751
1847
        self._workingtree_format = wt_format
1752
1848
 
1753
 
    def __repr__(self):
1754
 
        return "<%r>" % (self.__class__.__name__,)
1755
 
 
1756
1849
    workingtree_format = property(__get_workingtree_format,
1757
1850
                                  __set_workingtree_format)
1758
1851
 
1763
1856
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1764
1857
 
1765
1858
 
1766
 
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
1767
 
    """BzrDirMeta1 format with support for colocated branches."""
1768
 
 
1769
 
    colocated_branches = True
1770
 
 
1771
 
    @classmethod
1772
 
    def get_format_string(cls):
1773
 
        """See BzrDirFormat.get_format_string()."""
1774
 
        return "Bazaar meta directory, format 1 (with colocated branches)\n"
1775
 
 
1776
 
    def get_format_description(self):
1777
 
        """See BzrDirFormat.get_format_description()."""
1778
 
        return "Meta directory format 1 with support for colocated branches"
1779
 
 
1780
 
    def _open(self, transport):
1781
 
        """See BzrDirFormat._open."""
1782
 
        # Create a new format instance because otherwise initialisation of new
1783
 
        # metadirs share the global default format object leading to alias
1784
 
        # problems.
1785
 
        format = BzrDirMetaFormat1Colo()
1786
 
        self._supply_sub_formats_to(format)
1787
 
        return BzrDirMeta1(transport, format)
1788
 
 
1789
 
 
1790
 
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1791
 
    BzrDirMetaFormat1Colo)
1792
 
 
1793
 
 
1794
1859
class ConvertMetaToMeta(controldir.Converter):
1795
1860
    """Converts the components of metadirs."""
1796
1861
 
1815
1880
        else:
1816
1881
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
1817
1882
                from bzrlib.repository import CopyConverter
1818
 
                ui.ui_factory.note(gettext('starting repository conversion'))
 
1883
                ui.ui_factory.note('starting repository conversion')
1819
1884
                converter = CopyConverter(self.target_format.repository_format)
1820
1885
                converter.convert(repo, pb)
1821
1886
        for branch in self.bzrdir.list_branches():
1869
1934
        return to_convert
1870
1935
 
1871
1936
 
1872
 
class ConvertMetaToColo(controldir.Converter):
1873
 
    """Add colocated branch support."""
1874
 
 
1875
 
    def __init__(self, target_format):
1876
 
        """Create a converter.that upgrades a metadir to the colo format.
1877
 
 
1878
 
        :param target_format: The final metadir format that is desired.
1879
 
        """
1880
 
        self.target_format = target_format
1881
 
 
1882
 
    def convert(self, to_convert, pb):
1883
 
        """See Converter.convert()."""
1884
 
        to_convert.transport.put_bytes('branch-format',
1885
 
            self.target_format.as_string())
1886
 
        return BzrDir.open_from_transport(to_convert.root_transport)
1887
 
 
1888
 
 
1889
 
class ConvertMetaToColo(controldir.Converter):
1890
 
    """Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
1891
 
 
1892
 
    def __init__(self, target_format):
1893
 
        """Create a converter that converts a 'development-colo' metadir
1894
 
        to a '2a' metadir.
1895
 
 
1896
 
        :param target_format: The final metadir format that is desired.
1897
 
        """
1898
 
        self.target_format = target_format
1899
 
 
1900
 
    def convert(self, to_convert, pb):
1901
 
        """See Converter.convert()."""
1902
 
        to_convert.transport.put_bytes('branch-format',
1903
 
            self.target_format.as_string())
1904
 
        return BzrDir.open_from_transport(to_convert.root_transport)
1905
 
 
1906
 
 
1907
1937
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1908
1938
 
1909
1939
 
1986
2016
        else:
1987
2017
            self._require_stacking = True
1988
2018
 
1989
 
    def acquire_repository(self, make_working_trees=None, shared=False,
1990
 
            possible_transports=None):
 
2019
    def acquire_repository(self, make_working_trees=None, shared=False):
1991
2020
        """Acquire a repository for this bzrdir.
1992
2021
 
1993
2022
        Implementations may create a new repository or use a pre-exising
1999
2028
        :return: A repository, is_new_flag (True if the repository was
2000
2029
            created).
2001
2030
        """
2002
 
        raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
 
2031
        raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2003
2032
 
2004
2033
 
2005
2034
class CreateRepository(RepositoryAcquisitionPolicy):
2018
2047
                                             require_stacking)
2019
2048
        self._bzrdir = bzrdir
2020
2049
 
2021
 
    def acquire_repository(self, make_working_trees=None, shared=False,
2022
 
            possible_transports=None):
 
2050
    def acquire_repository(self, make_working_trees=None, shared=False):
2023
2051
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
2024
2052
 
2025
2053
        Creates the desired repository in the bzrdir we already have.
2026
2054
        """
2027
 
        if possible_transports is None:
2028
 
            possible_transports = []
2029
 
        else:
2030
 
            possible_transports = list(possible_transports)
2031
 
        possible_transports.append(self._bzrdir.root_transport)
2032
2055
        stack_on = self._get_full_stack_on()
2033
2056
        if stack_on:
2034
2057
            format = self._bzrdir._format
2035
2058
            format.require_stacking(stack_on=stack_on,
2036
 
                                    possible_transports=possible_transports)
 
2059
                                    possible_transports=[self._bzrdir.root_transport])
2037
2060
            if not self._require_stacking:
2038
2061
                # We have picked up automatic stacking somewhere.
2039
 
                note(gettext('Using default stacking branch {0} at {1}').format(
2040
 
                    self._stack_on, self._stack_on_pwd))
 
2062
                note('Using default stacking branch %s at %s', self._stack_on,
 
2063
                    self._stack_on_pwd)
2041
2064
        repository = self._bzrdir.create_repository(shared=shared)
2042
2065
        self._add_fallback(repository,
2043
 
                           possible_transports=possible_transports)
 
2066
                           possible_transports=[self._bzrdir.transport])
2044
2067
        if make_working_trees is not None:
2045
2068
            repository.set_make_working_trees(make_working_trees)
2046
2069
        return repository, True
2062
2085
                                             require_stacking)
2063
2086
        self._repository = repository
2064
2087
 
2065
 
    def acquire_repository(self, make_working_trees=None, shared=False,
2066
 
            possible_transports=None):
 
2088
    def acquire_repository(self, make_working_trees=None, shared=False):
2067
2089
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
2068
2090
 
2069
2091
        Returns an existing repository to use.
2070
2092
        """
2071
 
        if possible_transports is None:
2072
 
            possible_transports = []
2073
 
        else:
2074
 
            possible_transports = list(possible_transports)
2075
 
        possible_transports.append(self._repository.bzrdir.transport)
2076
2093
        self._add_fallback(self._repository,
2077
 
                       possible_transports=possible_transports)
 
2094
                       possible_transports=[self._repository.bzrdir.transport])
2078
2095
        return self._repository, False
2079
2096
 
2080
2097
 
2084
2101
         tree_format=None,
2085
2102
         hidden=False,
2086
2103
         experimental=False,
2087
 
         alias=False, bzrdir_format=None):
 
2104
         alias=False):
2088
2105
    """Register a metadir subformat.
2089
2106
 
2090
 
    These all use a meta bzrdir, but can be parameterized by the
2091
 
    Repository/Branch/WorkingTreeformats.
 
2107
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
2108
    by the Repository/Branch/WorkingTreeformats.
2092
2109
 
2093
2110
    :param repository_format: The fully-qualified repository format class
2094
2111
        name as a string.
2097
2114
    :param tree_format: Fully-qualified tree format class name as
2098
2115
        a string.
2099
2116
    """
2100
 
    if bzrdir_format is None:
2101
 
        bzrdir_format = BzrDirMetaFormat1
2102
2117
    # This should be expanded to support setting WorkingTree and Branch
2103
 
    # formats, once the API supports that.
 
2118
    # formats, once BzrDirMetaFormat1 supports that.
2104
2119
    def _load(full_name):
2105
2120
        mod_name, factory_name = full_name.rsplit('.', 1)
2106
2121
        try:
2113
2128
        return factory()
2114
2129
 
2115
2130
    def helper():
2116
 
        bd = bzrdir_format()
 
2131
        bd = BzrDirMetaFormat1()
2117
2132
        if branch_format is not None:
2118
2133
            bd.set_branch_format(_load(branch_format))
2119
2134
        if tree_format is not None:
2133
2148
    deprecated=True)
2134
2149
register_metadir(controldir.format_registry, 'dirstate',
2135
2150
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2136
 
    help='Format using dirstate for working trees. '
2137
 
        'Compatible with bzr 0.8 and '
2138
 
        'above when accessed over the network. Introduced in bzr 0.15.',
 
2151
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
 
2152
        'above when accessed over the network.',
2139
2153
    branch_format='bzrlib.branch.BzrBranchFormat5',
2140
2154
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2141
2155
    hidden=True,
2142
2156
    deprecated=True)
2143
2157
register_metadir(controldir.format_registry, 'dirstate-tags',
2144
2158
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2145
 
    help='Variant of dirstate with support for tags. '
2146
 
        'Introduced in bzr 0.15.',
 
2159
    help='New in 0.15: Fast local operations and improved scaling for '
 
2160
        'network operations. Additionally adds support for tags.'
 
2161
        ' Incompatible with bzr < 0.15.',
2147
2162
    branch_format='bzrlib.branch.BzrBranchFormat6',
2148
2163
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2149
2164
    hidden=True,
2150
2165
    deprecated=True)
2151
2166
register_metadir(controldir.format_registry, 'rich-root',
2152
2167
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2153
 
    help='Variant of dirstate with better handling of tree roots. '
2154
 
        'Introduced in bzr 1.0',
 
2168
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
 
2169
        ' bzr < 1.0.',
2155
2170
    branch_format='bzrlib.branch.BzrBranchFormat6',
2156
2171
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2157
2172
    hidden=True,
2158
2173
    deprecated=True)
2159
2174
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2160
2175
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2161
 
    help='Variant of dirstate with support for nested trees. '
2162
 
         'Introduced in 0.15.',
 
2176
    help='New in 0.15: Fast local operations and improved scaling for '
 
2177
        'network operations. Additionally adds support for versioning nested '
 
2178
        'bzr branches. Incompatible with bzr < 0.15.',
2163
2179
    branch_format='bzrlib.branch.BzrBranchFormat6',
2164
2180
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2165
2181
    experimental=True,
2167
2183
    )
2168
2184
register_metadir(controldir.format_registry, 'pack-0.92',
2169
2185
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2170
 
    help='Pack-based format used in 1.x series. Introduced in 0.92. '
2171
 
        'Interoperates with bzr repositories before 0.92 but cannot be '
2172
 
        'read by bzr < 0.92. '
 
2186
    help='New in 0.92: Pack-based format with data compatible with '
 
2187
        'dirstate-tags format repositories. Interoperates with '
 
2188
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2173
2189
        ,
2174
2190
    branch_format='bzrlib.branch.BzrBranchFormat6',
2175
2191
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2176
 
    deprecated=True,
2177
2192
    )
2178
2193
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2179
2194
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2180
 
    help='Pack-based format used in 1.x series, with subtree support. '
2181
 
        'Introduced in 0.92. Interoperates with '
 
2195
    help='New in 0.92: Pack-based format with data compatible with '
 
2196
        'dirstate-with-subtree format repositories. Interoperates with '
2182
2197
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2183
2198
        ,
2184
2199
    branch_format='bzrlib.branch.BzrBranchFormat6',
2185
2200
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2186
2201
    hidden=True,
2187
 
    deprecated=True,
2188
2202
    experimental=True,
2189
2203
    )
2190
2204
register_metadir(controldir.format_registry, 'rich-root-pack',
2191
2205
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2192
 
    help='A variant of pack-0.92 that supports rich-root data '
2193
 
         '(needed for bzr-svn and bzr-git). Introduced in 1.0.',
 
2206
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
 
2207
         '(needed for bzr-svn and bzr-git).',
2194
2208
    branch_format='bzrlib.branch.BzrBranchFormat6',
2195
2209
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2196
2210
    hidden=True,
2197
 
    deprecated=True,
2198
2211
    )
2199
2212
register_metadir(controldir.format_registry, '1.6',
2200
2213
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2204
2217
    branch_format='bzrlib.branch.BzrBranchFormat7',
2205
2218
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2206
2219
    hidden=True,
2207
 
    deprecated=True,
2208
2220
    )
2209
2221
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2210
2222
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2213
2225
    branch_format='bzrlib.branch.BzrBranchFormat7',
2214
2226
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2215
2227
    hidden=True,
2216
 
    deprecated=True,
2217
2228
    )
2218
2229
register_metadir(controldir.format_registry, '1.9',
2219
2230
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2223
2234
    branch_format='bzrlib.branch.BzrBranchFormat7',
2224
2235
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2225
2236
    hidden=True,
2226
 
    deprecated=True,
2227
2237
    )
2228
2238
register_metadir(controldir.format_registry, '1.9-rich-root',
2229
2239
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2232
2242
    branch_format='bzrlib.branch.BzrBranchFormat7',
2233
2243
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2234
2244
    hidden=True,
2235
 
    deprecated=True,
2236
2245
    )
2237
2246
register_metadir(controldir.format_registry, '1.14',
2238
2247
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2239
2248
    help='A working-tree format that supports content filtering.',
2240
2249
    branch_format='bzrlib.branch.BzrBranchFormat7',
2241
2250
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2242
 
    hidden=True,
2243
 
    deprecated=True,
2244
2251
    )
2245
2252
register_metadir(controldir.format_registry, '1.14-rich-root',
2246
2253
    'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2248
2255
         '(needed for bzr-svn and bzr-git).',
2249
2256
    branch_format='bzrlib.branch.BzrBranchFormat7',
2250
2257
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2251
 
    hidden=True,
2252
 
    deprecated=True,
2253
2258
    )
2254
2259
# The following un-numbered 'development' formats should always just be aliases.
2255
2260
register_metadir(controldir.format_registry, 'development-subtree',
2283
2288
    alias=False,
2284
2289
    )
2285
2290
 
2286
 
register_metadir(controldir.format_registry, 'development-colo',
2287
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2288
 
    help='The 2a format with experimental support for colocated branches.\n',
2289
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
2290
 
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2291
 
    experimental=True,
2292
 
    bzrdir_format=BzrDirMetaFormat1Colo,
2293
 
    )
2294
 
 
2295
 
 
2296
2291
# And the development formats above will have aliased one of the following:
2297
2292
 
2298
2293
# Finally, the current format.
2299
2294
register_metadir(controldir.format_registry, '2a',
2300
2295
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2301
 
    help='Format for the bzr 2.0 series.\n'
 
2296
    help='First format for bzr 2.0 series.\n'
2302
2297
        'Uses group-compress storage.\n'
2303
2298
        'Provides rich roots which are a one-way transition.\n',
2304
2299
        # 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2319
2314
    help='Same as 2a.')
2320
2315
 
2321
2316
# The current format that is made on 'bzr init'.
2322
 
format_name = config.GlobalStack().get('default_format')
2323
 
controldir.format_registry.set_default(format_name)
 
2317
format_name = config.GlobalConfig().get_user_option('default_format')
 
2318
if format_name is None:
 
2319
    controldir.format_registry.set_default('2a')
 
2320
else:
 
2321
    controldir.format_registry.set_default(format_name)
2324
2322
 
2325
2323
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2326
2324
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc