/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Neil Martinsen-Burrell
  • Date: 2010-09-26 02:27:37 UTC
  • mfrom: (5424 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5461.
  • Revision ID: nmb@wartburg.edu-20100926022737-cj2qvebm2mhpjzak
mergeĀ fromĀ trunk

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
38
37
 
39
38
import bzrlib
40
39
from bzrlib import (
41
40
    branch,
42
41
    config,
 
42
    controldir,
43
43
    errors,
44
44
    graph,
45
45
    lockable_files,
88
88
    )
89
89
 
90
90
 
91
 
class BzrDir(object):
 
91
class BzrDir(controldir.ControlDir):
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
 
 
132
128
    def check_conversion_target(self, target_format):
133
129
        """Check that a bzrdir as a whole can be converted to a new format."""
134
130
        # The only current restriction is that the repository content can be 
169
165
                format.get_format_description(),
170
166
                basedir)
171
167
 
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
 
 
191
168
    def clone_on_transport(self, transport, revision_id=None,
192
169
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
193
170
        create_prefix=False, use_existing_dir=True):
208
185
        """
209
186
        # Overview: put together a broad description of what we want to end up
210
187
        # with; then make as few api calls as possible to do it.
211
 
        
 
188
 
212
189
        # We may want to create a repo/branch/tree, if we do so what format
213
190
        # would we want for each:
214
191
        require_stacking = (stacked_on is not None)
215
192
        format = self.cloning_metadir(require_stacking)
216
 
        
 
193
 
217
194
        # Figure out what objects we want:
218
195
        try:
219
196
            local_repo = self.find_repository()
261
238
                # copied, and finally if we are copying up to a specific
262
239
                # revision_id then we can use the pending-ancestry-result which
263
240
                # does not require traversing all of history to describe it.
264
 
                if (result_repo.bzrdir.root_transport.base ==
265
 
                    result.root_transport.base and not require_stacking and
 
241
                if (result_repo.user_url == result.user_url
 
242
                    and not require_stacking and
266
243
                    revision_id is not None):
267
244
                    fetch_spec = graph.PendingAncestryResult(
268
245
                        [revision_id], local_repo)
296
273
        t = get_transport(url)
297
274
        t.ensure_base()
298
275
 
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
 
 
317
276
    @staticmethod
318
277
    def find_bzrdirs(transport, evaluate=None, list_current=None):
319
278
        """Find bzrdirs recursively from current location.
342
301
            recurse = True
343
302
            try:
344
303
                bzrdir = BzrDir.open_from_transport(current_transport)
345
 
            except errors.NotBranchError:
 
304
            except (errors.NotBranchError, errors.PermissionDenied):
346
305
                pass
347
306
            else:
348
307
                recurse, value = evaluate(bzrdir)
349
308
                yield value
350
309
            try:
351
310
                subdirs = list_current(current_transport)
352
 
            except errors.NoSuchFile:
 
311
            except (errors.NoSuchFile, errors.PermissionDenied):
353
312
                continue
354
313
            if recurse:
355
314
                for subdir in sorted(subdirs, reverse=True):
356
315
                    pending.append(current_transport.clone(subdir))
357
316
 
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
 
 
367
317
    @staticmethod
368
318
    def find_branches(transport):
369
319
        """Find all branches under a transport.
392
342
                ret.extend(branches)
393
343
        return ret
394
344
 
395
 
    def destroy_repository(self):
396
 
        """Destroy the repository in this BzrDir"""
397
 
        raise NotImplementedError(self.destroy_repository)
398
 
 
399
 
    def create_branch(self):
400
 
        """Create a branch in this BzrDir.
401
 
 
402
 
        The bzrdir's format will control what branch format is created.
403
 
        For more control see BranchFormatXX.create(a_bzrdir).
404
 
        """
405
 
        raise NotImplementedError(self.create_branch)
406
 
 
407
 
    def destroy_branch(self):
408
 
        """Destroy the branch in this BzrDir"""
409
 
        raise NotImplementedError(self.destroy_branch)
410
 
 
411
345
    @staticmethod
412
346
    def create_branch_and_repo(base, force_new_repo=False, format=None):
413
347
        """Create a new BzrDir, Branch and Repository at the url 'base'.
451
385
            stop = False
452
386
            stack_on = config.get_default_stack_on()
453
387
            if stack_on is not None:
454
 
                stack_on_pwd = found_bzrdir.root_transport.base
 
388
                stack_on_pwd = found_bzrdir.user_url
455
389
                stop = True
456
390
            # does it have a repository ?
457
391
            try:
459
393
            except errors.NoRepositoryPresent:
460
394
                repository = None
461
395
            else:
462
 
                if ((found_bzrdir.root_transport.base !=
463
 
                     self.root_transport.base) and not repository.is_shared()):
 
396
                if (found_bzrdir.user_url != self.user_url 
 
397
                    and not repository.is_shared()):
464
398
                    # Don't look higher, can't use a higher shared repo.
465
399
                    repository = None
466
400
                    stop = True
562
496
                                               format=format).bzrdir
563
497
        return bzrdir.create_workingtree()
564
498
 
565
 
    def create_workingtree(self, revision_id=None, from_branch=None,
566
 
        accelerator_tree=None, hardlink=False):
567
 
        """Create a working tree at this BzrDir.
568
 
 
569
 
        :param revision_id: create it as of this revision id.
570
 
        :param from_branch: override bzrdir branch (for lightweight checkouts)
571
 
        :param accelerator_tree: A tree which can be used for retrieving file
572
 
            contents more quickly than the revision tree, i.e. a workingtree.
573
 
            The revision tree will be used for cases where accelerator_tree's
574
 
            content is different.
575
 
        """
576
 
        raise NotImplementedError(self.create_workingtree)
 
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
577
507
 
578
508
    def backup_bzrdir(self):
579
509
        """Backup this bzr control directory.
580
510
 
581
511
        :return: Tuple with old path name and new path name
582
512
        """
 
513
 
 
514
        backup_dir=self.generate_backup_name('backup.bzr')
583
515
        pb = ui.ui_factory.nested_progress_bar()
584
516
        try:
585
517
            # FIXME: bug 300001 -- the backup fails if the backup directory
586
518
            # already exists, but it should instead either remove it or make
587
519
            # a new backup directory.
588
520
            #
589
 
            # FIXME: bug 262450 -- the backup directory should have the same
590
 
            # permissions as the .bzr directory (probably a bug in copy_tree)
591
521
            old_path = self.root_transport.abspath('.bzr')
592
 
            new_path = self.root_transport.abspath('backup.bzr')
 
522
            new_path = self.root_transport.abspath(backup_dir)
593
523
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
594
 
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
524
            self.root_transport.copy_tree('.bzr', backup_dir)
595
525
            return (old_path, new_path)
596
526
        finally:
597
527
            pb.finished()
621
551
                else:
622
552
                    pass
623
553
 
624
 
    def destroy_workingtree(self):
625
 
        """Destroy the working tree at this BzrDir.
626
 
 
627
 
        Formats that do not support this may raise UnsupportedOperation.
628
 
        """
629
 
        raise NotImplementedError(self.destroy_workingtree)
630
 
 
631
 
    def destroy_workingtree_metadata(self):
632
 
        """Destroy the control files for the working tree at this BzrDir.
633
 
 
634
 
        The contents of working tree files are not affected.
635
 
        Formats that do not support this may raise UnsupportedOperation.
636
 
        """
637
 
        raise NotImplementedError(self.destroy_workingtree_metadata)
638
 
 
639
554
    def _find_containing(self, evaluate):
