~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

(gz) Backslash escape selftest output when printing to non-unicode consoles
 (Martin [gz])

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
29
29
 
30
30
import os
31
31
import sys
 
32
import warnings
32
33
 
33
34
from bzrlib.lazy_import import lazy_import
34
35
lazy_import(globals(), """
35
36
from stat import S_ISDIR
36
 
import textwrap
37
37
 
38
38
import bzrlib
39
39
from bzrlib import (
40
40
    branch,
41
41
    config,
 
42
    controldir,
42
43
    errors,
43
44
    graph,
44
45
    lockable_files,
45
46
    lockdir,
46
47
    osutils,
 
48
    pyutils,
47
49
    remote,
48
50
    repository,
49
51
    revision as _mod_revision,
85
87
    registry,
86
88
    symbol_versioning,
87
89
    )
88
 
 
89
 
 
90
 
class BzrDir(object):
 
90
from bzrlib.symbol_versioning import (
 
91
    deprecated_in,
 
92
    deprecated_method,
 
93
    )
 
94
 
 
95
 
 
96
class BzrDir(controldir.ControlDir):
91
97
    """A .bzr control diretory.
92
98
 
93
99
    BzrDir instances let you create or open any of the things that can be
124
130
                    return
125
131
        thing_to_unlock.break_lock()
126
132
 
127
 
    def can_convert_format(self):
128
 
        """Return true if this bzrdir is one whose format we can convert from."""
129
 
        return True
130
 
 
131
133
    def check_conversion_target(self, target_format):
132
134
        """Check that a bzrdir as a whole can be converted to a new format."""
133
135
        # The only current restriction is that the repository content can be 
168
170
                format.get_format_description(),
169
171
                basedir)
170
172
 
171
 
    def clone(self, url, revision_id=None, force_new_repo=False,
172
 
              preserve_stacking=False):
173
 
        """Clone this bzrdir and its contents to url verbatim.
174
 
 
175
 
        :param url: The url create the clone at.  If url's last component does
176
 
            not exist, it will be created.
177
 
        :param revision_id: The tip revision-id to use for any branch or
178
 
            working tree.  If not None, then the clone operation may tune
179
 
            itself to download less data.
180
 
        :param force_new_repo: Do not use a shared repository for the target
181
 
                               even if one is available.
182
 
        :param preserve_stacking: When cloning a stacked branch, stack the
183
 
            new branch on top of the other branch's stacked-on branch.
184
 
        """
185
 
        return self.clone_on_transport(get_transport(url),
186
 
                                       revision_id=revision_id,
187
 
                                       force_new_repo=force_new_repo,
188
 
                                       preserve_stacking=preserve_stacking)
189
 
 
190
173
    def clone_on_transport(self, transport, revision_id=None,
191
174
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
192
 
        create_prefix=False, use_existing_dir=True):
 
175
        create_prefix=False, use_existing_dir=True, no_tree=False):
193
176
        """Clone this bzrdir and its contents to transport verbatim.
194
177
 
195
178
        :param transport: The transport for the location to produce the clone
207
190
        """
208
191
        # Overview: put together a broad description of what we want to end up
209
192
        # with; then make as few api calls as possible to do it.
210
 
        
 
193
 
211
194
        # We may want to create a repo/branch/tree, if we do so what format
212
195
        # would we want for each:
213
196
        require_stacking = (stacked_on is not None)
214
197
        format = self.cloning_metadir(require_stacking)
215
 
        
 
198
 
216
199
        # Figure out what objects we want:
217
200
        try:
218
201
            local_repo = self.find_repository()
237
220
        # we should look up the policy needs first, or just use it as a hint,
238
221
        # or something.
239
222
        if local_repo:
240
 
            make_working_trees = local_repo.make_working_trees()
 
223
            make_working_trees = local_repo.make_working_trees() and not no_tree
241
224
            want_shared = local_repo.is_shared()
242
225
            repo_format_name = format.repository_format.network_name()
243
226
        else:
260
243
                # copied, and finally if we are copying up to a specific
261
244
                # revision_id then we can use the pending-ancestry-result which
262
245
                # does not require traversing all of history to describe it.
