/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

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    remote,
45
45
    revision as _mod_revision,
46
46
    symbol_versioning,
 
47
    ui,
47
48
    urlutils,
48
49
    xml4,
49
50
    xml5,
60
61
from bzrlib.store.text import TextStore
61
62
from bzrlib.store.versioned import WeaveStore
62
63
from bzrlib.transactions import WriteTransaction
63
 
from bzrlib.transport import get_transport
 
64
from bzrlib.transport import (
 
65
    do_catching_redirections,
 
66
    get_transport,
 
67
    )
64
68
from bzrlib.weave import Weave
65
69
""")
66
70
 
67
 
from bzrlib.trace import mutter, note
 
71
from bzrlib.trace import (
 
72
    mutter,
 
73
    note,
 
74
    )
68
75
from bzrlib.transport.local import LocalTransport
69
76
 
70
77
 
110
117
        source_repo_format.check_conversion_target(target_repo_format)
111
118
 
112
119
    @staticmethod
113
 
    def _check_supported(format, allow_unsupported):
114
 
        """Check whether format is a supported format.
115
 
 
116
 
        If allow_unsupported is True, this is a no-op.
 
120
    def _check_supported(format, allow_unsupported,
 
121
        recommend_upgrade=True,
 
122
        basedir=None):
 
123
        """Give an error or warning on old formats.
 
124
 
 
125
        :param format: may be any kind of format - workingtree, branch, 
 
126
        or repository.
 
127
 
 
128
        :param allow_unsupported: If true, allow opening 
 
129
        formats that are strongly deprecated, and which may 
 
130
        have limited functionality.
 
131
 
 
132
        :param recommend_upgrade: If true (default), warn
 
133
        the user through the ui object that they may wish
 
134
        to upgrade the object.
117
135
        """
 
136
        # TODO: perhaps move this into a base Format class; it's not BzrDir
 
137
        # specific. mbp 20070323
118
138
        if not allow_unsupported and not format.is_supported():
119
139
            # see open_downlevel to open legacy branches.
120
140
            raise errors.UnsupportedFormatError(format=format)
 
141
        if recommend_upgrade \
 
142
            and getattr(format, 'upgrade_recommended', False):
 
143
            ui.ui_factory.recommend_upgrade(
 
144
                format.get_format_description(),
 
145
                basedir)
121
146
 
122
 
    def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
 
147
    def clone(self, url, revision_id=None, force_new_repo=False):
123
148
        """Clone this bzrdir and its contents to url verbatim.
124
149
 
125
150
        If urls last component does not exist, it will be created.
130
155
                               even if one is available.
131
156
        """
132
157
        self._make_tail(url)
133
 
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
134
158
        result = self._format.initialize(url)
135
159
        try:
136
160
            local_repo = self.find_repository()
141
165
            if force_new_repo:
142
166
                result_repo = local_repo.clone(
143
167
                    result,
144
 
                    revision_id=revision_id,
145
 
                    basis=basis_repo)
 
168
                    revision_id=revision_id)
146
169
                result_repo.set_make_working_trees(local_repo.make_working_trees())
147
170
            else:
148
171
                try:
149
172
                    result_repo = result.find_repository()
150
173
                    # fetch content this dir needs.
151
 
                    if basis_repo:
152
 
                        # XXX FIXME RBC 20060214 need tests for this when the basis
153
 
                        # is incomplete
154
 
                        result_repo.fetch(basis_repo, revision_id=revision_id)
155
174
                    result_repo.fetch(local_repo, revision_id=revision_id)
156
175
                except errors.NoRepositoryPresent:
157
176
                    # needed to make one anyway.
158
177
                    result_repo = local_repo.clone(
159
178
                        result,
160
 
                        revision_id=revision_id,
161
 
                        basis=basis_repo)
 
179
                        revision_id=revision_id)
162
180
                    result_repo.set_make_working_trees(local_repo.make_working_trees())
163
181
        # 1 if there is a branch present
164
182
        #   make sure its content is available in the target repository
168
186
        except errors.NotBranchError:
169
187
            pass
170
188
        try:
171
 
            self.open_workingtree().clone(result, basis=basis_tree)
 
189
            self.open_workingtree().clone(result)
172
190
        except (errors.NoWorkingTree, errors.NotLocalUrl):
173
191
            pass
174
192
        return result
175
193
 
176
 
    def _get_basis_components(self, basis):
177
 
        """Retrieve the basis components that are available at basis."""
178
 
        if basis is None:
179
 
            return None, None, None
180
 
        try:
