~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-06-05 04:05:05 UTC
  • mfrom: (3473.1.1 ianc-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080605040505-i9kqxg2fps2qjdi0
Add the 'alias' command (Tim Penhey)

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
# TODO: Move old formats into a plugin to make this file smaller.
29
29
 
 
30
from cStringIO import StringIO
30
31
import os
31
32
import sys
32
33
 
34
35
lazy_import(globals(), """
35
36
from stat import S_ISDIR
36
37
import textwrap
 
38
from warnings import warn
37
39
 
38
40
import bzrlib
39
41
from bzrlib import (
40
 
    config,
41
42
    errors,
42
43
    graph,
43
44
    lockable_files,
44
45
    lockdir,
45
 
    osutils,
 
46
    registry,
46
47
    remote,
47
48
    revision as _mod_revision,
 
49
    symbol_versioning,
48
50
    ui,
49
51
    urlutils,
50
 
    versionedfile,
51
52
    win32utils,
52
53
    workingtree,
53
54
    workingtree_4,
55
56
    xml5,
56
57
    )
57
58
from bzrlib.osutils import (
 
59
    sha_strings,
58
60
    sha_string,
59
61
    )
60
62
from bzrlib.smart.client import _SmartClient
 
63
from bzrlib.smart import protocol
 
64
from bzrlib.store.revision.text import TextRevisionStore
 
65
from bzrlib.store.text import TextStore
61
66
from bzrlib.store.versioned import WeaveStore
62
67
from bzrlib.transactions import WriteTransaction
63
68
from bzrlib.transport import (
64
69
    do_catching_redirections,
65
70
    get_transport,
66
 
    local,
67
71
    )
68
72
from bzrlib.weave import Weave
69
73
""")
72
76
    mutter,
73
77
    note,
74
78
    )
75
 
 
76
 
from bzrlib import (
77
 
    registry,
78
 
    symbol_versioning,
 
79
from bzrlib.transport.local import LocalTransport
 
80
from bzrlib.symbol_versioning import (
 
81
    deprecated_function,
 
82
    deprecated_method,
79
83
    )
80
84
 
81
85
 
151
155
                format.get_format_description(),
152
156
                basedir)
153
157
 
154
 
    def clone(self, url, revision_id=None, force_new_repo=False,
155
 
              preserve_stacking=False):
 
158
    def clone(self, url, revision_id=None, force_new_repo=False):
156
159
        """Clone this bzrdir and its contents to url verbatim.
157
160
 
158
 
        :param url: The url create the clone at.  If url's last component does
159
 
            not exist, it will be created.
160
 
        :param revision_id: The tip revision-id to use for any branch or
161
 
            working tree.  If not None, then the clone operation may tune
 
161
        If url's last component does not exist, it will be created.
 
162
 
 
163
        if revision_id is not None, then the clone operation may tune
162
164
            itself to download less data.
163
 
        :param force_new_repo: Do not use a shared repository for the target
 
165
        :param force_new_repo: Do not use a shared repository for the target 
164
166
                               even if one is available.
165
 
        :param preserve_stacking: When cloning a stacked branch, stack the
166
 
            new branch on top of the other branch's stacked-on branch.
167
167
        """
168
168
        return self.clone_on_transport(get_transport(url),
169
169
                                       revision_id=revision_id,
170
 
                                       force_new_repo=force_new_repo,
171
 
                                       preserve_stacking=preserve_stacking)
 
170
                                       force_new_repo=force_new_repo)
172
171
 
173
172
    def clone_on_transport(self, transport, revision_id=None,
174
 
                           force_new_repo=False, preserve_stacking=False,
175
 
                           stacked_on=None):
 
173
                           force_new_repo=False):
176
174
        """Clone this bzrdir and its contents to transport verbatim.
177
175
 
178
 
        :param transport: The transport for the location to produce the clone
179
 
            at.  If the target directory does not exist, it will be created.
180
 
        :param revision_id: The tip revision-id to use for any branch or
181
 
            working tree.  If not None, then the clone operation may tune
 
176
        If the target directory does not exist, it will be created.
 
177
 
 
178
        if revision_id is not None, then the clone operation may tune
182
179
            itself to download less data.
183
 
        :param force_new_repo: Do not use a shared repository for the target,
 
180
        :param force_new_repo: Do not use a shared repository for the target 
184
181
                               even if one is available.
185
 
        :param preserve_stacking: When cloning a stacked branch, stack the
186
 
            new branch on top of the other branch's stacked-on branch.
187
182
        """
188
183
        transport.ensure_base()
189
 
        require_stacking = (stacked_on is not None)
190
 
        metadir = self.cloning_metadir(require_stacking)
191
 
        result = metadir.initialize_on_transport(transport)
 
184
        result = self.cloning_metadir().initialize_on_transport(transport)
192
185
        repository_policy = None
193
186
        try:
194
187
            local_repo = self.find_repository()
195
188
        except errors.NoRepositoryPresent:
196
189
            local_repo = None
197
 
        try:
198
 
            local_branch = self.open_branch()
199
 
        except errors.NotBranchError:
200
 
            local_branch = None
201
 
        else:
202
 
            # enable fallbacks when branch is not a branch reference
203
 
            if local_branch.repository.has_same_location(local_repo):
204
 
                local_repo = local_branch.repository
205
 
            if preserve_stacking:
206
 
                try:
207
 
                    stacked_on = local_branch.get_stacked_on_url()
208
 
                except (errors.UnstackableBranchFormat,
209
 
                        errors.UnstackableRepositoryFormat,
210
 
                        errors.NotStacked):
211
 
                    pass
212
 
 
213
190
        if local_repo:
214
191
            # may need to copy content in
215
192
            repository_policy = result.determine_repository_policy(
216
 
                force_new_repo, stacked_on, self.root_transport.base,
217
 
                require_stacking=require_stacking)
 
193
                force_new_repo)
218
194
            make_working_trees = local_repo.make_working_trees()
219
195
            result_repo = repository_policy.acquire_repository(
220
196
                make_working_trees, local_repo.is_shared())
221
197
            result_repo.fetch(local_repo, revision_id=revision_id)
222
 
        else:
223
 
            result_repo = None
224
198
        # 1 if there is a branch present
225
199
        #   make sure its content is available in the target repository
226
200
        #   clone it.
227
 
        if local_branch is not None:
 
201
        try:
 
202
            local_branch = self.open_branch()
 
203
        except errors.NotBranchError:
 
204
            pass
 
205
        else:
228
206
            result_branch = local_branch.clone(result, revision_id=revision_id)
229
207
            if repository_policy is not None:
230
208
                repository_policy.configure_branch(result_branch)
 
209
        try:
 
210
            result_repo = result.find_repository()
 
211
        except errors.NoRepositoryPresent:
 
212
            result_repo = None
231
213
        if result_repo is None or result_repo.make_working_trees():
232
214
            try:
233
215
                self.open_workingtree().clone(result)
369
351
        bzrdir._find_or_create_repository(force_new_repo)
370
352
        return bzrdir.create_branch()
371
353
 
372
 
    def determine_repository_policy(self, force_new_repo=False, stack_on=None,
373
 
                                    stack_on_pwd=None, require_stacking=False):
 
354
    def determine_repository_policy(self, force_new_repo=False):
374
355
        """Return an object representing a policy to use.
375
356
 
376
357
        This controls whether a new repository is created, or a shared
377
358
        repository used instead.
378
 
 
379
 
        If stack_on is supplied, will not seek a containing shared repo.
380
 
 
381
 
        :param force_new_repo: If True, require a new repository to be created.
382
 
        :param stack_on: If supplied, the location to stack on.  If not
383
 
            supplied, a default_stack_on location may be used.
384
 
        :param stack_on_pwd: If stack_on is relative, the location it is
385
 
            relative to.
386
359
        """
387
360
        def repository_policy(found_bzrdir):
388
 
            stack_on = None
389
 
            stack_on_pwd = None
390
 
            config = found_bzrdir.get_config()
391
361
            stop = False
392
 
            if config is not None:
393
 
                stack_on = config.get_default_stack_on()
394
 
                if stack_on is not None:
395
 
                    stack_on_pwd = found_bzrdir.root_transport.base
396
 
                    stop = True
397
 
                    note('Using default stacking branch %s at %s', stack_on,
398
 
                         stack_on_pwd)
399
362
            # does it have a repository ?
400
363
            try:
401
364
                repository = found_bzrdir.open_repository()
410
373
            if not stop:
411
374
                return None, False
412
375
            if repository:
413
 
                return UseExistingRepository(repository, stack_on,
414
 
                    stack_on_pwd, require_stacking=require_stacking), True
 
376
                return UseExistingRepository(repository), True
415
377
            else:
416
 
                return CreateRepository(self, stack_on, stack_on_pwd,
417
 
                    require_stacking=require_stacking), True
 
378
                return CreateRepository(self), True
418
379
 
419
380
        if not force_new_repo:
420
 
            if stack_on is None:
421
 
                policy = self._find_containing(repository_policy)
422
 
                if policy is not None:
423
 
                    return policy
424
 
            else:
425
 
                try:
426
 
                    return UseExistingRepository(self.open_repository(),
427
 
                        stack_on, stack_on_pwd,
428
 
                        require_stacking=require_stacking)
429
 
                except errors.NoRepositoryPresent:
430
 
                    pass
431
 
        return CreateRepository(self, stack_on, stack_on_pwd,
432
 
                                require_stacking=require_stacking)
 
381
            policy = self._find_containing(repository_policy)
 
382
            if policy is not None:
 
383
                return policy
 
384
        return CreateRepository(self)
433
385
 
434
386
    def _find_or_create_repository(self, force_new_repo):
435
387
        """Create a new repository if needed, returning the repository."""
468
420
        if force_new_tree:
469
421
            # check for non local urls
470
422
            t = get_transport(base, possible_transports)
471
 
            if not isinstance(t, local.LocalTransport):
 
423
            if not isinstance(t, LocalTransport):
472
424
                raise errors.NotLocalUrl(base)
473
425
        bzrdir = BzrDir.create(base, format, possible_transports)
474
426
        repo = bzrdir._find_or_create_repository(force_new_repo)
496
448
        :return: The WorkingTree object.
497
449
        """
498
450
        t = get_transport(base)
499
 
        if not isinstance(t, local.LocalTransport):
 
451
        if not isinstance(t, LocalTransport):
500
452
            raise errors.NotLocalUrl(base)
501
453
        bzrdir = BzrDir.create_branch_and_repo(base,
502
454
                                               force_new_repo=True,
634
586
 
635
587
    def _find_creation_modes(self):
636
588
        """Determine the appropriate modes for files and directories.
637
 
 
 
589
        
638
590
        They're always set to be consistent with the base directory,
639
591
        assuming that this transport allows setting modes.
640
592
        """
653
605
            # directories and files are read-write for this user. This is
654
606
            # mostly a workaround for filesystems which lie about being able to
655
607
            # write to a directory (cygwin & win32)
656
 
            if (st.st_mode & 07777 == 00000):
657
 
                # FTP allows stat but does not return dir/file modes
658
 
                self._dir_mode = None
659
 
                self._file_mode = None
660
 
            else:
661
 
                self._dir_mode = (st.st_mode & 07777) | 00700
662
 
                # Remove the sticky and execute bits for files
663
 
                self._file_mode = self._dir_mode & ~07111
 
608
            self._dir_mode = (st.st_mode & 07777) | 00700
 
609
            # Remove the sticky and execute bits for files
 
610
            self._file_mode = self._dir_mode & ~07111
664
611
 
665
612
    def _get_file_mode(self):
666
613
        """Return Unix mode for newly created files, or None.
701
648
        guaranteed to point to an existing directory ready for use.
702
649
        """
703
650
        raise NotImplementedError(self.get_workingtree_transport)
704
 
 
705
 
    def get_config(self):
706
 
        if getattr(self, '_get_config', None) is None:
707
 
            return None
708
 
        return self._get_config()
709
 
 
 
651
        
710
652
    def __init__(self, _transport, _format):
711
653
        """Initialize a Bzr control dir object.
712
654
        
902
844
        tree, branch = bzrdir._get_tree_branch()
903
845
        return tree, branch, relpath
904
846
 
905
 
    @classmethod
906
 
    def open_containing_tree_branch_or_repository(klass, location):
907
 
        """Return the working tree, branch and repo contained by a location.
908
 
 
909
 
        Returns (tree, branch, repository, relpath).
910
 
        If there is no tree containing the location, tree will be None.
911
 
        If there is no branch containing the location, branch will be None.
912
 
        If there is no repository containing the location, repository will be
913
 
        None.
914
 
        relpath is the portion of the path that is contained by the innermost
915
 
        BzrDir.
916
 
 
917
 
        If no tree, branch or repository is found, a NotBranchError is raised.
918
 
        """
919
 
        bzrdir, relpath = klass.open_containing(location)
920
 
        try:
921
 
            tree, branch = bzrdir._get_tree_branch()
922
 
        except errors.NotBranchError:
923
 
            try:
924
 
                repo = bzrdir.find_repository()
925
 
                return None, None, repo, relpath
926
 
            except (errors.NoRepositoryPresent):
927
 
                raise errors.NotBranchError(location)
928
 
        return tree, branch, branch.repository, relpath
929
 
 
930
847
    def open_repository(self, _unsupported=False):
931
848
        """Open the repository object at this BzrDir if one is present.
932
849
 
981
898
            return False
982
899
 
983
900
    def _cloning_metadir(self):
984
 
        """Produce a metadir suitable for cloning with.
985
 
        
986
 
        :returns: (destination_bzrdir_format, source_repository)
987
 
        """
 
901
        """Produce a metadir suitable for cloning with."""
988
902
        result_format = self._format.__class__()
989
903
        try:
990
904
            try:
991
905
                branch = self.open_branch()
992
906
                source_repository = branch.repository
993
 
                result_format._branch_format = branch._format
994
907
            except errors.NotBranchError:
995
908
                source_branch = None
996
909
                source_repository = self.open_repository()
1001
914
            # the fix recommended in bug # 103195 - to delegate this choice the
1002
915
            # repository itself.
1003
916
            repo_format = source_repository._format
1004
 
            if isinstance(repo_format, remote.RemoteRepositoryFormat):
1005
 
                source_repository._ensure_real()
1006
 
                repo_format = source_repository._real_repository._format
1007
 
            result_format.repository_format = repo_format
 
917
            if not isinstance(repo_format, remote.RemoteRepositoryFormat):
 
918
                result_format.repository_format = repo_format
1008
919
        try:
1009
920
            # TODO: Couldn't we just probe for the format in these cases,
1010
921
            # rather than opening the whole tree?  It would be a little
1016
927
            result_format.workingtree_format = tree._format.__class__()
1017
928
        return result_format, source_repository
1018
929
 
1019
 
    def cloning_metadir(self, require_stacking=False):
 
930
    def cloning_metadir(self):
1020
931
        """Produce a metadir suitable for cloning or sprouting with.
1021
932
 
1022
933
        These operations may produce workingtrees (yes, even though they're
1023
934
        "cloning" something that doesn't have a tree), so a viable workingtree
1024
935
        format must be selected.
1025
 
 
1026
 
        :require_stacking: If True, non-stackable formats will be upgraded
1027
 
            to similar stackable formats.
1028
 
        :returns: a BzrDirFormat with all component formats either set
1029
 
            appropriately or set to None if that component should not be
1030
 
            created.
1031
936
        """
1032
937
        format, repository = self._cloning_metadir()
1033
938
        if format._workingtree_format is None:
1035
940
                return format
1036
941
            tree_format = repository._format._matchingbzrdir.workingtree_format
1037
942
            format.workingtree_format = tree_format.__class__()
1038
 
        if (require_stacking and not
1039
 
            format.get_branch_format().supports_stacking()):
1040
 
            # We need to make a stacked branch, but the default format for the
1041
 
            # target doesn't support stacking.  So force a branch that *can*
1042
 
            # support stacking.
1043
 
            from bzrlib.branch import BzrBranchFormat7
1044
 
            format._branch_format = BzrBranchFormat7()
1045
 
            mutter("using %r for stacking" % (format._branch_format,))
1046
 
            from bzrlib.repofmt import pack_repo
1047
 
            if format.repository_format.rich_root_data:
1048
 
                bzrdir_format_name = '1.6.1-rich-root'
1049
 
                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
1050
 
            else:
1051
 
                bzrdir_format_name = '1.6'
1052
 
                repo_format = pack_repo.RepositoryFormatKnitPack5()
1053
 
            note('Source format does not support stacking, using format:'
1054
 
                 ' \'%s\'\n  %s\n',
1055
 
                 bzrdir_format_name, repo_format.get_format_description())
1056
 
            format.repository_format = repo_format
1057
943
        return format
1058
944
 
1059
945
    def checkout_metadir(self):
1061
947
 
1062
948
    def sprout(self, url, revision_id=None, force_new_repo=False,
1063
949
               recurse='down', possible_transports=None,
1064
 
               accelerator_tree=None, hardlink=False, stacked=False):
 
950
               accelerator_tree=None, hardlink=False):
1065
951
        """Create a copy of this bzrdir prepared for use as a new line of
1066
952
        development.
1067
953
 
1080
966
            content is different.
1081
967
        :param hardlink: If true, hard-link files from accelerator_tree,
1082
968
            where possible.
1083
 
        :param stacked: If true, create a stacked branch referring to the
1084
 
            location of this control directory.
1085
969
        """
1086
970
        target_transport = get_transport(url, possible_transports)
1087
971
        target_transport.ensure_base()
1088
 
        cloning_format = self.cloning_metadir(stacked)
1089
 
        # Create/update the result branch
 
972
        cloning_format = self.cloning_metadir()
1090
973
        result = cloning_format.initialize_on_transport(target_transport)
1091
974
        try:
1092
975
            source_branch = self.open_branch()
1093
976
            source_repository = source_branch.repository
1094
 
            if stacked:
1095
 
                stacked_branch_url = self.root_transport.base
1096
 
            else:
1097
 
                # if a stacked branch wasn't requested, we don't create one
1098
 
                # even if the origin was stacked
1099
 
                stacked_branch_url = None
1100
977
        except errors.NotBranchError:
1101
978
            source_branch = None
1102
979
            try:
1103
980
                source_repository = self.open_repository()
1104
981
            except errors.NoRepositoryPresent:
1105
982
                source_repository = None
1106
 
            stacked_branch_url = None
1107
 
        repository_policy = result.determine_repository_policy(
1108
 
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1109
 
        result_repo = repository_policy.acquire_repository()
1110
 
        if source_repository is not None:
1111
 
            # Fetch while stacked to prevent unstacked fetch from
1112
 
            # Branch.sprout.
1113
 
            result_repo.fetch(source_repository, revision_id=revision_id)
1114
 
 
1115
 
        if source_branch is None:
1116
 
            # this is for sprouting a bzrdir without a branch; is that
1117
 
            # actually useful?
1118
 
            # Not especially, but it's part of the contract.
1119
 
            result_branch = result.create_branch()
1120
 
        else:
1121
 
            # Force NULL revision to avoid using repository before stacking
1122
 
            # is configured.
1123
 
            result_branch = source_branch.sprout(
1124
 
                result, revision_id=_mod_revision.NULL_REVISION)
1125
 
            parent_location = result_branch.get_parent()
1126
 
        mutter("created new branch %r" % (result_branch,))
1127
 
        repository_policy.configure_branch(result_branch)
 
983
        if force_new_repo:
 
984
            result_repo = None
 
985
        else:
 
986
            try:
 
987
                result_repo = result.find_repository()
 
988
            except errors.NoRepositoryPresent:
 
989
                result_repo = None
 
990
        if source_repository is None and result_repo is not None:
 
991
            pass
 
992
        elif source_repository is None and result_repo is None:
 
993
            # no repo available, make a new one
 
994
            result.create_repository()
 
995
        elif source_repository is not None and result_repo is None:
 
996
            # have source, and want to make a new target repo
 
997
            result_repo = source_repository.sprout(result,
 
998
                                                   revision_id=revision_id)
 
999
        else:
 
1000
            # fetch needed content into target.
 
1001
            if source_repository is not None:
 
1002
                # would rather do 
 
1003
                # source_repository.copy_content_into(result_repo,
 
1004
                #                                     revision_id=revision_id)
 
1005
                # so we can override the copy method
 
1006
                result_repo.fetch(source_repository, revision_id=revision_id)
1128
1007
        if source_branch is not None:
1129
 
            source_branch.copy_content_into(result_branch, revision_id)
1130
 
            # Override copy_content_into
1131
 
            result_branch.set_parent(parent_location)
1132
 
 
1133
 
        # Create/update the result working tree
1134
 
        if isinstance(target_transport, local.LocalTransport) and (
 
1008
            source_branch.sprout(result, revision_id=revision_id)
 
1009
        else:
 
1010
            result.create_branch()
 
1011
        if isinstance(target_transport, LocalTransport) and (
1135
1012
            result_repo is None or result_repo.make_working_trees()):
1136
1013
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1137
1014
                hardlink=hardlink)
1151
1028
                basis = wt.basis_tree()
1152
1029
                basis.lock_read()
1153
1030
                subtrees = basis.iter_references()
1154
 
            elif result_branch is not None:
1155
 
                basis = result_branch.basis_tree()
1156
 
                basis.lock_read()
1157
 
                subtrees = basis.iter_references()
 
1031
                recurse_branch = wt.branch
1158
1032
            elif source_branch is not None:
1159
1033
                basis = source_branch.basis_tree()
1160
1034
                basis.lock_read()
1161
1035
                subtrees = basis.iter_references()
 
1036
                recurse_branch = source_branch
1162
1037
            else:
1163
1038
                subtrees = []
1164
1039
                basis = None
1168
1043
                    sublocation = source_branch.reference_parent(file_id, path)
1169
1044
                    sublocation.bzrdir.sprout(target,
1170
1045
                        basis.get_reference_revision(file_id, path),
1171
 
                        force_new_repo=force_new_repo, recurse=recurse,
1172
 
                        stacked=stacked)
 
1046
                        force_new_repo=force_new_repo, recurse=recurse)
1173
1047
            finally:
1174
1048
                if basis is not None:
1175
1049
                    basis.unlock()
1191
1065
        """Pre-splitout bzrdirs do not suffer from stale locks."""
1192
1066
        raise NotImplementedError(self.break_lock)
1193
1067
 
1194
 
    def cloning_metadir(self, require_stacking=False):
 
1068
    def cloning_metadir(self):
1195
1069
        """Produce a metadir suitable for cloning with."""
1196
 
        if require_stacking:
1197
 
            return format_registry.make_bzrdir('1.6')
1198
1070
        return self._format.__class__()
1199
1071
 
1200
 
    def clone(self, url, revision_id=None, force_new_repo=False,
1201
 
              preserve_stacking=False):
1202
 
        """See BzrDir.clone().
1203
 
 
1204
 
        force_new_repo has no effect, since this family of formats always
1205
 
        require a new repository.
1206
 
        preserve_stacking has no effect, since no source branch using this
1207
 
        family of formats can be stacked, so there is no stacking to preserve.
1208
 
        """
 
1072
    def clone(self, url, revision_id=None, force_new_repo=False):
 
1073
        """See BzrDir.clone()."""
 
1074
        from bzrlib.workingtree import WorkingTreeFormat2
1209
1075
        self._make_tail(url)
1210
1076
        result = self._format._initialize_for_clone(url)
1211
1077
        self.open_repository().clone(result, revision_id=revision_id)
1212
1078
        from_branch = self.open_branch()
1213
1079
        from_branch.clone(result, revision_id=revision_id)
1214
1080
        try:
1215
 
            tree = self.open_workingtree()
 
1081
            self.open_workingtree().clone(result)
1216
1082
        except errors.NotLocalUrl:
1217
1083
            # make a new one, this format always has to have one.
1218
 
            result._init_workingtree()
1219
 
        else:
1220
 
            tree.clone(result)
 
1084
            try:
 
1085
                WorkingTreeFormat2().initialize(result)
 
1086
            except errors.NotLocalUrl:
 
1087
                # but we cannot do it for remote trees.
 
1088
                to_branch = result.open_branch()
 
1089
                WorkingTreeFormat2()._stub_initialize_remote(to_branch)
1221
1090
        return result
1222
1091
 
1223
1092
    def create_branch(self):
1224
1093
        """See BzrDir.create_branch."""
1225
 
        return self._format.get_branch_format().initialize(self)
 
1094
        return self.open_branch()
1226
1095
 
1227
1096
    def destroy_branch(self):
1228
1097
        """See BzrDir.destroy_branch."""
1241
1110
    def create_workingtree(self, revision_id=None, from_branch=None,
1242
1111
                           accelerator_tree=None, hardlink=False):
1243
1112
        """See BzrDir.create_workingtree."""
1244
 
        # The workingtree is sometimes created when the bzrdir is created,
1245
 
        # but not when cloning.
1246
 
 
1247
1113
        # this looks buggy but is not -really-
1248
1114
        # because this format creates the workingtree when the bzrdir is
1249
1115
        # created
1253
1119
        # that can do wonky stuff here, and that only
1254
1120
        # happens for creating checkouts, which cannot be 
1255
1121
        # done on this format anyway. So - acceptable wart.
1256
 
        try:
1257
 
            result = self.open_workingtree(recommend_upgrade=False)
1258
 
        except errors.NoSuchFile:
1259
 
            result = self._init_workingtree()
 
1122
        result = self.open_workingtree(recommend_upgrade=False)
1260
1123
        if revision_id is not None:
1261
1124
            if revision_id == _mod_revision.NULL_REVISION:
1262
1125
                result.set_parent_ids([])
1264
1127
                result.set_parent_ids([revision_id])
1265
1128
        return result
1266
1129
 
1267
 
    def _init_workingtree(self):
1268
 
        from bzrlib.workingtree import WorkingTreeFormat2
1269
 
        try:
1270
 
            return WorkingTreeFormat2().initialize(self)
1271
 
        except errors.NotLocalUrl:
1272
 
            # Even though we can't access the working tree, we need to
1273
 
            # create its control files.
1274
 
            return WorkingTreeFormat2()._stub_initialize_on_transport(
1275
 
                self.transport, self._control_files._file_mode)
1276
 
 
1277
1130
    def destroy_workingtree(self):
1278
1131
        """See BzrDir.destroy_workingtree."""
1279
1132
        raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1330
1183
 
1331
1184
    def sprout(self, url, revision_id=None, force_new_repo=False,
1332
1185
               possible_transports=None, accelerator_tree=None,
1333
 
               hardlink=False, stacked=False):
 
1186
               hardlink=False):
1334
1187
        """See BzrDir.sprout()."""
1335
 
        if stacked:
1336
 
            raise errors.UnstackableBranchFormat(
1337
 
                self._format, self.root_transport.base)
1338
1188
        from bzrlib.workingtree import WorkingTreeFormat2
1339
1189
        self._make_tail(url)
1340
1190
        result = self._format._initialize_for_clone(url)
1578
1428
            basedir=self.root_transport.base)
1579
1429
        return format.open(self, _found=True)
1580
1430
 
1581
 
    def _get_config(self):
1582
 
        return config.BzrDirConfig(self.transport)
1583
 
 
1584
1431
 
1585
1432
class BzrDirFormat(object):
1586
1433
    """An encapsulation of the initialization and open routines for a format.
1696
1543
                                      # FIXME: RBC 20060121 don't peek under
1697
1544
                                      # the covers
1698
1545
                                      mode=temp_control._dir_mode)
1699
 
        if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
 
1546
        if sys.platform == 'win32' and isinstance(transport, LocalTransport):
1700
1547
            win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1701
1548
        file_mode = temp_control._file_mode
1702
1549
        del temp_control
1886
1733
        """See BzrDirFormat.get_format_string()."""
1887
1734
        return "Bazaar-NG branch, format 5\n"
1888
1735
 
1889
 
    def get_branch_format(self):
1890
 
        from bzrlib import branch
1891
 
        return branch.BzrBranchFormat4()
1892
 
 
1893
1736
    def get_format_description(self):
1894
1737
        """See BzrDirFormat.get_format_description()."""
1895
1738
        return "All-in-one format 5"
1909
1752
        """
1910
1753
        from bzrlib.branch import BzrBranchFormat4
1911
1754
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
 
1755
        from bzrlib.workingtree import WorkingTreeFormat2
1912
1756
        result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1913
1757
        RepositoryFormat5().initialize(result, _internal=True)
1914
1758
        if not _cloning:
1915
1759
            branch = BzrBranchFormat4().initialize(result)
1916
 
            result._init_workingtree()
 
1760
            try:
 
1761
                WorkingTreeFormat2().initialize(result)
 
1762
            except errors.NotLocalUrl:
 
1763
                # Even though we can't access the working tree, we need to
 
1764
                # create its control files.
 
1765
                WorkingTreeFormat2()._stub_initialize_remote(branch)
1917
1766
        return result
1918
1767
 
1919
1768
    def _open(self, transport):
1947
1796
        """See BzrDirFormat.get_format_description()."""
1948
1797
        return "All-in-one format 6"
1949
1798
 
1950
 
    def get_branch_format(self):
1951
 
        from bzrlib import branch
1952
 
        return branch.BzrBranchFormat4()
1953
 
 
1954
1799
    def get_converter(self, format=None):
1955
1800
        """See BzrDirFormat.get_converter()."""
1956
1801
        # there is one and only one upgrade path here.
1966
1811
        """
1967
1812
        from bzrlib.branch import BzrBranchFormat4
1968
1813
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
 
1814
        from bzrlib.workingtree import WorkingTreeFormat2
1969
1815
        result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1970
1816
        RepositoryFormat6().initialize(result, _internal=True)
1971
1817
        if not _cloning:
1972
1818
            branch = BzrBranchFormat4().initialize(result)
1973
 
            result._init_workingtree()
 
1819
            try:
 
1820
                WorkingTreeFormat2().initialize(result)
 
1821
            except errors.NotLocalUrl:
 
1822
                # Even though we can't access the working tree, we need to
 
1823
                # create its control files.
 
1824
                WorkingTreeFormat2()._stub_initialize_remote(branch)
1974
1825
        return result
1975
1826
 
1976
1827
    def _open(self, transport):
2112
1963
        self.bzrdir = to_convert
2113
1964
        self.pb = pb
2114
1965
        self.pb.note('starting upgrade from format 4 to 5')
2115
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
 
1966
        if isinstance(self.bzrdir.transport, LocalTransport):
2116
1967
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2117
1968
        self._convert_to_weaves()
2118
1969
        return BzrDir.open(self.bzrdir.root_transport.base)
2204
2055
        self.bzrdir.transport.mkdir('revision-store')
2205
2056
        revision_transport = self.bzrdir.transport.clone('revision-store')
2206
2057
        # TODO permissions
2207
 
        from bzrlib.xml5 import serializer_v5
2208
 
        from bzrlib.repofmt.weaverepo import RevisionTextStore
2209
 
        revision_store = RevisionTextStore(revision_transport,
2210
 
            serializer_v5, False, versionedfile.PrefixMapper(),
2211
 
            lambda:True, lambda:True)
 
2058
        _revision_store = TextRevisionStore(TextStore(revision_transport,
 
2059
                                                      prefixed=False,
 
2060
                                                      compressed=True))
2212
2061
        try:
 
2062
            transaction = WriteTransaction()
2213
2063
            for i, rev_id in enumerate(self.converted_revs):
2214
2064
                self.pb.update('write revision', i, len(self.converted_revs))
2215
 
                text = serializer_v5.write_revision_to_string(
2216
 
                    self.revisions[rev_id])
2217
 
                key = (rev_id,)
2218
 
                revision_store.add_lines(key, None, osutils.split_lines(text))
 
2065
                _revision_store.add_revision(self.revisions[rev_id], transaction)
2219
2066
        finally:
2220
2067
            self.pb.clear()
2221
2068
            
2234
2081
                         rev_id)
2235
2082
            self.absent_revisions.add(rev_id)
2236
2083
        else:
2237
 
            rev = self.branch.repository.get_revision(rev_id)
 
2084
            rev = self.branch.repository._revision_store.get_revision(rev_id,
 
2085
                self.branch.repository.get_transaction())
2238
2086
            for parent_id in rev.parent_ids:
2239
2087
                self.known_revisions.add(parent_id)
2240
2088
                self.to_read.append(parent_id)
2330
2178
                ie.revision = previous_ie.revision
2331
2179
                return
2332
2180
        if ie.has_text():
2333
 
            text = self.branch.repository._text_store.get(ie.text_id)
 
2181
            text = self.branch.repository.weave_store.get(ie.text_id)
2334
2182
            file_lines = text.readlines()
2335
2183
            w.add_lines(rev_id, previous_revisions, file_lines)
2336
2184
            self.text_count += 1
2384
2232
                if (filename.endswith(".weave") or
2385
2233
                    filename.endswith(".gz") or
2386
2234
                    filename.endswith(".sig")):
2387
 
                    file_id, suffix = os.path.splitext(filename)
 
2235
                    file_id = os.path.splitext(filename)[0]
2388
2236
                else:
2389
2237
                    file_id = filename
2390
 
                    suffix = ''
2391
 
                new_name = store._mapper.map((file_id,)) + suffix
 
2238
                prefix_dir = store.hash_prefix(file_id)
2392
2239
                # FIXME keep track of the dirs made RBC 20060121
2393
2240
                try:
2394
 
                    store_transport.move(filename, new_name)
 
2241
                    store_transport.move(filename, prefix_dir + '/' + filename)
2395
2242
                except errors.NoSuchFile: # catches missing dirs strangely enough
2396
 
                    store_transport.mkdir(osutils.dirname(new_name))
2397
 
                    store_transport.move(filename, new_name)
 
2243
                    store_transport.mkdir(prefix_dir)
 
2244
                    store_transport.move(filename, prefix_dir + '/' + filename)
2398
2245
        self.bzrdir.transport.put_bytes(
2399
2246
            'branch-format',
2400
2247
            BzrDirFormat6().get_format_string(),
2556
2403
            pass
2557
2404
        else:
2558
2405
            # TODO: conversions of Branch and Tree should be done by
2559
 
            # InterXFormat lookups/some sort of registry.
 
2406
            # InterXFormat lookups
2560
2407
            # Avoid circular imports
2561
2408
            from bzrlib import branch as _mod_branch
2562
 
            old = branch._format.__class__
2563
 
            new = self.target_format.get_branch_format().__class__
2564
 
            while old != new:
2565
 
                if (old == _mod_branch.BzrBranchFormat5 and
2566
 
                    new in (_mod_branch.BzrBranchFormat6,
2567
 
                        _mod_branch.BzrBranchFormat7)):
2568
 
                    branch_converter = _mod_branch.Converter5to6()
2569
 
                elif (old == _mod_branch.BzrBranchFormat6 and
2570
 
                    new == _mod_branch.BzrBranchFormat7):
2571
 
                    branch_converter = _mod_branch.Converter6to7()
2572
 
                else:
2573
 
                    raise errors.BadConversionTarget("No converter", new)
 
2409
            if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
 
2410
                self.target_format.get_branch_format().__class__ is
 
2411
                _mod_branch.BzrBranchFormat6):
 
2412
                branch_converter = _mod_branch.Converter5to6()
2574
2413
                branch_converter.convert(branch)
2575
 
                branch = self.bzrdir.open_branch()
2576
 
                old = branch._format.__class__
2577
2414
        try:
2578
2415
            tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2579
2416
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2827
2664
    for a branch that is being created.  The most basic policy decision is
2828
2665
    whether to create a new repository or use an existing one.
2829
2666
    """
2830
 
    def __init__(self, stack_on, stack_on_pwd, require_stacking):
2831
 
        """Constructor.
2832
 
 
2833
 
        :param stack_on: A location to stack on
2834
 
        :param stack_on_pwd: If stack_on is relative, the location it is
2835
 
            relative to.
2836
 
        :param require_stacking: If True, it is a failure to not stack.
2837
 
        """
2838
 
        self._stack_on = stack_on
2839
 
        self._stack_on_pwd = stack_on_pwd
2840
 
        self._require_stacking = require_stacking
2841
2667
 
2842
2668
    def configure_branch(self, branch):
2843
2669
        """Apply any configuration data from this policy to the branch.
2844
2670
 
2845
 
        Default implementation sets repository stacking.
 
2671
        Default implementation does nothing.
2846
2672
        """
2847
 
        if self._stack_on is None:
2848
 
            return
2849
 
        if self._stack_on_pwd is None:
2850
 
            stack_on = self._stack_on
2851
 
        else:
2852
 
            try:
2853
 
                stack_on = urlutils.rebase_url(self._stack_on,
2854
 
                    self._stack_on_pwd,
2855
 
                    branch.bzrdir.root_transport.base)
2856
 
            except errors.InvalidRebaseURLs:
2857
 
                stack_on = self._get_full_stack_on()
2858
 
        try:
2859
 
            branch.set_stacked_on_url(stack_on)
2860
 
        except errors.UnstackableBranchFormat:
2861
 
            if self._require_stacking:
2862
 
                raise
2863
 
 
2864
 
    def _get_full_stack_on(self):
2865
 
        """Get a fully-qualified URL for the stack_on location."""
2866
 
        if self._stack_on is None:
2867
 
            return None
2868
 
        if self._stack_on_pwd is None:
2869
 
            return self._stack_on
2870
 
        else:
2871
 
            return urlutils.join(self._stack_on_pwd, self._stack_on)
2872
 
 
2873
 
    def _add_fallback(self, repository):
2874
 
        """Add a fallback to the supplied repository, if stacking is set."""
2875
 
        stack_on = self._get_full_stack_on()
2876
 
        if stack_on is None:
2877
 
            return
2878
 
        stacked_dir = BzrDir.open(stack_on)
2879
 
        try:
2880
 
            stacked_repo = stacked_dir.open_branch().repository
2881
 
        except errors.NotBranchError:
2882
 
            stacked_repo = stacked_dir.open_repository()
2883
 
        try:
2884
 
            repository.add_fallback_repository(stacked_repo)
2885
 
        except errors.UnstackableRepositoryFormat:
2886
 
            if self._require_stacking:
2887
 
                raise
 
2673
        pass
2888
2674
 
2889
2675
    def acquire_repository(self, make_working_trees=None, shared=False):
2890
2676
        """Acquire a repository for this bzrdir.
2902
2688
class CreateRepository(RepositoryAcquisitionPolicy):
2903
2689
    """A policy of creating a new repository"""
2904
2690
 
2905
 
    def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2906
 
                 require_stacking=False):
2907
 
        """
2908
 
        Constructor.
2909
 
        :param bzrdir: The bzrdir to create the repository on.
2910
 
        :param stack_on: A location to stack on
2911
 
        :param stack_on_pwd: If stack_on is relative, the location it is
2912
 
            relative to.
2913
 
        """
2914
 
        RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2915
 
                                             require_stacking)
 
2691
    def __init__(self, bzrdir):
 
2692
        RepositoryAcquisitionPolicy.__init__(self)
2916
2693
        self._bzrdir = bzrdir
2917
2694
 
2918
2695
    def acquire_repository(self, make_working_trees=None, shared=False):
2921
2698
        Creates the desired repository in the bzrdir we already have.
2922
2699
        """
2923
2700
        repository = self._bzrdir.create_repository(shared=shared)
2924
 
        self._add_fallback(repository)
2925
2701
        if make_working_trees is not None:
2926
2702
            repository.set_make_working_trees(make_working_trees)
2927
2703
        return repository
2930
2706
class UseExistingRepository(RepositoryAcquisitionPolicy):
2931
2707
    """A policy of reusing an existing repository"""
2932
2708
 
2933
 
    def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2934
 
                 require_stacking=False):
2935
 
        """Constructor.
2936
 
 
2937
 
        :param repository: The repository to use.
2938
 
        :param stack_on: A location to stack on
2939
 
        :param stack_on_pwd: If stack_on is relative, the location it is
2940
 
            relative to.
2941
 
        """
2942
 
        RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2943
 
                                             require_stacking)
 
2709
    def __init__(self, repository):
 
2710
        RepositoryAcquisitionPolicy.__init__(self)
2944
2711
        self._repository = repository
2945
2712
 
2946
2713
    def acquire_repository(self, make_working_trees=None, shared=False):
2948
2715
 
2949
2716
        Returns an existing repository to use
2950
2717
        """
2951
 
        self._add_fallback(self._repository)
2952
2718
        return self._repository
2953
2719
 
2954
2720
 
3034
2800
    branch_format='bzrlib.branch.BzrBranchFormat6',
3035
2801
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3036
2802
    )
3037
 
format_registry.register_metadir('1.6',
3038
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3039
 
    help='A branch and pack based repository that supports stacking. ',
3040
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3041
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3042
 
    )
3043
 
format_registry.register_metadir('1.6.1-rich-root',
3044
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3045
 
    help='A branch and pack based repository that supports stacking '
3046
 
         'and rich root data (needed for bzr-svn). ',
3047
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3048
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3049
 
    )
3050
2803
# The following two formats should always just be aliases.
3051
2804
format_registry.register_metadir('development',
3052
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
 
2805
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0',
3053
2806
    help='Current development format. Can convert data to and from pack-0.92 '
3054
2807
        '(and anything compatible with pack-0.92) format repositories. '
3055
 
        'Repositories and branches in this format can only be read by bzr.dev. '
 
2808
        'Repositories in this format can only be read by bzr.dev. '
3056
2809
        'Please read '
3057
2810
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3058
2811
        'before use.',
3059
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
2812
    branch_format='bzrlib.branch.BzrBranchFormat6',
3060
2813
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3061
2814
    experimental=True,
3062
2815
    alias=True,
3063
2816
    )
3064
2817
format_registry.register_metadir('development-subtree',
3065
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
2818
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0Subtree',
3066
2819
    help='Current development format, subtree variant. Can convert data to and '
3067
 
        'from pack-0.92-subtree (and anything compatible with '
3068
 
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3069
 
        'this format can only be read by bzr.dev. Please read '
 
2820
        'from pack-0.92 (and anything compatible with pack-0.92) format '
 
2821
        'repositories. Repositories in this format can only be read by '
 
2822
        'bzr.dev. Please read '
3070
2823
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3071
2824
        'before use.',
3072
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
2825
    branch_format='bzrlib.branch.BzrBranchFormat6',
3073
2826
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3074
2827
    experimental=True,
3075
2828
    alias=True,
3076
2829
    )
3077
 
# And the development formats above will have aliased one of the following:
3078
 
format_registry.register_metadir('development2',
3079
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3080
 
    help='1.6.1 with B+Tree based index. '
3081
 
        'Please read '
3082
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3083
 
        'before use.',
3084
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3085
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3086
 
    hidden=True,
3087
 
    experimental=True,
3088
 
    )
3089
 
format_registry.register_metadir('development2-subtree',
3090
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3091
 
    help='1.6.1-subtree with B+Tree based index. '
3092
 
        'Please read '
3093
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3094
 
        'before use.',
3095
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3096
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3097
 
    hidden=True,
3098
 
    experimental=True,
3099
 
    )
3100
 
# The current format that is made on 'bzr init'.
 
2830
# And the development formats which the will have aliased one of follow:
 
2831
format_registry.register_metadir('development0',
 
2832
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0',
 
2833
    help='Trivial rename of pack-0.92 to provide a development format. '
 
2834
        'Please read '
 
2835
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
2836
        'before use.',
 
2837
    branch_format='bzrlib.branch.BzrBranchFormat6',
 
2838
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
2839
    hidden=True,
 
2840
    experimental=True,
 
2841
    )
 
2842
format_registry.register_metadir('development0-subtree',
 
2843
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0Subtree',
 
2844
    help='Trivial rename of pack-0.92-subtree to provide a development format. '
 
2845
        'Please read '
 
2846
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
2847
        'before use.',
 
2848
    branch_format='bzrlib.branch.BzrBranchFormat6',
 
2849
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
2850
    hidden=True,
 
2851
    experimental=True,
 
2852
    )
3101
2853
format_registry.set_default('pack-0.92')