640
555
        """Find something in a containing control directory.
641
556
 
655
570
            if stop:
656
571
                return result
657
572
            next_transport = found_bzrdir.root_transport.clone('..')
658
 
            if (found_bzrdir.root_transport.base == next_transport.base):
 
573
            if (found_bzrdir.user_url == next_transport.base):
659
574
                # top of the file system
660
575
                return None
661
576
            # find the next containing bzrdir
678
593
                repository = found_bzrdir.open_repository()
679
594
            except errors.NoRepositoryPresent:
680
595
                return None, False
681
 
            if found_bzrdir.root_transport.base == self.root_transport.base:
 
596
            if found_bzrdir.user_url == self.user_url:
682
597
                return repository, True
683
598
            elif repository.is_shared():
684
599
                return repository, True
690
605
            raise errors.NoRepositoryPresent(self)
691
606
        return found_repo
692
607
 
693
 
    def get_branch_reference(self):
694
 
        """Return the referenced URL for the branch in this bzrdir.
695
 
 
696
 
        :raises NotBranchError: If there is no Branch.
697
 
        :return: The URL the branch in this bzrdir references if it is a
698
 
            reference branch, or None for regular branches.
699
 
        """
700
 
        return None
701
 
 
702
 
    def get_branch_transport(self, branch_format):
703
 
        """Get the transport for use by branch format in this BzrDir.
704
 
 
705
 
        Note that bzr dirs that do not support format strings will raise
706
 
        IncompatibleFormat if the branch format they are given has
707
 
        a format string, and vice versa.
708
 
 
709
 
        If branch_format is None, the transport is returned with no
710
 
        checking. If it is not None, then the returned transport is
711
 
        guaranteed to point to an existing directory ready for use.
712
 
        """
713
 
        raise NotImplementedError(self.get_branch_transport)
714
 
 
715
608
    def _find_creation_modes(self):
716
609
        """Determine the appropriate modes for files and directories.
717
610
 
756
649
            self._find_creation_modes()
757
650
        return self._dir_mode
758
651
 
759
 
    def get_repository_transport(self, repository_format):
760
 
        """Get the transport for use by repository format in this BzrDir.
761
 
 
762
 
        Note that bzr dirs that do not support format strings will raise
763
 
        IncompatibleFormat if the repository format they are given has
764
 
        a format string, and vice versa.
765
 
 
766
 
        If repository_format is None, the transport is returned with no
767
 
        checking. If it is not None, then the returned transport is
768
 
        guaranteed to point to an existing directory ready for use.
769
 
        """
770
 
        raise NotImplementedError(self.get_repository_transport)
771
 
 
772
 
    def get_workingtree_transport(self, tree_format):
773
 
        """Get the transport for use by workingtree format in this BzrDir.
774
 
 
775
 
        Note that bzr dirs that do not support format strings will raise
776
 
        IncompatibleFormat if the workingtree format they are given has a
777
 
        format string, and vice versa.
778
 
 
779
 
        If workingtree_format is None, the transport is returned with no
780
 
        checking. If it is not None, then the returned transport is
781
 
        guaranteed to point to an existing directory ready for use.
782
 
        """
783
 
        raise NotImplementedError(self.get_workingtree_transport)
784
 
 
785
652
    def get_config(self):
786
653
        """Get configuration for this BzrDir."""
787
654
        return config.BzrDirConfig(self)
800
667
        :param _transport: the transport this dir is based at.
801
668
        """
802
669
        self._format = _format
 
670
        # these are also under the more standard names of 
 
671
        # control_transport and user_transport
803
672
        self.transport = _transport.clone('.bzr')
804
673
        self.root_transport = _transport
805
674
        self._mode_check_done = False
806
675
 
 
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
 
807
684
    def is_control_filename(self, filename):
808
685
        """True if filename is the name of a path which is reserved for bzrdir's.
809
686
 
811
688
 
812
689
        This is true IF and ONLY IF the filename is part of the namespace reserved
813
690
        for bzr control dirs. Currently this is the '.bzr' directory in the root
814
 
        of the root_transport. it is expected that plugins will need to extend
815
 
        this in the future - for instance to make bzr talk with svn working
816
 
        trees.
 
691
        of the root_transport. 
817
692
        """
818
693
        # this might be better on the BzrDirFormat class because it refers to
819
694
        # all the possible bzrdir disk formats.
823
698
        # add new tests for it to the appropriate place.
824
699
        return filename == '.bzr' or filename.startswith('.bzr/')
825
700
 
826
 
    def needs_format_conversion(self, format=None):
827
 
        """Return true if this bzrdir needs convert_format run on it.
828
 
 
829
 
        For instance, if the repository format is out of date but the
830
 
        branch and working tree are not, this should return True.
831
 
 
832
 
        :param format: Optional parameter indicating a specific desired
833
 
                       format we plan to arrive at.
834
 
        """
835
 
        raise NotImplementedError(self.needs_format_conversion)
836
 
 
837
701
    @staticmethod
838
702
    def open_unsupported(base):
839
703
        """Open a branch which is not supported."""
862
726
        # the redirections.
863
727
        base = transport.base
864
728
        def find_format(transport):
865
 
            return transport, BzrDirFormat.find_format(
 
729
            return transport, controldir.ControlDirFormat.find_format(
866
730
                transport, _server_formats=_server_formats)
867
731
 
868
732
        def redirected(transport, e, redirection_notice):
883
747
        BzrDir._check_supported(format, _unsupported)
884
748
        return format.open(transport, _found=True)
885
749
 
886
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
887
 
        """Open the branch object at this BzrDir if one is present.
888
 
 
889
 
        If unsupported is True, then no longer supported branch formats can
890
 
        still be opened.
891
 
 
892
 
        TODO: static convenience version of this?
893
 
        """
894
 
        raise NotImplementedError(self.open_branch)
895
 
 
896
750
    @staticmethod
897
751
    def open_containing(url, possible_transports=None):
898
752
        """Open an existing branch which contains url.
936
790
                raise errors.NotBranchError(path=url)
937
791
            a_transport = new_t
938
792
 
939
 
    def _get_tree_branch(self):
940
 
        """Return the branch and tree, if any, for this bzrdir.
941
 
 
942
 
        Return None for tree if not present or inaccessible.
943
 
        Raise NotBranchError if no branch is present.
944
 
        :return: (tree, branch)
945
 
        """
946
 
        try:
947
 
            tree = self.open_workingtree()
948
 
        except (errors.NoWorkingTree, errors.NotLocalUrl):
949
 
            tree = None
950
 
            branch = self.open_branch()
951
 
        else:
952
 
            branch = tree.branch
953
 
        return tree, branch
954
 
 
955
793
    @classmethod
956
794
    def open_tree_or_branch(klass, location):
957
795
        """Return the branch and working tree at a location.
1003
841
                raise errors.NotBranchError(location)
1004
842
        return tree, branch, branch.repository, relpath
1005
843
 
1006
 
    def open_repository(self, _unsupported=False):
1007
 
        """Open the repository object at this BzrDir if one is present.
1008
 
 
1009
 
        This will not follow the Branch object pointer - it's strictly a direct
1010
 
        open facility. Most client code should use open_branch().repository to
1011
 
        get at a repository.
1012
 
 
1013
 
        :param _unsupported: a private parameter, not part of the api.
1014
 
        TODO: static convenience version of this?
1015
 
        """
1016
 
        raise NotImplementedError(self.open_repository)
1017
 
 
1018
 
    def open_workingtree(self, _unsupported=False,
1019
 
                         recommend_upgrade=True, from_branch=None):
1020
 
        """Open the workingtree object at this BzrDir if one is present.
1021
 
 
1022
 
        :param recommend_upgrade: Optional keyword parameter, when True (the
1023
 
            default), emit through the ui module a recommendation that the user
1024
 
            upgrade the working tree when the workingtree being opened is old
1025
 
            (but still fully supported).
1026
 
        :param from_branch: override bzrdir branch (for lightweight checkouts)
1027
 
        """
1028
 
        raise NotImplementedError(self.open_workingtree)
1029
 
 
1030
 
    def has_branch(self):
1031
 
        """Tell if this bzrdir contains a branch.
1032
 
 
1033
 
        Note: if you're going to open the branch, you should just go ahead