181
 
            basis_tree = basis.open_workingtree()
182
 
            basis_branch = basis_tree.branch
183
 
            basis_repo = basis_branch.repository
184
 
        except (errors.NoWorkingTree, errors.NotLocalUrl):
185
 
            basis_tree = None
186
 
            try:
187
 
                basis_branch = basis.open_branch()
188
 
                basis_repo = basis_branch.repository
189
 
            except errors.NotBranchError:
190
 
                basis_branch = None
191
 
                try:
192
 
                    basis_repo = basis.open_repository()
193
 
                except errors.NoRepositoryPresent:
194
 
                    basis_repo = None
195
 
        return basis_repo, basis_branch, basis_tree
196
 
 
197
194
    # TODO: This should be given a Transport, and should chdir up; otherwise
198
195
    # this will open a new connection.
199
196
    def _make_tail(self, url):
536
533
        :param transport: Transport containing the bzrdir.
537
534
        :param _unsupported: private.
538
535
        """
539
 
        format = BzrDirFormat.find_format(transport)
 
536
        base = transport.base
 
537
 
 
538
        def find_format(transport):
 
539
            return transport, BzrDirFormat.find_format(transport)
 
540
 
 
541
        def redirected(transport, e, redirection_notice):
 
542
            qualified_source = e.get_source_url()
 
543
            relpath = transport.relpath(qualified_source)
 
544
            if not e.target.endswith(relpath):
 
545
                # Not redirected to a branch-format, not a branch
 
546
                raise errors.NotBranchError(path=e.target)
 
547
            target = e.target[:-len(relpath)]
 
548
            note('%s is%s redirected to %s',
 
549
                 transport.base, e.permanently, target)
 
550
            # Let's try with a new transport
 
551
            qualified_target = e.get_target_url()[:-len(relpath)]
 
552
            # FIXME: If 'transport' has a qualifier, this should
 
553
            # be applied again to the new transport *iff* the
 
554
            # schemes used are the same. It's a bit tricky to
 
555
            # verify, so I'll punt for now
 
556
            # -- vila20070212
 
557
            return get_transport(target)
 
558
 
 
559
        try:
 
560
            transport, format = do_catching_redirections(find_format,
 
561
                                                         transport,
 
562
                                                         redirected)
 
563
        except errors.TooManyRedirections:
 
564
            raise errors.NotBranchError(base)
 
565
 
540
566
        BzrDir._check_supported(format, _unsupported)
541
567
        return format.open(transport, _found=True)
542
568
 
624
650
        """
625
651
        raise NotImplementedError(self.open_repository)
626
652
 
627
 
    def open_workingtree(self, _unsupported=False):
 
653
    def open_workingtree(self, _unsupported=False,
 
654
            recommend_upgrade=True):
628
655
        """Open the workingtree object at this BzrDir if one is present.
629
656
        
630
657
        TODO: static convenience version of this?
655
682
        workingtree and discards it, and that's somewhat expensive.) 
656
683
        """
657
684
        try:
658
 
            self.open_workingtree()
 
685
            self.open_workingtree(recommend_upgrade=False)
659
686
            return True
660
687
        except errors.NoWorkingTree:
661
688
            return False
662
689
 
663
690
    def _cloning_metadir(self):
664
691
        """Produce a metadir suitable for cloning with"""
665
 
        def related_repository(bzrdir):
 
692
        result_format = self._format.__class__()
 
693
        try:
666
694
            try:
667
 
                branch = bzrdir.open_branch()
668
 
                return branch.repository
 
695
                branch = self.open_branch()
 
696
                source_repository = branch.repository
669
697
            except errors.NotBranchError:
670
698
                source_branch = None
671
 
                return bzrdir.open_repository()
672
 
        result_format = self._format.__class__()
673
 
        try:
674
 
            source_repository = related_repository(self)
 
699
                source_repository = self.open_repository()
675
700
        except errors.NoRepositoryPresent:
676
701
            source_repository = None
677
702
        else:
 
703
            # XXX TODO: This isinstance is here because we have not implemented
 
704
            # the fix recommended in bug # 103195 - to delegate this choice the
 
705
            # repository itself.
678
706
            repo_format = source_repository._format
679
707
            if not isinstance(repo_format, remote.RemoteRepositoryFormat):
680
708
                result_format.repository_format = repo_format
681
709
        try:
682
 
            tree = self.open_workingtree()
 
710
            # TODO: Couldn't we just probe for the format in these cases,
 
711
            # rather than opening the whole tree?  It would be a little
 