263
 
                if (result_repo.bzrdir.root_transport.base ==
264
 
                    result.root_transport.base and not require_stacking and
 
246
                if (result_repo.user_url == result.user_url
 
247
                    and not require_stacking and
265
248
                    revision_id is not None):
266
249
                    fetch_spec = graph.PendingAncestryResult(
267
250
                        [revision_id], local_repo)
295
278
        t = get_transport(url)
296
279
        t.ensure_base()
297
280
 
298
 
    @classmethod
299
 
    def create(cls, base, format=None, possible_transports=None):
300
 
        """Create a new BzrDir at the url 'base'.
301
 
 
302
 
        :param format: If supplied, the format of branch to create.  If not
303
 
            supplied, the default is used.
304
 
        :param possible_transports: If supplied, a list of transports that
305
 
            can be reused to share a remote connection.
306
 
        """
307
 
        if cls is not BzrDir:
308
 
            raise AssertionError("BzrDir.create always creates the default"
309
 
                " format, not one of %r" % cls)
310
 
        t = get_transport(base, possible_transports)
311
 
        t.ensure_base()
312
 
        if format is None:
313
 
            format = BzrDirFormat.get_default_format()
314
 
        return format.initialize_on_transport(t)
315
 
 
316
281
    @staticmethod
317
282
    def find_bzrdirs(transport, evaluate=None, list_current=None):
318
283
        """Find bzrdirs recursively from current location.
341
306
            recurse = True
342
307
            try:
343
308
                bzrdir = BzrDir.open_from_transport(current_transport)
344
 
            except errors.NotBranchError:
 
309
            except (errors.NotBranchError, errors.PermissionDenied):
345
310
                pass
346
311
            else:
347
312
                recurse, value = evaluate(bzrdir)
348
313
                yield value
349
314
            try:
350
315
                subdirs = list_current(current_transport)
351
 
            except errors.NoSuchFile:
 
316
            except (errors.NoSuchFile, errors.PermissionDenied):
352
317
                continue
353
318
            if recurse:
354
319
                for subdir in sorted(subdirs, reverse=True):
371
336
            except errors.NoRepositoryPresent:
372
337
                pass
373
338
            else:
374
 
                return False, (None, repository)
375
 
            try:
376
 
                branch = bzrdir.open_branch()
377
 
            except errors.NotBranchError:
378
 
                return True, (None, None)
379
 
            else:
380
 
                return True, (branch, None)
381
 
        branches = []
382
 
        for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
 
339
                return False, ([], repository)
 
340
            return True, (bzrdir.list_branches(), None)
 
341
        ret = []
 
342
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
343
                                                  evaluate=evaluate):
383
344
            if repo is not None:
384
 
                branches.extend(repo.find_branches())
385
 
            if branch is not None:
386
 
                branches.append(branch)
387
 
        return branches
388
 
 
389
 
    def destroy_repository(self):
390
 
        """Destroy the repository in this BzrDir"""
391
 
        raise NotImplementedError(self.destroy_repository)
392
 
 
393
 
    def create_branch(self):
394
 
        """Create a branch in this BzrDir.
395
 
 
396
 
        The bzrdir's format will control what branch format is created.
397
 
        For more control see BranchFormatXX.create(a_bzrdir).
398
 
        """
399
 
        raise NotImplementedError(self.create_branch)
400
 
 
401
 
    def destroy_branch(self):
402
 
        """Destroy the branch in this BzrDir"""
403
 
        raise NotImplementedError(self.destroy_branch)
 
345
                ret.extend(repo.find_branches())
 
346
            if branches is not None:
 
347
                ret.extend(branches)
 
348
        return ret
404
349
 
405
350
    @staticmethod
406
351
    def create_branch_and_repo(base, force_new_repo=False, format=None):
445
390
            stop = False
446
391
            stack_on = config.get_default_stack_on()
447
392
            if stack_on is not None:
448
 
                stack_on_pwd = found_bzrdir.root_transport.base
 
393
                stack_on_pwd = found_bzrdir.user_url
449
394
                stop = True
450
395
            # does it have a repository ?
451
396
            try:
453
398
            except errors.NoRepositoryPresent:
454
399
                repository = None
455
400
            else:
456
 
                if ((found_bzrdir.root_transport.base !=
457
 
                     self.root_transport.base) and not repository.is_shared()):
 
401
                if (found_bzrdir.user_url != self.user_url 
 
402
                    and not repository.is_shared()):
458
403
                    # Don't look higher, can't use a higher shared repo.
459
404
                    repository = None
460
405
                    stop = True
556
501
                                               format=format).bzrdir
557
502
        return bzrdir.create_workingtree()
558
503
 
559
 
    def create_workingtree(self, revision_id=None, from_branch=None,
560
 
        accelerator_tree=None, hardlink=False):
561
 
        """Create a working tree at this BzrDir.
562
 
 
563
 
        :param revision_id: create it as of this revision id.
564
 
        :param from_branch: override bzrdir branch (for lightweight checkouts)
565
 
        :param accelerator_tree: A tree which can be used for retrieving file
566
 
            contents more quickly than the revision tree, i.e. a workingtree.
567
 
            The revision tree will be used for cases where accelerator_tree's
568
 
            content is different.
 
504
    @deprecated_method(deprecated_in((2, 3, 0)))
 
505
    def generate_backup_name(self, base):
 
506
        return self._available_backup_name(base)
 
507
 
 
508
    def _available_backup_name(self, base):
 
509
        """Find a non-existing backup file name based on base.
 
510
 
 
511
        See bzrlib.osutils.available_backup_name about race conditions.
569
512
        """
570
 
        raise NotImplementedError(self.create_workingtree)
 
513
        return osutils.available_backup_name(base, self.root_transport.has)
571
514
 
572
515
    def backup_bzrdir(self):
573
516
        """Backup this bzr control directory.
574
517
 
575
518
        :return: Tuple with old path name and new path name
576
519
        """
 
520
 
577
521
        pb = ui.ui_factory.nested_progress_bar()
578
522
        try:
579
 
            # FIXME: bug 300001 -- the backup fails if the backup directory
580
 
            # already exists, but it should instead either remove it or make
581
 
            # a new backup directory.
582
 
            #
583
 
            # FIXME: bug 262450 -- the backup directory should have the same
584
 
            # permissions as the .bzr directory (probably a bug in copy_tree)
585
523
            old_path = self.root_transport.abspath('.bzr')
586
 
            new_path = self.root_transport.abspath('backup.bzr')
587
 
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
588
 
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
524
            backup_dir = self._available_backup_name('backup.bzr')
 
525
            new_path = self.root_transport.abspath(backup_dir)
 
526
            ui.ui_factory.note('making backup of %s\n  to %s'
 
527
                               % (old_path, new_path,))
 
528
            self.root_transport.copy_tree('.bzr', backup_dir)
589
529
            return (old_path, new_path)
590
530
        finally:
591
531
            pb.finished()
615
555
                else:
616
556
                    pass
617
557
 
618
 
    def destroy_workingtree(self):
619
 
        """Destroy the working tree at this BzrDir.
620
 
 
621
 
        Formats that do not support this may raise UnsupportedOperation.
622
 
        """
623
 
        raise NotImplementedError(self.destroy_workingtree)
624
 
 
625
 
    def destroy_workingtree_metadata(self):
626
 
        """Destroy the control files for the working tree at this BzrDir.
627
 
 
628
 
        The contents of working tree files are not affected.
629
 
        Formats that do not support this may raise UnsupportedOperation.
630
 
        """
631
 
        raise NotImplementedError(self.destroy_workingtree_metadata)
632
 
 
633
558
    def _find_containing(self, evaluate):
634
559
        """Find something in a containing control directory.
635
560
 
649
574
            if stop:
650
575
                return result
651
576
            next_transport = found_bzrdir.root_transport.clone('..')
652
 
            if (found_bzrdir.root_transport.base == next_transport.base):
 
577
            if (found_bzrdir.user_url == next_transport.base):
653
578
                # top of the file system
654
579
                return None
655
580
            # find the next containing bzrdir
672
597
                repository = found_bzrdir.open_repository()
673
598
            except errors.NoRepositoryPresent:
674
599
                return None, False
675
 
            if found_bzrdir.root_transport.base == self.root_transport.base:
 
600
            if found_bzrdir.user_url == self.user_url:
676
601
                return repository, True
677
602
            elif repository.is_shared():
678
603
                return repository, True
684
609
            raise errors.NoRepositoryPresent(self)
685
610
        return found_repo
686
611
 
687
 
    def get_branch_reference(self):
688
 
        """Return the referenced URL for the branch in this bzrdir.
689
 
 
690
 
        :raises NotBranchError: If there is no Branch.
691
 
        :return: The URL the branch in this bzrdir references if it is a
692
 
            reference branch, or None for regular branches.
693
 
        """
694
 
        return None
695
 
 
696
 
    def get_branch_transport(self, branch_format):
697
 
        """Get the transport for use by branch format in this BzrDir.
698
 
 
699
 
        Note that bzr dirs that do not support format strings will raise
700
 
        IncompatibleFormat if the branch format they are given has
701
 
        a format string, and vice versa.
702
 
 
703
 
        If branch_format is None, the transport is returned with no
704
 
        checking. If it is not None, then the returned transport is
705
 
        guaranteed to point to an existing directory ready for use.
706
 
        """
707
 
        raise NotImplementedError(self.get_branch_transport)
708
 
 
709
612
    def _find_creation_modes(self):
710
613
        """Determine the appropriate modes for files and directories.
711
614
 
750
653
            self._find_creation_modes()
751
654
        return self._dir_mode
752
655
 
753
 
    def get_repository_transport(self, repository_format):
754
 
        """Get the transport for use by repository format in this BzrDir.
755
 
 
756
 
        Note that bzr dirs that do not support format strings will raise
757
 
        IncompatibleFormat if the repository format they are given has
758
 
        a format string, and vice versa.
759
 
 
760
 
        If repository_format is None, the transport is returned with no
761
 
        checking. If it is not None, then the returned transport is
762
 
        guaranteed to point to an existing directory ready for use.
763
 
        """
764
 
        raise NotImplementedError(self.get_repository_transport)
765
 
 
766
 
    def get_workingtree_transport(self, tree_format):
767
 
        """Get the transport for use by workingtree format in this BzrDir.
768
 
 
769
 
        Note that bzr dirs that do not support format strings will raise
770
 
        IncompatibleFormat if the workingtree format they are given has a
771
 
        format string, and vice versa.
772
 
 
773
 
        If workingtree_format is None, the transport is returned with no
774
 
        checking. If it is not None, then the returned transport is
775
 
        guaranteed to point to an existing directory ready for use.
776
 
        """
777
 
        raise NotImplementedError(self.get_workingtree_transport)
778
 
 
779
656
    def get_config(self):
780
657
        """Get configuration for this BzrDir."""
781
658
        return config.BzrDirConfig(self)
794
671
        :param _transport: the transport this dir is based at.
795
672
        """
796
673
        self._format = _format
 
674
        # these are also under the more standard names of 
 
675
        # control_transport and user_transport
797
676
        self.transport = _transport.clone('.bzr')
798
677
        self.root_transport = _transport
799
678
        self._mode_check_done = False
800
679
 
 
680
    @property 
 
681
    def user_transport(self):
 
682
        return self.root_transport
 
683
 
 
684
    @property
 
685
    def control_transport(self):
 
686
        return self.transport
 
687
 
801
688
    def is_control_filename(self, filename):
802
689
        """True if filename is the name of a path which is reserved for bzrdir's.
803
690
 
805
692
 
806
693
        This is true IF and ONLY IF the filename is part of the namespace reserved
807
694
        for bzr control dirs. Currently this is the '.bzr' directory in the root
808
 
        of the root_transport. it is expected that plugins will need to extend
809
 
        this in the future - for instance to make bzr talk with svn working
810
 
        trees.
 
695
        of the root_transport. 
811
696
        """
812
697
        # this might be better on the BzrDirFormat class because it refers to
813
698
        # all the possible bzrdir disk formats.
817
702
        # add new tests for it to the appropriate place.
818
703
        return filename == '.bzr' or filename.startswith('.bzr/')
819
704
 
820
 
    def needs_format_conversion(self, format=None):
821
 
        """Return true if this bzrdir needs convert_format run on it.
822
 
 
823
 
        For instance, if the repository format is out of date but the
824
 
        branch and working tree are not, this should return True.
825
 
 
826
 
        :param format: Optional parameter indicating a specific desired
827
 
                       format we plan to arrive at.
828
 
        """
829
 
        raise NotImplementedError(self.needs_format_conversion)
830
 
 
831
705
    @staticmethod
832
706
    def open_unsupported(base):
833
707
        """Open a branch which is not supported."""
856
730
        # the redirections.
857
731
        base = transport.base
858
732
        def find_format(transport):
859
 
            return transport, BzrDirFormat.find_format(
 
733
            return transport, controldir.ControlDirFormat.find_format(
860
734
                transport, _server_formats=_server_formats)
861
735
 
862
736
        def redirected(transport, e, redirection_notice):
877
751
        BzrDir._check_supported(format, _unsupported)
878
752
        return format.open(transport, _found=True)
879
753
 
880
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
881
 
        """Open the branch object at this BzrDir if one is present.
882
 
 
883
 
        If unsupported is True, then no longer supported branch formats can
884
 
        still be opened.
885
 
 
886
 
        TODO: static convenience version of this?
887
 
        """
888
 
        raise NotImplementedError(self.open_branch)
889
 
 
890
754
    @staticmethod
891
755
    def open_containing(url, possible_transports=None):
892
756
        """Open an existing branch which contains url.
930
794
                raise errors.NotBranchError(path=url)
931
795
            a_transport = new_t
932
796
 
933
 
    def _get_tree_branch(self):
934
 
        """Return the branch and tree, if any, for this bzrdir.
935
 
 
936
 
        Return None for tree if not present or inaccessible.
937
 
        Raise NotBranchError if no branch is present.
938
 
        :return: (tree, branch)
939
 
        """
940
 
        try:
941
 
            tree = self.open_workingtree()
942
 
        except (errors.NoWorkingTree, errors.NotLocalUrl):
943
 
            tree = None
944
 
            branch = self.open_branch()
945
 
        else:
946
 
            branch = tree.branch
947
 
        return tree, branch
948
 
 
949
797
    @classmethod
950
798
    def open_tree_or_branch(klass, location):
951
799
        """Return the branch and working tree at a location.
997
845
                raise errors.NotBranchError(location)
998
846
        return tree, branch, branch.repository, relpath
999
847
 
1000
 
    def open_repository(self, _unsupported=False):
1001
 
        """Open the repository object at this BzrDir if one is present.
1002
 
 
1003
 
        This will not follow the Branch object pointer - it's strictly a direct
1004
 
        open facility. Most client code should use open_branch().repository to
1005
 
        get at a repository.
1006
 
 
1007
 
        :param _unsupported: a private parameter, not part of the api.
1008
 
        TODO: static convenience version of this?
1009
 
        """
1010
 
        raise NotImplementedError(self.open_repository)
1011
 
 
1012
 
    def open_workingtree(self, _unsupported=False,
1013
 
                         recommend_upgrade=True, from_branch=None):
1014
 
        """Open the workingtree object at this BzrDir if one is present.
1015
 
 
1016
 
        :param recommend_upgrade: Optional keyword parameter, when True (the
1017
 
            default), emit through the ui module a recommendation that the user
1018
 
            upgrade the working tree when the workingtree being opened is old
1019
 
            (but still fully supported).
1020
 
        :param from_branch: override bzrdir branch (for lightweight checkouts)
1021
 
        """
1022
 
        raise NotImplementedError(self.open_workingtree)
1023
 
 
1024
 
    def has_branch(self):
1025
 
        """Tell if this bzrdir contains a branch.
1026
 
 
1027
 
        Note: if you're going to open the branch, you should just go ahead
1028
 
        and try, and not ask permission first.  (This method just opens the
1029
 
        branch and discards it, and that's somewhat expensive.)
1030
 
        """
1031
 
        try:
1032
 
            self.open_branch()
1033
 
            return True
1034
 
        except errors.NotBranchError:
1035
 
            return False
1036
 
 
1037
 
    def has_workingtree(self):
1038
 
        """Tell if this bzrdir contains a working tree.
1039
 
 
1040
 
        This will still raise an exception if the bzrdir has a workingtree that
1041
 
        is remote & inaccessible.
1042
 
 
1043
 
        Note: if you're going to open the working tree, you should just go ahead
1044
 
        and try, and not ask permission first.  (This method just opens the
1045
 
        workingtree and discards it, and that's somewhat expensive.)
1046
 
        """
1047
 
        try:
1048
 
            self.open_workingtree(recommend_upgrade=False)
1049
 
            return True
1050
 
        except errors.NoWorkingTree:
1051
 
            return False
1052
 
 
1053
848
    def _cloning_metadir(self):
1054
849
        """Produce a metadir suitable for cloning with.
1055
850
 
1113
908
            format.require_stacking()
1114
909
        return format
1115
910
 
1116
 
    def checkout_metadir(self):
1117
 
        return self.cloning_metadir()
1118
 
 
1119
 
    def sprout(self, url, revision_id=None, force_new_repo=False,
1120
 
               recurse='down', possible_transports=None,
1121
 
               accelerator_tree=None, hardlink=False, stacked=False,
1122
 
               source_branch=None, create_tree_if_local=True):
1123
 
        """Create a copy of this bzrdir prepared for use as a new line of
1124
 
        development.
1125
 
 
1126
 
        If url's last component does not exist, it will be created.
1127
 
 
1128
 
        Attributes related to the identity of the source branch like
1129
 
        branch nickname will be cleaned, a working tree is created
1130
 
        whether one existed before or not; and a local branch is always
1131
 
        created.
1132
 
 
1133
 
        if revision_id is not None, then the clone operation may tune
1134
 
            itself to download less data.
1135
 
        :param accelerator_tree: A tree which can be used for retrieving file
1136
 
            contents more quickly than the revision tree, i.e. a workingtree.
1137
 
            The revision tree will be used for cases where accelerator_tree's
1138
 
            content is different.
1139
 
        :param hardlink: If true, hard-link files from accelerator_tree,
1140
 
            where possible.
1141
 
        :param stacked: If true, create a stacked branch referring to the
1142
 
            location of this control directory.
1143
 
        :param create_tree_if_local: If true, a working-tree will be created
1144
 
            when working locally.
 
911
    @classmethod
 
912
    def create(cls, base, format=None, possible_transports=None):
 
913
        """Create a new BzrDir at the url 'base'.
 
914
 
 
915
        :param format: If supplied, the format of branch to create.  If not
 
916
            supplied, the default is used.
 
917
        :param possible_transports: If supplied, a list of transports that
 
918
            can be reused to share a remote connection.
1145
919
        """
1146
 
        target_transport = get_transport(url, possible_transports)
1147
 
        target_transport.ensure_base()
1148
 
        cloning_format = self.cloning_metadir(stacked)
1149
 
        # Create/update the result branch
1150
 
        result = cloning_format.initialize_on_transport(target_transport)
1151
 
        # if a stacked branch wasn't requested, we don't create one
1152
 
        # even if the origin was stacked
1153
 
        stacked_branch_url = None
1154
 
        if source_branch is not None:
1155
 
            if stacked:
1156
 
                stacked_branch_url = self.root_transport.base
1157
 
            source_repository = source_branch.repository
1158
 
        else:
1159
 
            try:
1160
 
                source_branch = self.open_branch()
1161
 
                source_repository = source_branch.repository
1162
 
                if stacked:
1163
 
                    stacked_branch_url = self.root_transport.base
1164
 
            except errors.NotBranchError:
1165
 
                source_branch = None
1166
 
                try:
1167
 
                    source_repository = self.open_repository()
1168
 
                except errors.NoRepositoryPresent:
1169
 
                    source_repository = None
1170
 
        repository_policy = result.determine_repository_policy(
1171
 
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1172
 
        result_repo, is_new_repo = repository_policy.acquire_repository()
1173
 
        if is_new_repo and revision_id is not None and not stacked:
1174
 
            fetch_spec = graph.PendingAncestryResult(
1175
 
                [revision_id], source_repository)
1176
 
        else:
1177
 
            fetch_spec = None
1178
 
        if source_repository is not None:
1179
 
            # Fetch while stacked to prevent unstacked fetch from
1180
 
            # Branch.sprout.
1181
 
            if fetch_spec is None:
1182
 
                result_repo.fetch(source_repository, revision_id=revision_id)
1183
 
            else:
1184
 
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1185
 
 
1186
 
        if source_branch is None:
1187
 
            # this is for sprouting a bzrdir without a branch; is that
1188
 
            # actually useful?
1189
 
            # Not especially, but it's part of the contract.
1190
 
            result_branch = result.create_branch()
1191
 
        else:
1192
 
            result_branch = source_branch.sprout(result,
1193
 
                revision_id=revision_id, repository_policy=repository_policy)
1194
 
        mutter("created new branch %r" % (result_branch,))
1195
 
 
1196
 
        # Create/update the result working tree
1197
 
        if (create_tree_if_local and
1198
 
            isinstance(target_transport, local.LocalTransport) and
1199
 
            (result_repo is None or result_repo.make_working_trees())):
1200
 
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1201
 
                hardlink=hardlink)
1202
 
            wt.lock_write()
1203
 
            try:
1204
 
                if wt.path2id('') is None:
1205
 
                    try:
1206
 
                        wt.set_root_id(self.open_workingtree.get_root_id())
1207
 
                    except errors.NoWorkingTree:
1208
 
                        pass
1209
 
            finally:
1210
 
                wt.unlock()
1211
 
        else:
1212
 
            wt = None
1213
 
        if recurse == 'down':
1214
 
            if wt is not None:
1215
 
                basis = wt.basis_tree()
1216
 
                basis.lock_read()
1217
 
                subtrees = basis.iter_references()
1218
 
            elif result_branch is not None:
1219
 
                basis = result_branch.basis_tree()
1220
 
                basis.lock_read()
1221
 
                subtrees = basis.iter_references()
1222
 
            elif source_branch is not None:
1223
 
                basis = source_branch.basis_tree()
1224
 
                basis.lock_read()
1225
 
                subtrees = basis.iter_references()
1226
 
            else:
1227
 
                subtrees = []
1228
 
                basis = None
1229
 
            try:
1230
 
                for path, file_id in subtrees:
1231
 
                    target = urlutils.join(url, urlutils.escape(path))
1232
 
                    sublocation = source_branch.reference_parent(file_id, path)
1233
 
                    sublocation.bzrdir.sprout(target,
1234
 
                        basis.get_reference_revision(file_id, path),
1235
 
                        force_new_repo=force_new_repo, recurse=recurse,
1236
 
                        stacked=stacked)
1237
 
            finally:
1238
 
                if basis is not None:
1239
 
                    basis.unlock()
1240
 
        return result
1241
 
 
1242
 
    def push_branch(self, source, revision_id=None, overwrite=False, 
1243
 
        remember=False, create_prefix=False):
1244
 
        """Push the source branch into this BzrDir."""
1245
 
        br_to = None
1246
 
        # If we can open a branch, use its direct repository, otherwise see
1247
 
        # if there is a repository without a branch.
1248
 
        try:
1249
 
            br_to = self.open_branch()
1250
 
        except errors.NotBranchError:
1251
 
            # Didn't find a branch, can we find a repository?
1252
 
            repository_to = self.find_repository()
1253
 
        else:
1254
 
            # Found a branch, so we must have found a repository
1255
 
            repository_to = br_to.repository
1256
 
 
1257
 
        push_result = PushResult()
1258
 
        push_result.source_branch = source
1259
 
        if br_to is None:
1260
 
            # We have a repository but no branch, copy the revisions, and then
1261
 
            # create a branch.
1262
 
            repository_to.fetch(source.repository, revision_id=revision_id)
1263
 
            br_to = source.clone(self, revision_id=revision_id)
1264
 
            if source.get_push_location() is None or remember:
1265
 
                source.set_push_location(br_to.base)
1266
 
            push_result.stacked_on = None
1267
 
            push_result.branch_push_result = None
1268
 
            push_result.old_revno = None
1269
 
            push_result.old_revid = _mod_revision.NULL_REVISION
1270
 
            push_result.target_branch = br_to
1271
 
            push_result.master_branch = None
1272
 
            push_result.workingtree_updated = False
1273
 
        else:
1274
 
            # We have successfully opened the branch, remember if necessary:
1275
 
            if source.get_push_location() is None or remember:
1276
 
                source.set_push_location(br_to.base)
1277
 
            try:
1278
 
                tree_to = self.open_workingtree()
1279
 
            except errors.NotLocalUrl:
1280
 
                push_result.branch_push_result = source.push(br_to, 
1281
 
                    overwrite, stop_revision=revision_id)
1282
 
                push_result.workingtree_updated = False
1283
 
            except errors.NoWorkingTree:
1284
 
                push_result.branch_push_result = source.push(br_to,
1285
 
                    overwrite, stop_revision=revision_id)
1286
 
                push_result.workingtree_updated = None # Not applicable
1287
 
            else:
1288
 
                tree_to.lock_write()
1289
 
                try:
1290
 
                    push_result.branch_push_result = source.push(
1291
 
                        tree_to.branch, overwrite, stop_revision=revision_id)
1292
 
                    tree_to.update()
1293
 
                finally:
1294
 
                    tree_to.unlock()
1295
 
                push_result.workingtree_updated = True
1296
 
            push_result.old_revno = push_result.branch_push_result.old_revno
1297
 
            push_result.old_revid = push_result.branch_push_result.old_revid
1298
 
            push_result.target_branch = \
1299
 
                push_result.branch_push_result.target_branch
1300
 
        return push_result
 
920
        if cls is not BzrDir:
 
921
            raise AssertionError("BzrDir.create always creates the"
 
922
                "default format, not one of %r" % cls)
 
923
        t = get_transport(base, possible_transports)
 
924
        t.ensure_base()
 
925
        if format is None:
 
926
            format = controldir.ControlDirFormat.get_default_format()
 
927
        return format.initialize_on_transport(t)
 
928
 
1301
929
 
1302
930
 
1303
931
class BzrDirHooks(hooks.Hooks):
1309
937
        self.create_hook(hooks.HookPoint('pre_open',
1310
938
            "Invoked before attempting to open a BzrDir with the transport "
1311
939
            "that the open will use.", (1, 14), None))
 
940
        self.create_hook(hooks.HookPoint('post_repo_init',
 
941
            "Invoked after a repository has been initialized. "
 
942
            "post_repo_init is called with a "
 
943
            "bzrlib.bzrdir.RepoInitHookParams.",
 
944
            (2, 2), None))
1312
945
 
1313
946
# install the default hooks
1314
947
BzrDir.hooks = BzrDirHooks()
1315
948
 
1316
949
 
 
950
class RepoInitHookParams(object):
 
951
    """Object holding parameters passed to *_repo_init hooks.
 
952
 
 
953
    There are 4 fields that hooks may wish to access:
 
954
 
 
955
    :ivar repository: Repository created
 
956
    :ivar format: Repository format
 
957
    :ivar bzrdir: The bzrdir for the repository
 
958
    :ivar shared: The repository is shared
 
959
    """
 
960
 
 
961
    def __init__(self, repository, format, a_bzrdir, shared):
 
962
        """Create a group of RepoInitHook parameters.
 
963
 
 
964
        :param repository: Repository created
 
965
        :param format: Repository format
 
966
        :param bzrdir: The bzrdir for the repository
 
967
        :param shared: The repository is shared
 
968
        """
 
969
        self.repository = repository
 
970
        self.format = format
 
971
        self.bzrdir = a_bzrdir
 
972
        self.shared = shared
 
973
 
 
974
    def __eq__(self, other):
 
975
        return self.__dict__ == other.__dict__
 
976
 
 
977
    def __repr__(self):
 
978
        if self.repository:
 
979
            return "<%s for %s>" % (self.__class__.__name__,
 
980
                self.repository)
 
981
        else:
 
982
            return "<%s for %s>" % (self.__class__.__name__,
 
983
                self.bzrdir)
 
984
 
 
985
 
1317
986
class BzrDirPreSplitOut(BzrDir):
1318
987
    """A common class for the all-in-one formats."""
1319
988
 
1332
1001
    def cloning_metadir(self, require_stacking=False):
1333
1002
        """Produce a metadir suitable for cloning with."""
1334
1003
        if require_stacking:
1335
 
            return format_registry.make_bzrdir('1.6')
 
1004
            return controldir.format_registry.make_bzrdir('1.6')
1336
1005
        return self._format.__class__()
1337
1006
 
1338
1007
    def clone(self, url, revision_id=None, force_new_repo=False,
1358
1027
            tree.clone(result)
1359
1028
        return result
1360
1029
 
1361
 
    def create_branch(self):
 
1030
    def create_branch(self, name=None):
1362
1031
        """See BzrDir.create_branch."""
1363
 
        return self._format.get_branch_format().initialize(self)
 
1032
        return self._format.get_branch_format().initialize(self, name=name)
1364
1033
 
1365
 
    def destroy_branch(self):
 
1034
    def destroy_branch(self, name=None):
1366
1035
        """See BzrDir.destroy_branch."""
1367
1036
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1368
1037
 
1424
1093
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1425
1094
                                          self)
1426
1095
 
1427
 
    def get_branch_transport(self, branch_format):
 
1096
    def get_branch_transport(self, branch_format, name=None):
1428
1097
        """See BzrDir.get_branch_transport()."""
 
1098
        if name is not None:
 
1099
            raise errors.NoColocatedBranchSupport(self)
1429
1100
        if branch_format is None:
1430
1101
            return self.transport
1431
1102
        try:
1464
1135
            format = BzrDirFormat.get_default_format()
1465
1136
        return not isinstance(self._format, format.__class__)
1466
1137
 
1467
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1138
    def open_branch(self, name=None, unsupported=False,
 
1139
                    ignore_fallbacks=False):
1468
1140
        """See BzrDir.open_branch."""
1469
1141
        from bzrlib.branch import BzrBranchFormat4
1470
1142
        format = BzrBranchFormat4()
1471
1143
        self._check_supported(format, unsupported)
1472
 
        return format.open(self, _found=True)
 
1144
        return format.open(self, name, _found=True)
1473
1145
 
1474
1146
    def sprout(self, url, revision_id=None, force_new_repo=False,
1475
1147
               possible_transports=None, accelerator_tree=None,
1592
1264
        """See BzrDir.can_convert_format()."""
1593
1265
        return True
1594
1266
 
1595
 
    def create_branch(self):
 
1267
    def create_branch(self, name=None):
1596
1268
        """See BzrDir.create_branch."""
1597
 
        return self._format.get_branch_format().initialize(self)
 
1269
        return self._format.get_branch_format().initialize(self, name=name)
1598
1270
 
1599
 
    def destroy_branch(self):
 
1271
    def destroy_branch(self, name=None):
1600
1272
        """See BzrDir.create_branch."""
 
1273
        if name is not None:
 
1274
            raise errors.NoColocatedBranchSupport(self)
1601
1275
        self.transport.delete_tree('branch')
1602
1276
 
1603
1277
    def create_repository(self, shared=False):
1620
1294
        wt = self.open_workingtree(recommend_upgrade=False)
1621
1295
        repository = wt.branch.repository
1622
1296
        empty = repository.revision_tree(_mod_revision.NULL_REVISION)
1623
 
        wt.revert(old_tree=empty)
 
1297
        # We ignore the conflicts returned by wt.revert since we're about to
 
1298
        # delete the wt metadata anyway, all that should be left here are
 
1299
        # detritus. But see bug #634470 about subtree .bzr dirs.
 
1300
        conflicts = wt.revert(old_tree=empty)
1624
1301
        self.destroy_workingtree_metadata()
1625
1302
 
1626
1303
    def destroy_workingtree_metadata(self):
1627
1304
        self.transport.delete_tree('checkout')
1628
1305
 
1629
 
    def find_branch_format(self):
 
1306
    def find_branch_format(self, name=None):
1630
1307
        """Find the branch 'format' for this bzrdir.
1631
1308
 
1632
1309
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1633
1310
        """
1634
1311
        from bzrlib.branch import BranchFormat
1635
 
        return BranchFormat.find_format(self)
 
1312
        return BranchFormat.find_format(self, name=name)
1636
1313
 
1637
1314
    def _get_mkdir_mode(self):
1638
1315
        """Figure out the mode to use when creating a bzrdir subdir."""
1640
1317
                                     lockable_files.TransportLock)
1641
1318
        return temp_control._dir_mode
1642
1319
 
1643
 
    def get_branch_reference(self):
 
1320
    def get_branch_reference(self, name=None):
1644
1321
        """See BzrDir.get_branch_reference()."""
1645
1322
        from bzrlib.branch import BranchFormat
1646
 
        format = BranchFormat.find_format(self)
1647
 
        return format.get_reference(self)
 
1323
        format = BranchFormat.find_format(self, name=name)
 
1324
        return format.get_reference(self, name=name)
1648
1325
 
1649
 
    def get_branch_transport(self, branch_format):
 
1326
    def get_branch_transport(self, branch_format, name=None):
1650
1327
        """See BzrDir.get_branch_transport()."""
 
1328
        if name is not None:
 
1329
            raise errors.NoColocatedBranchSupport(self)
1651
1330
        # XXX: this shouldn't implicitly create the directory if it's just
1652
1331
        # promising to get a transport -- mbp 20090727
1653
1332
        if branch_format is None:
1724
1403
                return True
1725
1404
        except errors.NoRepositoryPresent:
1726
1405
            pass
1727
 
        try:
1728
 
            if not isinstance(self.open_branch()._format,
 
1406
        for branch in self.list_branches():
 
1407
            if not isinstance(branch._format,
1729
1408
                              format.get_branch_format().__class__):
1730
1409
                # the branch needs an upgrade.
1731
1410
                return True
1732
 
        except errors.NotBranchError:
1733
 
            pass
1734
1411
        try:
1735
1412
            my_wt = self.open_workingtree(recommend_upgrade=False)
1736
1413
            if not isinstance(my_wt._format,
1741
1418
            pass
1742
1419
        return False
1743
1420
 
1744
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1421
    def open_branch(self, name=None, unsupported=False,
 
1422
                    ignore_fallbacks=False):
1745
1423
        """See BzrDir.open_branch."""
1746
 
        format = self.find_branch_format()
 
1424
        format = self.find_branch_format(name=name)
1747
1425
        self._check_supported(format, unsupported)
1748
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1426
        return format.open(self, name=name,
 
1427
            _found=True, ignore_fallbacks=ignore_fallbacks)
1749
1428
 
1750
1429
    def open_repository(self, unsupported=False):
1751
1430
        """See BzrDir.open_repository."""
1768
1447
        return config.TransportConfig(self.transport, 'control.conf')
1769
1448
 
1770
1449
 
1771
 
class BzrDirFormat(object):
1772
 
    """An encapsulation of the initialization and open routines for a format.
1773
 
 
1774
 
    Formats provide three things:
1775
 
     * An initialization routine,
1776
 
     * a format string,
1777
 
     * an open routine.
 
1450
class BzrProber(controldir.Prober):
 
1451
    """Prober for formats that use a .bzr/ control directory."""
 
1452
 
 
1453
    _formats = {}
 
1454
    """The known .bzr formats."""
 
1455
 
 
1456
    @classmethod
 
1457
    def register_bzrdir_format(klass, format):
 
1458
        klass._formats[format.get_format_string()] = format
 
1459
 
 
1460
    @classmethod
 
1461
    def unregister_bzrdir_format(klass, format):
 
1462
        del klass._formats[format.get_format_string()]
 
1463
 
 
1464
    @classmethod
 
1465
    def probe_transport(klass, transport):
 
1466
        """Return the .bzrdir style format present in a directory."""
 
1467
        try:
 
1468
            format_string = transport.get_bytes(".bzr/branch-format")
 
1469
        except errors.NoSuchFile:
 
1470
            raise errors.NotBranchError(path=transport.base)
 
1471
        try:
 
1472
            return klass._formats[format_string]
 
1473
        except KeyError:
 
1474
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
 
1475
 
 
1476
 
 
1477
controldir.ControlDirFormat.register_prober(BzrProber)
 
1478
 
 
1479
 
 
1480
class RemoteBzrProber(controldir.Prober):
 
1481
    """Prober for remote servers that provide a Bazaar smart server."""
 
1482
 
 
1483
    @classmethod
 
1484
    def probe_transport(klass, transport):
 
1485
        """Return a RemoteBzrDirFormat object if it looks possible."""
 
1486
        try:
 
1487
            medium = transport.get_smart_medium()
 
1488
        except (NotImplementedError, AttributeError,
 
1489
                errors.TransportNotPossible, errors.NoSmartMedium,
 
1490
                errors.SmartProtocolError):
 
1491
            # no smart server, so not a branch for this format type.
 
1492
            raise errors.NotBranchError(path=transport.base)
 
1493
        else:
 
1494
            # Decline to open it if the server doesn't support our required
 
1495
            # version (3) so that the VFS-based transport will do it.
 
1496
            if medium.should_probe():
 
1497
                try:
 
1498
                    server_version = medium.protocol_version()
 
1499
                except errors.SmartProtocolError:
 
1500
                    # Apparently there's no usable smart server there, even though
 
1501
                    # the medium supports the smart protocol.
 
1502
                    raise errors.NotBranchError(path=transport.base)
 
1503
                if server_version != '2':
 
1504
                    raise errors.NotBranchError(path=transport.base)
 
1505
            return RemoteBzrDirFormat()
 
1506
 
 
1507
 
 
1508
class BzrDirFormat(controldir.ControlDirFormat):
 
1509
    """ControlDirFormat base class for .bzr/ directories.
1778
1510
 
1779
1511
    Formats are placed in a dict by their format string for reference
1780
1512
    during bzrdir opening. These should be subclasses of BzrDirFormat
1785
1517
    object will be created every system load.
1786
1518
    """
1787
1519
 
1788
 
    _default_format = None
1789
 
    """The default format used for new .bzr dirs."""
1790
 
 
1791
 
    _formats = {}
1792
 
    """The known formats."""
1793
 
 
1794
 
    _control_formats = []
1795
 
    """The registered control formats - .bzr, ....
1796
 
 
1797
 
    This is a list of BzrDirFormat objects.
1798
 
    """
1799
 
 
1800
 
    _control_server_formats = []
1801
 
    """The registered control server formats, e.g. RemoteBzrDirs.
1802
 
 
1803
 
    This is a list of BzrDirFormat objects.
1804
 
    """
1805
 
 
1806
1520
    _lock_file_name = 'branch-lock'
1807
1521
 
1808
1522
    # _lock_class must be set in subclasses to the lock type, typ.
1809
1523
    # TransportLock or LockDir
1810
1524
 
1811
 
    @classmethod
1812
 
    def find_format(klass, transport, _server_formats=True):
1813
 
        """Return the format present at transport."""
1814
 
        if _server_formats:
1815
 
            formats = klass._control_server_formats + klass._control_formats
1816
 
        else:
1817
 
            formats = klass._control_formats
1818
 
        for format in formats:
1819
 
            try:
1820
 
                return format.probe_transport(transport)
1821
 
            except errors.NotBranchError:
1822
 
                # this format does not find a control dir here.
1823
 
                pass
1824
 
        raise errors.NotBranchError(path=transport.base)
1825
 
 
1826
 
    @classmethod
1827
 
    def probe_transport(klass, transport):
1828
 
        """Return the .bzrdir style format present in a directory."""
1829
 
        try:
1830
 
            format_string = transport.get_bytes(".bzr/branch-format")
1831
 
        except errors.NoSuchFile:
1832
 
            raise errors.NotBranchError(path=transport.base)
1833
 
 
1834
 
        try:
1835
 
            return klass._formats[format_string]
1836
 
        except KeyError:
1837
 
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1838
 
 
1839
 
    @classmethod
1840
 
    def get_default_format(klass):
1841
 
        """Return the current default format."""
1842
 
        return klass._default_format
1843
 
 
1844
1525
    def get_format_string(self):
1845
1526
        """Return the ASCII format string that identifies this format."""
1846
1527
        raise NotImplementedError(self.get_format_string)
1847
1528
 
1848
 
    def get_format_description(self):
1849
 
        """Return the short description for this format."""
1850
 
        raise NotImplementedError(self.get_format_description)
1851
 
 
1852
 
    def get_converter(self, format=None):
1853
 
        """Return the converter to use to convert bzrdirs needing converts.
1854
 
 
1855
 
        This returns a bzrlib.bzrdir.Converter object.
1856
 
 
1857
 
        This should return the best upgrader to step this format towards the
1858
 
        current default format. In the case of plugins we can/should provide
1859
 
        some means for them to extend the range of returnable converters.
1860
 
 
1861
 
        :param format: Optional format to override the default format of the
1862
 
                       library.
1863
 
        """
1864
 
        raise NotImplementedError(self.get_converter)
1865
 
 
1866
 
    def initialize(self, url, possible_transports=None):
1867
 
        """Create a bzr control dir at this url and return an opened copy.
1868
 
 
1869
 
        While not deprecated, this method is very specific and its use will
1870
 
        lead to many round trips to setup a working environment. See
1871
 
        initialize_on_transport_ex for a [nearly] all-in-one method.
1872
 
 
1873
 
        Subclasses should typically override initialize_on_transport
1874
 
        instead of this method.
1875
 
        """
1876
 
        return self.initialize_on_transport(get_transport(url,
1877
 
                                                          possible_transports))
1878
 
 
1879
1529
    def initialize_on_transport(self, transport):
1880
1530
        """Initialize a new bzrdir in the base directory of a Transport."""
1881
1531
        try:
2029
1679
            control_files.unlock()
2030
1680
        return self.open(transport, _found=True)
2031
1681
 
2032
 
    def is_supported(self):
2033
 
        """Is this format supported?
2034
 
 
2035
 
        Supported formats must be initializable and openable.
2036
 
        Unsupported formats may not support initialization or committing or
2037
 
        some other features depending on the reason for not being supported.
2038
 
        """
2039
 
        return True
2040
 
 
2041
 
    def network_name(self):
2042
 
        """A simple byte string uniquely identifying this format for RPC calls.
2043
 
 
2044
 
        Bzr control formats use thir disk format string to identify the format
2045
 
        over the wire. Its possible that other control formats have more
2046
 
        complex detection requirements, so we permit them to use any unique and
2047
 
        immutable string they desire.
2048
 
        """
2049
 
        raise NotImplementedError(self.network_name)
2050
 
 
2051
 
    def same_model(self, target_format):
2052
 
        return (self.repository_format.rich_root_data ==
2053
 
            target_format.rich_root_data)
2054
 
 
2055
 
    @classmethod
2056
 
    def known_formats(klass):
2057
 
        """Return all the known formats.
2058
 
 
2059
 
        Concrete formats should override _known_formats.
2060
 
        """
2061
 
        # There is double indirection here to make sure that control
2062
 
        # formats used by more than one dir format will only be probed
2063
 
        # once. This can otherwise be quite expensive for remote connections.
2064
 
        result = set()
2065
 
        for format in klass._control_formats:
2066
 
            result.update(format._known_formats())
2067
 
        return result
2068
 
 
2069
 
    @classmethod
2070
 
    def _known_formats(klass):
2071
 
        """Return the known format instances for this control format."""
2072
 
        return set(klass._formats.values())
2073
 
 
2074
1682
    def open(self, transport, _found=False):
2075
1683
        """Return an instance of this format for the dir transport points at.
2076
1684
 
2077
1685
        _found is a private parameter, do not use it.
2078
1686
        """
2079
1687
        if not _found:
2080
 
            found_format = BzrDirFormat.find_format(transport)
 
1688
            found_format = controldir.ControlDirFormat.find_format(transport)
2081
1689
            if not isinstance(found_format, self.__class__):
2082
1690
                raise AssertionError("%s was asked to open %s, but it seems to need "
2083
1691
                        "format %s"
2097
1705
 
2098
1706
    @classmethod
2099
1707
    def register_format(klass, format):
2100
 
        klass._formats[format.get_format_string()] = format
 
1708
        BzrProber.register_bzrdir_format(format)
2101
1709
        # bzr native formats have a network name of their format string.
2102
 
        network_format_registry.register(format.get_format_string(), format.__class__)
2103
 
 
2104
 
    @classmethod
2105
 
    def register_control_format(klass, format):
2106
 
        """Register a format that does not use '.bzr' for its control dir.
2107
 
 
2108
 
        TODO: This should be pulled up into a 'ControlDirFormat' base class
2109
 
        which BzrDirFormat can inherit from, and renamed to register_format
2110
 
        there. It has been done without that for now for simplicity of
2111
 
        implementation.
2112
 
        """
2113
 
        klass._control_formats.append(format)
2114
 
 
2115
 
    @classmethod
2116
 
    def register_control_server_format(klass, format):
2117
 
        """Register a control format for client-server environments.
2118
 
 
2119
 
        These formats will be tried before ones registered with
2120
 
        register_control_format.  This gives implementations that decide to the
2121
 
        chance to grab it before anything looks at the contents of the format
2122
 
        file.
2123
 
        """
2124
 
        klass._control_server_formats.append(format)
2125
 
 
2126
 
    @classmethod
2127
 
    def _set_default_format(klass, format):
2128
 
        """Set default format (for testing behavior of defaults only)"""
2129
 
        klass._default_format = format
2130
 
 
2131
 
    def __str__(self):
2132
 
        # Trim the newline
2133
 
        return self.get_format_description().rstrip()
 
1710
        controldir.network_format_registry.register(format.get_format_string(), format.__class__)
 
1711
        controldir.ControlDirFormat.register_format(format)
2134
1712
 
2135
1713
    def _supply_sub_formats_to(self, other_format):
2136
1714
        """Give other_format the same values for sub formats as this has.
2146
1724
 
2147
1725
    @classmethod
2148
1726
    def unregister_format(klass, format):
2149
 
        del klass._formats[format.get_format_string()]
2150
 
 
2151
 
    @classmethod
2152
 
    def unregister_control_format(klass, format):
2153
 
        klass._control_formats.remove(format)
 
1727
        BzrProber.unregister_bzrdir_format(format)
 
1728
        controldir.ControlDirFormat.unregister_format(format)
 
1729
        controldir.network_format_registry.remove(format.get_format_string())
2154
1730
 
2155
1731
 
2156
1732
class BzrDirFormat4(BzrDirFormat):
2559
2135
                                  __set_workingtree_format)
2560
2136
 
2561
2137
 
2562
 
network_format_registry = registry.FormatRegistry()
2563
 
"""Registry of formats indexed by their network name.
2564
 
 
2565
 
The network name for a BzrDirFormat is an identifier that can be used when
2566
 
referring to formats with smart server operations. See
2567
 
BzrDirFormat.network_name() for more detail.
2568
 
"""
2569
 
 
2570
 
 
2571
 
# Register bzr control format
2572
 
BzrDirFormat.register_control_format(BzrDirFormat)
2573
 
 
2574
2138
# Register bzr formats
2575
2139
BzrDirFormat.register_format(BzrDirFormat4())
2576
2140
BzrDirFormat.register_format(BzrDirFormat5())
2577
2141
BzrDirFormat.register_format(BzrDirFormat6())
2578
2142
__default_format = BzrDirMetaFormat1()
2579
2143
BzrDirFormat.register_format(__default_format)
2580
 
BzrDirFormat._default_format = __default_format
 
2144
controldir.ControlDirFormat._default_format = __default_format
2581
2145
 
2582
2146
 
2583
2147
class Converter(object):
2609
2173
    def convert(self, to_convert, pb):
2610
2174
        """See Converter.convert()."""
2611
2175
        self.bzrdir = to_convert
2612
 
        self.pb = pb
2613
 
        ui.ui_factory.note('starting upgrade from format 4 to 5')
2614
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2615
 
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2616
 
        self._convert_to_weaves()
2617
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2176
        if pb is not None:
 
2177
            warnings.warn("pb parameter to convert() is deprecated")
 
2178
        self.pb = ui.ui_factory.nested_progress_bar()
 
2179
        try:
 
2180
            ui.ui_factory.note('starting upgrade from format 4 to 5')
 
2181
            if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2182
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2183
            self._convert_to_weaves()
 
2184
            return BzrDir.open(self.bzrdir.user_url)
 
2185
        finally:
 
2186
            self.pb.finished()
2618
2187
 
2619
2188
    def _convert_to_weaves(self):
2620
2189
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2740
2309
            self.revisions[rev_id] = rev
2741
2310
 
2742
2311
    def _load_old_inventory(self, rev_id):
2743
 
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
 
2312
        f = self.branch.repository.inventory_store.get(rev_id)
 
2313
        try:
 
2314
            old_inv_xml = f.read()
 
2315
        finally:
 
2316
            f.close()
2744
2317
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2745
2318
        inv.revision_id = rev_id
2746
2319
        rev = self.revisions[rev_id]
2802
2375
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2803
2376
            in heads)
2804
2377
        self.snapshot_ie(previous_entries, ie, w, rev_id)
2805
 
        del ie.text_id
2806
2378
 
2807
2379
    def get_parent_map(self, revision_ids):
2808
2380
        """See graph.StackedParentsProvider.get_parent_map"""
2824
2396
                ie.revision = previous_ie.revision
2825
2397
                return
2826
2398
        if ie.has_text():
2827
 
            text = self.branch.repository._text_store.get(ie.text_id)
2828
 
            file_lines = text.readlines()
 
2399
            f = self.branch.repository._text_store.get(ie.text_id)
 
2400
            try:
 
2401
                file_lines = f.readlines()
 
2402
            finally:
 
2403
                f.close()
2829
2404
            w.add_lines(rev_id, previous_revisions, file_lines)
2830
2405
            self.text_count += 1
2831
2406
        else:
2861
2436
    def convert(self, to_convert, pb):
2862
2437
        """See Converter.convert()."""
2863
2438
        self.bzrdir = to_convert
2864
 
        self.pb = pb
2865
 
        ui.ui_factory.note('starting upgrade from format 5 to 6')
2866
 
        self._convert_to_prefixed()
2867
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2439
        pb = ui.ui_factory.nested_progress_bar()
 
2440
        try:
 
2441
            ui.ui_factory.note('starting upgrade from format 5 to 6')
 
2442
            self._convert_to_prefixed()
 
2443
            return BzrDir.open(self.bzrdir.user_url)
 
2444
        finally:
 
2445
            pb.finished()
2868
2446
 
2869
2447
    def _convert_to_prefixed(self):
2870
2448
        from bzrlib.store import TransportStore
2903
2481
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2904
2482
        from bzrlib.branch import BzrBranchFormat5
2905
2483
        self.bzrdir = to_convert
2906
 
        self.pb = pb
 
2484
        self.pb = ui.ui_factory.nested_progress_bar()
2907
2485
        self.count = 0
2908
2486
        self.total = 20 # the steps we know about
2909
2487
        self.garbage_inventories = []
2989
2567
            'branch-format',
2990
2568
            BzrDirMetaFormat1().get_format_string(),
2991
2569
            mode=self.file_mode)
2992
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2570
        self.pb.finished()
 
2571
        return BzrDir.open(self.bzrdir.user_url)
2993
2572
 
2994
2573
    def make_lock(self, name):
2995
2574
        """Make a lock for the new control dir name."""
3030
2609
    def convert(self, to_convert, pb):
3031
2610
        """See Converter.convert()."""
3032
2611
        self.bzrdir = to_convert
3033
 
        self.pb = pb
 
2612
        self.pb = ui.ui_factory.nested_progress_bar()
3034
2613
        self.count = 0
3035
2614
        self.total = 1
3036
2615
        self.step('checking repository format')
3044
2623
                ui.ui_factory.note('starting repository conversion')
3045
2624
                converter = CopyConverter(self.target_format.repository_format)
3046
2625
                converter.convert(repo, pb)
3047
 
        try:
3048
 
            branch = self.bzrdir.open_branch()
3049
 
        except errors.NotBranchError:
3050
 
            pass
3051
 
        else:
 
2626
        for branch in self.bzrdir.list_branches():
3052
2627
            # TODO: conversions of Branch and Tree should be done by
3053
2628
            # InterXFormat lookups/some sort of registry.
3054
2629
            # Avoid circular imports
3096
2671
                isinstance(self.target_format.workingtree_format,
3097
2672
                    workingtree_4.WorkingTreeFormat6)):
3098
2673
                workingtree_4.Converter4or5to6().convert(tree)
 
2674
        self.pb.finished()
3099
2675
        return to_convert
3100
2676
 
3101
2677
 
3106
2682
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3107
2683
    """Format representing bzrdirs accessed via a smart server"""
3108
2684
 
 
2685
    supports_workingtrees = False
 
2686
 
3109
2687
    def __init__(self):
3110
2688
        BzrDirMetaFormat1.__init__(self)
3111
2689
        # XXX: It's a bit ugly that the network name is here, because we'd
3112
2690
        # like to believe that format objects are stateless or at least
3113
2691
        # immutable,  However, we do at least avoid mutating the name after
3114
 
        # it's returned.  See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
 
2692
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
3115
2693
        self._network_name = None
3116
2694
 
3117
2695
    def __repr__(self):
3120
2698
 
3121
2699
    def get_format_description(self):
3122
2700
        if self._network_name:
3123
 
            real_format = network_format_registry.get(self._network_name)
 
2701
            real_format = controldir.network_format_registry.get(self._network_name)
3124
2702
            return 'Remote: ' + real_format.get_format_description()
3125
2703
        return 'bzr remote bzrdir'
3126
2704
 
3133
2711
        else:
3134
2712
            raise AssertionError("No network name set.")
3135
2713
 
3136
 
    @classmethod
3137
 
    def probe_transport(klass, transport):
3138
 
        """Return a RemoteBzrDirFormat object if it looks possible."""
3139
 
        try:
3140
 
            medium = transport.get_smart_medium()
3141
 
        except (NotImplementedError, AttributeError,
3142
 
                errors.TransportNotPossible, errors.NoSmartMedium,
3143
 
                errors.SmartProtocolError):
3144
 
            # no smart server, so not a branch for this format type.
3145
 
            raise errors.NotBranchError(path=transport.base)
3146
 
        else:
3147
 
            # Decline to open it if the server doesn't support our required
3148
 
            # version (3) so that the VFS-based transport will do it.
3149
 
            if medium.should_probe():
3150
 
                try:
3151
 
                    server_version = medium.protocol_version()
3152
 
                except errors.SmartProtocolError:
3153
 
                    # Apparently there's no usable smart server there, even though
3154
 
                    # the medium supports the smart protocol.
3155
 
                    raise errors.NotBranchError(path=transport.base)
3156
 
                if server_version != '2':
3157
 
                    raise errors.NotBranchError(path=transport.base)
3158
 
            return klass()
3159
 
 
3160
2714
    def initialize_on_transport(self, transport):
3161
2715
        try:
3162
2716
            # hand off the request to the smart server
3361
2915
        BzrDirMetaFormat1._set_repository_format) #.im_func)
3362
2916
 
3363
2917
 
3364
 
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3365
 
 
3366
 
 
3367
 
class BzrDirFormatInfo(object):
3368
 
 
3369
 
    def __init__(self, native, deprecated, hidden, experimental):
3370
 
        self.deprecated = deprecated
3371
 
        self.native = native
3372
 
        self.hidden = hidden
3373
 
        self.experimental = experimental
3374
 
 
3375
 
 
3376
 
class BzrDirFormatRegistry(registry.Registry):
3377
 
    """Registry of user-selectable BzrDir subformats.
3378
 
 
3379
 
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3380
 
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
3381
 
    """
3382
 
 
3383
 
    def __init__(self):
3384
 
        """Create a BzrDirFormatRegistry."""
3385
 
        self._aliases = set()
3386
 
        self._registration_order = list()
3387
 
        super(BzrDirFormatRegistry, self).__init__()
3388
 
 
3389
 
    def aliases(self):
3390
 
        """Return a set of the format names which are aliases."""
3391
 
        return frozenset(self._aliases)
3392
 
 
3393
 
    def register_metadir(self, key,
3394
 
             repository_format, help, native=True, deprecated=False,
3395
 
             branch_format=None,
3396
 
             tree_format=None,
3397
 
             hidden=False,
3398
 
             experimental=False,
3399
 
             alias=False):
3400
 
        """Register a metadir subformat.
3401
 
 
3402
 
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3403
 
        by the Repository/Branch/WorkingTreeformats.
3404
 
 
3405
 
        :param repository_format: The fully-qualified repository format class
3406
 
            name as a string.
3407
 
        :param branch_format: Fully-qualified branch format class name as
3408
 
            a string.
3409
 
        :param tree_format: Fully-qualified tree format class name as
3410
 
            a string.
3411
 
        """
3412
 
        # This should be expanded to support setting WorkingTree and Branch
3413
 
        # formats, once BzrDirMetaFormat1 supports that.
3414
 
        def _load(full_name):
3415
 
            mod_name, factory_name = full_name.rsplit('.', 1)
3416
 
            try:
3417
 
                mod = __import__(mod_name, globals(), locals(),
3418
 
                        [factory_name])
3419
 
            except ImportError, e:
3420
 
                raise ImportError('failed to load %s: %s' % (full_name, e))
3421
 
            try:
3422
 
                factory = getattr(mod, factory_name)
3423
 
            except AttributeError:
3424
 
                raise AttributeError('no factory %s in module %r'
3425
 
                    % (full_name, mod))
3426
 
            return factory()
3427
 
 
3428
 
        def helper():
3429
 
            bd = BzrDirMetaFormat1()
3430
 
            if branch_format is not None:
3431
 
                bd.set_branch_format(_load(branch_format))
3432
 
            if tree_format is not None:
3433
 
                bd.workingtree_format = _load(tree_format)
3434
 
            if repository_format is not None:
3435
 
                bd.repository_format = _load(repository_format)
3436
 
            return bd
3437
 
        self.register(key, helper, help, native, deprecated, hidden,
3438
 
            experimental, alias)
3439
 
 
3440
 
    def register(self, key, factory, help, native=True, deprecated=False,
3441
 
                 hidden=False, experimental=False, alias=False):
3442
 
        """Register a BzrDirFormat factory.
3443
 
 
3444
 
        The factory must be a callable that takes one parameter: the key.
3445
 
        It must produce an instance of the BzrDirFormat when called.
3446
 
 
3447
 
        This function mainly exists to prevent the info object from being
3448
 
        supplied directly.
3449
 
        """
3450
 
        registry.Registry.register(self, key, factory, help,
3451
 
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
3452
 
        if alias:
3453
 
            self._aliases.add(key)
3454
 
        self._registration_order.append(key)
3455
 
 
3456
 
    def register_lazy(self, key, module_name, member_name, help, native=True,
3457
 
        deprecated=False, hidden=False, experimental=False, alias=False):
3458
 
        registry.Registry.register_lazy(self, key, module_name, member_name,
3459
 
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3460
 
        if alias:
3461
 
            self._aliases.add(key)
3462
 
        self._registration_order.append(key)
3463
 
 
3464
 
    def set_default(self, key):
3465
 
        """Set the 'default' key to be a clone of the supplied key.
3466
 
 
3467
 
        This method must be called once and only once.
3468
 
        """
3469
 
        registry.Registry.register(self, 'default', self.get(key),
3470
 
            self.get_help(key), info=self.get_info(key))
3471
 
        self._aliases.add('default')
3472
 
 
3473
 
    def set_default_repository(self, key):
3474
 
        """Set the FormatRegistry default and Repository default.
3475
 
 
3476
 
        This is a transitional method while Repository.set_default_format
3477
 
        is deprecated.
3478
 
        """
3479
 
        if 'default' in self:
3480
 
            self.remove('default')
3481
 
        self.set_default(key)
3482
 
        format = self.get('default')()
3483
 
 
3484
 
    def make_bzrdir(self, key):
3485
 
        return self.get(key)()
3486
 
 
3487
 
    def help_topic(self, topic):
3488
 
        output = ""
3489
 
        default_realkey = None
3490
 
        default_help = self.get_help('default')
3491
 
        help_pairs = []
3492
 
        for key in self._registration_order:
3493
 
            if key == 'default':
3494
 
                continue
3495
 
            help = self.get_help(key)
3496
 
            if help == default_help:
3497
 
                default_realkey = key
3498
 
            else:
3499
 
                help_pairs.append((key, help))
3500
 
 
3501
 
        def wrapped(key, help, info):
3502
 
            if info.native:
3503
 
                help = '(native) ' + help
3504
 
            return ':%s:\n%s\n\n' % (key,
3505
 
                textwrap.fill(help, initial_indent='    ',
3506
 
                    subsequent_indent='    ',
3507
 
                    break_long_words=False))
3508
 
        if default_realkey is not None:
3509
 
            output += wrapped(default_realkey, '(default) %s' % default_help,
3510
 
                              self.get_info('default'))
3511
 
        deprecated_pairs = []
3512
 
        experimental_pairs = []
3513
 
        for key, help in help_pairs:
3514
 
            info = self.get_info(key)
3515
 
            if info.hidden:
3516
 
                continue
3517
 
            elif info.deprecated:
3518
 
                deprecated_pairs.append((key, help))
3519
 
            elif info.experimental:
3520
 
                experimental_pairs.append((key, help))
3521
 
            else:
3522
 
                output += wrapped(key, help, info)
3523
 
        output += "\nSee :doc:`formats-help` for more about storage formats."
3524
 
        other_output = ""
3525
 
        if len(experimental_pairs) > 0:
3526
 
            other_output += "Experimental formats are shown below.\n\n"
3527
 
            for key, help in experimental_pairs:
3528
 
                info = self.get_info(key)
3529
 
                other_output += wrapped(key, help, info)
3530
 
        else:
3531
 
            other_output += \
3532
 
                "No experimental formats are available.\n\n"
3533
 
        if len(deprecated_pairs) > 0:
3534
 
            other_output += "\nDeprecated formats are shown below.\n\n"
3535
 
            for key, help in deprecated_pairs:
3536
 
                info = self.get_info(key)
3537
 
                other_output += wrapped(key, help, info)
3538
 
        else:
3539
 
            other_output += \
3540
 
                "\nNo deprecated formats are available.\n\n"
3541
 
        other_output += \
3542
 
                "\nSee :doc:`formats-help` for more about storage formats."
3543
 
 
3544
 
        if topic == 'other-formats':
3545
 
            return other_output
3546
 
        else:
3547
 
            return output
 
2918
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
3548
2919
 
3549
2920
 
3550
2921
class RepositoryAcquisitionPolicy(object):
3579
2950
            try:
3580
2951
                stack_on = urlutils.rebase_url(self._stack_on,
3581
2952
                    self._stack_on_pwd,
3582
 
                    branch.bzrdir.root_transport.base)
 
2953
                    branch.user_url)
3583
2954
            except errors.InvalidRebaseURLs:
3584
2955
                stack_on = self._get_full_stack_on()
3585
2956
        try:
3704
3075
        return self._repository, False
3705
3076
 
3706
3077
 
3707
 
# Please register new formats after old formats so that formats
3708
 
# appear in chronological order and format descriptions can build
3709
 
# on previous ones.
3710
 
format_registry = BzrDirFormatRegistry()
 
3078
def register_metadir(registry, key,
 
3079
         repository_format, help, native=True, deprecated=False,
 
3080
         branch_format=None,
 
3081
         tree_format=None,
 
3082
         hidden=False,
 
3083
         experimental=False,
 
3084
         alias=False):
 
3085
    """Register a metadir subformat.
 
3086
 
 
3087
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
3088
    by the Repository/Branch/WorkingTreeformats.
 
3089
 
 
3090
    :param repository_format: The fully-qualified repository format class
 
3091
        name as a string.
 
3092
    :param branch_format: Fully-qualified branch format class name as
 
3093
        a string.
 
3094
    :param tree_format: Fully-qualified tree format class name as
 
3095
        a string.
 
3096
    """
 
3097
    # This should be expanded to support setting WorkingTree and Branch
 
3098
    # formats, once BzrDirMetaFormat1 supports that.
 
3099
    def _load(full_name):
 
3100
        mod_name, factory_name = full_name.rsplit('.', 1)
 
3101
        try:
 
3102
            factory = pyutils.get_named_object(mod_name, factory_name)
 
3103
        except ImportError, e:
 
3104
            raise ImportError('failed to load %s: %s' % (full_name, e))
 
3105
        except AttributeError:
 
3106
            raise AttributeError('no factory %s in module %r'
 
3107
                % (full_name, sys.modules[mod_name]))
 
3108
        return factory()
 
3109
 
 
3110
    def helper():
 
3111
        bd = BzrDirMetaFormat1()
 
3112
        if branch_format is not None:
 
3113
            bd.set_branch_format(_load(branch_format))
 
3114
        if tree_format is not None:
 
3115
            bd.workingtree_format = _load(tree_format)
 
3116
        if repository_format is not None:
 
3117
            bd.repository_format = _load(repository_format)
 
3118
        return bd
 
3119
    registry.register(key, helper, help, native, deprecated, hidden,
 
3120
        experimental, alias)
 
3121
 
3711
3122
# The pre-0.8 formats have their repository format network name registered in
3712
3123
# repository.py. MetaDir formats have their repository format network name
3713
3124
# inferred from their disk format string.
3714
 
format_registry.register('weave', BzrDirFormat6,
 
3125
controldir.format_registry.register('weave', BzrDirFormat6,
3715
3126
    'Pre-0.8 format.  Slower than knit and does not'
3716
3127
    ' support checkouts or shared repositories.',
3717
3128
    hidden=True,
3718
3129
    deprecated=True)
3719
 
format_registry.register_metadir('metaweave',
 
3130
register_metadir(controldir.format_registry, 'metaweave',
3720
3131
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3721
3132
    'Transitional format in 0.8.  Slower than knit.',
3722
3133
    branch_format='bzrlib.branch.BzrBranchFormat5',
3723
3134
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3724
3135
    hidden=True,
3725
3136
    deprecated=True)
3726
 
format_registry.register_metadir('knit',
 
3137
register_metadir(controldir.format_registry, 'knit',
3727
3138
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3728
3139
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3729
3140
    branch_format='bzrlib.branch.BzrBranchFormat5',
3730
3141
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3731
3142
    hidden=True,
3732
3143
    deprecated=True)
3733
 
format_registry.register_metadir('dirstate',
 
3144
register_metadir(controldir.format_registry, 'dirstate',
3734
3145
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3735
3146
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3736
3147
        'above when accessed over the network.',
3740
3151
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3741
3152
    hidden=True,
3742
3153
    deprecated=True)
3743
 
format_registry.register_metadir('dirstate-tags',
 
3154
register_metadir(controldir.format_registry, 'dirstate-tags',
3744
3155
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3745
3156
    help='New in 0.15: Fast local operations and improved scaling for '
3746
3157
        'network operations. Additionally adds support for tags.'
3749
3160
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3750
3161
    hidden=True,
3751
3162
    deprecated=True)
3752
 
format_registry.register_metadir('rich-root',
 
3163
register_metadir(controldir.format_registry, 'rich-root',
3753
3164
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3754
3165
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3755
3166
        ' bzr < 1.0.',
3757
3168
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3758
3169
    hidden=True,
3759
3170
    deprecated=True)
3760
 
format_registry.register_metadir('dirstate-with-subtree',
 
3171
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
3761
3172
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3762
3173
    help='New in 0.15: Fast local operations and improved scaling for '
3763
3174
        'network operations. Additionally adds support for versioning nested '
3767
3178
    experimental=True,
3768
3179
    hidden=True,
3769
3180
    )
3770
 
format_registry.register_metadir('pack-0.92',
 
3181
register_metadir(controldir.format_registry, 'pack-0.92',
3771
3182
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3772
3183
    help='New in 0.92: Pack-based format with data compatible with '
3773
3184
        'dirstate-tags format repositories. Interoperates with '
3776
3187
    branch_format='bzrlib.branch.BzrBranchFormat6',
3777
3188
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3778
3189
    )
3779
 
format_registry.register_metadir('pack-0.92-subtree',
 
3190
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
3780
3191
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3781
3192
    help='New in 0.92: Pack-based format with data compatible with '
3782
3193
        'dirstate-with-subtree format repositories. Interoperates with '
3787
3198
    hidden=True,
3788
3199
    experimental=True,
3789
3200
    )
3790
 
format_registry.register_metadir('rich-root-pack',
 
3201
register_metadir(controldir.format_registry, 'rich-root-pack',
3791
3202
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3792
3203
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3793
3204
         '(needed for bzr-svn and bzr-git).',
3795
3206
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3796
3207
    hidden=True,
3797
3208
    )
3798
 
format_registry.register_metadir('1.6',
 
3209
register_metadir(controldir.format_registry, '1.6',
3799
3210
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3800
3211
    help='A format that allows a branch to indicate that there is another '
3801
3212
         '(stacked) repository that should be used to access data that is '
3804
3215
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3805
3216
    hidden=True,
3806
3217
    )
3807
 
format_registry.register_metadir('1.6.1-rich-root',
 
3218
register_metadir(controldir.format_registry, '1.6.1-rich-root',
3808
3219
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3809
3220
    help='A variant of 1.6 that supports rich-root data '
3810
3221
         '(needed for bzr-svn and bzr-git).',
3812
3223
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3813
3224
    hidden=True,
3814
3225
    )
3815
 
format_registry.register_metadir('1.9',
 
3226
register_metadir(controldir.format_registry, '1.9',
3816
3227
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3817
3228
    help='A repository format using B+tree indexes. These indexes '
3818
3229
         'are smaller in size, have smarter caching and provide faster '
3821
3232
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3822
3233
    hidden=True,
3823
3234
    )
3824
 
format_registry.register_metadir('1.9-rich-root',
 
3235
register_metadir(controldir.format_registry, '1.9-rich-root',
3825
3236
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3826
3237
    help='A variant of 1.9 that supports rich-root data '
3827
3238
         '(needed for bzr-svn and bzr-git).',
3829
3240
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3830
3241
    hidden=True,
3831
3242
    )
3832
 
format_registry.register_metadir('1.14',
 
3243
register_metadir(controldir.format_registry, '1.14',
3833
3244
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3834
3245
    help='A working-tree format that supports content filtering.',
3835
3246
    branch_format='bzrlib.branch.BzrBranchFormat7',
3836
3247
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3837
3248
    )
3838
 
format_registry.register_metadir('1.14-rich-root',
 
3249
register_metadir(controldir.format_registry, '1.14-rich-root',
3839
3250
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3840
3251
    help='A variant of 1.14 that supports rich-root data '
3841
3252
         '(needed for bzr-svn and bzr-git).',
3843
3254
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3844
3255
    )
3845
3256
# The following un-numbered 'development' formats should always just be aliases.
3846
 
format_registry.register_metadir('development-rich-root',
3847
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3848
 
    help='Current development format. Supports rich roots. Can convert data '
3849
 
        'to and from rich-root-pack (and anything compatible with '
3850
 
        'rich-root-pack) format repositories. Repositories and branches in '
3851
 
        'this format can only be read by bzr.dev. Please read '
3852
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3853
 
        'before use.',
3854
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3855
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3856
 
    experimental=True,
3857
 
    alias=True,
3858
 
    hidden=True,
3859
 
    )
3860
 
format_registry.register_metadir('development-subtree',
3861
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
3257
register_metadir(controldir.format_registry, 'development-subtree',
 
3258
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
3862
3259
    help='Current development format, subtree variant. Can convert data to and '
3863
3260
        'from pack-0.92-subtree (and anything compatible with '
3864
3261
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3873
3270
                 # This current non-alias status is simply because we did not introduce a
3874
3271
                 # chk based subtree format.
3875
3272
    )
 
3273
register_metadir(controldir.format_registry, 'development5-subtree',
 
3274
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
3275
    help='Development format, subtree variant. Can convert data to and '
 
3276
        'from pack-0.92-subtree (and anything compatible with '
 
3277
        'pack-0.92-subtree) format repositories. Repositories and branches in '
 
3278
        'this format can only be read by bzr.dev. Please read '
 
3279
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3280
        'before use.',
 
3281
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3282
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3283
    experimental=True,
 
3284
    hidden=True,
 
3285
    alias=False,
 
3286
    )
3876
3287
 
3877
3288
# And the development formats above will have aliased one of the following:
3878
 
format_registry.register_metadir('development6-rich-root',
3879
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3880
 
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3881
 
        'Please read '
3882
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3883
 
        'before use.',
3884
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3885
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3886
 
    hidden=True,
3887
 
    experimental=True,
3888
 
    )
3889
 
 
3890
 
format_registry.register_metadir('development7-rich-root',
3891
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3892
 
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3893
 
        'rich roots. Please read '
3894
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3895
 
        'before use.',
3896
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3897
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3898
 
    hidden=True,
3899
 
    experimental=True,
3900
 
    )
3901
 
 
3902
 
format_registry.register_metadir('2a',
 
3289
 
 
3290
# Finally, the current format.
 
3291
register_metadir(controldir.format_registry, '2a',
3903
3292
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3904
3293
    help='First format for bzr 2.0 series.\n'
3905
3294
        'Uses group-compress storage.\n'
3908
3297
        # 'rich roots. Supported by bzr 1.16 and later.',
3909
3298
    branch_format='bzrlib.branch.BzrBranchFormat7',
3910
3299
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3911
 
    experimental=True,
 
3300
    experimental=False,
3912
3301
    )
3913
3302
 
3914
3303
# The following format should be an alias for the rich root equivalent 
3915
3304
# of the default format
3916
 
format_registry.register_metadir('default-rich-root',
 
3305
register_metadir(controldir.format_registry, 'default-rich-root',
3917
3306
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3918
3307
    branch_format='bzrlib.branch.BzrBranchFormat7',
3919
3308
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3922
3311
    help='Same as 2a.')
3923
3312
 
3924
3313
# The current format that is made on 'bzr init'.
3925
 
format_registry.set_default('2a')
 
3314
format_name = config.GlobalConfig().get_user_option('default_format')
 
3315
if format_name is None:
 
3316
    controldir.format_registry.set_default('2a')
 
3317
else:
 
3318
    controldir.format_registry.set_default(format_name)
 
3319
 
 
3320
# XXX 2010-08-20 JRV: There is still a lot of code relying on
 
3321
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
 
3322
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
 
3323
format_registry = controldir.format_registry