1034
 
        and try, and not ask permission first.  (This method just opens the
1035
 
        branch and discards it, and that's somewhat expensive.)
1036
 
        """
1037
 
        try:
1038
 
            self.open_branch()
1039
 
            return True
1040
 
        except errors.NotBranchError:
1041
 
            return False
1042
 
 
1043
 
    def has_workingtree(self):
1044
 
        """Tell if this bzrdir contains a working tree.
1045
 
 
1046
 
        This will still raise an exception if the bzrdir has a workingtree that
1047
 
        is remote & inaccessible.
1048
 
 
1049
 
        Note: if you're going to open the working tree, you should just go ahead
1050
 
        and try, and not ask permission first.  (This method just opens the
1051
 
        workingtree and discards it, and that's somewhat expensive.)
1052
 
        """
1053
 
        try:
1054
 
            self.open_workingtree(recommend_upgrade=False)
1055
 
            return True
1056
 
        except errors.NoWorkingTree:
1057
 
            return False
1058
 
 
1059
844
    def _cloning_metadir(self):
1060
845
        """Produce a metadir suitable for cloning with.
1061
846
 
1119
904
            format.require_stacking()
1120
905
        return format
1121
906
 
1122
 
    def checkout_metadir(self):
1123
 
        return self.cloning_metadir()
1124
 
 
1125
 
    def sprout(self, url, revision_id=None, force_new_repo=False,
1126
 
               recurse='down', possible_transports=None,
1127
 
               accelerator_tree=None, hardlink=False, stacked=False,
1128
 
               source_branch=None, create_tree_if_local=True):
1129
 
        """Create a copy of this bzrdir prepared for use as a new line of
1130
 
        development.
1131
 
 
1132
 
        If url's last component does not exist, it will be created.
1133
 
 
1134
 
        Attributes related to the identity of the source branch like
1135
 
        branch nickname will be cleaned, a working tree is created
1136
 
        whether one existed before or not; and a local branch is always
1137
 
        created.
1138
 
 
1139
 
        if revision_id is not None, then the clone operation may tune
1140
 
            itself to download less data.
1141
 
        :param accelerator_tree: A tree which can be used for retrieving file
1142
 
            contents more quickly than the revision tree, i.e. a workingtree.
1143
 
            The revision tree will be used for cases where accelerator_tree's
1144
 
            content is different.
1145
 
        :param hardlink: If true, hard-link files from accelerator_tree,
1146
 
            where possible.
1147
 
        :param stacked: If true, create a stacked branch referring to the
1148
 
            location of this control directory.
1149
 
        :param create_tree_if_local: If true, a working-tree will be created
1150
 
            when working locally.
 
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.
1151
915
        """
1152
 
        target_transport = get_transport(url, possible_transports)
1153
 
        target_transport.ensure_base()
1154
 
        cloning_format = self.cloning_metadir(stacked)
1155
 
        # Create/update the result branch
1156
 
        result = cloning_format.initialize_on_transport(target_transport)
1157
 
        # if a stacked branch wasn't requested, we don't create one
1158
 
        # even if the origin was stacked
1159
 
        stacked_branch_url = None
1160
 
        if source_branch is not None:
1161
 
            if stacked:
1162
 
                stacked_branch_url = self.root_transport.base
1163
 
            source_repository = source_branch.repository
1164
 
        else:
1165
 
            try:
1166
 
                source_branch = self.open_branch()
1167
 
                source_repository = source_branch.repository
1168
 
                if stacked:
1169
 
                    stacked_branch_url = self.root_transport.base
1170
 
            except errors.NotBranchError:
1171
 
                source_branch = None
1172
 
                try:
1173
 
                    source_repository = self.open_repository()
1174
 
                except errors.NoRepositoryPresent:
1175
 
                    source_repository = None
1176
 
        repository_policy = result.determine_repository_policy(
1177
 
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1178
 
        result_repo, is_new_repo = repository_policy.acquire_repository()
1179
 
        if is_new_repo and revision_id is not None and not stacked:
1180
 
            fetch_spec = graph.PendingAncestryResult(
1181
 
                [revision_id], source_repository)
1182
 
        else:
1183
 
            fetch_spec = None
1184
 
        if source_repository is not None:
1185
 
            # Fetch while stacked to prevent unstacked fetch from
1186
 
            # Branch.sprout.
1187
 
            if fetch_spec is None:
1188
 
                result_repo.fetch(source_repository, revision_id=revision_id)
1189
 
            else:
1190
 
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1191
 
 
1192
 
        if source_branch is None:
1193
 
            # this is for sprouting a bzrdir without a branch; is that
1194
 
            # actually useful?
1195
 
            # Not especially, but it's part of the contract.
1196
 
            result_branch = result.create_branch()
1197
 
        else:
1198
 
            result_branch = source_branch.sprout(result,
1199
 
                revision_id=revision_id, repository_policy=repository_policy)
1200
 
        mutter("created new branch %r" % (result_branch,))
1201
 
 
1202
 
        # Create/update the result working tree
1203
 
        if (create_tree_if_local and
1204
 
            isinstance(target_transport, local.LocalTransport) and
1205
 
            (result_repo is None or result_repo.make_working_trees())):
1206
 
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1207
 
                hardlink=hardlink)
1208
 
            wt.lock_write()
1209
 
            try:
1210
 
                if wt.path2id('') is None:
1211
 
                    try:
1212
 
                        wt.set_root_id(self.open_workingtree.get_root_id())
1213
 
                    except errors.NoWorkingTree:
1214
 
                        pass
1215
 
            finally:
1216
 
                wt.unlock()
1217
 
        else:
1218
 
            wt = None
1219
 
        if recurse == 'down':
1220
 
            if wt is not None:
1221
 
                basis = wt.basis_tree()
1222
 
                basis.lock_read()
1223
 
                subtrees = basis.iter_references()
1224
 
            elif result_branch is not None:
1225
 
                basis = result_branch.basis_tree()
1226
 
                basis.lock_read()
1227
 
                subtrees = basis.iter_references()
1228
 
            elif source_branch is not None:
1229
 
                basis = source_branch.basis_tree()
1230
 
                basis.lock_read()
1231
 
                subtrees = basis.iter_references()
1232
 
            else:
1233
 
                subtrees = []
1234
 
                basis = None
1235
 
            try:
1236
 
                for path, file_id in subtrees:
1237
 
                    target = urlutils.join(url, urlutils.escape(path))
1238
 
                    sublocation = source_branch.reference_parent(file_id, path)
1239
 
                    sublocation.bzrdir.sprout(target,
1240
 
                        basis.get_reference_revision(file_id, path),
1241
 
                        force_new_repo=force_new_repo, recurse=recurse,
1242
 
                        stacked=stacked)
1243
 
            finally:
1244
 
                if basis is not None:
1245
 
                    basis.unlock()
1246
 
        return result
1247
 
 
1248
 
    def push_branch(self, source, revision_id=None, overwrite=False, 
1249
 
        remember=False, create_prefix=False):
1250
 
        """Push the source branch into this BzrDir."""
1251
 
        br_to = None
1252
 
        # If we can open a branch, use its direct repository, otherwise see
1253
 
        # if there is a repository without a branch.
1254
 
        try:
1255
 
            br_to = self.open_branch()
1256
 
        except errors.NotBranchError:
1257
 
            # Didn't find a branch, can we find a repository?
1258
 
            repository_to = self.find_repository()
1259
 
        else:
1260
 
            # Found a branch, so we must have found a repository
1261
 
            repository_to = br_to.repository
1262
 
 
1263
 
        push_result = PushResult()
1264
 
        push_result.source_branch = source
1265
 
        if br_to is None:
1266
 
            # We have a repository but no branch, copy the revisions, and then
1267
 
            # create a branch.
1268
 
            repository_to.fetch(source.repository, revision_id=revision_id)
1269
 
            br_to = source.clone(self, revision_id=revision_id)
1270
 
            if source.get_push_location() is None or remember:
1271
 
                source.set_push_location(br_to.base)
1272
 
            push_result.stacked_on = None
1273
 
            push_result.branch_push_result = None
1274
 
            push_result.old_revno = None
1275
 
            push_result.old_revid = _mod_revision.NULL_REVISION
1276
 
            push_result.target_branch = br_to
1277
 
            push_result.master_branch = None
1278
 
            push_result.workingtree_updated = False
1279
 
        else:
1280
 
            # We have successfully opened the branch, remember if necessary:
1281
 
            if source.get_push_location() is None or remember:
1282
 
                source.set_push_location(br_to.base)
1283
 
            try:
1284
 
                tree_to = self.open_workingtree()
1285
 
            except errors.NotLocalUrl:
1286
 
                push_result.branch_push_result = source.push(br_to, 
1287
 
                    overwrite, stop_revision=revision_id)
1288
 
                push_result.workingtree_updated = False
1289
 
            except errors.NoWorkingTree:
1290
 
                push_result.branch_push_result = source.push(br_to,
1291
 
                    overwrite, stop_revision=revision_id)
1292
 
                push_result.workingtree_updated = None # Not applicable
1293
 
            else:
1294
 
                tree_to.lock_write()
1295
 
                try:
1296
 
                    push_result.branch_push_result = source.push(
1297
 
                        tree_to.branch, overwrite, stop_revision=revision_id)
1298
 
                    tree_to.update()
1299
 
                finally:
1300
 
                    tree_to.unlock()
1301
 
                push_result.workingtree_updated = True
1302
 
            push_result.old_revno = push_result.branch_push_result.old_revno
1303
 
            push_result.old_revid = push_result.branch_push_result.old_revid
1304
 
            push_result.target_branch = \
1305
 
                push_result.branch_push_result.target_branch
1306
 
        return push_result
 
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
 
1307
925
 
1308
926
 
1309
927
class BzrDirHooks(hooks.Hooks):
1315
933
        self.create_hook(hooks.HookPoint('pre_open',
1316
934
            "Invoked before attempting to open a BzrDir with the transport "
1317
935
            "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))
1318
941
 
1319
942
# install the default hooks
1320
943
BzrDir.hooks = BzrDirHooks()
1321
944
 
1322
945
 
 
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
 
1323
982
class BzrDirPreSplitOut(BzrDir):
1324
983
    """A common class for the all-in-one formats."""
1325
984
 
1338
997
    def cloning_metadir(self, require_stacking=False):
1339
998
        """Produce a metadir suitable for cloning with."""
1340
999
        if require_stacking:
1341
 
            return format_registry.make_bzrdir('1.6')
 
1000
            return controldir.format_registry.make_bzrdir('1.6')
1342
1001
        return self._format.__class__()
1343
1002
 
1344
1003
    def clone(self, url, revision_id=None, force_new_repo=False,
1364
1023
            tree.clone(result)
1365
1024
        return result
1366
1025
 
1367
 
    def create_branch(self):
 
1026
    def create_branch(self, name=None):
1368
1027
        """See BzrDir.create_branch."""
1369
 
        return self._format.get_branch_format().initialize(self)
 
1028
        return self._format.get_branch_format().initialize(self, name=name)
1370
1029
 
1371
 
    def destroy_branch(self):
 
1030
    def destroy_branch(self, name=None):
1372
1031
        """See BzrDir.destroy_branch."""
1373
1032
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1374
1033
 
1430
1089
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1431
1090
                                          self)
1432
1091
 
1433
 
    def get_branch_transport(self, branch_format):
 
1092
    def get_branch_transport(self, branch_format, name=None):
1434
1093
        """See BzrDir.get_branch_transport()."""
 
1094
        if name is not None:
 
1095
            raise errors.NoColocatedBranchSupport(self)
1435
1096
        if branch_format is None:
1436
1097
            return self.transport
1437
1098
        try:
1470
1131
            format = BzrDirFormat.get_default_format()
1471
1132
        return not isinstance(self._format, format.__class__)
1472
1133
 
1473
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1134
    def open_branch(self, name=None, unsupported=False,
 
1135
                    ignore_fallbacks=False):
1474
1136
        """See BzrDir.open_branch."""
1475
1137
        from bzrlib.branch import BzrBranchFormat4
1476
1138
        format = BzrBranchFormat4()
1477
1139
        self._check_supported(format, unsupported)
1478
 
        return format.open(self, _found=True)
 
1140
        return format.open(self, name, _found=True)
1479
1141
 
1480
1142
    def sprout(self, url, revision_id=None, force_new_repo=False,
1481
1143
               possible_transports=None, accelerator_tree=None,
1598
1260
        """See BzrDir.can_convert_format()."""
1599
1261
        return True
1600
1262
 
1601
 
    def create_branch(self):
 
1263
    def create_branch(self, name=None):
1602
1264
        """See BzrDir.create_branch."""
1603
 
        return self._format.get_branch_format().initialize(self)
 
1265
        return self._format.get_branch_format().initialize(self, name=name)
1604
1266
 
1605
 
    def destroy_branch(self):
 
1267
    def destroy_branch(self, name=None):
1606
1268
        """See BzrDir.create_branch."""
 
1269
        if name is not None:
 
1270
            raise errors.NoColocatedBranchSupport(self)
1607
1271
        self.transport.delete_tree('branch')
1608
1272
 
1609
1273
    def create_repository(self, shared=False):
1632
1296
    def destroy_workingtree_metadata(self):
1633
1297
        self.transport.delete_tree('checkout')
1634
1298
 
1635
 
    def find_branch_format(self):
 
1299
    def find_branch_format(self, name=None):
1636
1300
        """Find the branch 'format' for this bzrdir.
1637
1301
 
1638
1302
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1639
1303
        """
1640
1304
        from bzrlib.branch import BranchFormat
1641
 
        return BranchFormat.find_format(self)
 
1305
        return BranchFormat.find_format(self, name=name)
1642
1306
 
1643
1307
    def _get_mkdir_mode(self):
1644
1308
        """Figure out the mode to use when creating a bzrdir subdir."""
1646
1310
                                     lockable_files.TransportLock)
1647
1311
        return temp_control._dir_mode
1648
1312
 
1649
 
    def get_branch_reference(self):
 
1313
    def get_branch_reference(self, name=None):
1650
1314
        """See BzrDir.get_branch_reference()."""
1651
1315
        from bzrlib.branch import BranchFormat
1652
 
        format = BranchFormat.find_format(self)
1653
 
        return format.get_reference(self)
 
1316
        format = BranchFormat.find_format(self, name=name)
 
1317
        return format.get_reference(self, name=name)
1654
1318
 
1655
 
    def get_branch_transport(self, branch_format):
 
1319
    def get_branch_transport(self, branch_format, name=None):
1656
1320
        """See BzrDir.get_branch_transport()."""
 
1321
        if name is not None:
 
1322
            raise errors.NoColocatedBranchSupport(self)
1657
1323
        # XXX: this shouldn't implicitly create the directory if it's just
1658
1324
        # promising to get a transport -- mbp 20090727
1659
1325
        if branch_format is None:
1730
1396
                return True
1731
1397
        except errors.NoRepositoryPresent:
1732
1398
            pass
1733
 
        try:
1734
 
            if not isinstance(self.open_branch()._format,
 
1399
        for branch in self.list_branches():
 
1400
            if not isinstance(branch._format,
1735
1401
                              format.get_branch_format().__class__):
1736
1402
                # the branch needs an upgrade.
1737
1403
                return True
1738
 
        except errors.NotBranchError:
1739
 
            pass
1740
1404
        try:
1741
1405
            my_wt = self.open_workingtree(recommend_upgrade=False)
1742
1406
            if not isinstance(my_wt._format,
1747
1411
            pass
1748
1412
        return False
1749
1413
 
1750
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1414
    def open_branch(self, name=None, unsupported=False,
 
1415
                    ignore_fallbacks=False):
1751
1416
        """See BzrDir.open_branch."""
1752
 
        format = self.find_branch_format()
 
1417
        format = self.find_branch_format(name=name)
1753
1418
        self._check_supported(format, unsupported)
1754
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1419
        return format.open(self, name=name,
 
1420
            _found=True, ignore_fallbacks=ignore_fallbacks)
1755
1421
 
1756
1422
    def open_repository(self, unsupported=False):
1757
1423
        """See BzrDir.open_repository."""
1774
1440
        return config.TransportConfig(self.transport, 'control.conf')
1775
1441
 
1776
1442
 
1777
 
class BzrDirFormat(object):
1778
 
    """An encapsulation of the initialization and open routines for a format.
1779
 
 
1780
 
    Formats provide three things:
1781
 
     * An initialization routine,
1782
 
     * a format string,
1783
 
     * an open routine.
 
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.
1784
1503
 
1785
1504
    Formats are placed in a dict by their format string for reference
1786
1505
    during bzrdir opening. These should be subclasses of BzrDirFormat
1791
1510
    object will be created every system load.
1792
1511
    """
1793
1512
 
1794
 
    _default_format = None
1795
 
    """The default format used for new .bzr dirs."""
1796
 
 
1797
 
    _formats = {}
1798
 
    """The known formats."""
1799
 
 
1800
 
    _control_formats = []
1801
 
    """The registered control formats - .bzr, ....
1802
 
 
1803
 
    This is a list of BzrDirFormat objects.
1804
 
    """
1805
 
 
1806
 
    _control_server_formats = []
1807
 
    """The registered control server formats, e.g. RemoteBzrDirs.
1808
 
 
1809
 
    This is a list of BzrDirFormat objects.
1810
 
    """
1811
 
 
1812
1513
    _lock_file_name = 'branch-lock'
1813
1514
 
1814
1515
    # _lock_class must be set in subclasses to the lock type, typ.
1815
1516
    # TransportLock or LockDir
1816
1517
 
1817
 
    @classmethod
1818
 
    def find_format(klass, transport, _server_formats=True):
1819
 
        """Return the format present at transport."""
1820
 
        if _server_formats:
1821
 
            formats = klass._control_server_formats + klass._control_formats
1822
 
        else:
1823
 
            formats = klass._control_formats
1824
 
        for format in formats:
1825
 
            try:
1826
 
                return format.probe_transport(transport)
1827
 
            except errors.NotBranchError:
1828
 
                # this format does not find a control dir here.
1829
 
                pass
1830
 
        raise errors.NotBranchError(path=transport.base)
1831
 
 
1832
 
    @classmethod
1833
 
    def probe_transport(klass, transport):
1834
 
        """Return the .bzrdir style format present in a directory."""
1835
 
        try:
1836
 
            format_string = transport.get_bytes(".bzr/branch-format")
1837
 
        except errors.NoSuchFile:
1838
 
            raise errors.NotBranchError(path=transport.base)
1839
 
 
1840
 
        try:
1841
 
            return klass._formats[format_string]
1842
 
        except KeyError:
1843
 
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1844
 
 
1845
 
    @classmethod
1846
 
    def get_default_format(klass):
1847
 
        """Return the current default format."""
1848
 
        return klass._default_format
1849
 
 
1850
1518
    def get_format_string(self):
1851
1519
        """Return the ASCII format string that identifies this format."""
1852
1520
        raise NotImplementedError(self.get_format_string)
1853
1521
 
1854
 
    def get_format_description(self):
1855
 
        """Return the short description for this format."""
1856
 
        raise NotImplementedError(self.get_format_description)
1857
 
 
1858
 
    def get_converter(self, format=None):
1859
 
        """Return the converter to use to convert bzrdirs needing converts.
1860
 
 
1861
 
        This returns a bzrlib.bzrdir.Converter object.
1862
 
 
1863
 
        This should return the best upgrader to step this format towards the
1864
 
        current default format. In the case of plugins we can/should provide
1865
 
        some means for them to extend the range of returnable converters.
1866
 
 
1867
 
        :param format: Optional format to override the default format of the
1868
 
                       library.
1869
 
        """
1870
 
        raise NotImplementedError(self.get_converter)
1871
 
 
1872
 
    def initialize(self, url, possible_transports=None):
1873
 
        """Create a bzr control dir at this url and return an opened copy.
1874
 
 
1875
 
        While not deprecated, this method is very specific and its use will
1876
 
        lead to many round trips to setup a working environment. See
1877
 
        initialize_on_transport_ex for a [nearly] all-in-one method.
1878
 
 
1879
 
        Subclasses should typically override initialize_on_transport
1880
 
        instead of this method.
1881
 
        """
1882
 
        return self.initialize_on_transport(get_transport(url,
1883
 
                                                          possible_transports))
1884
 
 
1885
1522
    def initialize_on_transport(self, transport):
1886
1523
        """Initialize a new bzrdir in the base directory of a Transport."""
1887
1524
        try:
2035
1672
            control_files.unlock()
2036
1673
        return self.open(transport, _found=True)
2037
1674
 
2038
 
    def is_supported(self):
2039
 
        """Is this format supported?
2040
 
 
2041
 
        Supported formats must be initializable and openable.
2042
 
        Unsupported formats may not support initialization or committing or
2043
 
        some other features depending on the reason for not being supported.
2044
 
        """
2045
 
        return True
2046
 
 
2047
 
    def network_name(self):
2048
 
        """A simple byte string uniquely identifying this format for RPC calls.
2049
 
 
2050
 
        Bzr control formats use thir disk format string to identify the format
2051
 
        over the wire. Its possible that other control formats have more
2052
 
        complex detection requirements, so we permit them to use any unique and
2053
 
        immutable string they desire.
2054
 
        """
2055
 
        raise NotImplementedError(self.network_name)
2056
 
 
2057
 
    def same_model(self, target_format):
2058
 
        return (self.repository_format.rich_root_data ==
2059
 
            target_format.rich_root_data)
2060
 
 
2061
 
    @classmethod
2062
 
    def known_formats(klass):
2063
 
        """Return all the known formats.
2064
 
 
2065
 
        Concrete formats should override _known_formats.
2066
 
        """
2067
 
        # There is double indirection here to make sure that control
2068
 
        # formats used by more than one dir format will only be probed
2069
 
        # once. This can otherwise be quite expensive for remote connections.
2070
 
        result = set()
2071
 
        for format in klass._control_formats:
2072
 
            result.update(format._known_formats())
2073
 
        return result
2074
 
 
2075
 
    @classmethod
2076
 
    def _known_formats(klass):
2077
 
        """Return the known format instances for this control format."""
2078
 
        return set(klass._formats.values())
2079
 
 
2080
1675
    def open(self, transport, _found=False):
2081
1676
        """Return an instance of this format for the dir transport points at.
2082
1677
 
2083
1678
        _found is a private parameter, do not use it.
2084
1679
        """
2085
1680
        if not _found:
2086
 
            found_format = BzrDirFormat.find_format(transport)
 
1681
            found_format = controldir.ControlDirFormat.find_format(transport)
2087
1682
            if not isinstance(found_format, self.__class__):
2088
1683
                raise AssertionError("%s was asked to open %s, but it seems to need "
2089
1684
                        "format %s"
2103
1698
 
2104
1699
    @classmethod
2105
1700
    def register_format(klass, format):
2106
 
        klass._formats[format.get_format_string()] = format
 
1701
        BzrProber.register_bzrdir_format(format)
2107
1702
        # bzr native formats have a network name of their format string.
2108
 
        network_format_registry.register(format.get_format_string(), format.__class__)
2109
 
 
2110
 
    @classmethod
2111
 
    def register_control_format(klass, format):
2112
 
        """Register a format that does not use '.bzr' for its control dir.
2113
 
 
2114
 
        TODO: This should be pulled up into a 'ControlDirFormat' base class
2115
 
        which BzrDirFormat can inherit from, and renamed to register_format
2116
 
        there. It has been done without that for now for simplicity of
2117
 
        implementation.
2118
 
        """
2119
 
        klass._control_formats.append(format)
2120
 
 
2121
 
    @classmethod
2122
 
    def register_control_server_format(klass, format):
2123
 
        """Register a control format for client-server environments.
2124
 
 
2125
 
        These formats will be tried before ones registered with
2126
 
        register_control_format.  This gives implementations that decide to the
2127
 
        chance to grab it before anything looks at the contents of the format
2128
 
        file.
2129
 
        """
2130
 
        klass._control_server_formats.append(format)
2131
 
 
2132
 
    @classmethod
2133
 
    def _set_default_format(klass, format):
2134
 
        """Set default format (for testing behavior of defaults only)"""
2135
 
        klass._default_format = format
2136
 
 
2137
 
    def __str__(self):
2138
 
        # Trim the newline
2139
 
        return self.get_format_description().rstrip()
 
1703
        controldir.network_format_registry.register(format.get_format_string(), format.__class__)
 
1704
        controldir.ControlDirFormat.register_format(format)
2140
1705
 
2141
1706
    def _supply_sub_formats_to(self, other_format):
2142
1707
        """Give other_format the same values for sub formats as this has.
2152
1717
 
2153
1718
    @classmethod
2154
1719
    def unregister_format(klass, format):
2155
 
        del klass._formats[format.get_format_string()]
2156
 
 
2157
 
    @classmethod
2158
 
    def unregister_control_format(klass, format):
2159
 
        klass._control_formats.remove(format)
 
1720
        BzrProber.unregister_bzrdir_format(format)
 
1721
        controldir.ControlDirFormat.unregister_format(format)
 
1722
        controldir.network_format_registry.remove(format.get_format_string())
2160
1723
 
2161
1724
 
2162
1725
class BzrDirFormat4(BzrDirFormat):
2565
2128
                                  __set_workingtree_format)
2566
2129
 
2567
2130
 
2568
 
network_format_registry = registry.FormatRegistry()
2569
 
"""Registry of formats indexed by their network name.
2570
 
 
2571
 
The network name for a BzrDirFormat is an identifier that can be used when
2572
 
referring to formats with smart server operations. See
2573
 
BzrDirFormat.network_name() for more detail.
2574
 
"""
2575
 
 
2576
 
 
2577
 
# Register bzr control format
2578
 
BzrDirFormat.register_control_format(BzrDirFormat)
2579
 
 
2580
2131
# Register bzr formats
2581
2132
BzrDirFormat.register_format(BzrDirFormat4())
2582
2133
BzrDirFormat.register_format(BzrDirFormat5())
2583
2134
BzrDirFormat.register_format(BzrDirFormat6())
2584
2135
__default_format = BzrDirMetaFormat1()
2585
2136
BzrDirFormat.register_format(__default_format)
2586
 
BzrDirFormat._default_format = __default_format
 
2137
controldir.ControlDirFormat._default_format = __default_format
2587
2138
 
2588
2139
 
2589
2140
class Converter(object):
2623
2174
            if isinstance(self.bzrdir.transport, local.LocalTransport):
2624
2175
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2625
2176
            self._convert_to_weaves()
2626
 
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2177
            return BzrDir.open(self.bzrdir.user_url)
2627
2178
        finally:
2628
2179
            self.pb.finished()
2629
2180
 
2751
2302
            self.revisions[rev_id] = rev
2752
2303
 
2753
2304
    def _load_old_inventory(self, rev_id):
2754
 
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
 
2305
        f = self.branch.repository.inventory_store.get(rev_id)
 
2306
        try:
 
2307
            old_inv_xml = f.read()
 
2308
        finally:
 
2309
            f.close()
2755
2310
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2756
2311
        inv.revision_id = rev_id
2757
2312
        rev = self.revisions[rev_id]
2813
2368
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2814
2369
            in heads)
2815
2370
        self.snapshot_ie(previous_entries, ie, w, rev_id)
2816
 
        del ie.text_id
2817
2371
 
2818
2372
    def get_parent_map(self, revision_ids):
2819
2373
        """See graph.StackedParentsProvider.get_parent_map"""
2835
2389
                ie.revision = previous_ie.revision
2836
2390
                return
2837
2391
        if ie.has_text():
2838
 
            text = self.branch.repository._text_store.get(ie.text_id)
2839
 
            file_lines = text.readlines()
 
2392
            f = self.branch.repository._text_store.get(ie.text_id)
 
2393
            try:
 
2394
                file_lines = f.readlines()
 
2395
            finally:
 
2396
                f.close()
2840
2397
            w.add_lines(rev_id, previous_revisions, file_lines)
2841
2398
            self.text_count += 1
2842
2399
        else:
2876
2433
        try:
2877
2434
            ui.ui_factory.note('starting upgrade from format 5 to 6')
2878
2435
            self._convert_to_prefixed()
2879
 
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2436
            return BzrDir.open(self.bzrdir.user_url)
2880
2437
        finally:
2881
2438
            pb.finished()
2882
2439
 
3004
2561
            BzrDirMetaFormat1().get_format_string(),
3005
2562
            mode=self.file_mode)
3006
2563
        self.pb.finished()
3007
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2564
        return BzrDir.open(self.bzrdir.user_url)
3008
2565
 
3009
2566
    def make_lock(self, name):
3010
2567
        """Make a lock for the new control dir name."""
3118
2675
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3119
2676
    """Format representing bzrdirs accessed via a smart server"""
3120
2677
 
 
2678
    supports_workingtrees = False
 
2679
 
3121
2680
    def __init__(self):
3122
2681
        BzrDirMetaFormat1.__init__(self)
3123
2682
        # XXX: It's a bit ugly that the network name is here, because we'd
3124
2683
        # like to believe that format objects are stateless or at least
3125
2684
        # immutable,  However, we do at least avoid mutating the name after
3126
 
        # it's returned.  See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
 
2685
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
3127
2686
        self._network_name = None
3128
2687
 
3129
2688
    def __repr__(self):
3132
2691
 
3133
2692
    def get_format_description(self):
3134
2693
        if self._network_name:
3135
 
            real_format = network_format_registry.get(self._network_name)
 
2694
            real_format = controldir.network_format_registry.get(self._network_name)
3136
2695
            return 'Remote: ' + real_format.get_format_description()
3137
2696
        return 'bzr remote bzrdir'
3138
2697
 
3145
2704
        else:
3146
2705
            raise AssertionError("No network name set.")
3147
2706
 
3148
 
    @classmethod
3149
 
    def probe_transport(klass, transport):
3150
 
        """Return a RemoteBzrDirFormat object if it looks possible."""
3151
 
        try:
3152
 
            medium = transport.get_smart_medium()
3153
 
        except (NotImplementedError, AttributeError,
3154
 
                errors.TransportNotPossible, errors.NoSmartMedium,
3155
 
                errors.SmartProtocolError):
3156
 
            # no smart server, so not a branch for this format type.
3157
 
            raise errors.NotBranchError(path=transport.base)
3158
 
        else:
3159
 
            # Decline to open it if the server doesn't support our required
3160
 
            # version (3) so that the VFS-based transport will do it.
3161
 
            if medium.should_probe():
3162
 
                try:
3163
 
                    server_version = medium.protocol_version()
3164
 
                except errors.SmartProtocolError:
3165
 
                    # Apparently there's no usable smart server there, even though
3166
 
                    # the medium supports the smart protocol.
3167
 
                    raise errors.NotBranchError(path=transport.base)
3168
 
                if server_version != '2':
3169
 
                    raise errors.NotBranchError(path=transport.base)
3170
 
            return klass()
3171
 
 
3172
2707
    def initialize_on_transport(self, transport):
3173
2708
        try:
3174
2709
            # hand off the request to the smart server
3373
2908
        BzrDirMetaFormat1._set_repository_format) #.im_func)
3374
2909
 
3375
2910
 
3376
 
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3377
 
 
3378
 
 
3379
 
class BzrDirFormatInfo(object):
3380
 
 
3381
 
    def __init__(self, native, deprecated, hidden, experimental):
3382
 
        self.deprecated = deprecated
3383
 
        self.native = native
3384
 
        self.hidden = hidden
3385
 
        self.experimental = experimental
3386
 
 
3387
 
 
3388
 
class BzrDirFormatRegistry(registry.Registry):
3389
 
    """Registry of user-selectable BzrDir subformats.
3390
 
 
3391
 
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3392
 
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
3393
 
    """
3394
 
 
3395
 
    def __init__(self):
3396
 
        """Create a BzrDirFormatRegistry."""
3397
 
        self._aliases = set()
3398
 
        self._registration_order = list()
3399
 
        super(BzrDirFormatRegistry, self).__init__()
3400
 
 
3401
 
    def aliases(self):
3402
 
        """Return a set of the format names which are aliases."""
3403
 
        return frozenset(self._aliases)
3404
 
 
3405
 
    def register_metadir(self, key,
3406
 
             repository_format, help, native=True, deprecated=False,
3407
 
             branch_format=None,
3408
 
             tree_format=None,
3409
 
             hidden=False,
3410
 
             experimental=False,
3411
 
             alias=False):
3412
 
        """Register a metadir subformat.
3413
 
 
3414
 
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3415
 
        by the Repository/Branch/WorkingTreeformats.
3416
 
 
3417
 
        :param repository_format: The fully-qualified repository format class
3418
 
            name as a string.
3419
 
        :param branch_format: Fully-qualified branch format class name as
3420
 
            a string.
3421
 
        :param tree_format: Fully-qualified tree format class name as
3422
 
            a string.
3423
 
        """
3424
 
        # This should be expanded to support setting WorkingTree and Branch
3425
 
        # formats, once BzrDirMetaFormat1 supports that.
3426
 
        def _load(full_name):
3427
 
            mod_name, factory_name = full_name.rsplit('.', 1)
3428
 
            try:
3429
 
                mod = __import__(mod_name, globals(), locals(),
3430
 
                        [factory_name])
3431
 
            except ImportError, e:
3432
 
                raise ImportError('failed to load %s: %s' % (full_name, e))
3433
 
            try:
3434
 
                factory = getattr(mod, factory_name)
3435
 
            except AttributeError:
3436
 
                raise AttributeError('no factory %s in module %r'
3437
 
                    % (full_name, mod))
3438
 
            return factory()
3439
 
 
3440
 
        def helper():
3441
 
            bd = BzrDirMetaFormat1()
3442
 
            if branch_format is not None:
3443
 
                bd.set_branch_format(_load(branch_format))
3444
 
            if tree_format is not None:
3445
 
                bd.workingtree_format = _load(tree_format)
3446
 
            if repository_format is not None:
3447
 
                bd.repository_format = _load(repository_format)
3448
 
            return bd
3449
 
        self.register(key, helper, help, native, deprecated, hidden,
3450
 
            experimental, alias)
3451
 
 
3452
 
    def register(self, key, factory, help, native=True, deprecated=False,
3453
 
                 hidden=False, experimental=False, alias=False):
3454
 
        """Register a BzrDirFormat factory.
3455
 
 
3456
 
        The factory must be a callable that takes one parameter: the key.
3457
 
        It must produce an instance of the BzrDirFormat when called.
3458
 
 
3459
 
        This function mainly exists to prevent the info object from being
3460
 
        supplied directly.
3461
 
        """
3462
 
        registry.Registry.register(self, key, factory, help,
3463
 
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
3464
 
        if alias:
3465
 
            self._aliases.add(key)
3466
 
        self._registration_order.append(key)
3467
 
 
3468
 
    def register_lazy(self, key, module_name, member_name, help, native=True,
3469
 
        deprecated=False, hidden=False, experimental=False, alias=False):
3470
 
        registry.Registry.register_lazy(self, key, module_name, member_name,
3471
 
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3472
 
        if alias:
3473
 
            self._aliases.add(key)
3474
 
        self._registration_order.append(key)
3475
 
 
3476
 
    def set_default(self, key):
3477
 
        """Set the 'default' key to be a clone of the supplied key.
3478
 
 
3479
 
        This method must be called once and only once.
3480
 
        """
3481
 
        registry.Registry.register(self, 'default', self.get(key),
3482
 
            self.get_help(key), info=self.get_info(key))
3483
 
        self._aliases.add('default')
3484
 
 
3485
 
    def set_default_repository(self, key):
3486
 
        """Set the FormatRegistry default and Repository default.
3487
 
 
3488
 
        This is a transitional method while Repository.set_default_format
3489
 
        is deprecated.
3490
 
        """
3491
 
        if 'default' in self:
3492
 
            self.remove('default')
3493
 
        self.set_default(key)
3494
 
        format = self.get('default')()
3495
 
 
3496
 
    def make_bzrdir(self, key):
3497
 
        return self.get(key)()
3498
 
 
3499
 
    def help_topic(self, topic):
3500
 
        output = ""
3501
 
        default_realkey = None
3502
 
        default_help = self.get_help('default')
3503
 
        help_pairs = []
3504
 
        for key in self._registration_order:
3505
 
            if key == 'default':
3506
 
                continue
3507
 
            help = self.get_help(key)
3508
 
            if help == default_help:
3509
 
                default_realkey = key
3510
 
            else:
3511
 
                help_pairs.append((key, help))
3512
 
 
3513
 
        def wrapped(key, help, info):
3514
 
            if info.native:
3515
 
                help = '(native) ' + help
3516
 
            return ':%s:\n%s\n\n' % (key,
3517
 
                textwrap.fill(help, initial_indent='    ',
3518
 
                    subsequent_indent='    ',
3519
 
                    break_long_words=False))
3520
 
        if default_realkey is not None:
3521
 
            output += wrapped(default_realkey, '(default) %s' % default_help,
3522
 
                              self.get_info('default'))
3523
 
        deprecated_pairs = []
3524
 
        experimental_pairs = []
3525
 
        for key, help in help_pairs:
3526
 
            info = self.get_info(key)
3527
 
            if info.hidden:
3528
 
                continue
3529
 
            elif info.deprecated:
3530
 
                deprecated_pairs.append((key, help))
3531
 
            elif info.experimental:
3532
 
                experimental_pairs.append((key, help))
3533
 
            else:
3534
 
                output += wrapped(key, help, info)
3535
 
        output += "\nSee :doc:`formats-help` for more about storage formats."
3536
 
        other_output = ""
3537
 
        if len(experimental_pairs) > 0:
3538
 
            other_output += "Experimental formats are shown below.\n\n"
3539
 
            for key, help in experimental_pairs:
3540
 
                info = self.get_info(key)
3541
 
                other_output += wrapped(key, help, info)
3542
 
        else:
3543
 
            other_output += \
3544
 
                "No experimental formats are available.\n\n"
3545
 
        if len(deprecated_pairs) > 0:
3546
 
            other_output += "\nDeprecated formats are shown below.\n\n"
3547
 
            for key, help in deprecated_pairs:
3548
 
                info = self.get_info(key)
3549
 
                other_output += wrapped(key, help, info)
3550
 
        else:
3551
 
            other_output += \
3552
 
                "\nNo deprecated formats are available.\n\n"
3553
 
        other_output += \
3554
 
                "\nSee :doc:`formats-help` for more about storage formats."
3555
 
 
3556
 
        if topic == 'other-formats':
3557
 
            return other_output
3558
 
        else:
3559
 
            return output
 
2911
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
3560
2912
 
3561
2913
 
3562
2914
class RepositoryAcquisitionPolicy(object):
3591
2943
            try:
3592
2944
                stack_on = urlutils.rebase_url(self._stack_on,
3593
2945
                    self._stack_on_pwd,
3594
 
                    branch.bzrdir.root_transport.base)
 
2946
                    branch.user_url)
3595
2947
            except errors.InvalidRebaseURLs:
3596
2948
                stack_on = self._get_full_stack_on()
3597
2949
        try:
3716
3068
        return self._repository, False
3717
3069
 
3718
3070
 
3719
 
# Please register new formats after old formats so that formats
3720
 
# appear in chronological order and format descriptions can build
3721
 
# on previous ones.
3722
 
format_registry = BzrDirFormatRegistry()
 
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
 
3723
3118
# The pre-0.8 formats have their repository format network name registered in
3724
3119
# repository.py. MetaDir formats have their repository format network name
3725
3120
# inferred from their disk format string.
3726
 
format_registry.register('weave', BzrDirFormat6,
 
3121
controldir.format_registry.register('weave', BzrDirFormat6,
3727
3122
    'Pre-0.8 format.  Slower than knit and does not'
3728
3123
    ' support checkouts or shared repositories.',
3729
3124
    hidden=True,
3730
3125
    deprecated=True)
3731
 
format_registry.register_metadir('metaweave',
 
3126
register_metadir(controldir.format_registry, 'metaweave',
3732
3127
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3733
3128
    'Transitional format in 0.8.  Slower than knit.',
3734
3129
    branch_format='bzrlib.branch.BzrBranchFormat5',
3735
3130
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3736
3131
    hidden=True,
3737
3132
    deprecated=True)
3738
 
format_registry.register_metadir('knit',
 
3133
register_metadir(controldir.format_registry, 'knit',
3739
3134
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3740
3135
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3741
3136
    branch_format='bzrlib.branch.BzrBranchFormat5',
3742
3137
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3743
3138
    hidden=True,
3744
3139
    deprecated=True)
3745
 
format_registry.register_metadir('dirstate',
 
3140
register_metadir(controldir.format_registry, 'dirstate',
3746
3141
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3747
3142
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3748
3143
        'above when accessed over the network.',
3752
3147
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3753
3148
    hidden=True,
3754
3149
    deprecated=True)
3755
 
format_registry.register_metadir('dirstate-tags',
 
3150
register_metadir(controldir.format_registry, 'dirstate-tags',
3756
3151
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3757
3152
    help='New in 0.15: Fast local operations and improved scaling for '
3758
3153
        'network operations. Additionally adds support for tags.'
3761
3156
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3762
3157
    hidden=True,
3763
3158
    deprecated=True)
3764
 
format_registry.register_metadir('rich-root',
 
3159
register_metadir(controldir.format_registry, 'rich-root',
3765
3160
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3766
3161
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3767
3162
        ' bzr < 1.0.',
3769
3164
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3770
3165
    hidden=True,
3771
3166
    deprecated=True)
3772
 
format_registry.register_metadir('dirstate-with-subtree',
 
3167
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
3773
3168
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3774
3169
    help='New in 0.15: Fast local operations and improved scaling for '
3775
3170
        'network operations. Additionally adds support for versioning nested '
3779
3174
    experimental=True,
3780
3175
    hidden=True,
3781
3176
    )
3782
 
format_registry.register_metadir('pack-0.92',
 
3177
register_metadir(controldir.format_registry, 'pack-0.92',
3783
3178
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3784
3179
    help='New in 0.92: Pack-based format with data compatible with '
3785
3180
        'dirstate-tags format repositories. Interoperates with '
3788
3183
    branch_format='bzrlib.branch.BzrBranchFormat6',
3789
3184
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3790
3185
    )
3791
 
format_registry.register_metadir('pack-0.92-subtree',
 
3186
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
3792
3187
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3793
3188
    help='New in 0.92: Pack-based format with data compatible with '
3794
3189
        'dirstate-with-subtree format repositories. Interoperates with '
3799
3194
    hidden=True,
3800
3195
    experimental=True,
3801
3196
    )
3802
 
format_registry.register_metadir('rich-root-pack',
 
3197
register_metadir(controldir.format_registry, 'rich-root-pack',
3803
3198
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3804
3199
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3805
3200
         '(needed for bzr-svn and bzr-git).',
3807
3202
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3808
3203
    hidden=True,
3809
3204
    )
3810
 
format_registry.register_metadir('1.6',
 
3205
register_metadir(controldir.format_registry, '1.6',
3811
3206
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3812
3207
    help='A format that allows a branch to indicate that there is another '
3813
3208
         '(stacked) repository that should be used to access data that is '
3816
3211
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3817
3212
    hidden=True,
3818
3213
    )
3819
 
format_registry.register_metadir('1.6.1-rich-root',
 
3214
register_metadir(controldir.format_registry, '1.6.1-rich-root',
3820
3215
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3821
3216
    help='A variant of 1.6 that supports rich-root data '
3822
3217
         '(needed for bzr-svn and bzr-git).',
3824
3219
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3825
3220
    hidden=True,
3826
3221
    )
3827
 
format_registry.register_metadir('1.9',
 
3222
register_metadir(controldir.format_registry, '1.9',
3828
3223
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3829
3224
    help='A repository format using B+tree indexes. These indexes '
3830
3225
         'are smaller in size, have smarter caching and provide faster '
3833
3228
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3834
3229
    hidden=True,
3835
3230
    )
3836
 
format_registry.register_metadir('1.9-rich-root',
 
3231
register_metadir(controldir.format_registry, '1.9-rich-root',
3837
3232
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3838
3233
    help='A variant of 1.9 that supports rich-root data '
3839
3234
         '(needed for bzr-svn and bzr-git).',
3841
3236
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3842
3237
    hidden=True,
3843
3238
    )
3844
 
format_registry.register_metadir('1.14',
 
3239
register_metadir(controldir.format_registry, '1.14',
3845
3240
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3846
3241
    help='A working-tree format that supports content filtering.',
3847
3242
    branch_format='bzrlib.branch.BzrBranchFormat7',
3848
3243
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3849
3244
    )
3850
 
format_registry.register_metadir('1.14-rich-root',
 
3245
register_metadir(controldir.format_registry, '1.14-rich-root',
3851
3246
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3852
3247
    help='A variant of 1.14 that supports rich-root data '
3853
3248
         '(needed for bzr-svn and bzr-git).',
3855
3250
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3856
3251
    )
3857
3252
# The following un-numbered 'development' formats should always just be aliases.
3858
 
format_registry.register_metadir('development-rich-root',
 
3253
register_metadir(controldir.format_registry, 'development-rich-root',
3859
3254
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3860
3255
    help='Current development format. Supports rich roots. Can convert data '
3861
3256
        'to and from rich-root-pack (and anything compatible with '
3869
3264
    alias=True,
3870
3265
    hidden=True,
3871
3266
    )
3872
 
format_registry.register_metadir('development-subtree',
 
3267
register_metadir(controldir.format_registry, 'development5-subtree',
3873
3268
    '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',
3874
3285
    help='Current development format, subtree variant. Can convert data to and '
3875
3286
        'from pack-0.92-subtree (and anything compatible with '
3876
3287
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3887
3298
    )
3888
3299
 
3889
3300
# And the development formats above will have aliased one of the following:
3890
 
format_registry.register_metadir('development6-rich-root',
 
3301
register_metadir(controldir.format_registry, 'development6-rich-root',
3891
3302
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3892
3303
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3893
3304
        'Please read '
3899
3310
    experimental=True,
3900
3311
    )
3901
3312
 
3902
 
format_registry.register_metadir('development7-rich-root',
 
3313
register_metadir(controldir.format_registry, 'development7-rich-root',
3903
3314
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3904
3315
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3905
3316
        'rich roots. Please read '
3911
3322
    experimental=True,
3912
3323
    )
3913
3324
 
3914
 
format_registry.register_metadir('2a',
 
3325
register_metadir(controldir.format_registry, '2a',
3915
3326
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3916
3327
    help='First format for bzr 2.0 series.\n'
3917
3328
        'Uses group-compress storage.\n'
3920
3331
        # 'rich roots. Supported by bzr 1.16 and later.',
3921
3332
    branch_format='bzrlib.branch.BzrBranchFormat7',
3922
3333
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3923
 
    experimental=True,
 
3334
    experimental=False,
3924
3335
    )
3925
3336
 
3926
3337
# The following format should be an alias for the rich root equivalent 
3927
3338
# of the default format
3928
 
format_registry.register_metadir('default-rich-root',
 
3339
register_metadir(controldir.format_registry, 'default-rich-root',
3929
3340
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3930
3341
    branch_format='bzrlib.branch.BzrBranchFormat7',
3931
3342
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3934
3345
    help='Same as 2a.')
3935
3346
 
3936
3347
# The current format that is made on 'bzr init'.
3937
 
format_registry.set_default('2a')
 
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