712
            # faster. mbp 20070401
 
713
            tree = self.open_workingtree(recommend_upgrade=False)
683
714
        except (errors.NoWorkingTree, errors.NotLocalUrl):
684
715
            result_format.workingtree_format = None
685
716
        else:
704
735
    def checkout_metadir(self):
705
736
        return self.cloning_metadir()
706
737
 
707
 
    def sprout(self, url, revision_id=None, basis=None, force_new_repo=False,
 
738
    def sprout(self, url, revision_id=None, force_new_repo=False,
708
739
               recurse='down'):
709
740
        """Create a copy of this bzrdir prepared for use as a new line of
710
741
        development.
722
753
        self._make_tail(url)
723
754
        cloning_format = self.cloning_metadir()
724
755
        result = cloning_format.initialize(url)
725
 
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
726
756
        try:
727
757
            source_branch = self.open_branch()
728
758
            source_repository = source_branch.repository
731
761
            try:
732
762
                source_repository = self.open_repository()
733
763
            except errors.NoRepositoryPresent:
734
 
                # copy the entire basis one if there is one
735
 
                # but there is no repository.
736
 
                source_repository = basis_repo
 
764
                source_repository = None
737
765
        if force_new_repo:
738
766
            result_repo = None
739
767
        else:
754
782
            result_repo = result.create_repository()
755
783
        if result_repo is not None:
756
784
            # fetch needed content into target.
757
 
            if basis_repo:
758
 
                # XXX FIXME RBC 20060214 need tests for this when the basis
759
 
                # is incomplete
760
 
                result_repo.fetch(basis_repo, revision_id=revision_id)
761
785
            if source_repository is not None:
762
786
                result_repo.fetch(source_repository, revision_id=revision_id)
763
787
        if source_branch is not None:
823
847
        """Pre-splitout bzrdirs do not suffer from stale locks."""
824
848
        raise NotImplementedError(self.break_lock)
825
849
 
826
 
    def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
 
850
    def clone(self, url, revision_id=None, force_new_repo=False):
827
851
        """See BzrDir.clone()."""
828
852
        from bzrlib.workingtree import WorkingTreeFormat2
829
853
        self._make_tail(url)
830
854
        result = self._format._initialize_for_clone(url)
831
 
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
832
 
        self.open_repository().clone(result, revision_id=revision_id, basis=basis_repo)
 
855
        self.open_repository().clone(result, revision_id=revision_id)
833
856
        from_branch = self.open_branch()
834
857
        from_branch.clone(result, revision_id=revision_id)
835
858
        try:
836
 
            self.open_workingtree().clone(result, basis=basis_tree)
 
859
            self.open_workingtree().clone(result)
837
860
        except errors.NotLocalUrl:
838
861
            # make a new one, this format always has to have one.
839
862
            try:
857
880
    def create_workingtree(self, revision_id=None):
858
881
        """See BzrDir.create_workingtree."""
859
882
        # this looks buggy but is not -really-
 
883
        # because this format creates the workingtree when the bzrdir is
 
884
        # created
860
885
        # clone and sprout will have set the revision_id
861
886
        # and that will have set it for us, its only
862
887
        # specific uses of create_workingtree in isolation
863
888
        # that can do wonky stuff here, and that only
864
889
        # happens for creating checkouts, which cannot be 
865
890
        # done on this format anyway. So - acceptable wart.
866
 
        result = self.open_workingtree()
 
891
        result = self.open_workingtree(recommend_upgrade=False)
867
892
        if revision_id is not None:
868
893
            if revision_id == _mod_revision.NULL_REVISION:
869
894
                result.set_parent_ids([])
925
950
        self._check_supported(format, unsupported)
926
951
        return format.open(self, _found=True)
927
952
 
928
 
    def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
 
953
    def sprout(self, url, revision_id=None, force_new_repo=False):
929
954
        """See BzrDir.sprout()."""
930
955
        from bzrlib.workingtree import WorkingTreeFormat2
931
956
        self._make_tail(url)
932
957
        result = self._format._initialize_for_clone(url)
933
 
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
934
958
        try:
935
 
            self.open_repository().clone(result, revision_id=revision_id, basis=basis_repo)
 
959
            self.open_repository().clone(result, revision_id=revision_id)
936
960
        except errors.NoRepositoryPresent:
937
961
            pass
938
962
        try:
975
999
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
976
1000
        return RepositoryFormat5().open(self, _found=True)
977
1001
 
978
 
    def open_workingtree(self, _unsupported=False):
 
1002
    def open_workingtree(self, _unsupported=False,
 
1003
            recommend_upgrade=True):
979
1004
        """See BzrDir.create_workingtree."""
980
1005
        from bzrlib.workingtree import WorkingTreeFormat2
981
 
        return WorkingTreeFormat2().open(self, _found=True)
 
1006
        wt_format = WorkingTreeFormat2()
 
1007
        # we don't warn here about upgrades; that ought to be handled for the
 
1008
        # bzrdir as a whole
 
1009
        return wt_format.open(self, _found=True)
982
1010
 
983
1011
 
984
1012
class BzrDir6(BzrDirPreSplitOut):
992
1020
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
993
1021
        return RepositoryFormat6().open(self, _found=True)
994
1022
 
995
 
    def open_workingtree(self, _unsupported=False):
 
1023
    def open_workingtree(self, _unsupported=False,
 
1024
        recommend_upgrade=True):
996
1025
        """See BzrDir.create_workingtree."""
 
1026
        # we don't warn here about upgrades; that ought to be handled for the
 
1027
        # bzrdir as a whole
997
1028
        from bzrlib.workingtree import WorkingTreeFormat2
998
1029
        return WorkingTreeFormat2().open(self, _found=True)
999
1030
 
1026
1057
 
1027
1058
    def destroy_workingtree(self):
1028
1059
        """See BzrDir.destroy_workingtree."""
1029
 
        wt = self.open_workingtree()
 
1060
        wt = self.open_workingtree(recommend_upgrade=False)
1030
1061
        repository = wt.branch.repository
1031
1062
        empty = repository.revision_tree(_mod_revision.NULL_REVISION)
1032
1063
        wt.revert([], old_tree=empty)
1120
1151
        except errors.NotBranchError:
1121
1152
            pass
1122
1153
        try:
1123
 
            if not isinstance(self.open_workingtree()._format,
 
1154
            my_wt = self.open_workingtree(recommend_upgrade=False)
 
1155
            if not isinstance(my_wt._format,
1124
1156
                              format.workingtree_format.__class__):
1125
1157
                # the workingtree needs an upgrade.
1126
1158
                return True
1141
1173
        self._check_supported(format, unsupported)
1142
1174
        return format.open(self, _found=True)
1143
1175
 
1144
 
    def open_workingtree(self, unsupported=False):
 
1176
    def open_workingtree(self, unsupported=False,
 
1177
            recommend_upgrade=True):
1145
1178
        """See BzrDir.open_workingtree."""
1146
1179
        from bzrlib.workingtree import WorkingTreeFormat
1147
1180
        format = WorkingTreeFormat.find_format(self)
1148
 
        self._check_supported(format, unsupported)
 
1181
        self._check_supported(format, unsupported,
 
1182
            recommend_upgrade,
 
1183
            basedir=self.root_transport.base)
1149
1184
        return format.open(self, _found=True)
1150
1185
 
1151
1186
 
1332
1367
 
1333
1368
    @classmethod
1334
1369
    def register_control_format(klass, format):
1335
 
        """Register a format that does not use '.bzrdir' for its control dir.
 
1370
        """Register a format that does not use '.bzr' for its control dir.
1336
1371
 
1337
1372
        TODO: This should be pulled up into a 'ControlDirFormat' base class
1338
1373
        which BzrDirFormat can inherit from, and renamed to register_format 
1364
1399
        klass._control_formats.remove(format)
1365
1400
 
1366
1401
 
1367
 
# register BzrDirFormat as a control format
1368
 
BzrDirFormat.register_control_format(BzrDirFormat)
1369
 
 
1370
 
 
1371
1402
class BzrDirFormat4(BzrDirFormat):
1372
1403
    """Bzr dir format 4.
1373
1404
 
1624
1655
                                  __set_workingtree_format)
1625
1656
 
1626
1657
 
 
1658
# Register bzr control format
 
1659
BzrDirFormat.register_control_format(BzrDirFormat)
 
1660
 
 
1661
# Register bzr formats
1627
1662
BzrDirFormat.register_format(BzrDirFormat4())
1628
1663
BzrDirFormat.register_format(BzrDirFormat5())
1629
1664
BzrDirFormat.register_format(BzrDirFormat6())
2143
2178
                branch_converter = _mod_branch.Converter5to6()
2144
2179
                branch_converter.convert(branch)
2145
2180
        try:
2146
 
            tree = self.bzrdir.open_workingtree()
 
2181
            tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2147
2182
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2148
2183
            pass
2149
2184
        else: