~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Martin von Gagern
  • Date: 2010-05-02 18:16:37 UTC
  • mto: This revision was merged to the branch mainline in revision 5203.
  • Revision ID: martin.vgagern@gmx.net-20100502181637-wlkqn31xuybzt9gy
Add blackbox test for cat --directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
from bzrlib.lazy_import import lazy_import
35
35
lazy_import(globals(), """
36
36
from stat import S_ISDIR
 
37
import textwrap
37
38
 
38
39
import bzrlib
39
40
from bzrlib import (
40
41
    branch,
41
42
    config,
42
 
    controldir,
43
43
    errors,
44
44
    graph,
45
45
    lockable_files,
88
88
    )
89
89
 
90
90
 
91
 
class BzrDir(controldir.ControlDir):
 
91
class BzrDir(object):
92
92
    """A .bzr control diretory.
93
93
 
94
94
    BzrDir instances let you create or open any of the things that can be
125
125
                    return
126
126
        thing_to_unlock.break_lock()
127
127
 
 
128
    def can_convert_format(self):
 
129
        """Return true if this bzrdir is one whose format we can convert from."""
 
130
        return True
 
131
 
128
132
    def check_conversion_target(self, target_format):
129
133
        """Check that a bzrdir as a whole can be converted to a new format."""
130
134
        # The only current restriction is that the repository content can be 
165
169
                format.get_format_description(),
166
170
                basedir)
167
171
 
 
172
    def clone(self, url, revision_id=None, force_new_repo=False,
 
173
              preserve_stacking=False):
 
174
        """Clone this bzrdir and its contents to url verbatim.
 
175
 
 
176
        :param url: The url create the clone at.  If url's last component does
 
177
            not exist, it will be created.
 
178
        :param revision_id: The tip revision-id to use for any branch or
 
179
            working tree.  If not None, then the clone operation may tune
 
180
            itself to download less data.
 
181
        :param force_new_repo: Do not use a shared repository for the target
 
182
                               even if one is available.
 
183
        :param preserve_stacking: When cloning a stacked branch, stack the
 
184
            new branch on top of the other branch's stacked-on branch.
 
185
        """
 
186
        return self.clone_on_transport(get_transport(url),
 
187
                                       revision_id=revision_id,
 
188
                                       force_new_repo=force_new_repo,
 
189
                                       preserve_stacking=preserve_stacking)
 
190
 
168
191
    def clone_on_transport(self, transport, revision_id=None,
169
192
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
170
193
        create_prefix=False, use_existing_dir=True):
185
208
        """
186
209
        # Overview: put together a broad description of what we want to end up
187
210
        # with; then make as few api calls as possible to do it.
188
 
 
 
211
        
189
212
        # We may want to create a repo/branch/tree, if we do so what format
190
213
        # would we want for each:
191
214
        require_stacking = (stacked_on is not None)
192
215
        format = self.cloning_metadir(require_stacking)
193
 
 
 
216
        
194
217
        # Figure out what objects we want:
195
218
        try:
196
219
            local_repo = self.find_repository()
238
261
                # copied, and finally if we are copying up to a specific
239
262
                # revision_id then we can use the pending-ancestry-result which
240
263
                # does not require traversing all of history to describe it.
241
 
                if (result_repo.user_url == result.user_url
242
 
                    and not require_stacking and
 
264
                if (result_repo.bzrdir.root_transport.base ==
 
265
                    result.root_transport.base and not require_stacking and
243
266
                    revision_id is not None):
244
267
                    fetch_spec = graph.PendingAncestryResult(
245
268
                        [revision_id], local_repo)
273
296
        t = get_transport(url)
274
297
        t.ensure_base()
275
298
 
 
299
    @classmethod
 
300
    def create(cls, base, format=None, possible_transports=None):
 
301
        """Create a new BzrDir at the url 'base'.
 
302
 
 
303
        :param format: If supplied, the format of branch to create.  If not
 
304
            supplied, the default is used.
 
305
        :param possible_transports: If supplied, a list of transports that
 
306
            can be reused to share a remote connection.
 
307
        """
 
308
        if cls is not BzrDir:
 
309
            raise AssertionError("BzrDir.create always creates the default"
 
310
                " format, not one of %r" % cls)
 
311
        t = get_transport(base, possible_transports)
 
312
        t.ensure_base()
 
313
        if format is None:
 
314
            format = BzrDirFormat.get_default_format()
 
315
        return format.initialize_on_transport(t)
 
316
 
276
317
    @staticmethod
277
318
    def find_bzrdirs(transport, evaluate=None, list_current=None):
278
319
        """Find bzrdirs recursively from current location.
301
342
            recurse = True
302
343
            try:
303
344
                bzrdir = BzrDir.open_from_transport(current_transport)
304
 
            except (errors.NotBranchError, errors.PermissionDenied):
 
345
            except errors.NotBranchError:
305
346
                pass
306
347
            else:
307
348
                recurse, value = evaluate(bzrdir)
308
349
                yield value
309
350
            try:
310
351
                subdirs = list_current(current_transport)
311
 
            except (errors.NoSuchFile, errors.PermissionDenied):
 
352
            except errors.NoSuchFile:
312
353
                continue
313
354
            if recurse:
314
355
                for subdir in sorted(subdirs, reverse=True):
315
356
                    pending.append(current_transport.clone(subdir))
316
357
 
 
358
    def list_branches(self):
 
359
        """Return a sequence of all branches local to this control directory.
 
360
 
 
361
        """
 
362
        try:
 
363
            return [self.open_branch()]
 
364
        except errors.NotBranchError:
 
365
            return []
 
366
 
317
367
    @staticmethod
318
368
    def find_branches(transport):
319
369
        """Find all branches under a transport.
342
392
                ret.extend(branches)
343
393
        return ret
344
394
 
 
395
    def destroy_repository(self):
 
396
        """Destroy the repository in this BzrDir"""
 
397
        raise NotImplementedError(self.destroy_repository)
 
398
 
 
399
    def create_branch(self, name=None):
 
400
        """Create a branch in this BzrDir.
 
401
 
 
402
        :param name: Name of the colocated branch to create, None for
 
403
            the default branch.
 
404
 
 
405
        The bzrdir's format will control what branch format is created.
 
406
        For more control see BranchFormatXX.create(a_bzrdir).
 
407
        """
 
408
        raise NotImplementedError(self.create_branch)
 
409
 
 
410
    def destroy_branch(self, name=None):
 
411
        """Destroy a branch in this BzrDir.
 
412
        
 
413
        :param name: Name of the branch to destroy, None for the default 
 
414
            branch.
 
415
        """
 
416
        raise NotImplementedError(self.destroy_branch)
 
417
 
345
418
    @staticmethod
346
419
    def create_branch_and_repo(base, force_new_repo=False, format=None):
347
420
        """Create a new BzrDir, Branch and Repository at the url 'base'.
385
458
            stop = False
386
459
            stack_on = config.get_default_stack_on()
387
460
            if stack_on is not None:
388
 
                stack_on_pwd = found_bzrdir.user_url
 
461
                stack_on_pwd = found_bzrdir.root_transport.base
389
462
                stop = True
390
463
            # does it have a repository ?
391
464
            try:
393
466
            except errors.NoRepositoryPresent:
394
467
                repository = None
395
468
            else:
396
 
                if (found_bzrdir.user_url != self.user_url 
397
 
                    and not repository.is_shared()):
 
469
                if ((found_bzrdir.root_transport.base !=
 
470
                     self.root_transport.base) and not repository.is_shared()):
398
471
                    # Don't look higher, can't use a higher shared repo.
399
472
                    repository = None
400
473
                    stop = True
496
569
                                               format=format).bzrdir
497
570
        return bzrdir.create_workingtree()
498
571
 
499
 
    def generate_backup_name(self, base):
500
 
        """Generate a non-existing backup file name based on base."""
501
 
        counter = 1
502
 
        name = "%s.~%d~" % (base, counter)
503
 
        while self.root_transport.has(name):
504
 
            counter += 1
505
 
            name = "%s.~%d~" % (base, counter)
506
 
        return name
 
572
    def create_workingtree(self, revision_id=None, from_branch=None,
 
573
        accelerator_tree=None, hardlink=False):
 
574
        """Create a working tree at this BzrDir.
 
575
 
 
576
        :param revision_id: create it as of this revision id.
 
577
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
578
        :param accelerator_tree: A tree which can be used for retrieving file
 
579
            contents more quickly than the revision tree, i.e. a workingtree.
 
580
            The revision tree will be used for cases where accelerator_tree's
 
581
            content is different.
 
582
        """
 
583
        raise NotImplementedError(self.create_workingtree)
507
584
 
508
585
    def backup_bzrdir(self):
509
586
        """Backup this bzr control directory.
510
587
 
511
588
        :return: Tuple with old path name and new path name
512
589
        """
 
590
        def name_gen(base='backup.bzr'):
 
591
            counter = 1
 
592
            name = "%s.~%d~" % (base, counter)
 
593
            while self.root_transport.has(name):
 
594
                counter += 1
 
595
                name = "%s.~%d~" % (base, counter)
 
596
            return name
513
597
 
514
 
        backup_dir=self.generate_backup_name('backup.bzr')
 
598
        backup_dir=name_gen()
515
599
        pb = ui.ui_factory.nested_progress_bar()
516
600
        try:
517
601
            # FIXME: bug 300001 -- the backup fails if the backup directory
551
635
                else:
552
636
                    pass
553
637
 
 
638
    def destroy_workingtree(self):
 
639
        """Destroy the working tree at this BzrDir.
 
640
 
 
641
        Formats that do not support this may raise UnsupportedOperation.
 
642
        """
 
643
        raise NotImplementedError(self.destroy_workingtree)
 
644
 
 
645
    def destroy_workingtree_metadata(self):
 
646
        """Destroy the control files for the working tree at this BzrDir.
 
647
 
 
648
        The contents of working tree files are not affected.
 
649
        Formats that do not support this may raise UnsupportedOperation.
 
650
        """
 
651
        raise NotImplementedError(self.destroy_workingtree_metadata)
 
652
 
554
653
    def _find_containing(self, evaluate):
555
654
        """Find something in a containing control directory.
556
655
 
570
669
            if stop:
571
670
                return result
572
671
            next_transport = found_bzrdir.root_transport.clone('..')
573
 
            if (found_bzrdir.user_url == next_transport.base):
 
672
            if (found_bzrdir.root_transport.base == next_transport.base):
574
673
                # top of the file system
575
674
                return None
576
675
            # find the next containing bzrdir
593
692
                repository = found_bzrdir.open_repository()
594
693
            except errors.NoRepositoryPresent:
595
694
                return None, False
596
 
            if found_bzrdir.user_url == self.user_url:
 
695
            if found_bzrdir.root_transport.base == self.root_transport.base:
597
696
                return repository, True
598
697
            elif repository.is_shared():
599
698
                return repository, True
605
704
            raise errors.NoRepositoryPresent(self)
606
705
        return found_repo
607
706
 
 
707
    def get_branch_reference(self):
 
708
        """Return the referenced URL for the branch in this bzrdir.
 
709
 
 
710
        :raises NotBranchError: If there is no Branch.
 
711
        :return: The URL the branch in this bzrdir references if it is a
 
712
            reference branch, or None for regular branches.
 
713
        """
 
714
        return None
 
715
 
 
716
    def get_branch_transport(self, branch_format, name=None):
 
717
        """Get the transport for use by branch format in this BzrDir.
 
718
 
 
719
        Note that bzr dirs that do not support format strings will raise
 
720
        IncompatibleFormat if the branch format they are given has
 
721
        a format string, and vice versa.
 
722
 
 
723
        If branch_format is None, the transport is returned with no
 
724
        checking. If it is not None, then the returned transport is
 
725
        guaranteed to point to an existing directory ready for use.
 
726
        """
 
727
        raise NotImplementedError(self.get_branch_transport)
 
728
 
608
729
    def _find_creation_modes(self):
609
730
        """Determine the appropriate modes for files and directories.
610
731
 
649
770
            self._find_creation_modes()
650
771
        return self._dir_mode
651
772
 
 
773
    def get_repository_transport(self, repository_format):
 
774
        """Get the transport for use by repository format in this BzrDir.
 
775
 
 
776
        Note that bzr dirs that do not support format strings will raise
 
777
        IncompatibleFormat if the repository format they are given has
 
778
        a format string, and vice versa.
 
779
 
 
780
        If repository_format is None, the transport is returned with no
 
781
        checking. If it is not None, then the returned transport is
 
782
        guaranteed to point to an existing directory ready for use.
 
783
        """
 
784
        raise NotImplementedError(self.get_repository_transport)
 
785
 
 
786
    def get_workingtree_transport(self, tree_format):
 
787
        """Get the transport for use by workingtree format in this BzrDir.
 
788
 
 
789
        Note that bzr dirs that do not support format strings will raise
 
790
        IncompatibleFormat if the workingtree format they are given has a
 
791
        format string, and vice versa.
 
792
 
 
793
        If workingtree_format is None, the transport is returned with no
 
794
        checking. If it is not None, then the returned transport is
 
795
        guaranteed to point to an existing directory ready for use.
 
796
        """
 
797
        raise NotImplementedError(self.get_workingtree_transport)
 
798
 
652
799
    def get_config(self):
653
800
        """Get configuration for this BzrDir."""
654
801
        return config.BzrDirConfig(self)
667
814
        :param _transport: the transport this dir is based at.
668
815
        """
669
816
        self._format = _format
670
 
        # these are also under the more standard names of 
671
 
        # control_transport and user_transport
672
817
        self.transport = _transport.clone('.bzr')
673
818
        self.root_transport = _transport
674
819
        self._mode_check_done = False
675
820
 
676
 
    @property 
677
 
    def user_transport(self):
678
 
        return self.root_transport
679
 
 
680
 
    @property
681
 
    def control_transport(self):
682
 
        return self.transport
683
 
 
684
821
    def is_control_filename(self, filename):
685
822
        """True if filename is the name of a path which is reserved for bzrdir's.
686
823
 
688
825
 
689
826
        This is true IF and ONLY IF the filename is part of the namespace reserved
690
827
        for bzr control dirs. Currently this is the '.bzr' directory in the root
691
 
        of the root_transport. 
 
828
        of the root_transport. it is expected that plugins will need to extend
 
829
        this in the future - for instance to make bzr talk with svn working
 
830
        trees.
692
831
        """
693
832
        # this might be better on the BzrDirFormat class because it refers to
694
833
        # all the possible bzrdir disk formats.
698
837
        # add new tests for it to the appropriate place.
699
838
        return filename == '.bzr' or filename.startswith('.bzr/')
700
839
 
 
840
    def needs_format_conversion(self, format=None):
 
841
        """Return true if this bzrdir needs convert_format run on it.
 
842
 
 
843
        For instance, if the repository format is out of date but the
 
844
        branch and working tree are not, this should return True.
 
845
 
 
846
        :param format: Optional parameter indicating a specific desired
 
847
                       format we plan to arrive at.
 
848
        """
 
849
        raise NotImplementedError(self.needs_format_conversion)
 
850
 
701
851
    @staticmethod
702
852
    def open_unsupported(base):
703
853
        """Open a branch which is not supported."""
726
876
        # the redirections.
727
877
        base = transport.base
728
878
        def find_format(transport):
729
 
            return transport, controldir.ControlDirFormat.find_format(
 
879
            return transport, BzrDirFormat.find_format(
730
880
                transport, _server_formats=_server_formats)
731
881
 
732
882
        def redirected(transport, e, redirection_notice):
747
897
        BzrDir._check_supported(format, _unsupported)
748
898
        return format.open(transport, _found=True)
749
899
 
 
900
    def open_branch(self, name=None, unsupported=False,
 
901
                    ignore_fallbacks=False):
 
902
        """Open the branch object at this BzrDir if one is present.
 
903
 
 
904
        If unsupported is True, then no longer supported branch formats can
 
905
        still be opened.
 
906
 
 
907
        TODO: static convenience version of this?
 
908
        """
 
909
        raise NotImplementedError(self.open_branch)
 
910
 
750
911
    @staticmethod
751
912
    def open_containing(url, possible_transports=None):
752
913
        """Open an existing branch which contains url.
790
951
                raise errors.NotBranchError(path=url)
791
952
            a_transport = new_t
792
953
 
 
954
    def _get_tree_branch(self):
 
955
        """Return the branch and tree, if any, for this bzrdir.
 
956
 
 
957
        Return None for tree if not present or inaccessible.
 
958
        Raise NotBranchError if no branch is present.
 
959
        :return: (tree, branch)
 
960
        """
 
961
        try:
 
962
            tree = self.open_workingtree()
 
963
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
964
            tree = None
 
965
            branch = self.open_branch()
 
966
        else:
 
967
            branch = tree.branch
 
968
        return tree, branch
 
969
 
793
970
    @classmethod
794
971
    def open_tree_or_branch(klass, location):
795
972
        """Return the branch and working tree at a location.
841
1018
                raise errors.NotBranchError(location)
842
1019
        return tree, branch, branch.repository, relpath
843
1020
 
 
1021
    def open_repository(self, _unsupported=False):
 
1022
        """Open the repository object at this BzrDir if one is present.
 
1023
 
 
1024
        This will not follow the Branch object pointer - it's strictly a direct
 
1025
        open facility. Most client code should use open_branch().repository to
 
1026
        get at a repository.
 
1027
 
 
1028
        :param _unsupported: a private parameter, not part of the api.
 
1029
        TODO: static convenience version of this?
 
1030
        """
 
1031
        raise NotImplementedError(self.open_repository)
 
1032
 
 
1033
    def open_workingtree(self, _unsupported=False,
 
1034
                         recommend_upgrade=True, from_branch=None):
 
1035
        """Open the workingtree object at this BzrDir if one is present.
 
1036
 
 
1037
        :param recommend_upgrade: Optional keyword parameter, when True (the
 
1038
            default), emit through the ui module a recommendation that the user
 
1039
            upgrade the working tree when the workingtree being opened is old
 
1040
            (but still fully supported).
 
1041
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
1042
        """
 
1043
        raise NotImplementedError(self.open_workingtree)
 
1044
 
 
1045
    def has_branch(self, name=None):
 
1046
        """Tell if this bzrdir contains a branch.
 
1047
 
 
1048
        Note: if you're going to open the branch, you should just go ahead
 
1049
        and try, and not ask permission first.  (This method just opens the
 
1050
        branch and discards it, and that's somewhat expensive.)
 
1051
        """
 
1052
        try:
 
1053
            self.open_branch(name)
 
1054
            return True
 
1055
        except errors.NotBranchError:
 
1056
            return False
 
1057
 
 
1058
    def has_workingtree(self):
 
1059
        """Tell if this bzrdir contains a working tree.
 
1060
 
 
1061
        This will still raise an exception if the bzrdir has a workingtree that
 
1062
        is remote & inaccessible.
 
1063
 
 
1064
        Note: if you're going to open the working tree, you should just go ahead
 
1065
        and try, and not ask permission first.  (This method just opens the
 
1066
        workingtree and discards it, and that's somewhat expensive.)
 
1067
        """
 
1068
        try:
 
1069
            self.open_workingtree(recommend_upgrade=False)
 
1070
            return True
 
1071
        except errors.NoWorkingTree:
 
1072
            return False
 
1073
 
844
1074
    def _cloning_metadir(self):
845
1075
        """Produce a metadir suitable for cloning with.
846
1076
 
904
1134
            format.require_stacking()
905
1135
        return format
906
1136
 
907
 
    @classmethod
908
 
    def create(cls, base, format=None, possible_transports=None):
909
 
        """Create a new BzrDir at the url 'base'.
910
 
 
911
 
        :param format: If supplied, the format of branch to create.  If not
912
 
            supplied, the default is used.
913
 
        :param possible_transports: If supplied, a list of transports that
914
 
            can be reused to share a remote connection.
 
1137
    def checkout_metadir(self):
 
1138
        return self.cloning_metadir()
 
1139
 
 
1140
    def sprout(self, url, revision_id=None, force_new_repo=False,
 
1141
               recurse='down', possible_transports=None,
 
1142
               accelerator_tree=None, hardlink=False, stacked=False,
 
1143
               source_branch=None, create_tree_if_local=True):
 
1144
        """Create a copy of this bzrdir prepared for use as a new line of
 
1145
        development.
 
1146
 
 
1147
        If url's last component does not exist, it will be created.
 
1148
 
 
1149
        Attributes related to the identity of the source branch like
 
1150
        branch nickname will be cleaned, a working tree is created
 
1151
        whether one existed before or not; and a local branch is always
 
1152
        created.
 
1153
 
 
1154
        if revision_id is not None, then the clone operation may tune
 
1155
            itself to download less data.
 
1156
        :param accelerator_tree: A tree which can be used for retrieving file
 
1157
            contents more quickly than the revision tree, i.e. a workingtree.
 
1158
            The revision tree will be used for cases where accelerator_tree's
 
1159
            content is different.
 
1160
        :param hardlink: If true, hard-link files from accelerator_tree,
 
1161
            where possible.
 
1162
        :param stacked: If true, create a stacked branch referring to the
 
1163
            location of this control directory.
 
1164
        :param create_tree_if_local: If true, a working-tree will be created
 
1165
            when working locally.
915
1166
        """
916
 
        if cls is not BzrDir:
917
 
            raise AssertionError("BzrDir.create always creates the"
918
 
                "default format, not one of %r" % cls)
919
 
        t = get_transport(base, possible_transports)
920
 
        t.ensure_base()
921
 
        if format is None:
922
 
            format = controldir.ControlDirFormat.get_default_format()
923
 
        return format.initialize_on_transport(t)
924
 
 
 
1167
        target_transport = get_transport(url, possible_transports)
 
1168
        target_transport.ensure_base()
 
1169
        cloning_format = self.cloning_metadir(stacked)
 
1170
        # Create/update the result branch
 
1171
        result = cloning_format.initialize_on_transport(target_transport)
 
1172
        # if a stacked branch wasn't requested, we don't create one
 
1173
        # even if the origin was stacked
 
1174
        stacked_branch_url = None
 
1175
        if source_branch is not None:
 
1176
            if stacked:
 
1177
                stacked_branch_url = self.root_transport.base
 
1178
            source_repository = source_branch.repository
 
1179
        else:
 
1180
            try:
 
1181
                source_branch = self.open_branch()
 
1182
                source_repository = source_branch.repository
 
1183
                if stacked:
 
1184
                    stacked_branch_url = self.root_transport.base
 
1185
            except errors.NotBranchError:
 
1186
                source_branch = None
 
1187
                try:
 
1188
                    source_repository = self.open_repository()
 
1189
                except errors.NoRepositoryPresent:
 
1190
                    source_repository = None
 
1191
        repository_policy = result.determine_repository_policy(
 
1192
            force_new_repo, stacked_branch_url, require_stacking=stacked)
 
1193
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
1194
        if is_new_repo and revision_id is not None and not stacked:
 
1195
            fetch_spec = graph.PendingAncestryResult(
 
1196
                [revision_id], source_repository)
 
1197
        else:
 
1198
            fetch_spec = None
 
1199
        if source_repository is not None:
 
1200
            # Fetch while stacked to prevent unstacked fetch from
 
1201
            # Branch.sprout.
 
1202
            if fetch_spec is None:
 
1203
                result_repo.fetch(source_repository, revision_id=revision_id)
 
1204
            else:
 
1205
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
1206
 
 
1207
        if source_branch is None:
 
1208
            # this is for sprouting a bzrdir without a branch; is that
 
1209
            # actually useful?
 
1210
            # Not especially, but it's part of the contract.
 
1211
            result_branch = result.create_branch()
 
1212
        else:
 
1213
            result_branch = source_branch.sprout(result,
 
1214
                revision_id=revision_id, repository_policy=repository_policy)
 
1215
        mutter("created new branch %r" % (result_branch,))
 
1216
 
 
1217
        # Create/update the result working tree
 
1218
        if (create_tree_if_local and
 
1219
            isinstance(target_transport, local.LocalTransport) and
 
1220
            (result_repo is None or result_repo.make_working_trees())):
 
1221
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
 
1222
                hardlink=hardlink)
 
1223
            wt.lock_write()
 
1224
            try:
 
1225
                if wt.path2id('') is None:
 
1226
                    try:
 
1227
                        wt.set_root_id(self.open_workingtree.get_root_id())
 
1228
                    except errors.NoWorkingTree:
 
1229
                        pass
 
1230
            finally:
 
1231
                wt.unlock()
 
1232
        else:
 
1233
            wt = None
 
1234
        if recurse == 'down':
 
1235
            if wt is not None:
 
1236
                basis = wt.basis_tree()
 
1237
                basis.lock_read()
 
1238
                subtrees = basis.iter_references()
 
1239
            elif result_branch is not None:
 
1240
                basis = result_branch.basis_tree()
 
1241
                basis.lock_read()
 
1242
                subtrees = basis.iter_references()
 
1243
            elif source_branch is not None:
 
1244
                basis = source_branch.basis_tree()
 
1245
                basis.lock_read()
 
1246
                subtrees = basis.iter_references()
 
1247
            else:
 
1248
                subtrees = []
 
1249
                basis = None
 
1250
            try:
 
1251
                for path, file_id in subtrees:
 
1252
                    target = urlutils.join(url, urlutils.escape(path))
 
1253
                    sublocation = source_branch.reference_parent(file_id, path)
 
1254
                    sublocation.bzrdir.sprout(target,
 
1255
                        basis.get_reference_revision(file_id, path),
 
1256
                        force_new_repo=force_new_repo, recurse=recurse,
 
1257
                        stacked=stacked)
 
1258
            finally:
 
1259
                if basis is not None:
 
1260
                    basis.unlock()
 
1261
        return result
 
1262
 
 
1263
    def push_branch(self, source, revision_id=None, overwrite=False, 
 
1264
        remember=False, create_prefix=False):
 
1265
        """Push the source branch into this BzrDir."""
 
1266
        br_to = None
 
1267
        # If we can open a branch, use its direct repository, otherwise see
 
1268
        # if there is a repository without a branch.
 
1269
        try:
 
1270
            br_to = self.open_branch()
 
1271
        except errors.NotBranchError:
 
1272
            # Didn't find a branch, can we find a repository?
 
1273
            repository_to = self.find_repository()
 
1274
        else:
 
1275
            # Found a branch, so we must have found a repository
 
1276
            repository_to = br_to.repository
 
1277
 
 
1278
        push_result = PushResult()
 
1279
        push_result.source_branch = source
 
1280
        if br_to is None:
 
1281
            # We have a repository but no branch, copy the revisions, and then
 
1282
            # create a branch.
 
1283
            repository_to.fetch(source.repository, revision_id=revision_id)
 
1284
            br_to = source.clone(self, revision_id=revision_id)
 
1285
            if source.get_push_location() is None or remember:
 
1286
                source.set_push_location(br_to.base)
 
1287
            push_result.stacked_on = None
 
1288
            push_result.branch_push_result = None
 
1289
            push_result.old_revno = None
 
1290
            push_result.old_revid = _mod_revision.NULL_REVISION
 
1291
            push_result.target_branch = br_to
 
1292
            push_result.master_branch = None
 
1293
            push_result.workingtree_updated = False
 
1294
        else:
 
1295
            # We have successfully opened the branch, remember if necessary:
 
1296
            if source.get_push_location() is None or remember:
 
1297
                source.set_push_location(br_to.base)
 
1298
            try:
 
1299
                tree_to = self.open_workingtree()
 
1300
            except errors.NotLocalUrl:
 
1301
                push_result.branch_push_result = source.push(br_to, 
 
1302
                    overwrite, stop_revision=revision_id)
 
1303
                push_result.workingtree_updated = False
 
1304
            except errors.NoWorkingTree:
 
1305
                push_result.branch_push_result = source.push(br_to,
 
1306
                    overwrite, stop_revision=revision_id)
 
1307
                push_result.workingtree_updated = None # Not applicable
 
1308
            else:
 
1309
                tree_to.lock_write()
 
1310
                try:
 
1311
                    push_result.branch_push_result = source.push(
 
1312
                        tree_to.branch, overwrite, stop_revision=revision_id)
 
1313
                    tree_to.update()
 
1314
                finally:
 
1315
                    tree_to.unlock()
 
1316
                push_result.workingtree_updated = True
 
1317
            push_result.old_revno = push_result.branch_push_result.old_revno
 
1318
            push_result.old_revid = push_result.branch_push_result.old_revid
 
1319
            push_result.target_branch = \
 
1320
                push_result.branch_push_result.target_branch
 
1321
        return push_result
925
1322
 
926
1323
 
927
1324
class BzrDirHooks(hooks.Hooks):
933
1330
        self.create_hook(hooks.HookPoint('pre_open',
934
1331
            "Invoked before attempting to open a BzrDir with the transport "
935
1332
            "that the open will use.", (1, 14), None))
936
 
        self.create_hook(hooks.HookPoint('post_repo_init',
937
 
            "Invoked after a repository has been initialized. "
938
 
            "post_repo_init is called with a "
939
 
            "bzrlib.bzrdir.RepoInitHookParams.",
940
 
            (2, 2), None))
941
1333
 
942
1334
# install the default hooks
943
1335
BzrDir.hooks = BzrDirHooks()
944
1336
 
945
1337
 
946
 
class RepoInitHookParams(object):
947
 
    """Object holding parameters passed to *_repo_init hooks.
948
 
 
949
 
    There are 4 fields that hooks may wish to access:
950
 
 
951
 
    :ivar repository: Repository created
952
 
    :ivar format: Repository format
953
 
    :ivar bzrdir: The bzrdir for the repository
954
 
    :ivar shared: The repository is shared
955
 
    """
956
 
 
957
 
    def __init__(self, repository, format, a_bzrdir, shared):
958
 
        """Create a group of RepoInitHook parameters.
959
 
 
960
 
        :param repository: Repository created
961
 
        :param format: Repository format
962
 
        :param bzrdir: The bzrdir for the repository
963
 
        :param shared: The repository is shared
964
 
        """
965
 
        self.repository = repository
966
 
        self.format = format
967
 
        self.bzrdir = a_bzrdir
968
 
        self.shared = shared
969
 
 
970
 
    def __eq__(self, other):
971
 
        return self.__dict__ == other.__dict__
972
 
 
973
 
    def __repr__(self):
974
 
        if self.repository:
975
 
            return "<%s for %s>" % (self.__class__.__name__,
976
 
                self.repository)
977
 
        else:
978
 
            return "<%s for %s>" % (self.__class__.__name__,
979
 
                self.bzrdir)
980
 
 
981
 
 
982
1338
class BzrDirPreSplitOut(BzrDir):
983
1339
    """A common class for the all-in-one formats."""
984
1340
 
997
1353
    def cloning_metadir(self, require_stacking=False):
998
1354
        """Produce a metadir suitable for cloning with."""
999
1355
        if require_stacking:
1000
 
            return controldir.format_registry.make_bzrdir('1.6')
 
1356
            return format_registry.make_bzrdir('1.6')
1001
1357
        return self._format.__class__()
1002
1358
 
1003
1359
    def clone(self, url, revision_id=None, force_new_repo=False,
1296
1652
    def destroy_workingtree_metadata(self):
1297
1653
        self.transport.delete_tree('checkout')
1298
1654
 
1299
 
    def find_branch_format(self, name=None):
 
1655
    def find_branch_format(self):
1300
1656
        """Find the branch 'format' for this bzrdir.
1301
1657
 
1302
1658
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1303
1659
        """
1304
1660
        from bzrlib.branch import BranchFormat
1305
 
        return BranchFormat.find_format(self, name=name)
 
1661
        return BranchFormat.find_format(self)
1306
1662
 
1307
1663
    def _get_mkdir_mode(self):
1308
1664
        """Figure out the mode to use when creating a bzrdir subdir."""
1310
1666
                                     lockable_files.TransportLock)
1311
1667
        return temp_control._dir_mode
1312
1668
 
1313
 
    def get_branch_reference(self, name=None):
 
1669
    def get_branch_reference(self):
1314
1670
        """See BzrDir.get_branch_reference()."""
1315
1671
        from bzrlib.branch import BranchFormat
1316
 
        format = BranchFormat.find_format(self, name=name)
1317
 
        return format.get_reference(self, name=name)
 
1672
        format = BranchFormat.find_format(self)
 
1673
        return format.get_reference(self)
1318
1674
 
1319
1675
    def get_branch_transport(self, branch_format, name=None):
1320
1676
        """See BzrDir.get_branch_transport()."""
1414
1770
    def open_branch(self, name=None, unsupported=False,
1415
1771
                    ignore_fallbacks=False):
1416
1772
        """See BzrDir.open_branch."""
1417
 
        format = self.find_branch_format(name=name)
 
1773
        format = self.find_branch_format()
1418
1774
        self._check_supported(format, unsupported)
1419
1775
        return format.open(self, name=name,
1420
1776
            _found=True, ignore_fallbacks=ignore_fallbacks)
1440
1796
        return config.TransportConfig(self.transport, 'control.conf')
1441
1797
 
1442
1798
 
1443
 
class BzrProber(controldir.Prober):
1444
 
    """Prober for formats that use a .bzr/ control directory."""
1445
 
 
1446
 
    _formats = {}
1447
 
    """The known .bzr formats."""
1448
 
 
1449
 
    @classmethod
1450
 
    def register_bzrdir_format(klass, format):
1451
 
        klass._formats[format.get_format_string()] = format
1452
 
 
1453
 
    @classmethod
1454
 
    def unregister_bzrdir_format(klass, format):
1455
 
        del klass._formats[format.get_format_string()]
1456
 
 
1457
 
    @classmethod
1458
 
    def probe_transport(klass, transport):
1459
 
        """Return the .bzrdir style format present in a directory."""
1460
 
        try:
1461
 
            format_string = transport.get_bytes(".bzr/branch-format")
1462
 
        except errors.NoSuchFile:
1463
 
            raise errors.NotBranchError(path=transport.base)
1464
 
        try:
1465
 
            return klass._formats[format_string]
1466
 
        except KeyError:
1467
 
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1468
 
 
1469
 
 
1470
 
controldir.ControlDirFormat.register_prober(BzrProber)
1471
 
 
1472
 
 
1473
 
class RemoteBzrProber(controldir.Prober):
1474
 
    """Prober for remote servers that provide a Bazaar smart server."""
1475
 
 
1476
 
    @classmethod
1477
 
    def probe_transport(klass, transport):
1478
 
        """Return a RemoteBzrDirFormat object if it looks possible."""
1479
 
        try:
1480
 
            medium = transport.get_smart_medium()
1481
 
        except (NotImplementedError, AttributeError,
1482
 
                errors.TransportNotPossible, errors.NoSmartMedium,
1483
 
                errors.SmartProtocolError):
1484
 
            # no smart server, so not a branch for this format type.
1485
 
            raise errors.NotBranchError(path=transport.base)
1486
 
        else:
1487
 
            # Decline to open it if the server doesn't support our required
1488
 
            # version (3) so that the VFS-based transport will do it.
1489
 
            if medium.should_probe():
1490
 
                try:
1491
 
                    server_version = medium.protocol_version()
1492
 
                except errors.SmartProtocolError:
1493
 
                    # Apparently there's no usable smart server there, even though
1494
 
                    # the medium supports the smart protocol.
1495
 
                    raise errors.NotBranchError(path=transport.base)
1496
 
                if server_version != '2':
1497
 
                    raise errors.NotBranchError(path=transport.base)
1498
 
            return RemoteBzrDirFormat()
1499
 
 
1500
 
 
1501
 
class BzrDirFormat(controldir.ControlDirFormat):
1502
 
    """ControlDirFormat base class for .bzr/ directories.
 
1799
class BzrDirFormat(object):
 
1800
    """An encapsulation of the initialization and open routines for a format.
 
1801
 
 
1802
    Formats provide three things:
 
1803
     * An initialization routine,
 
1804
     * a format string,
 
1805
     * an open routine.
1503
1806
 
1504
1807
    Formats are placed in a dict by their format string for reference
1505
1808
    during bzrdir opening. These should be subclasses of BzrDirFormat
1508
1811
    Once a format is deprecated, just deprecate the initialize and open
1509
1812
    methods on the format class. Do not deprecate the object, as the
1510
1813
    object will be created every system load.
 
1814
 
 
1815
    :cvar colocated_branches: Whether this formats supports colocated branches.
 
1816
    """
 
1817
 
 
1818
    _default_format = None
 
1819
    """The default format used for new .bzr dirs."""
 
1820
 
 
1821
    _formats = {}
 
1822
    """The known formats."""
 
1823
 
 
1824
    _control_formats = []
 
1825
    """The registered control formats - .bzr, ....
 
1826
 
 
1827
    This is a list of BzrDirFormat objects.
 
1828
    """
 
1829
 
 
1830
    _control_server_formats = []
 
1831
    """The registered control server formats, e.g. RemoteBzrDirs.
 
1832
 
 
1833
    This is a list of BzrDirFormat objects.
1511
1834
    """
1512
1835
 
1513
1836
    _lock_file_name = 'branch-lock'
1514
1837
 
 
1838
    colocated_branches = False
 
1839
    """Whether co-located branches are supported for this control dir format.
 
1840
    """
 
1841
 
1515
1842
    # _lock_class must be set in subclasses to the lock type, typ.
1516
1843
    # TransportLock or LockDir
1517
1844
 
 
1845
    @classmethod
 
1846
    def find_format(klass, transport, _server_formats=True):
 
1847
        """Return the format present at transport."""
 
1848
        if _server_formats:
 
1849
            formats = klass._control_server_formats + klass._control_formats
 
1850
        else:
 
1851
            formats = klass._control_formats
 
1852
        for format in formats:
 
1853
            try:
 
1854
                return format.probe_transport(transport)
 
1855
            except errors.NotBranchError:
 
1856
                # this format does not find a control dir here.
 
1857
                pass
 
1858
        raise errors.NotBranchError(path=transport.base)
 
1859
 
 
1860
    @classmethod
 
1861
    def probe_transport(klass, transport):
 
1862
        """Return the .bzrdir style format present in a directory."""
 
1863
        try:
 
1864
            format_string = transport.get_bytes(".bzr/branch-format")
 
1865
        except errors.NoSuchFile:
 
1866
            raise errors.NotBranchError(path=transport.base)
 
1867
 
 
1868
        try:
 
1869
            return klass._formats[format_string]
 
1870
        except KeyError:
 
1871
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
 
1872
 
 
1873
    @classmethod
 
1874
    def get_default_format(klass):
 
1875
        """Return the current default format."""
 
1876
        return klass._default_format
 
1877
 
1518
1878
    def get_format_string(self):
1519
1879
        """Return the ASCII format string that identifies this format."""
1520
1880
        raise NotImplementedError(self.get_format_string)
1521
1881
 
 
1882
    def get_format_description(self):
 
1883
        """Return the short description for this format."""
 
1884
        raise NotImplementedError(self.get_format_description)
 
1885
 
 
1886
    def get_converter(self, format=None):
 
1887
        """Return the converter to use to convert bzrdirs needing converts.
 
1888
 
 
1889
        This returns a bzrlib.bzrdir.Converter object.
 
1890
 
 
1891
        This should return the best upgrader to step this format towards the
 
1892
        current default format. In the case of plugins we can/should provide
 
1893
        some means for them to extend the range of returnable converters.
 
1894
 
 
1895
        :param format: Optional format to override the default format of the
 
1896
                       library.
 
1897
        """
 
1898
        raise NotImplementedError(self.get_converter)
 
1899
 
 
1900
    def initialize(self, url, possible_transports=None):
 
1901
        """Create a bzr control dir at this url and return an opened copy.
 
1902
 
 
1903
        While not deprecated, this method is very specific and its use will
 
1904
        lead to many round trips to setup a working environment. See
 
1905
        initialize_on_transport_ex for a [nearly] all-in-one method.
 
1906
 
 
1907
        Subclasses should typically override initialize_on_transport
 
1908
        instead of this method.
 
1909
        """
 
1910
        return self.initialize_on_transport(get_transport(url,
 
1911
                                                          possible_transports))
 
1912
 
1522
1913
    def initialize_on_transport(self, transport):
1523
1914
        """Initialize a new bzrdir in the base directory of a Transport."""
1524
1915
        try:
1672
2063
            control_files.unlock()
1673
2064
        return self.open(transport, _found=True)
1674
2065
 
 
2066
    def is_supported(self):
 
2067
        """Is this format supported?
 
2068
 
 
2069
        Supported formats must be initializable and openable.
 
2070
        Unsupported formats may not support initialization or committing or
 
2071
        some other features depending on the reason for not being supported.
 
2072
        """
 
2073
        return True
 
2074
 
 
2075
    def network_name(self):
 
2076
        """A simple byte string uniquely identifying this format for RPC calls.
 
2077
 
 
2078
        Bzr control formats use thir disk format string to identify the format
 
2079
        over the wire. Its possible that other control formats have more
 
2080
        complex detection requirements, so we permit them to use any unique and
 
2081
        immutable string they desire.
 
2082
        """
 
2083
        raise NotImplementedError(self.network_name)
 
2084
 
 
2085
    def same_model(self, target_format):
 
2086
        return (self.repository_format.rich_root_data ==
 
2087
            target_format.rich_root_data)
 
2088
 
 
2089
    @classmethod
 
2090
    def known_formats(klass):
 
2091
        """Return all the known formats.
 
2092
 
 
2093
        Concrete formats should override _known_formats.
 
2094
        """
 
2095
        # There is double indirection here to make sure that control
 
2096
        # formats used by more than one dir format will only be probed
 
2097
        # once. This can otherwise be quite expensive for remote connections.
 
2098
        result = set()
 
2099
        for format in klass._control_formats:
 
2100
            result.update(format._known_formats())
 
2101
        return result
 
2102
 
 
2103
    @classmethod
 
2104
    def _known_formats(klass):
 
2105
        """Return the known format instances for this control format."""
 
2106
        return set(klass._formats.values())
 
2107
 
1675
2108
    def open(self, transport, _found=False):
1676
2109
        """Return an instance of this format for the dir transport points at.
1677
2110
 
1678
2111
        _found is a private parameter, do not use it.
1679
2112
        """
1680
2113
        if not _found:
1681
 
            found_format = controldir.ControlDirFormat.find_format(transport)
 
2114
            found_format = BzrDirFormat.find_format(transport)
1682
2115
            if not isinstance(found_format, self.__class__):
1683
2116
                raise AssertionError("%s was asked to open %s, but it seems to need "
1684
2117
                        "format %s"
1698
2131
 
1699
2132
    @classmethod
1700
2133
    def register_format(klass, format):
1701
 
        BzrProber.register_bzrdir_format(format)
 
2134
        klass._formats[format.get_format_string()] = format
1702
2135
        # bzr native formats have a network name of their format string.
1703
 
        controldir.network_format_registry.register(format.get_format_string(), format.__class__)
1704
 
        controldir.ControlDirFormat.register_format(format)
 
2136
        network_format_registry.register(format.get_format_string(), format.__class__)
 
2137
 
 
2138
    @classmethod
 
2139
    def register_control_format(klass, format):
 
2140
        """Register a format that does not use '.bzr' for its control dir.
 
2141
 
 
2142
        TODO: This should be pulled up into a 'ControlDirFormat' base class
 
2143
        which BzrDirFormat can inherit from, and renamed to register_format
 
2144
        there. It has been done without that for now for simplicity of
 
2145
        implementation.
 
2146
        """
 
2147
        klass._control_formats.append(format)
 
2148
 
 
2149
    @classmethod
 
2150
    def register_control_server_format(klass, format):
 
2151
        """Register a control format for client-server environments.
 
2152
 
 
2153
        These formats will be tried before ones registered with
 
2154
        register_control_format.  This gives implementations that decide to the
 
2155
        chance to grab it before anything looks at the contents of the format
 
2156
        file.
 
2157
        """
 
2158
        klass._control_server_formats.append(format)
 
2159
 
 
2160
    @classmethod
 
2161
    def _set_default_format(klass, format):
 
2162
        """Set default format (for testing behavior of defaults only)"""
 
2163
        klass._default_format = format
 
2164
 
 
2165
    def __str__(self):
 
2166
        # Trim the newline
 
2167
        return self.get_format_description().rstrip()
1705
2168
 
1706
2169
    def _supply_sub_formats_to(self, other_format):
1707
2170
        """Give other_format the same values for sub formats as this has.
1717
2180
 
1718
2181
    @classmethod
1719
2182
    def unregister_format(klass, format):
1720
 
        BzrProber.unregister_bzrdir_format(format)
1721
 
        controldir.ControlDirFormat.unregister_format(format)
1722
 
        controldir.network_format_registry.remove(format.get_format_string())
 
2183
        del klass._formats[format.get_format_string()]
 
2184
 
 
2185
    @classmethod
 
2186
    def unregister_control_format(klass, format):
 
2187
        klass._control_formats.remove(format)
1723
2188
 
1724
2189
 
1725
2190
class BzrDirFormat4(BzrDirFormat):
2128
2593
                                  __set_workingtree_format)
2129
2594
 
2130
2595
 
 
2596
network_format_registry = registry.FormatRegistry()
 
2597
"""Registry of formats indexed by their network name.
 
2598
 
 
2599
The network name for a BzrDirFormat is an identifier that can be used when
 
2600
referring to formats with smart server operations. See
 
2601
BzrDirFormat.network_name() for more detail.
 
2602
"""
 
2603
 
 
2604
 
 
2605
# Register bzr control format
 
2606
BzrDirFormat.register_control_format(BzrDirFormat)
 
2607
 
2131
2608
# Register bzr formats
2132
2609
BzrDirFormat.register_format(BzrDirFormat4())
2133
2610
BzrDirFormat.register_format(BzrDirFormat5())
2134
2611
BzrDirFormat.register_format(BzrDirFormat6())
2135
2612
__default_format = BzrDirMetaFormat1()
2136
2613
BzrDirFormat.register_format(__default_format)
2137
 
controldir.ControlDirFormat._default_format = __default_format
 
2614
BzrDirFormat._default_format = __default_format
2138
2615
 
2139
2616
 
2140
2617
class Converter(object):
2174
2651
            if isinstance(self.bzrdir.transport, local.LocalTransport):
2175
2652
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2176
2653
            self._convert_to_weaves()
2177
 
            return BzrDir.open(self.bzrdir.user_url)
 
2654
            return BzrDir.open(self.bzrdir.root_transport.base)
2178
2655
        finally:
2179
2656
            self.pb.finished()
2180
2657
 
2302
2779
            self.revisions[rev_id] = rev
2303
2780
 
2304
2781
    def _load_old_inventory(self, rev_id):
2305
 
        f = self.branch.repository.inventory_store.get(rev_id)
2306
 
        try:
2307
 
            old_inv_xml = f.read()
2308
 
        finally:
2309
 
            f.close()
 
2782
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2310
2783
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2311
2784
        inv.revision_id = rev_id
2312
2785
        rev = self.revisions[rev_id]
2368
2841
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2369
2842
            in heads)
2370
2843
        self.snapshot_ie(previous_entries, ie, w, rev_id)
 
2844
        del ie.text_id
2371
2845
 
2372
2846
    def get_parent_map(self, revision_ids):
2373
2847
        """See graph.StackedParentsProvider.get_parent_map"""
2389
2863
                ie.revision = previous_ie.revision
2390
2864
                return
2391
2865
        if ie.has_text():
2392
 
            f = self.branch.repository._text_store.get(ie.text_id)
2393
 
            try:
2394
 
                file_lines = f.readlines()
2395
 
            finally:
2396
 
                f.close()
 
2866
            text = self.branch.repository._text_store.get(ie.text_id)
 
2867
            file_lines = text.readlines()
2397
2868
            w.add_lines(rev_id, previous_revisions, file_lines)
2398
2869
            self.text_count += 1
2399
2870
        else:
2433
2904
        try:
2434
2905
            ui.ui_factory.note('starting upgrade from format 5 to 6')
2435
2906
            self._convert_to_prefixed()
2436
 
            return BzrDir.open(self.bzrdir.user_url)
 
2907
            return BzrDir.open(self.bzrdir.root_transport.base)
2437
2908
        finally:
2438
2909
            pb.finished()
2439
2910
 
2561
3032
            BzrDirMetaFormat1().get_format_string(),
2562
3033
            mode=self.file_mode)
2563
3034
        self.pb.finished()
2564
 
        return BzrDir.open(self.bzrdir.user_url)
 
3035
        return BzrDir.open(self.bzrdir.root_transport.base)
2565
3036
 
2566
3037
    def make_lock(self, name):
2567
3038
        """Make a lock for the new control dir name."""
2675
3146
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2676
3147
    """Format representing bzrdirs accessed via a smart server"""
2677
3148
 
2678
 
    supports_workingtrees = False
2679
 
 
2680
3149
    def __init__(self):
2681
3150
        BzrDirMetaFormat1.__init__(self)
2682
3151
        # XXX: It's a bit ugly that the network name is here, because we'd
2683
3152
        # like to believe that format objects are stateless or at least
2684
3153
        # immutable,  However, we do at least avoid mutating the name after
2685
 
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
 
3154
        # it's returned.  See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
2686
3155
        self._network_name = None
2687
3156
 
2688
3157
    def __repr__(self):
2691
3160
 
2692
3161
    def get_format_description(self):
2693
3162
        if self._network_name:
2694
 
            real_format = controldir.network_format_registry.get(self._network_name)
 
3163
            real_format = network_format_registry.get(self._network_name)
2695
3164
            return 'Remote: ' + real_format.get_format_description()
2696
3165
        return 'bzr remote bzrdir'
2697
3166
 
2704
3173
        else:
2705
3174
            raise AssertionError("No network name set.")
2706
3175
 
 
3176
    @classmethod
 
3177
    def probe_transport(klass, transport):
 
3178
        """Return a RemoteBzrDirFormat object if it looks possible."""
 
3179
        try:
 
3180
            medium = transport.get_smart_medium()
 
3181
        except (NotImplementedError, AttributeError,
 
3182
                errors.TransportNotPossible, errors.NoSmartMedium,
 
3183
                errors.SmartProtocolError):
 
3184
            # no smart server, so not a branch for this format type.
 
3185
            raise errors.NotBranchError(path=transport.base)
 
3186
        else:
 
3187
            # Decline to open it if the server doesn't support our required
 
3188
            # version (3) so that the VFS-based transport will do it.
 
3189
            if medium.should_probe():
 
3190
                try:
 
3191
                    server_version = medium.protocol_version()
 
3192
                except errors.SmartProtocolError:
 
3193
                    # Apparently there's no usable smart server there, even though
 
3194
                    # the medium supports the smart protocol.
 
3195
                    raise errors.NotBranchError(path=transport.base)
 
3196
                if server_version != '2':
 
3197
                    raise errors.NotBranchError(path=transport.base)
 
3198
            return klass()
 
3199
 
2707
3200
    def initialize_on_transport(self, transport):
2708
3201
        try:
2709
3202
            # hand off the request to the smart server
2908
3401
        BzrDirMetaFormat1._set_repository_format) #.im_func)
2909
3402
 
2910
3403
 
2911
 
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
 
3404
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
 
3405
 
 
3406
 
 
3407
class BzrDirFormatInfo(object):
 
3408
 
 
3409
    def __init__(self, native, deprecated, hidden, experimental):
 
3410
        self.deprecated = deprecated
 
3411
        self.native = native
 
3412
        self.hidden = hidden
 
3413
        self.experimental = experimental
 
3414
 
 
3415
 
 
3416
class BzrDirFormatRegistry(registry.Registry):
 
3417
    """Registry of user-selectable BzrDir subformats.
 
3418
 
 
3419
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
 
3420
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
 
3421
    """
 
3422
 
 
3423
    def __init__(self):
 
3424
        """Create a BzrDirFormatRegistry."""
 
3425
        self._aliases = set()
 
3426
        self._registration_order = list()
 
3427
        super(BzrDirFormatRegistry, self).__init__()
 
3428
 
 
3429
    def aliases(self):
 
3430
        """Return a set of the format names which are aliases."""
 
3431
        return frozenset(self._aliases)
 
3432
 
 
3433
    def register_metadir(self, key,
 
3434
             repository_format, help, native=True, deprecated=False,
 
3435
             branch_format=None,
 
3436
             tree_format=None,
 
3437
             hidden=False,
 
3438
             experimental=False,
 
3439
             alias=False):
 
3440
        """Register a metadir subformat.
 
3441
 
 
3442
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
3443
        by the Repository/Branch/WorkingTreeformats.
 
3444
 
 
3445
        :param repository_format: The fully-qualified repository format class
 
3446
            name as a string.
 
3447
        :param branch_format: Fully-qualified branch format class name as
 
3448
            a string.
 
3449
        :param tree_format: Fully-qualified tree format class name as
 
3450
            a string.
 
3451
        """
 
3452
        # This should be expanded to support setting WorkingTree and Branch
 
3453
        # formats, once BzrDirMetaFormat1 supports that.
 
3454
        def _load(full_name):
 
3455
            mod_name, factory_name = full_name.rsplit('.', 1)
 
3456
            try:
 
3457
                mod = __import__(mod_name, globals(), locals(),
 
3458
                        [factory_name])
 
3459
            except ImportError, e:
 
3460
                raise ImportError('failed to load %s: %s' % (full_name, e))
 
3461
            try:
 
3462
                factory = getattr(mod, factory_name)
 
3463
            except AttributeError:
 
3464
                raise AttributeError('no factory %s in module %r'
 
3465
                    % (full_name, mod))
 
3466
            return factory()
 
3467
 
 
3468
        def helper():
 
3469
            bd = BzrDirMetaFormat1()
 
3470
            if branch_format is not None:
 
3471
                bd.set_branch_format(_load(branch_format))
 
3472
            if tree_format is not None:
 
3473
                bd.workingtree_format = _load(tree_format)
 
3474
            if repository_format is not None:
 
3475
                bd.repository_format = _load(repository_format)
 
3476
            return bd
 
3477
        self.register(key, helper, help, native, deprecated, hidden,
 
3478
            experimental, alias)
 
3479
 
 
3480
    def register(self, key, factory, help, native=True, deprecated=False,
 
3481
                 hidden=False, experimental=False, alias=False):
 
3482
        """Register a BzrDirFormat factory.
 
3483
 
 
3484
        The factory must be a callable that takes one parameter: the key.
 
3485
        It must produce an instance of the BzrDirFormat when called.
 
3486
 
 
3487
        This function mainly exists to prevent the info object from being
 
3488
        supplied directly.
 
3489
        """
 
3490
        registry.Registry.register(self, key, factory, help,
 
3491
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
3492
        if alias:
 
3493
            self._aliases.add(key)
 
3494
        self._registration_order.append(key)
 
3495
 
 
3496
    def register_lazy(self, key, module_name, member_name, help, native=True,
 
3497
        deprecated=False, hidden=False, experimental=False, alias=False):
 
3498
        registry.Registry.register_lazy(self, key, module_name, member_name,
 
3499
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
3500
        if alias:
 
3501
            self._aliases.add(key)
 
3502
        self._registration_order.append(key)
 
3503
 
 
3504
    def set_default(self, key):
 
3505
        """Set the 'default' key to be a clone of the supplied key.
 
3506
 
 
3507
        This method must be called once and only once.
 
3508
        """
 
3509
        registry.Registry.register(self, 'default', self.get(key),
 
3510
            self.get_help(key), info=self.get_info(key))
 
3511
        self._aliases.add('default')
 
3512
 
 
3513
    def set_default_repository(self, key):
 
3514
        """Set the FormatRegistry default and Repository default.
 
3515
 
 
3516
        This is a transitional method while Repository.set_default_format
 
3517
        is deprecated.
 
3518
        """
 
3519
        if 'default' in self:
 
3520
            self.remove('default')
 
3521
        self.set_default(key)
 
3522
        format = self.get('default')()
 
3523
 
 
3524
    def make_bzrdir(self, key):
 
3525
        return self.get(key)()
 
3526
 
 
3527
    def help_topic(self, topic):
 
3528
        output = ""
 
3529
        default_realkey = None
 
3530
        default_help = self.get_help('default')
 
3531
        help_pairs = []
 
3532
        for key in self._registration_order:
 
3533
            if key == 'default':
 
3534
                continue
 
3535
            help = self.get_help(key)
 
3536
            if help == default_help:
 
3537
                default_realkey = key
 
3538
            else:
 
3539
                help_pairs.append((key, help))
 
3540
 
 
3541
        def wrapped(key, help, info):
 
3542
            if info.native:
 
3543
                help = '(native) ' + help
 
3544
            return ':%s:\n%s\n\n' % (key,
 
3545
                textwrap.fill(help, initial_indent='    ',
 
3546
                    subsequent_indent='    ',
 
3547
                    break_long_words=False))
 
3548
        if default_realkey is not None:
 
3549
            output += wrapped(default_realkey, '(default) %s' % default_help,
 
3550
                              self.get_info('default'))
 
3551
        deprecated_pairs = []
 
3552
        experimental_pairs = []
 
3553
        for key, help in help_pairs:
 
3554
            info = self.get_info(key)
 
3555
            if info.hidden:
 
3556
                continue
 
3557
            elif info.deprecated:
 
3558
                deprecated_pairs.append((key, help))
 
3559
            elif info.experimental:
 
3560
                experimental_pairs.append((key, help))
 
3561
            else:
 
3562
                output += wrapped(key, help, info)
 
3563
        output += "\nSee :doc:`formats-help` for more about storage formats."
 
3564
        other_output = ""
 
3565
        if len(experimental_pairs) > 0:
 
3566
            other_output += "Experimental formats are shown below.\n\n"
 
3567
            for key, help in experimental_pairs:
 
3568
                info = self.get_info(key)
 
3569
                other_output += wrapped(key, help, info)
 
3570
        else:
 
3571
            other_output += \
 
3572
                "No experimental formats are available.\n\n"
 
3573
        if len(deprecated_pairs) > 0:
 
3574
            other_output += "\nDeprecated formats are shown below.\n\n"
 
3575
            for key, help in deprecated_pairs:
 
3576
                info = self.get_info(key)
 
3577
                other_output += wrapped(key, help, info)
 
3578
        else:
 
3579
            other_output += \
 
3580
                "\nNo deprecated formats are available.\n\n"
 
3581
        other_output += \
 
3582
                "\nSee :doc:`formats-help` for more about storage formats."
 
3583
 
 
3584
        if topic == 'other-formats':
 
3585
            return other_output
 
3586
        else:
 
3587
            return output
2912
3588
 
2913
3589
 
2914
3590
class RepositoryAcquisitionPolicy(object):
2943
3619
            try:
2944
3620
                stack_on = urlutils.rebase_url(self._stack_on,
2945
3621
                    self._stack_on_pwd,
2946
 
                    branch.user_url)
 
3622
                    branch.bzrdir.root_transport.base)
2947
3623
            except errors.InvalidRebaseURLs:
2948
3624
                stack_on = self._get_full_stack_on()
2949
3625
        try:
3068
3744
        return self._repository, False
3069
3745
 
3070
3746
 
3071
 
def register_metadir(registry, key,
3072
 
         repository_format, help, native=True, deprecated=False,
3073
 
         branch_format=None,
3074
 
         tree_format=None,
3075
 
         hidden=False,
3076
 
         experimental=False,
3077
 
         alias=False):
3078
 
    """Register a metadir subformat.
3079
 
 
3080
 
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3081
 
    by the Repository/Branch/WorkingTreeformats.
3082
 
 
3083
 
    :param repository_format: The fully-qualified repository format class
3084
 
        name as a string.
3085
 
    :param branch_format: Fully-qualified branch format class name as
3086
 
        a string.
3087
 
    :param tree_format: Fully-qualified tree format class name as
3088
 
        a string.
3089
 
    """
3090
 
    # This should be expanded to support setting WorkingTree and Branch
3091
 
    # formats, once BzrDirMetaFormat1 supports that.
3092
 
    def _load(full_name):
3093
 
        mod_name, factory_name = full_name.rsplit('.', 1)
3094
 
        try:
3095
 
            mod = __import__(mod_name, globals(), locals(),
3096
 
                    [factory_name])
3097
 
        except ImportError, e:
3098
 
            raise ImportError('failed to load %s: %s' % (full_name, e))
3099
 
        try:
3100
 
            factory = getattr(mod, factory_name)
3101
 
        except AttributeError:
3102
 
            raise AttributeError('no factory %s in module %r'
3103
 
                % (full_name, mod))
3104
 
        return factory()
3105
 
 
3106
 
    def helper():
3107
 
        bd = BzrDirMetaFormat1()
3108
 
        if branch_format is not None:
3109
 
            bd.set_branch_format(_load(branch_format))
3110
 
        if tree_format is not None:
3111
 
            bd.workingtree_format = _load(tree_format)
3112
 
        if repository_format is not None:
3113
 
            bd.repository_format = _load(repository_format)
3114
 
        return bd
3115
 
    registry.register(key, helper, help, native, deprecated, hidden,
3116
 
        experimental, alias)
3117
 
 
 
3747
# Please register new formats after old formats so that formats
 
3748
# appear in chronological order and format descriptions can build
 
3749
# on previous ones.
 
3750
format_registry = BzrDirFormatRegistry()
3118
3751
# The pre-0.8 formats have their repository format network name registered in
3119
3752
# repository.py. MetaDir formats have their repository format network name
3120
3753
# inferred from their disk format string.
3121
 
controldir.format_registry.register('weave', BzrDirFormat6,
 
3754
format_registry.register('weave', BzrDirFormat6,
3122
3755
    'Pre-0.8 format.  Slower than knit and does not'
3123
3756
    ' support checkouts or shared repositories.',
3124
3757
    hidden=True,
3125
3758
    deprecated=True)
3126
 
register_metadir(controldir.format_registry, 'metaweave',
 
3759
format_registry.register_metadir('metaweave',
3127
3760
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3128
3761
    'Transitional format in 0.8.  Slower than knit.',
3129
3762
    branch_format='bzrlib.branch.BzrBranchFormat5',
3130
3763
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3131
3764
    hidden=True,
3132
3765
    deprecated=True)
3133
 
register_metadir(controldir.format_registry, 'knit',
 
3766
format_registry.register_metadir('knit',
3134
3767
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3135
3768
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3136
3769
    branch_format='bzrlib.branch.BzrBranchFormat5',
3137
3770
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3138
3771
    hidden=True,
3139
3772
    deprecated=True)
3140
 
register_metadir(controldir.format_registry, 'dirstate',
 
3773
format_registry.register_metadir('dirstate',
3141
3774
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3142
3775
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3143
3776
        'above when accessed over the network.',
3147
3780
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3148
3781
    hidden=True,
3149
3782
    deprecated=True)
3150
 
register_metadir(controldir.format_registry, 'dirstate-tags',
 
3783
format_registry.register_metadir('dirstate-tags',
3151
3784
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3152
3785
    help='New in 0.15: Fast local operations and improved scaling for '
3153
3786
        'network operations. Additionally adds support for tags.'
3156
3789
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3157
3790
    hidden=True,
3158
3791
    deprecated=True)
3159
 
register_metadir(controldir.format_registry, 'rich-root',
 
3792
format_registry.register_metadir('rich-root',
3160
3793
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3161
3794
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3162
3795
        ' bzr < 1.0.',
3164
3797
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3165
3798
    hidden=True,
3166
3799
    deprecated=True)
3167
 
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
 
3800
format_registry.register_metadir('dirstate-with-subtree',
3168
3801
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3169
3802
    help='New in 0.15: Fast local operations and improved scaling for '
3170
3803
        'network operations. Additionally adds support for versioning nested '
3174
3807
    experimental=True,
3175
3808
    hidden=True,
3176
3809
    )
3177
 
register_metadir(controldir.format_registry, 'pack-0.92',
 
3810
format_registry.register_metadir('pack-0.92',
3178
3811
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3179
3812
    help='New in 0.92: Pack-based format with data compatible with '
3180
3813
        'dirstate-tags format repositories. Interoperates with '
3183
3816
    branch_format='bzrlib.branch.BzrBranchFormat6',
3184
3817
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3185
3818
    )
3186
 
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
 
3819
format_registry.register_metadir('pack-0.92-subtree',
3187
3820
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3188
3821
    help='New in 0.92: Pack-based format with data compatible with '
3189
3822
        'dirstate-with-subtree format repositories. Interoperates with '
3194
3827
    hidden=True,
3195
3828
    experimental=True,
3196
3829
    )
3197
 
register_metadir(controldir.format_registry, 'rich-root-pack',
 
3830
format_registry.register_metadir('rich-root-pack',
3198
3831
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3199
3832
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3200
3833
         '(needed for bzr-svn and bzr-git).',
3202
3835
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3203
3836
    hidden=True,
3204
3837
    )
3205
 
register_metadir(controldir.format_registry, '1.6',
 
3838
format_registry.register_metadir('1.6',
3206
3839
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3207
3840
    help='A format that allows a branch to indicate that there is another '
3208
3841
         '(stacked) repository that should be used to access data that is '
3211
3844
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3212
3845
    hidden=True,
3213
3846
    )
3214
 
register_metadir(controldir.format_registry, '1.6.1-rich-root',
 
3847
format_registry.register_metadir('1.6.1-rich-root',
3215
3848
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3216
3849
    help='A variant of 1.6 that supports rich-root data '
3217
3850
         '(needed for bzr-svn and bzr-git).',
3219
3852
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3220
3853
    hidden=True,
3221
3854
    )
3222
 
register_metadir(controldir.format_registry, '1.9',
 
3855
format_registry.register_metadir('1.9',
3223
3856
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3224
3857
    help='A repository format using B+tree indexes. These indexes '
3225
3858
         'are smaller in size, have smarter caching and provide faster '
3228
3861
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3229
3862
    hidden=True,
3230
3863
    )
3231
 
register_metadir(controldir.format_registry, '1.9-rich-root',
 
3864
format_registry.register_metadir('1.9-rich-root',
3232
3865
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3233
3866
    help='A variant of 1.9 that supports rich-root data '
3234
3867
         '(needed for bzr-svn and bzr-git).',
3236
3869
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3237
3870
    hidden=True,
3238
3871
    )
3239
 
register_metadir(controldir.format_registry, '1.14',
 
3872
format_registry.register_metadir('1.14',
3240
3873
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3241
3874
    help='A working-tree format that supports content filtering.',
3242
3875
    branch_format='bzrlib.branch.BzrBranchFormat7',
3243
3876
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3244
3877
    )
3245
 
register_metadir(controldir.format_registry, '1.14-rich-root',
 
3878
format_registry.register_metadir('1.14-rich-root',
3246
3879
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3247
3880
    help='A variant of 1.14 that supports rich-root data '
3248
3881
         '(needed for bzr-svn and bzr-git).',
3250
3883
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3251
3884
    )
3252
3885
# The following un-numbered 'development' formats should always just be aliases.
3253
 
register_metadir(controldir.format_registry, 'development-rich-root',
 
3886
format_registry.register_metadir('development-rich-root',
3254
3887
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3255
3888
    help='Current development format. Supports rich roots. Can convert data '
3256
3889
        'to and from rich-root-pack (and anything compatible with '
3264
3897
    alias=True,
3265
3898
    hidden=True,
3266
3899
    )
3267
 
register_metadir(controldir.format_registry, 'development5-subtree',
 
3900
format_registry.register_metadir('development-subtree',
3268
3901
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3269
 
    help='Development format, subtree variant. Can convert data to and '
3270
 
        'from pack-0.92-subtree (and anything compatible with '
3271
 
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3272
 
        'this format can only be read by bzr.dev. Please read '
3273
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3274
 
        'before use.',
3275
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3276
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3277
 
    experimental=True,
3278
 
    hidden=True,
3279
 
    alias=False,
3280
 
    )
3281
 
 
3282
 
 
3283
 
register_metadir(controldir.format_registry, 'development-subtree',
3284
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
3285
3902
    help='Current development format, subtree variant. Can convert data to and '
3286
3903
        'from pack-0.92-subtree (and anything compatible with '
3287
3904
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3298
3915
    )
3299
3916
 
3300
3917
# And the development formats above will have aliased one of the following:
3301
 
register_metadir(controldir.format_registry, 'development6-rich-root',
 
3918
format_registry.register_metadir('development6-rich-root',
3302
3919
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3303
3920
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3304
3921
        'Please read '
3310
3927
    experimental=True,
3311
3928
    )
3312
3929
 
3313
 
register_metadir(controldir.format_registry, 'development7-rich-root',
 
3930
format_registry.register_metadir('development7-rich-root',
3314
3931
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3315
3932
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3316
3933
        'rich roots. Please read '
3322
3939
    experimental=True,
3323
3940
    )
3324
3941
 
3325
 
register_metadir(controldir.format_registry, '2a',
 
3942
format_registry.register_metadir('2a',
3326
3943
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3327
3944
    help='First format for bzr 2.0 series.\n'
3328
3945
        'Uses group-compress storage.\n'
3331
3948
        # 'rich roots. Supported by bzr 1.16 and later.',
3332
3949
    branch_format='bzrlib.branch.BzrBranchFormat7',
3333
3950
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3334
 
    experimental=False,
 
3951
    experimental=True,
3335
3952
    )
3336
3953
 
3337
3954
# The following format should be an alias for the rich root equivalent 
3338
3955
# of the default format
3339
 
register_metadir(controldir.format_registry, 'default-rich-root',
 
3956
format_registry.register_metadir('default-rich-root',
3340
3957
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3341
3958
    branch_format='bzrlib.branch.BzrBranchFormat7',
3342
3959
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3345
3962
    help='Same as 2a.')
3346
3963
 
3347
3964
# The current format that is made on 'bzr init'.
3348
 
controldir.format_registry.set_default('2a')
3349
 
 
3350
 
# XXX 2010-08-20 JRV: There is still a lot of code relying on
3351
 
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
3352
 
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
3353
 
format_registry = controldir.format_registry
 
3965
format_registry.set_default('2a')