~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Robert Collins
  • Date: 2010-06-26 02:15:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5324.
  • Revision ID: robertc@robertcollins.net-20100626021526-m9z3q3r4tw5rdoo6
Remove XXX global line that is too brief to be useful landing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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(), """
37
38
 
38
39
import bzrlib
39
40
from bzrlib import (
 
41
    branch,
40
42
    config,
41
43
    errors,
42
44
    graph,
44
46
    lockdir,
45
47
    osutils,
46
48
    remote,
 
49
    repository,
47
50
    revision as _mod_revision,
48
51
    ui,
49
52
    urlutils,
57
60
from bzrlib.osutils import (
58
61
    sha_string,
59
62
    )
 
63
from bzrlib.push import (
 
64
    PushResult,
 
65
    )
 
66
from bzrlib.repofmt import pack_repo
60
67
from bzrlib.smart.client import _SmartClient
61
68
from bzrlib.store.versioned import WeaveStore
62
69
from bzrlib.transactions import WriteTransaction
64
71
    do_catching_redirections,
65
72
    get_transport,
66
73
    local,
67
 
    remote as remote_transport,
68
74
    )
69
75
from bzrlib.weave import Weave
70
76
""")
72
78
from bzrlib.trace import (
73
79
    mutter,
74
80
    note,
 
81
    warning,
75
82
    )
76
83
 
77
84
from bzrlib import (
79
86
    registry,
80
87
    symbol_versioning,
81
88
    )
82
 
 
83
 
 
84
 
class BzrDir(object):
 
89
    
 
90
    
 
91
class ControlComponent(object):
 
92
    """Abstract base class for control directory components.
 
93
    
 
94
    This provides interfaces that are common across bzrdirs, 
 
95
    repositories, branches, and workingtree control directories.
 
96
    
 
97
    They all expose two urls and transports: the *user* URL is the 
 
98
    one that stops above the control directory (eg .bzr) and that 
 
99
    should normally be used in messages, and the *control* URL is
 
100
    under that in eg .bzr/checkout and is used to read the control
 
101
    files.
 
102
    
 
103
    This can be used as a mixin and is intended to fit with 
 
104
    foreign formats.
 
105
    """
 
106
    
 
107
    @property
 
108
    def control_transport(self):
 
109
        raise NotImplementedError
 
110
   
 
111
    @property
 
112
    def control_url(self):
 
113
        return self.control_transport.base
 
114
    
 
115
    @property
 
116
    def user_transport(self):
 
117
        raise NotImplementedError
 
118
        
 
119
    @property
 
120
    def user_url(self):
 
121
        return self.user_transport.base
 
122
    
 
123
 
 
124
class BzrDir(ControlComponent):
85
125
    """A .bzr control diretory.
86
126
 
87
127
    BzrDir instances let you create or open any of the things that can be
123
163
        return True
124
164
 
125
165
    def check_conversion_target(self, target_format):
 
166
        """Check that a bzrdir as a whole can be converted to a new format."""
 
167
        # The only current restriction is that the repository content can be 
 
168
        # fetched compatibly with the target.
126
169
        target_repo_format = target_format.repository_format
127
 
        source_repo_format = self._format.repository_format
128
 
        source_repo_format.check_conversion_target(target_repo_format)
 
170
        try:
 
171
            self.open_repository()._format.check_conversion_target(
 
172
                target_repo_format)
 
173
        except errors.NoRepositoryPresent:
 
174
            # No repo, no problem.
 
175
            pass
129
176
 
130
177
    @staticmethod
131
178
    def _check_supported(format, allow_unsupported,
175
222
                                       preserve_stacking=preserve_stacking)
176
223
 
177
224
    def clone_on_transport(self, transport, revision_id=None,
178
 
                           force_new_repo=False, preserve_stacking=False,
179
 
                           stacked_on=None):
 
225
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
226
        create_prefix=False, use_existing_dir=True):
180
227
        """Clone this bzrdir and its contents to transport verbatim.
181
228
 
182
229
        :param transport: The transport for the location to produce the clone
188
235
                               even if one is available.
189
236
        :param preserve_stacking: When cloning a stacked branch, stack the
190
237
            new branch on top of the other branch's stacked-on branch.
 
238
        :param create_prefix: Create any missing directories leading up to
 
239
            to_transport.
 
240
        :param use_existing_dir: Use an existing directory if one exists.
191
241
        """
192
 
        transport.ensure_base()
 
242
        # Overview: put together a broad description of what we want to end up
 
243
        # with; then make as few api calls as possible to do it.
 
244
        
 
245
        # We may want to create a repo/branch/tree, if we do so what format
 
246
        # would we want for each:
193
247
        require_stacking = (stacked_on is not None)
194
248
        format = self.cloning_metadir(require_stacking)
195
 
        # Bug: We create a metadir without knowing if it can support stacking,
196
 
        # we should look up the policy needs first.
197
 
        result = format.initialize_on_transport(transport)
198
 
        repository_policy = None
 
249
        
 
250
        # Figure out what objects we want:
199
251
        try:
200
252
            local_repo = self.find_repository()
201
253
        except errors.NoRepositoryPresent:
215
267
                        errors.UnstackableRepositoryFormat,
216
268
                        errors.NotStacked):
217
269
                    pass
218
 
 
 
270
        # Bug: We create a metadir without knowing if it can support stacking,
 
271
        # we should look up the policy needs first, or just use it as a hint,
 
272
        # or something.
219
273
        if local_repo:
220
 
            # may need to copy content in
221
 
            repository_policy = result.determine_repository_policy(
222
 
                force_new_repo, stacked_on, self.root_transport.base,
223
 
                require_stacking=require_stacking)
224
274
            make_working_trees = local_repo.make_working_trees()
225
 
            result_repo, is_new_repo = repository_policy.acquire_repository(
226
 
                make_working_trees, local_repo.is_shared())
227
 
            if not require_stacking and repository_policy._require_stacking:
228
 
                require_stacking = True
229
 
                result._format.require_stacking()
230
 
            if is_new_repo and not require_stacking and revision_id is not None:
231
 
                fetch_spec = graph.PendingAncestryResult(
232
 
                    [revision_id], local_repo)
233
 
                result_repo.fetch(local_repo, fetch_spec=fetch_spec)
234
 
            else:
235
 
                result_repo.fetch(local_repo, revision_id=revision_id)
236
 
        else:
237
 
            result_repo = None
 
275
            want_shared = local_repo.is_shared()
 
276
            repo_format_name = format.repository_format.network_name()
 
277
        else:
 
278
            make_working_trees = False
 
279
            want_shared = False
 
280
            repo_format_name = None
 
281
 
 
282
        result_repo, result, require_stacking, repository_policy = \
 
283
            format.initialize_on_transport_ex(transport,
 
284
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
285
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
286
            stack_on_pwd=self.root_transport.base,
 
287
            repo_format_name=repo_format_name,
 
288
            make_working_trees=make_working_trees, shared_repo=want_shared)
 
289
        if repo_format_name:
 
290
            try:
 
291
                # If the result repository is in the same place as the
 
292
                # resulting bzr dir, it will have no content, further if the
 
293
                # result is not stacked then we know all content should be
 
294
                # copied, and finally if we are copying up to a specific
 
295
                # revision_id then we can use the pending-ancestry-result which
 
296
                # does not require traversing all of history to describe it.
 
297
                if (result_repo.user_url == result.user_url
 
298
                    and not require_stacking and
 
299
                    revision_id is not None):
 
300
                    fetch_spec = graph.PendingAncestryResult(
 
301
                        [revision_id], local_repo)
 
302
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
 
303
                else:
 
304
                    result_repo.fetch(local_repo, revision_id=revision_id)
 
305
            finally:
 
306
                result_repo.unlock()
 
307
        else:
 
308
            if result_repo is not None:
 
309
                raise AssertionError('result_repo not None(%r)' % result_repo)
238
310
        # 1 if there is a branch present
239
311
        #   make sure its content is available in the target repository
240
312
        #   clone it.
303
375
            recurse = True
304
376
            try:
305
377
                bzrdir = BzrDir.open_from_transport(current_transport)
306
 
            except errors.NotBranchError:
 
378
            except (errors.NotBranchError, errors.PermissionDenied):
307
379
                pass
308
380
            else:
309
381
                recurse, value = evaluate(bzrdir)
310
382
                yield value
311
383
            try:
312
384
                subdirs = list_current(current_transport)
313
 
            except errors.NoSuchFile:
 
385
            except (errors.NoSuchFile, errors.PermissionDenied):
314
386
                continue
315
387
            if recurse:
316
388
                for subdir in sorted(subdirs, reverse=True):
317
389
                    pending.append(current_transport.clone(subdir))
318
390
 
 
391
    def list_branches(self):
 
392
        """Return a sequence of all branches local to this control directory.
 
393
 
 
394
        """
 
395
        try:
 
396
            return [self.open_branch()]
 
397
        except errors.NotBranchError:
 
398
            return []
 
399
 
319
400
    @staticmethod
320
401
    def find_branches(transport):
321
402
        """Find all branches under a transport.
333
414
            except errors.NoRepositoryPresent:
334
415
                pass
335
416
            else:
336
 
                return False, (None, repository)
337
 
            try:
338
 
                branch = bzrdir.open_branch()
339
 
            except errors.NotBranchError:
340
 
                return True, (None, None)
341
 
            else:
342
 
                return True, (branch, None)
343
 
        branches = []
344
 
        for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
 
417
                return False, ([], repository)
 
418
            return True, (bzrdir.list_branches(), None)
 
419
        ret = []
 
420
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
421
                                                  evaluate=evaluate):
345
422
            if repo is not None:
346
 
                branches.extend(repo.find_branches())
347
 
            if branch is not None:
348
 
                branches.append(branch)
349
 
        return branches
 
423
                ret.extend(repo.find_branches())
 
424
            if branches is not None:
 
425
                ret.extend(branches)
 
426
        return ret
350
427
 
351
428
    def destroy_repository(self):
352
429
        """Destroy the repository in this BzrDir"""
353
430
        raise NotImplementedError(self.destroy_repository)
354
431
 
355
 
    def create_branch(self):
 
432
    def create_branch(self, name=None):
356
433
        """Create a branch in this BzrDir.
357
434
 
 
435
        :param name: Name of the colocated branch to create, None for
 
436
            the default branch.
 
437
 
358
438
        The bzrdir's format will control what branch format is created.
359
439
        For more control see BranchFormatXX.create(a_bzrdir).
360
440
        """
361
441
        raise NotImplementedError(self.create_branch)
362
442
 
363
 
    def destroy_branch(self):
364
 
        """Destroy the branch in this BzrDir"""
 
443
    def destroy_branch(self, name=None):
 
444
        """Destroy a branch in this BzrDir.
 
445
        
 
446
        :param name: Name of the branch to destroy, None for the default 
 
447
            branch.
 
448
        """
365
449
        raise NotImplementedError(self.destroy_branch)
366
450
 
367
451
    @staticmethod
405
489
            stack_on_pwd = None
406
490
            config = found_bzrdir.get_config()
407
491
            stop = False
408
 
            if config is not None:
409
 
                stack_on = config.get_default_stack_on()
410
 
                if stack_on is not None:
411
 
                    stack_on_pwd = found_bzrdir.root_transport.base
412
 
                    stop = True
 
492
            stack_on = config.get_default_stack_on()
 
493
            if stack_on is not None:
 
494
                stack_on_pwd = found_bzrdir.user_url
 
495
                stop = True
413
496
            # does it have a repository ?
414
497
            try:
415
498
                repository = found_bzrdir.open_repository()
416
499
            except errors.NoRepositoryPresent:
417
500
                repository = None
418
501
            else:
419
 
                if ((found_bzrdir.root_transport.base !=
420
 
                     self.root_transport.base) and not repository.is_shared()):
 
502
                if (found_bzrdir.user_url != self.user_url 
 
503
                    and not repository.is_shared()):
421
504
                    # Don't look higher, can't use a higher shared repo.
422
505
                    repository = None
423
506
                    stop = True
537
620
 
538
621
        :return: Tuple with old path name and new path name
539
622
        """
 
623
        def name_gen(base='backup.bzr'):
 
624
            counter = 1
 
625
            name = "%s.~%d~" % (base, counter)
 
626
            while self.root_transport.has(name):
 
627
                counter += 1
 
628
                name = "%s.~%d~" % (base, counter)
 
629
            return name
 
630
 
 
631
        backup_dir=name_gen()
540
632
        pb = ui.ui_factory.nested_progress_bar()
541
633
        try:
542
634
            # FIXME: bug 300001 -- the backup fails if the backup directory
543
635
            # already exists, but it should instead either remove it or make
544
636
            # a new backup directory.
545
637
            #
546
 
            # FIXME: bug 262450 -- the backup directory should have the same
547
 
            # permissions as the .bzr directory (probably a bug in copy_tree)
548
638
            old_path = self.root_transport.abspath('.bzr')
549
 
            new_path = self.root_transport.abspath('backup.bzr')
550
 
            pb.note('making backup of %s' % (old_path,))
551
 
            pb.note('  to %s' % (new_path,))
552
 
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
639
            new_path = self.root_transport.abspath(backup_dir)
 
640
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
 
641
            self.root_transport.copy_tree('.bzr', backup_dir)
553
642
            return (old_path, new_path)
554
643
        finally:
555
644
            pb.finished()
613
702
            if stop:
614
703
                return result
615
704
            next_transport = found_bzrdir.root_transport.clone('..')
616
 
            if (found_bzrdir.root_transport.base == next_transport.base):
 
705
            if (found_bzrdir.user_url == next_transport.base):
617
706
                # top of the file system
618
707
                return None
619
708
            # find the next containing bzrdir
636
725
                repository = found_bzrdir.open_repository()
637
726
            except errors.NoRepositoryPresent:
638
727
                return None, False
639
 
            if found_bzrdir.root_transport.base == self.root_transport.base:
 
728
            if found_bzrdir.user_url == self.user_url:
640
729
                return repository, True
641
730
            elif repository.is_shared():
642
731
                return repository, True
648
737
            raise errors.NoRepositoryPresent(self)
649
738
        return found_repo
650
739
 
651
 
    def get_branch_reference(self):
 
740
    def get_branch_reference(self, name=None):
652
741
        """Return the referenced URL for the branch in this bzrdir.
653
742
 
 
743
        :param name: Optional colocated branch name
654
744
        :raises NotBranchError: If there is no Branch.
 
745
        :raises NoColocatedBranchSupport: If a branch name was specified
 
746
            but colocated branches are not supported.
655
747
        :return: The URL the branch in this bzrdir references if it is a
656
748
            reference branch, or None for regular branches.
657
749
        """
 
750
        if name is not None:
 
751
            raise errors.NoColocatedBranchSupport(self)
658
752
        return None
659
753
 
660
 
    def get_branch_transport(self, branch_format):
 
754
    def get_branch_transport(self, branch_format, name=None):
661
755
        """Get the transport for use by branch format in this BzrDir.
662
756
 
663
757
        Note that bzr dirs that do not support format strings will raise
741
835
        raise NotImplementedError(self.get_workingtree_transport)
742
836
 
743
837
    def get_config(self):
744
 
        if getattr(self, '_get_config', None) is None:
745
 
            return None
746
 
        return self._get_config()
 
838
        """Get configuration for this BzrDir."""
 
839
        return config.BzrDirConfig(self)
 
840
 
 
841
    def _get_config(self):
 
842
        """By default, no configuration is available."""
 
843
        return None
747
844
 
748
845
    def __init__(self, _transport, _format):
749
846
        """Initialize a Bzr control dir object.
755
852
        :param _transport: the transport this dir is based at.
756
853
        """
757
854
        self._format = _format
 
855
        # these are also under the more standard names of 
 
856
        # control_transport and user_transport
758
857
        self.transport = _transport.clone('.bzr')
759
858
        self.root_transport = _transport
760
859
        self._mode_check_done = False
 
860
        
 
861
    @property 
 
862
    def user_transport(self):
 
863
        return self.root_transport
 
864
        
 
865
    @property
 
866
    def control_transport(self):
 
867
        return self.transport
761
868
 
762
869
    def is_control_filename(self, filename):
763
870
        """True if filename is the name of a path which is reserved for bzrdir's.
838
945
        BzrDir._check_supported(format, _unsupported)
839
946
        return format.open(transport, _found=True)
840
947
 
841
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
948
    def open_branch(self, name=None, unsupported=False,
 
949
                    ignore_fallbacks=False):
842
950
        """Open the branch object at this BzrDir if one is present.
843
951
 
844
952
        If unsupported is True, then no longer supported branch formats can
891
999
                raise errors.NotBranchError(path=url)
892
1000
            a_transport = new_t
893
1001
 
894
 
    def _get_tree_branch(self):
 
1002
    def _get_tree_branch(self, name=None):
895
1003
        """Return the branch and tree, if any, for this bzrdir.
896
1004
 
 
1005
        :param name: Name of colocated branch to open.
 
1006
 
897
1007
        Return None for tree if not present or inaccessible.
898
1008
        Raise NotBranchError if no branch is present.
899
1009
        :return: (tree, branch)
902
1012
            tree = self.open_workingtree()
903
1013
        except (errors.NoWorkingTree, errors.NotLocalUrl):
904
1014
            tree = None
905
 
            branch = self.open_branch()
 
1015
            branch = self.open_branch(name=name)
906
1016
        else:
907
 
            branch = tree.branch
 
1017
            if name is not None:
 
1018
                branch = self.open_branch(name=name)
 
1019
            else:
 
1020
                branch = tree.branch
908
1021
        return tree, branch
909
1022
 
910
1023
    @classmethod
982
1095
        """
983
1096
        raise NotImplementedError(self.open_workingtree)
984
1097
 
985
 
    def has_branch(self):
 
1098
    def has_branch(self, name=None):
986
1099
        """Tell if this bzrdir contains a branch.
987
1100
 
988
1101
        Note: if you're going to open the branch, you should just go ahead
990
1103
        branch and discards it, and that's somewhat expensive.)
991
1104
        """
992
1105
        try:
993
 
            self.open_branch()
 
1106
            self.open_branch(name)
994
1107
            return True
995
1108
        except errors.NotBranchError:
996
1109
            return False
1062
1175
        """
1063
1176
        format, repository = self._cloning_metadir()
1064
1177
        if format._workingtree_format is None:
 
1178
            # No tree in self.
1065
1179
            if repository is None:
 
1180
                # No repository either
1066
1181
                return format
 
1182
            # We have a repository, so set a working tree? (Why? This seems to
 
1183
            # contradict the stated return value in the docstring).
1067
1184
            tree_format = repository._format._matchingbzrdir.workingtree_format
1068
1185
            format.workingtree_format = tree_format.__class__()
1069
1186
        if require_stacking:
1127
1244
        repository_policy = result.determine_repository_policy(
1128
1245
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1129
1246
        result_repo, is_new_repo = repository_policy.acquire_repository()
1130
 
        if is_new_repo and revision_id is not None and not stacked:
 
1247
        is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
 
1248
        if is_new_repo and revision_id is not None and not is_stacked:
1131
1249
            fetch_spec = graph.PendingAncestryResult(
1132
1250
                [revision_id], source_repository)
1133
1251
        else:
1196
1314
                    basis.unlock()
1197
1315
        return result
1198
1316
 
 
1317
    def push_branch(self, source, revision_id=None, overwrite=False, 
 
1318
        remember=False, create_prefix=False):
 
1319
        """Push the source branch into this BzrDir."""
 
1320
        br_to = None
 
1321
        # If we can open a branch, use its direct repository, otherwise see
 
1322
        # if there is a repository without a branch.
 
1323
        try:
 
1324
            br_to = self.open_branch()
 
1325
        except errors.NotBranchError:
 
1326
            # Didn't find a branch, can we find a repository?
 
1327
            repository_to = self.find_repository()
 
1328
        else:
 
1329
            # Found a branch, so we must have found a repository
 
1330
            repository_to = br_to.repository
 
1331
 
 
1332
        push_result = PushResult()
 
1333
        push_result.source_branch = source
 
1334
        if br_to is None:
 
1335
            # We have a repository but no branch, copy the revisions, and then
 
1336
            # create a branch.
 
1337
            repository_to.fetch(source.repository, revision_id=revision_id)
 
1338
            br_to = source.clone(self, revision_id=revision_id)
 
1339
            if source.get_push_location() is None or remember:
 
1340
                source.set_push_location(br_to.base)
 
1341
            push_result.stacked_on = None
 
1342
            push_result.branch_push_result = None
 
1343
            push_result.old_revno = None
 
1344
            push_result.old_revid = _mod_revision.NULL_REVISION
 
1345
            push_result.target_branch = br_to
 
1346
            push_result.master_branch = None
 
1347
            push_result.workingtree_updated = False
 
1348
        else:
 
1349
            # We have successfully opened the branch, remember if necessary:
 
1350
            if source.get_push_location() is None or remember:
 
1351
                source.set_push_location(br_to.base)
 
1352
            try:
 
1353
                tree_to = self.open_workingtree()
 
1354
            except errors.NotLocalUrl:
 
1355
                push_result.branch_push_result = source.push(br_to, 
 
1356
                    overwrite, stop_revision=revision_id)
 
1357
                push_result.workingtree_updated = False
 
1358
            except errors.NoWorkingTree:
 
1359
                push_result.branch_push_result = source.push(br_to,
 
1360
                    overwrite, stop_revision=revision_id)
 
1361
                push_result.workingtree_updated = None # Not applicable
 
1362
            else:
 
1363
                tree_to.lock_write()
 
1364
                try:
 
1365
                    push_result.branch_push_result = source.push(
 
1366
                        tree_to.branch, overwrite, stop_revision=revision_id)
 
1367
                    tree_to.update()
 
1368
                finally:
 
1369
                    tree_to.unlock()
 
1370
                push_result.workingtree_updated = True
 
1371
            push_result.old_revno = push_result.branch_push_result.old_revno
 
1372
            push_result.old_revid = push_result.branch_push_result.old_revid
 
1373
            push_result.target_branch = \
 
1374
                push_result.branch_push_result.target_branch
 
1375
        return push_result
 
1376
 
1199
1377
 
1200
1378
class BzrDirHooks(hooks.Hooks):
1201
1379
    """Hooks for BzrDir operations."""
1206
1384
        self.create_hook(hooks.HookPoint('pre_open',
1207
1385
            "Invoked before attempting to open a BzrDir with the transport "
1208
1386
            "that the open will use.", (1, 14), None))
 
1387
        self.create_hook(hooks.HookPoint('post_repo_init',
 
1388
            "Invoked after a repository has been initialized. "
 
1389
            "post_repo_init is called with a "
 
1390
            "bzrlib.bzrdir.RepoInitHookParams.",
 
1391
            (2, 2), None))
1209
1392
 
1210
1393
# install the default hooks
1211
1394
BzrDir.hooks = BzrDirHooks()
1212
1395
 
1213
1396
 
 
1397
class RepoInitHookParams(object):
 
1398
    """Object holding parameters passed to *_repo_init hooks.
 
1399
 
 
1400
    There are 4 fields that hooks may wish to access:
 
1401
 
 
1402
    :ivar repository: Repository created
 
1403
    :ivar format: Repository format
 
1404
    :ivar bzrdir: The bzrdir for the repository
 
1405
    :ivar shared: The repository is shared
 
1406
    """
 
1407
 
 
1408
    def __init__(self, repository, format, a_bzrdir, shared):
 
1409
        """Create a group of RepoInitHook parameters.
 
1410
 
 
1411
        :param repository: Repository created
 
1412
        :param format: Repository format
 
1413
        :param bzrdir: The bzrdir for the repository
 
1414
        :param shared: The repository is shared
 
1415
        """
 
1416
        self.repository = repository
 
1417
        self.format = format
 
1418
        self.bzrdir = a_bzrdir
 
1419
        self.shared = shared
 
1420
 
 
1421
    def __eq__(self, other):
 
1422
        return self.__dict__ == other.__dict__
 
1423
 
 
1424
    def __repr__(self):
 
1425
        if self.repository:
 
1426
            return "<%s for %s>" % (self.__class__.__name__,
 
1427
                self.repository)
 
1428
        else:
 
1429
            return "<%s for %s>" % (self.__class__.__name__,
 
1430
                self.bzrdir)
 
1431
 
 
1432
 
1214
1433
class BzrDirPreSplitOut(BzrDir):
1215
1434
    """A common class for the all-in-one formats."""
1216
1435
 
1255
1474
            tree.clone(result)
1256
1475
        return result
1257
1476
 
1258
 
    def create_branch(self):
 
1477
    def create_branch(self, name=None):
1259
1478
        """See BzrDir.create_branch."""
1260
 
        return self._format.get_branch_format().initialize(self)
 
1479
        return self._format.get_branch_format().initialize(self, name=name)
1261
1480
 
1262
 
    def destroy_branch(self):
 
1481
    def destroy_branch(self, name=None):
1263
1482
        """See BzrDir.destroy_branch."""
1264
1483
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1265
1484
 
1288
1507
        # that can do wonky stuff here, and that only
1289
1508
        # happens for creating checkouts, which cannot be
1290
1509
        # done on this format anyway. So - acceptable wart.
 
1510
        if hardlink:
 
1511
            warning("can't support hardlinked working trees in %r"
 
1512
                % (self,))
1291
1513
        try:
1292
1514
            result = self.open_workingtree(recommend_upgrade=False)
1293
1515
        except errors.NoSuchFile:
1318
1540
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1319
1541
                                          self)
1320
1542
 
1321
 
    def get_branch_transport(self, branch_format):
 
1543
    def get_branch_transport(self, branch_format, name=None):
1322
1544
        """See BzrDir.get_branch_transport()."""
 
1545
        if name is not None:
 
1546
            raise errors.NoColocatedBranchSupport(self)
1323
1547
        if branch_format is None:
1324
1548
            return self.transport
1325
1549
        try:
1358
1582
            format = BzrDirFormat.get_default_format()
1359
1583
        return not isinstance(self._format, format.__class__)
1360
1584
 
1361
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1585
    def open_branch(self, name=None, unsupported=False,
 
1586
                    ignore_fallbacks=False):
1362
1587
        """See BzrDir.open_branch."""
1363
1588
        from bzrlib.branch import BzrBranchFormat4
1364
1589
        format = BzrBranchFormat4()
1365
1590
        self._check_supported(format, unsupported)
1366
 
        return format.open(self, _found=True)
 
1591
        return format.open(self, name, _found=True)
1367
1592
 
1368
1593
    def sprout(self, url, revision_id=None, force_new_repo=False,
1369
1594
               possible_transports=None, accelerator_tree=None,
1430
1655
    This is a deprecated format and may be removed after sept 2006.
1431
1656
    """
1432
1657
 
 
1658
    def has_workingtree(self):
 
1659
        """See BzrDir.has_workingtree."""
 
1660
        return True
 
1661
    
1433
1662
    def open_repository(self):
1434
1663
        """See BzrDir.open_repository."""
1435
1664
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1451
1680
    This is a deprecated format and may be removed after sept 2006.
1452
1681
    """
1453
1682
 
 
1683
    def has_workingtree(self):
 
1684
        """See BzrDir.has_workingtree."""
 
1685
        return True
 
1686
    
1454
1687
    def open_repository(self):
1455
1688
        """See BzrDir.open_repository."""
1456
1689
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1478
1711
        """See BzrDir.can_convert_format()."""
1479
1712
        return True
1480
1713
 
1481
 
    def create_branch(self):
 
1714
    def create_branch(self, name=None):
1482
1715
        """See BzrDir.create_branch."""
1483
 
        return self._format.get_branch_format().initialize(self)
 
1716
        return self._format.get_branch_format().initialize(self, name=name)
1484
1717
 
1485
 
    def destroy_branch(self):
 
1718
    def destroy_branch(self, name=None):
1486
1719
        """See BzrDir.create_branch."""
 
1720
        if name is not None:
 
1721
            raise errors.NoColocatedBranchSupport(self)
1487
1722
        self.transport.delete_tree('branch')
1488
1723
 
1489
1724
    def create_repository(self, shared=False):
1512
1747
    def destroy_workingtree_metadata(self):
1513
1748
        self.transport.delete_tree('checkout')
1514
1749
 
1515
 
    def find_branch_format(self):
 
1750
    def find_branch_format(self, name=None):
1516
1751
        """Find the branch 'format' for this bzrdir.
1517
1752
 
1518
1753
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1519
1754
        """
1520
1755
        from bzrlib.branch import BranchFormat
1521
 
        return BranchFormat.find_format(self)
 
1756
        return BranchFormat.find_format(self, name=name)
1522
1757
 
1523
1758
    def _get_mkdir_mode(self):
1524
1759
        """Figure out the mode to use when creating a bzrdir subdir."""
1526
1761
                                     lockable_files.TransportLock)
1527
1762
        return temp_control._dir_mode
1528
1763
 
1529
 
    def get_branch_reference(self):
 
1764
    def get_branch_reference(self, name=None):
1530
1765
        """See BzrDir.get_branch_reference()."""
1531
1766
        from bzrlib.branch import BranchFormat
1532
 
        format = BranchFormat.find_format(self)
1533
 
        return format.get_reference(self)
 
1767
        format = BranchFormat.find_format(self, name=name)
 
1768
        return format.get_reference(self, name=name)
1534
1769
 
1535
 
    def get_branch_transport(self, branch_format):
 
1770
    def get_branch_transport(self, branch_format, name=None):
1536
1771
        """See BzrDir.get_branch_transport()."""
 
1772
        if name is not None:
 
1773
            raise errors.NoColocatedBranchSupport(self)
 
1774
        # XXX: this shouldn't implicitly create the directory if it's just
 
1775
        # promising to get a transport -- mbp 20090727
1537
1776
        if branch_format is None:
1538
1777
            return self.transport.clone('branch')
1539
1778
        try:
1574
1813
            pass
1575
1814
        return self.transport.clone('checkout')
1576
1815
 
 
1816
    def has_workingtree(self):
 
1817
        """Tell if this bzrdir contains a working tree.
 
1818
 
 
1819
        This will still raise an exception if the bzrdir has a workingtree that
 
1820
        is remote & inaccessible.
 
1821
 
 
1822
        Note: if you're going to open the working tree, you should just go
 
1823
        ahead and try, and not ask permission first.
 
1824
        """
 
1825
        from bzrlib.workingtree import WorkingTreeFormat
 
1826
        try:
 
1827
            WorkingTreeFormat.find_format(self)
 
1828
        except errors.NoWorkingTree:
 
1829
            return False
 
1830
        return True
 
1831
 
1577
1832
    def needs_format_conversion(self, format=None):
1578
1833
        """See BzrDir.needs_format_conversion()."""
1579
1834
        if format is None:
1592
1847
                return True
1593
1848
        except errors.NoRepositoryPresent:
1594
1849
            pass
1595
 
        try:
1596
 
            if not isinstance(self.open_branch()._format,
 
1850
        for branch in self.list_branches():
 
1851
            if not isinstance(branch._format,
1597
1852
                              format.get_branch_format().__class__):
1598
1853
                # the branch needs an upgrade.
1599
1854
                return True
1600
 
        except errors.NotBranchError:
1601
 
            pass
1602
1855
        try:
1603
1856
            my_wt = self.open_workingtree(recommend_upgrade=False)
1604
1857
            if not isinstance(my_wt._format,
1609
1862
            pass
1610
1863
        return False
1611
1864
 
1612
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1865
    def open_branch(self, name=None, unsupported=False,
 
1866
                    ignore_fallbacks=False):
1613
1867
        """See BzrDir.open_branch."""
1614
 
        format = self.find_branch_format()
 
1868
        format = self.find_branch_format(name=name)
1615
1869
        self._check_supported(format, unsupported)
1616
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1870
        return format.open(self, name=name,
 
1871
            _found=True, ignore_fallbacks=ignore_fallbacks)
1617
1872
 
1618
1873
    def open_repository(self, unsupported=False):
1619
1874
        """See BzrDir.open_repository."""
1633
1888
        return format.open(self, _found=True)
1634
1889
 
1635
1890
    def _get_config(self):
1636
 
        return config.BzrDirConfig(self.transport)
 
1891
        return config.TransportConfig(self.transport, 'control.conf')
1637
1892
 
1638
1893
 
1639
1894
class BzrDirFormat(object):
1651
1906
    Once a format is deprecated, just deprecate the initialize and open
1652
1907
    methods on the format class. Do not deprecate the object, as the
1653
1908
    object will be created every system load.
 
1909
 
 
1910
    :cvar colocated_branches: Whether this formats supports colocated branches.
1654
1911
    """
1655
1912
 
1656
1913
    _default_format = None
1673
1930
 
1674
1931
    _lock_file_name = 'branch-lock'
1675
1932
 
 
1933
    colocated_branches = False
 
1934
    """Whether co-located branches are supported for this control dir format.
 
1935
    """
 
1936
 
1676
1937
    # _lock_class must be set in subclasses to the lock type, typ.
1677
1938
    # TransportLock or LockDir
1678
1939
 
1695
1956
    def probe_transport(klass, transport):
1696
1957
        """Return the .bzrdir style format present in a directory."""
1697
1958
        try:
1698
 
            format_string = transport.get(".bzr/branch-format").read()
 
1959
            format_string = transport.get_bytes(".bzr/branch-format")
1699
1960
        except errors.NoSuchFile:
1700
1961
            raise errors.NotBranchError(path=transport.base)
1701
 
 
1702
1962
        try:
1703
1963
            return klass._formats[format_string]
1704
1964
        except KeyError:
1734
1994
    def initialize(self, url, possible_transports=None):
1735
1995
        """Create a bzr control dir at this url and return an opened copy.
1736
1996
 
 
1997
        While not deprecated, this method is very specific and its use will
 
1998
        lead to many round trips to setup a working environment. See
 
1999
        initialize_on_transport_ex for a [nearly] all-in-one method.
 
2000
 
1737
2001
        Subclasses should typically override initialize_on_transport
1738
2002
        instead of this method.
1739
2003
        """
1758
2022
            self._supply_sub_formats_to(remote_format)
1759
2023
            return remote_format.initialize_on_transport(transport)
1760
2024
 
 
2025
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
2026
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
2027
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
2028
        shared_repo=False, vfs_only=False):
 
2029
        """Create this format on transport.
 
2030
 
 
2031
        The directory to initialize will be created.
 
2032
 
 
2033
        :param force_new_repo: Do not use a shared repository for the target,
 
2034
                               even if one is available.
 
2035
        :param create_prefix: Create any missing directories leading up to
 
2036
            to_transport.
 
2037
        :param use_existing_dir: Use an existing directory if one exists.
 
2038
        :param stacked_on: A url to stack any created branch on, None to follow
 
2039
            any target stacking policy.
 
2040
        :param stack_on_pwd: If stack_on is relative, the location it is
 
2041
            relative to.
 
2042
        :param repo_format_name: If non-None, a repository will be
 
2043
            made-or-found. Should none be found, or if force_new_repo is True
 
2044
            the repo_format_name is used to select the format of repository to
 
2045
            create.
 
2046
        :param make_working_trees: Control the setting of make_working_trees
 
2047
            for a new shared repository when one is made. None to use whatever
 
2048
            default the format has.
 
2049
        :param shared_repo: Control whether made repositories are shared or
 
2050
            not.
 
2051
        :param vfs_only: If True do not attempt to use a smart server
 
2052
        :return: repo, bzrdir, require_stacking, repository_policy. repo is
 
2053
            None if none was created or found, bzrdir is always valid.
 
2054
            require_stacking is the result of examining the stacked_on
 
2055
            parameter and any stacking policy found for the target.
 
2056
        """
 
2057
        if not vfs_only:
 
2058
            # Try to hand off to a smart server 
 
2059
            try:
 
2060
                client_medium = transport.get_smart_medium()
 
2061
            except errors.NoSmartMedium:
 
2062
                pass
 
2063
            else:
 
2064
                # TODO: lookup the local format from a server hint.
 
2065
                remote_dir_format = RemoteBzrDirFormat()
 
2066
                remote_dir_format._network_name = self.network_name()
 
2067
                self._supply_sub_formats_to(remote_dir_format)
 
2068
                return remote_dir_format.initialize_on_transport_ex(transport,
 
2069
                    use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
2070
                    force_new_repo=force_new_repo, stacked_on=stacked_on,
 
2071
                    stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
2072
                    make_working_trees=make_working_trees, shared_repo=shared_repo)
 
2073
        # XXX: Refactor the create_prefix/no_create_prefix code into a
 
2074
        #      common helper function
 
2075
        # The destination may not exist - if so make it according to policy.
 
2076
        def make_directory(transport):
 
2077
            transport.mkdir('.')
 
2078
            return transport
 
2079
        def redirected(transport, e, redirection_notice):
 
2080
            note(redirection_notice)
 
2081
            return transport._redirected_to(e.source, e.target)
 
2082
        try:
 
2083
            transport = do_catching_redirections(make_directory, transport,
 
2084
                redirected)
 
2085
        except errors.FileExists:
 
2086
            if not use_existing_dir:
 
2087
                raise
 
2088
        except errors.NoSuchFile:
 
2089
            if not create_prefix:
 
2090
                raise
 
2091
            transport.create_prefix()
 
2092
 
 
2093
        require_stacking = (stacked_on is not None)
 
2094
        # Now the target directory exists, but doesn't have a .bzr
 
2095
        # directory. So we need to create it, along with any work to create
 
2096
        # all of the dependent branches, etc.
 
2097
 
 
2098
        result = self.initialize_on_transport(transport)
 
2099
        if repo_format_name:
 
2100
            try:
 
2101
                # use a custom format
 
2102
                result._format.repository_format = \
 
2103
                    repository.network_format_registry.get(repo_format_name)
 
2104
            except AttributeError:
 
2105
                # The format didn't permit it to be set.
 
2106
                pass
 
2107
            # A repository is desired, either in-place or shared.
 
2108
            repository_policy = result.determine_repository_policy(
 
2109
                force_new_repo, stacked_on, stack_on_pwd,
 
2110
                require_stacking=require_stacking)
 
2111
            result_repo, is_new_repo = repository_policy.acquire_repository(
 
2112
                make_working_trees, shared_repo)
 
2113
            if not require_stacking and repository_policy._require_stacking:
 
2114
                require_stacking = True
 
2115
                result._format.require_stacking()
 
2116
            result_repo.lock_write()
 
2117
        else:
 
2118
            result_repo = None
 
2119
            repository_policy = None
 
2120
        return result_repo, result, require_stacking, repository_policy
 
2121
 
1761
2122
    def _initialize_on_transport_vfs(self, transport):
1762
2123
        """Initialize a new bzrdir using VFS calls.
1763
2124
 
1975
2336
    repository_format = property(__return_repository_format)
1976
2337
 
1977
2338
 
1978
 
class BzrDirFormat5(BzrDirFormat):
 
2339
class BzrDirFormatAllInOne(BzrDirFormat):
 
2340
    """Common class for formats before meta-dirs."""
 
2341
 
 
2342
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
2343
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
2344
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
2345
        shared_repo=False):
 
2346
        """See BzrDirFormat.initialize_on_transport_ex."""
 
2347
        require_stacking = (stacked_on is not None)
 
2348
        # Format 5 cannot stack, but we've been asked to - actually init
 
2349
        # a Meta1Dir
 
2350
        if require_stacking:
 
2351
            format = BzrDirMetaFormat1()
 
2352
            return format.initialize_on_transport_ex(transport,
 
2353
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
2354
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
2355
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
2356
                make_working_trees=make_working_trees, shared_repo=shared_repo)
 
2357
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
 
2358
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
2359
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
2360
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
2361
            make_working_trees=make_working_trees, shared_repo=shared_repo)
 
2362
 
 
2363
 
 
2364
class BzrDirFormat5(BzrDirFormatAllInOne):
1979
2365
    """Bzr control format 5.
1980
2366
 
1981
2367
    This format is a combined format for working tree, branch and repository.
2036
2422
    repository_format = property(__return_repository_format)
2037
2423
 
2038
2424
 
2039
 
class BzrDirFormat6(BzrDirFormat):
 
2425
class BzrDirFormat6(BzrDirFormatAllInOne):
2040
2426
    """Bzr control format 6.
2041
2427
 
2042
2428
    This format is a combined format for working tree, branch and repository.
2135
2521
    def set_branch_format(self, format):
2136
2522
        self._branch_format = format
2137
2523
 
2138
 
    def require_stacking(self):
 
2524
    def require_stacking(self, stack_on=None, possible_transports=None,
 
2525
            _skip_repo=False):
 
2526
        """We have a request to stack, try to ensure the formats support it.
 
2527
 
 
2528
        :param stack_on: If supplied, it is the URL to a branch that we want to
 
2529
            stack on. Check to see if that format supports stacking before
 
2530
            forcing an upgrade.
 
2531
        """
 
2532
        # Stacking is desired. requested by the target, but does the place it
 
2533
        # points at support stacking? If it doesn't then we should
 
2534
        # not implicitly upgrade. We check this here.
 
2535
        new_repo_format = None
 
2536
        new_branch_format = None
 
2537
 
 
2538
        # a bit of state for get_target_branch so that we don't try to open it
 
2539
        # 2 times, for both repo *and* branch
 
2540
        target = [None, False, None] # target_branch, checked, upgrade anyway
 
2541
        def get_target_branch():
 
2542
            if target[1]:
 
2543
                # We've checked, don't check again
 
2544
                return target
 
2545
            if stack_on is None:
 
2546
                # No target format, that means we want to force upgrading
 
2547
                target[:] = [None, True, True]
 
2548
                return target
 
2549
            try:
 
2550
                target_dir = BzrDir.open(stack_on,
 
2551
                    possible_transports=possible_transports)
 
2552
            except errors.NotBranchError:
 
2553
                # Nothing there, don't change formats
 
2554
                target[:] = [None, True, False]
 
2555
                return target
 
2556
            except errors.JailBreak:
 
2557
                # JailBreak, JFDI and upgrade anyway
 
2558
                target[:] = [None, True, True]
 
2559
                return target
 
2560
            try:
 
2561
                target_branch = target_dir.open_branch()
 
2562
            except errors.NotBranchError:
 
2563
                # No branch, don't upgrade formats
 
2564
                target[:] = [None, True, False]
 
2565
                return target
 
2566
            target[:] = [target_branch, True, False]
 
2567
            return target
 
2568
 
 
2569
        if (not _skip_repo and
 
2570
                 not self.repository_format.supports_external_lookups):
 
2571
            # We need to upgrade the Repository.
 
2572
            target_branch, _, do_upgrade = get_target_branch()
 
2573
            if target_branch is None:
 
2574
                # We don't have a target branch, should we upgrade anyway?
 
2575
                if do_upgrade:
 
2576
                    # stack_on is inaccessible, JFDI.
 
2577
                    # TODO: bad monkey, hard-coded formats...
 
2578
                    if self.repository_format.rich_root_data:
 
2579
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
 
2580
                    else:
 
2581
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
 
2582
            else:
 
2583
                # If the target already supports stacking, then we know the
 
2584
                # project is already able to use stacking, so auto-upgrade
 
2585
                # for them
 
2586
                new_repo_format = target_branch.repository._format
 
2587
                if not new_repo_format.supports_external_lookups:
 
2588
                    # target doesn't, source doesn't, so don't auto upgrade
 
2589
                    # repo
 
2590
                    new_repo_format = None
 
2591
            if new_repo_format is not None:
 
2592
                self.repository_format = new_repo_format
 
2593
                note('Source repository format does not support stacking,'
 
2594
                     ' using format:\n  %s',
 
2595
                     new_repo_format.get_format_description())
 
2596
 
2139
2597
        if not self.get_branch_format().supports_stacking():
2140
 
            # We need to make a stacked branch, but the default format for the
2141
 
            # target doesn't support stacking.  So force a branch that *can*
2142
 
            # support stacking.
2143
 
            from bzrlib.branch import BzrBranchFormat7
2144
 
            branch_format = BzrBranchFormat7()
2145
 
            self.set_branch_format(branch_format)
2146
 
            mutter("using %r for stacking" % (branch_format,))
2147
 
            from bzrlib.repofmt import pack_repo
2148
 
            if self.repository_format.rich_root_data:
2149
 
                bzrdir_format_name = '1.6.1-rich-root'
2150
 
                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
 
2598
            # We just checked the repo, now lets check if we need to
 
2599
            # upgrade the branch format
 
2600
            target_branch, _, do_upgrade = get_target_branch()
 
2601
            if target_branch is None:
 
2602
                if do_upgrade:
 
2603
                    # TODO: bad monkey, hard-coded formats...
 
2604
                    new_branch_format = branch.BzrBranchFormat7()
2151
2605
            else:
2152
 
                bzrdir_format_name = '1.6'
2153
 
                repo_format = pack_repo.RepositoryFormatKnitPack5()
2154
 
            note('Source format does not support stacking, using format:'
2155
 
                 ' \'%s\'\n  %s\n',
2156
 
                 bzrdir_format_name, repo_format.get_format_description())
2157
 
            self.repository_format = repo_format
 
2606
                new_branch_format = target_branch._format
 
2607
                if not new_branch_format.supports_stacking():
 
2608
                    new_branch_format = None
 
2609
            if new_branch_format is not None:
 
2610
                # Does support stacking, use its format.
 
2611
                self.set_branch_format(new_branch_format)
 
2612
                note('Source branch format does not support stacking,'
 
2613
                     ' using format:\n  %s',
 
2614
                     new_branch_format.get_format_description())
2158
2615
 
2159
2616
    def get_converter(self, format=None):
2160
2617
        """See BzrDirFormat.get_converter()."""
2178
2635
 
2179
2636
    def _open(self, transport):
2180
2637
        """See BzrDirFormat._open."""
2181
 
        return BzrDirMeta1(transport, self)
 
2638
        # Create a new format instance because otherwise initialisation of new
 
2639
        # metadirs share the global default format object leading to alias
 
2640
        # problems.
 
2641
        format = BzrDirMetaFormat1()
 
2642
        self._supply_sub_formats_to(format)
 
2643
        return BzrDirMeta1(transport, format)
2182
2644
 
2183
2645
    def __return_repository_format(self):
2184
2646
        """Circular import protection."""
2275
2737
    def convert(self, to_convert, pb):
2276
2738
        """See Converter.convert()."""
2277
2739
        self.bzrdir = to_convert
2278
 
        self.pb = pb
2279
 
        self.pb.note('starting upgrade from format 4 to 5')
2280
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2281
 
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2282
 
        self._convert_to_weaves()
2283
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2740
        if pb is not None:
 
2741
            warnings.warn("pb parameter to convert() is deprecated")
 
2742
        self.pb = ui.ui_factory.nested_progress_bar()
 
2743
        try:
 
2744
            ui.ui_factory.note('starting upgrade from format 4 to 5')
 
2745
            if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2746
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2747
            self._convert_to_weaves()
 
2748
            return BzrDir.open(self.bzrdir.user_url)
 
2749
        finally:
 
2750
            self.pb.finished()
2284
2751
 
2285
2752
    def _convert_to_weaves(self):
2286
 
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
 
2753
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2287
2754
        try:
2288
2755
            # TODO permissions
2289
2756
            stat = self.bzrdir.transport.stat('weaves')
2317
2784
        self.pb.clear()
2318
2785
        self._write_all_weaves()
2319
2786
        self._write_all_revs()
2320
 
        self.pb.note('upgraded to weaves:')
2321
 
        self.pb.note('  %6d revisions and inventories', len(self.revisions))
2322
 
        self.pb.note('  %6d revisions not present', len(self.absent_revisions))
2323
 
        self.pb.note('  %6d texts', self.text_count)
 
2787
        ui.ui_factory.note('upgraded to weaves:')
 
2788
        ui.ui_factory.note('  %6d revisions and inventories' % len(self.revisions))
 
2789
        ui.ui_factory.note('  %6d revisions not present' % len(self.absent_revisions))
 
2790
        ui.ui_factory.note('  %6d texts' % self.text_count)
2324
2791
        self._cleanup_spare_files_after_format4()
2325
2792
        self.branch._transport.put_bytes(
2326
2793
            'branch-format',
2394
2861
                       len(self.known_revisions))
2395
2862
        if not self.branch.repository.has_revision(rev_id):
2396
2863
            self.pb.clear()
2397
 
            self.pb.note('revision {%s} not present in branch; '
2398
 
                         'will be converted as a ghost',
 
2864
            ui.ui_factory.note('revision {%s} not present in branch; '
 
2865
                         'will be converted as a ghost' %
2399
2866
                         rev_id)
2400
2867
            self.absent_revisions.add(rev_id)
2401
2868
        else:
2406
2873
            self.revisions[rev_id] = rev
2407
2874
 
2408
2875
    def _load_old_inventory(self, rev_id):
2409
 
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
 
2876
        f = self.branch.repository.inventory_store.get(rev_id)
 
2877
        try:
 
2878
            old_inv_xml = f.read()
 
2879
        finally:
 
2880
            f.close()
2410
2881
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2411
2882
        inv.revision_id = rev_id
2412
2883
        rev = self.revisions[rev_id]
2471
2942
        del ie.text_id
2472
2943
 
2473
2944
    def get_parent_map(self, revision_ids):
2474
 
        """See graph._StackedParentsProvider.get_parent_map"""
 
2945
        """See graph.StackedParentsProvider.get_parent_map"""
2475
2946
        return dict((revision_id, self.revisions[revision_id])
2476
2947
                    for revision_id in revision_ids
2477
2948
                     if revision_id in self.revisions)
2490
2961
                ie.revision = previous_ie.revision
2491
2962
                return
2492
2963
        if ie.has_text():
2493
 
            text = self.branch.repository._text_store.get(ie.text_id)
2494
 
            file_lines = text.readlines()
 
2964
            f = self.branch.repository._text_store.get(ie.text_id)
 
2965
            try:
 
2966
                file_lines = f.readlines()
 
2967
            finally:
 
2968
                f.close()
2495
2969
            w.add_lines(rev_id, previous_revisions, file_lines)
2496
2970
            self.text_count += 1
2497
2971
        else:
2527
3001
    def convert(self, to_convert, pb):
2528
3002
        """See Converter.convert()."""
2529
3003
        self.bzrdir = to_convert
2530
 
        self.pb = pb
2531
 
        self.pb.note('starting upgrade from format 5 to 6')
2532
 
        self._convert_to_prefixed()
2533
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
3004
        pb = ui.ui_factory.nested_progress_bar()
 
3005
        try:
 
3006
            ui.ui_factory.note('starting upgrade from format 5 to 6')
 
3007
            self._convert_to_prefixed()
 
3008
            return BzrDir.open(self.bzrdir.user_url)
 
3009
        finally:
 
3010
            pb.finished()
2534
3011
 
2535
3012
    def _convert_to_prefixed(self):
2536
3013
        from bzrlib.store import TransportStore
2537
3014
        self.bzrdir.transport.delete('branch-format')
2538
3015
        for store_name in ["weaves", "revision-store"]:
2539
 
            self.pb.note("adding prefixes to %s" % store_name)
 
3016
            ui.ui_factory.note("adding prefixes to %s" % store_name)
2540
3017
            store_transport = self.bzrdir.transport.clone(store_name)
2541
3018
            store = TransportStore(store_transport, prefixed=True)
2542
3019
            for urlfilename in store_transport.list_dir('.'):
2569
3046
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2570
3047
        from bzrlib.branch import BzrBranchFormat5
2571
3048
        self.bzrdir = to_convert
2572
 
        self.pb = pb
 
3049
        self.pb = ui.ui_factory.nested_progress_bar()
2573
3050
        self.count = 0
2574
3051
        self.total = 20 # the steps we know about
2575
3052
        self.garbage_inventories = []
2576
3053
        self.dir_mode = self.bzrdir._get_dir_mode()
2577
3054
        self.file_mode = self.bzrdir._get_file_mode()
2578
3055
 
2579
 
        self.pb.note('starting upgrade from format 6 to metadir')
 
3056
        ui.ui_factory.note('starting upgrade from format 6 to metadir')
2580
3057
        self.bzrdir.transport.put_bytes(
2581
3058
                'branch-format',
2582
3059
                "Converting to format 6",
2632
3109
        else:
2633
3110
            has_checkout = True
2634
3111
        if not has_checkout:
2635
 
            self.pb.note('No working tree.')
 
3112
            ui.ui_factory.note('No working tree.')
2636
3113
            # If some checkout files are there, we may as well get rid of them.
2637
3114
            for name, mandatory in checkout_files:
2638
3115
                if name in bzrcontents:
2655
3132
            'branch-format',
2656
3133
            BzrDirMetaFormat1().get_format_string(),
2657
3134
            mode=self.file_mode)
2658
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
3135
        self.pb.finished()
 
3136
        return BzrDir.open(self.bzrdir.user_url)
2659
3137
 
2660
3138
    def make_lock(self, name):
2661
3139
        """Make a lock for the new control dir name."""
2696
3174
    def convert(self, to_convert, pb):
2697
3175
        """See Converter.convert()."""
2698
3176
        self.bzrdir = to_convert
2699
 
        self.pb = pb
 
3177
        self.pb = ui.ui_factory.nested_progress_bar()
2700
3178
        self.count = 0
2701
3179
        self.total = 1
2702
3180
        self.step('checking repository format')
2707
3185
        else:
2708
3186
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
2709
3187
                from bzrlib.repository import CopyConverter
2710
 
                self.pb.note('starting repository conversion')
 
3188
                ui.ui_factory.note('starting repository conversion')
2711
3189
                converter = CopyConverter(self.target_format.repository_format)
2712
3190
                converter.convert(repo, pb)
2713
 
        try:
2714
 
            branch = self.bzrdir.open_branch()
2715
 
        except errors.NotBranchError:
2716
 
            pass
2717
 
        else:
 
3191
        for branch in self.bzrdir.list_branches():
2718
3192
            # TODO: conversions of Branch and Tree should be done by
2719
3193
            # InterXFormat lookups/some sort of registry.
2720
3194
            # Avoid circular imports
2724
3198
            while old != new:
2725
3199
                if (old == _mod_branch.BzrBranchFormat5 and
2726
3200
                    new in (_mod_branch.BzrBranchFormat6,
2727
 
                        _mod_branch.BzrBranchFormat7)):
 
3201
                        _mod_branch.BzrBranchFormat7,
 
3202
                        _mod_branch.BzrBranchFormat8)):
2728
3203
                    branch_converter = _mod_branch.Converter5to6()
2729
3204
                elif (old == _mod_branch.BzrBranchFormat6 and
2730
 
                    new == _mod_branch.BzrBranchFormat7):
 
3205
                    new in (_mod_branch.BzrBranchFormat7,
 
3206
                            _mod_branch.BzrBranchFormat8)):
2731
3207
                    branch_converter = _mod_branch.Converter6to7()
 
3208
                elif (old == _mod_branch.BzrBranchFormat7 and
 
3209
                      new is _mod_branch.BzrBranchFormat8):
 
3210
                    branch_converter = _mod_branch.Converter7to8()
2732
3211
                else:
2733
 
                    raise errors.BadConversionTarget("No converter", new)
 
3212
                    raise errors.BadConversionTarget("No converter", new,
 
3213
                        branch._format)
2734
3214
                branch_converter.convert(branch)
2735
3215
                branch = self.bzrdir.open_branch()
2736
3216
                old = branch._format.__class__
2751
3231
                isinstance(self.target_format.workingtree_format,
2752
3232
                    workingtree_4.WorkingTreeFormat5)):
2753
3233
                workingtree_4.Converter4to5().convert(tree)
 
3234
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
3235
                not isinstance(tree, workingtree_4.WorkingTree6) and
 
3236
                isinstance(self.target_format.workingtree_format,
 
3237
                    workingtree_4.WorkingTreeFormat6)):
 
3238
                workingtree_4.Converter4or5to6().convert(tree)
 
3239
        self.pb.finished()
2754
3240
        return to_convert
2755
3241
 
2756
3242
 
2757
 
# This is not in remote.py because it's small, and needs to be registered.
2758
 
# Putting it in remote.py creates a circular import problem.
 
3243
# This is not in remote.py because it's relatively small, and needs to be
 
3244
# registered. Putting it in remote.py creates a circular import problem.
2759
3245
# we can make it a lazy object if the control formats is turned into something
2760
3246
# like a registry.
2761
3247
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2763
3249
 
2764
3250
    def __init__(self):
2765
3251
        BzrDirMetaFormat1.__init__(self)
 
3252
        # XXX: It's a bit ugly that the network name is here, because we'd
 
3253
        # like to believe that format objects are stateless or at least
 
3254
        # immutable,  However, we do at least avoid mutating the name after
 
3255
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
2766
3256
        self._network_name = None
2767
3257
 
 
3258
    def __repr__(self):
 
3259
        return "%s(_network_name=%r)" % (self.__class__.__name__,
 
3260
            self._network_name)
 
3261
 
2768
3262
    def get_format_description(self):
 
3263
        if self._network_name:
 
3264
            real_format = network_format_registry.get(self._network_name)
 
3265
            return 'Remote: ' + real_format.get_format_description()
2769
3266
        return 'bzr remote bzrdir'
2770
3267
 
2771
3268
    def get_format_string(self):
2811
3308
            return local_dir_format.initialize_on_transport(transport)
2812
3309
        client = _SmartClient(client_medium)
2813
3310
        path = client.remote_path_from_transport(transport)
2814
 
        response = client.call('BzrDirFormat.initialize', path)
 
3311
        try:
 
3312
            response = client.call('BzrDirFormat.initialize', path)
 
3313
        except errors.ErrorFromSmartServer, err:
 
3314
            remote._translate_error(err, path=path)
2815
3315
        if response[0] != 'ok':
2816
3316
            raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2817
3317
        format = RemoteBzrDirFormat()
2818
3318
        self._supply_sub_formats_to(format)
2819
3319
        return remote.RemoteBzrDir(transport, format)
2820
3320
 
 
3321
    def parse_NoneTrueFalse(self, arg):
 
3322
        if not arg:
 
3323
            return None
 
3324
        if arg == 'False':
 
3325
            return False
 
3326
        if arg == 'True':
 
3327
            return True
 
3328
        raise AssertionError("invalid arg %r" % arg)
 
3329
 
 
3330
    def _serialize_NoneTrueFalse(self, arg):
 
3331
        if arg is False:
 
3332
            return 'False'
 
3333
        if arg:
 
3334
            return 'True'
 
3335
        return ''
 
3336
 
 
3337
    def _serialize_NoneString(self, arg):
 
3338
        return arg or ''
 
3339
 
 
3340
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
3341
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
3342
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
3343
        shared_repo=False):
 
3344
        try:
 
3345
            # hand off the request to the smart server
 
3346
            client_medium = transport.get_smart_medium()
 
3347
        except errors.NoSmartMedium:
 
3348
            do_vfs = True
 
3349
        else:
 
3350
            # Decline to open it if the server doesn't support our required
 
3351
            # version (3) so that the VFS-based transport will do it.
 
3352
            if client_medium.should_probe():
 
3353
                try:
 
3354
                    server_version = client_medium.protocol_version()
 
3355
                    if server_version != '2':
 
3356
                        do_vfs = True
 
3357
                    else:
 
3358
                        do_vfs = False
 
3359
                except errors.SmartProtocolError:
 
3360
                    # Apparently there's no usable smart server there, even though
 
3361
                    # the medium supports the smart protocol.
 
3362
                    do_vfs = True
 
3363
            else:
 
3364
                do_vfs = False
 
3365
        if not do_vfs:
 
3366
            client = _SmartClient(client_medium)
 
3367
            path = client.remote_path_from_transport(transport)
 
3368
            if client_medium._is_remote_before((1, 16)):
 
3369
                do_vfs = True
 
3370
        if do_vfs:
 
3371
            # TODO: lookup the local format from a server hint.
 
3372
            local_dir_format = BzrDirMetaFormat1()
 
3373
            self._supply_sub_formats_to(local_dir_format)
 
3374
            return local_dir_format.initialize_on_transport_ex(transport,
 
3375
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
3376
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
3377
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
3378
                make_working_trees=make_working_trees, shared_repo=shared_repo,
 
3379
                vfs_only=True)
 
3380
        return self._initialize_on_transport_ex_rpc(client, path, transport,
 
3381
            use_existing_dir, create_prefix, force_new_repo, stacked_on,
 
3382
            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
 
3383
 
 
3384
    def _initialize_on_transport_ex_rpc(self, client, path, transport,
 
3385
        use_existing_dir, create_prefix, force_new_repo, stacked_on,
 
3386
        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
 
3387
        args = []
 
3388
        args.append(self._serialize_NoneTrueFalse(use_existing_dir))
 
3389
        args.append(self._serialize_NoneTrueFalse(create_prefix))
 
3390
        args.append(self._serialize_NoneTrueFalse(force_new_repo))
 
3391
        args.append(self._serialize_NoneString(stacked_on))
 
3392
        # stack_on_pwd is often/usually our transport
 
3393
        if stack_on_pwd:
 
3394
            try:
 
3395
                stack_on_pwd = transport.relpath(stack_on_pwd)
 
3396
                if not stack_on_pwd:
 
3397
                    stack_on_pwd = '.'
 
3398
            except errors.PathNotChild:
 
3399
                pass
 
3400
        args.append(self._serialize_NoneString(stack_on_pwd))
 
3401
        args.append(self._serialize_NoneString(repo_format_name))
 
3402
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
 
3403
        args.append(self._serialize_NoneTrueFalse(shared_repo))
 
3404
        request_network_name = self._network_name or \
 
3405
            BzrDirFormat.get_default_format().network_name()
 
3406
        try:
 
3407
            response = client.call('BzrDirFormat.initialize_ex_1.16',
 
3408
                request_network_name, path, *args)
 
3409
        except errors.UnknownSmartMethod:
 
3410
            client._medium._remember_remote_is_before((1,16))
 
3411
            local_dir_format = BzrDirMetaFormat1()
 
3412
            self._supply_sub_formats_to(local_dir_format)
 
3413
            return local_dir_format.initialize_on_transport_ex(transport,
 
3414
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
3415
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
3416
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
3417
                make_working_trees=make_working_trees, shared_repo=shared_repo,
 
3418
                vfs_only=True)
 
3419
        except errors.ErrorFromSmartServer, err:
 
3420
            remote._translate_error(err, path=path)
 
3421
        repo_path = response[0]
 
3422
        bzrdir_name = response[6]
 
3423
        require_stacking = response[7]
 
3424
        require_stacking = self.parse_NoneTrueFalse(require_stacking)
 
3425
        format = RemoteBzrDirFormat()
 
3426
        format._network_name = bzrdir_name
 
3427
        self._supply_sub_formats_to(format)
 
3428
        bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
 
3429
        if repo_path:
 
3430
            repo_format = remote.response_tuple_to_repo_format(response[1:])
 
3431
            if repo_path == '.':
 
3432
                repo_path = ''
 
3433
            if repo_path:
 
3434
                repo_bzrdir_format = RemoteBzrDirFormat()
 
3435
                repo_bzrdir_format._network_name = response[5]
 
3436
                repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
 
3437
                    repo_bzrdir_format)
 
3438
            else:
 
3439
                repo_bzr = bzrdir
 
3440
            final_stack = response[8] or None
 
3441
            final_stack_pwd = response[9] or None
 
3442
            if final_stack_pwd:
 
3443
                final_stack_pwd = urlutils.join(
 
3444
                    transport.base, final_stack_pwd)
 
3445
            remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
 
3446
            if len(response) > 10:
 
3447
                # Updated server verb that locks remotely.
 
3448
                repo_lock_token = response[10] or None
 
3449
                remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
 
3450
                if repo_lock_token:
 
3451
                    remote_repo.dont_leave_lock_in_place()
 
3452
            else:
 
3453
                remote_repo.lock_write()
 
3454
            policy = UseExistingRepository(remote_repo, final_stack,
 
3455
                final_stack_pwd, require_stacking)
 
3456
            policy.acquire_repository()
 
3457
        else:
 
3458
            remote_repo = None
 
3459
            policy = None
 
3460
        bzrdir._format.set_branch_format(self.get_branch_format())
 
3461
        if require_stacking:
 
3462
            # The repo has already been created, but we need to make sure that
 
3463
            # we'll make a stackable branch.
 
3464
            bzrdir._format.require_stacking(_skip_repo=True)
 
3465
        return remote_repo, bzrdir, require_stacking, policy
 
3466
 
2821
3467
    def _open(self, transport):
2822
3468
        return remote.RemoteBzrDir(transport, self)
2823
3469
 
2997
3643
            if info.native:
2998
3644
                help = '(native) ' + help
2999
3645
            return ':%s:\n%s\n\n' % (key,
3000
 
                    textwrap.fill(help, initial_indent='    ',
3001
 
                    subsequent_indent='    '))
 
3646
                textwrap.fill(help, initial_indent='    ',
 
3647
                    subsequent_indent='    ',
 
3648
                    break_long_words=False))
3002
3649
        if default_realkey is not None:
3003
3650
            output += wrapped(default_realkey, '(default) %s' % default_help,
3004
3651
                              self.get_info('default'))
3014
3661
                experimental_pairs.append((key, help))
3015
3662
            else:
3016
3663
                output += wrapped(key, help, info)
3017
 
        output += "\nSee ``bzr help formats`` for more about storage formats."
 
3664
        output += "\nSee :doc:`formats-help` for more about storage formats."
3018
3665
        other_output = ""
3019
3666
        if len(experimental_pairs) > 0:
3020
3667
            other_output += "Experimental formats are shown below.\n\n"
3033
3680
            other_output += \
3034
3681
                "\nNo deprecated formats are available.\n\n"
3035
3682
        other_output += \
3036
 
            "\nSee ``bzr help formats`` for more about storage formats."
 
3683
                "\nSee :doc:`formats-help` for more about storage formats."
3037
3684
 
3038
3685
        if topic == 'other-formats':
3039
3686
            return other_output
3073
3720
            try:
3074
3721
                stack_on = urlutils.rebase_url(self._stack_on,
3075
3722
                    self._stack_on_pwd,
3076
 
                    branch.bzrdir.root_transport.base)
 
3723
                    branch.user_url)
3077
3724
            except errors.InvalidRebaseURLs:
3078
3725
                stack_on = self._get_full_stack_on()
3079
3726
        try:
3083
3730
            if self._require_stacking:
3084
3731
                raise
3085
3732
 
 
3733
    def requires_stacking(self):
 
3734
        """Return True if this policy requires stacking."""
 
3735
        return self._stack_on is not None and self._require_stacking
 
3736
 
3086
3737
    def _get_full_stack_on(self):
3087
3738
        """Get a fully-qualified URL for the stack_on location."""
3088
3739
        if self._stack_on is None:
3097
3748
        stack_on = self._get_full_stack_on()
3098
3749
        if stack_on is None:
3099
3750
            return
3100
 
        stacked_dir = BzrDir.open(stack_on,
3101
 
                                  possible_transports=possible_transports)
 
3751
        try:
 
3752
            stacked_dir = BzrDir.open(stack_on,
 
3753
                                      possible_transports=possible_transports)
 
3754
        except errors.JailBreak:
 
3755
            # We keep the stacking details, but we are in the server code so
 
3756
            # actually stacking is not needed.
 
3757
            return
3102
3758
        try:
3103
3759
            stacked_repo = stacked_dir.open_branch().repository
3104
3760
        except errors.NotBranchError:
3148
3804
        """
3149
3805
        stack_on = self._get_full_stack_on()
3150
3806
        if stack_on:
3151
 
            # Stacking is desired. requested by the target, but does the place it
3152
 
            # points at support stacking? If it doesn't then we should
3153
 
            # not implicitly upgrade. We check this here.
3154
3807
            format = self._bzrdir._format
3155
 
            if not (format.repository_format.supports_external_lookups
3156
 
                and format.get_branch_format().supports_stacking()):
3157
 
                # May need to upgrade - but only do if the target also
3158
 
                # supports stacking. Note that this currently wastes
3159
 
                # network round trips to check - but we only do this
3160
 
                # when the source can't stack so it will fade away
3161
 
                # as people do upgrade.
3162
 
                try:
3163
 
                    target_dir = BzrDir.open(stack_on,
3164
 
                        possible_transports=[self._bzrdir.root_transport])
3165
 
                except errors.NotBranchError:
3166
 
                    # Nothing there, don't change formats
3167
 
                    pass
3168
 
                else:
3169
 
                    try:
3170
 
                        target_branch = target_dir.open_branch()
3171
 
                    except errors.NotBranchError:
3172
 
                        # No branch, don't change formats
3173
 
                        pass
3174
 
                    else:
3175
 
                        branch_format = target_branch._format
3176
 
                        repo_format = target_branch.repository._format
3177
 
                        if not (branch_format.supports_stacking()
3178
 
                            and repo_format.supports_external_lookups):
3179
 
                            # Doesn't stack itself, don't force an upgrade
3180
 
                            pass
3181
 
                        else:
3182
 
                            # Does support stacking, use its format.
3183
 
                            format.repository_format = repo_format
3184
 
                            format.set_branch_format(branch_format)
3185
 
                            note('Source format does not support stacking, '
3186
 
                                'using format: \'%s\'\n  %s\n',
3187
 
                                branch_format.get_format_description(),
3188
 
                                repo_format.get_format_description())
 
3808
            format.require_stacking(stack_on=stack_on,
 
3809
                                    possible_transports=[self._bzrdir.root_transport])
3189
3810
            if not self._require_stacking:
3190
3811
                # We have picked up automatic stacking somewhere.
3191
3812
                note('Using default stacking branch %s at %s', self._stack_on,
3234
3855
format_registry.register('weave', BzrDirFormat6,
3235
3856
    'Pre-0.8 format.  Slower than knit and does not'
3236
3857
    ' support checkouts or shared repositories.',
 
3858
    hidden=True,
3237
3859
    deprecated=True)
3238
3860
format_registry.register_metadir('metaweave',
3239
3861
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3240
3862
    'Transitional format in 0.8.  Slower than knit.',
3241
3863
    branch_format='bzrlib.branch.BzrBranchFormat5',
3242
3864
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3865
    hidden=True,
3243
3866
    deprecated=True)
3244
3867
format_registry.register_metadir('knit',
3245
3868
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3246
3869
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3247
3870
    branch_format='bzrlib.branch.BzrBranchFormat5',
3248
3871
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3872
    hidden=True,
3249
3873
    deprecated=True)
3250
3874
format_registry.register_metadir('dirstate',
3251
3875
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3255
3879
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3256
3880
    # directly from workingtree_4 triggers a circular import.
3257
3881
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3882
    hidden=True,
3258
3883
    deprecated=True)
3259
3884
format_registry.register_metadir('dirstate-tags',
3260
3885
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3263
3888
        ' Incompatible with bzr < 0.15.',
3264
3889
    branch_format='bzrlib.branch.BzrBranchFormat6',
3265
3890
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3891
    hidden=True,
3266
3892
    deprecated=True)
3267
3893
format_registry.register_metadir('rich-root',
3268
3894
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3270
3896
        ' bzr < 1.0.',
3271
3897
    branch_format='bzrlib.branch.BzrBranchFormat6',
3272
3898
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3899
    hidden=True,
3273
3900
    deprecated=True)
3274
3901
format_registry.register_metadir('dirstate-with-subtree',
3275
3902
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3286
3913
    help='New in 0.92: Pack-based format with data compatible with '
3287
3914
        'dirstate-tags format repositories. Interoperates with '
3288
3915
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3289
 
        'Previously called knitpack-experimental.  '
3290
 
        'For more information, see '
3291
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3916
        ,
3292
3917
    branch_format='bzrlib.branch.BzrBranchFormat6',
3293
3918
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3294
3919
    )
3297
3922
    help='New in 0.92: Pack-based format with data compatible with '
3298
3923
        'dirstate-with-subtree format repositories. Interoperates with '
3299
3924
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3300
 
        'Previously called knitpack-experimental.  '
3301
 
        'For more information, see '
3302
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3925
        ,
3303
3926
    branch_format='bzrlib.branch.BzrBranchFormat6',
3304
3927
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3305
3928
    hidden=True,
3311
3934
         '(needed for bzr-svn and bzr-git).',
3312
3935
    branch_format='bzrlib.branch.BzrBranchFormat6',
3313
3936
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3937
    hidden=True,
3314
3938
    )
3315
3939
format_registry.register_metadir('1.6',
3316
3940
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3319
3943
         'not present locally.',
3320
3944
    branch_format='bzrlib.branch.BzrBranchFormat7',
3321
3945
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3946
    hidden=True,
3322
3947
    )
3323
3948
format_registry.register_metadir('1.6.1-rich-root',
3324
3949
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3326
3951
         '(needed for bzr-svn and bzr-git).',
3327
3952
    branch_format='bzrlib.branch.BzrBranchFormat7',
3328
3953
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3954
    hidden=True,
3329
3955
    )
3330
3956
format_registry.register_metadir('1.9',
3331
3957
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3334
3960
         'performance for most operations.',
3335
3961
    branch_format='bzrlib.branch.BzrBranchFormat7',
3336
3962
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3963
    hidden=True,
3337
3964
    )
3338
3965
format_registry.register_metadir('1.9-rich-root',
3339
3966
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3341
3968
         '(needed for bzr-svn and bzr-git).',
3342
3969
    branch_format='bzrlib.branch.BzrBranchFormat7',
3343
3970
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3971
    hidden=True,
3344
3972
    )
3345
 
format_registry.register_metadir('development-wt5',
 
3973
format_registry.register_metadir('1.14',
3346
3974
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3347
 
    help='A working-tree format that supports views and content filtering.',
 
3975
    help='A working-tree format that supports content filtering.',
3348
3976
    branch_format='bzrlib.branch.BzrBranchFormat7',
3349
3977
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3350
 
    experimental=True,
3351
3978
    )
3352
 
format_registry.register_metadir('development-wt5-rich-root',
 
3979
format_registry.register_metadir('1.14-rich-root',
3353
3980
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3354
 
    help='A variant of development-wt5 that supports rich-root data '
 
3981
    help='A variant of 1.14 that supports rich-root data '
3355
3982
         '(needed for bzr-svn and bzr-git).',
3356
3983
    branch_format='bzrlib.branch.BzrBranchFormat7',
3357
3984
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3358
 
    experimental=True,
3359
3985
    )
3360
 
# The following two formats should always just be aliases.
3361
 
format_registry.register_metadir('development',
3362
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3363
 
    help='Current development format. Can convert data to and from pack-0.92 '
3364
 
        '(and anything compatible with pack-0.92) format repositories. '
3365
 
        'Repositories and branches in this format can only be read by bzr.dev. '
3366
 
        'Please read '
3367
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3986
# The following un-numbered 'development' formats should always just be aliases.
 
3987
format_registry.register_metadir('development-rich-root',
 
3988
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
 
3989
    help='Current development format. Supports rich roots. Can convert data '
 
3990
        'to and from rich-root-pack (and anything compatible with '
 
3991
        'rich-root-pack) format repositories. Repositories and branches in '
 
3992
        'this format can only be read by bzr.dev. Please read '
 
3993
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3368
3994
        'before use.',
3369
3995
    branch_format='bzrlib.branch.BzrBranchFormat7',
3370
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3996
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3371
3997
    experimental=True,
3372
3998
    alias=True,
 
3999
    hidden=True,
3373
4000
    )
3374
4001
format_registry.register_metadir('development-subtree',
3375
4002
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3377
4004
        'from pack-0.92-subtree (and anything compatible with '
3378
4005
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3379
4006
        'this format can only be read by bzr.dev. Please read '
3380
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
4007
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3381
4008
        'before use.',
3382
4009
    branch_format='bzrlib.branch.BzrBranchFormat7',
3383
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
4010
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3384
4011
    experimental=True,
3385
 
    alias=True,
 
4012
    hidden=True,
 
4013
    alias=False, # Restore to being an alias when an actual development subtree format is added
 
4014
                 # This current non-alias status is simply because we did not introduce a
 
4015
                 # chk based subtree format.
3386
4016
    )
 
4017
 
3387
4018
# And the development formats above will have aliased one of the following:
3388
 
format_registry.register_metadir('development2',
3389
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3390
 
    help='1.6.1 with B+Tree based index. '
3391
 
        'Please read '
3392
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3393
 
        'before use.',
3394
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3395
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3396
 
    hidden=True,
3397
 
    experimental=True,
3398
 
    )
3399
 
format_registry.register_metadir('development2-subtree',
3400
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3401
 
    help='1.6.1-subtree with B+Tree based index. '
3402
 
        'Please read '
3403
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3404
 
        'before use.',
3405
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3406
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3407
 
    hidden=True,
3408
 
    experimental=True,
3409
 
    )
3410
 
format_registry.register_metadir('development5',
3411
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5',
3412
 
    help='1.9 with CHK inventories with parent_id index. '
3413
 
        'Please read '
3414
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3415
 
        'before use.',
3416
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3417
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3418
 
    hidden=True,
3419
 
    experimental=True,
3420
 
    )
3421
 
format_registry.register_metadir('development5-subtree',
3422
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Subtree',
3423
 
    help='1.9-subtree with CHK Inventories with parent_id index. '
3424
 
        'Please read '
3425
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3426
 
        'before use.',
3427
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3428
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3429
 
    hidden=True,
3430
 
    experimental=True,
3431
 
    )
3432
 
format_registry.register_metadir('development5-hash16',
3433
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Hash16',
3434
 
    help='1.9 with CHK inventories with parent_id index and 16-way hash trie. '
3435
 
        'Please read '
3436
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3437
 
        'before use.',
3438
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3439
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3440
 
    hidden=True,
3441
 
    experimental=True,
3442
 
    )
3443
 
format_registry.register_metadir('development5-hash255',
3444
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Hash255',
3445
 
    help='1.9 with CHK inventories with parent_id index and 255-way hash trie. '
3446
 
        'Please read '
3447
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3448
 
        'before use.',
3449
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3450
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3451
 
    hidden=True,
3452
 
    experimental=True,
3453
 
    )
3454
 
# XXX: This format is scheduled for termination
3455
 
# format_registry.register_metadir('gc-no-rich-root',
3456
 
#     'bzrlib.repofmt.groupcompress_repo.RepositoryFormatPackGCPlain',
3457
 
#     help='pack-1.9 with xml inv, group compress '
3458
 
#         'Please read '
3459
 
#         'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3460
 
#         'before use.',
3461
 
#     branch_format='bzrlib.branch.BzrBranchFormat7',
3462
 
#     tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3463
 
#     hidden=False,
3464
 
#     experimental=True,
3465
 
#     )
3466
 
format_registry.register_metadir('gc-chk16',
3467
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatPackGCCHK16',
3468
 
    help='pack-1.9 with 16-way hashed CHK inv, group compress, rich roots. '
3469
 
        'Please read '
3470
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3471
 
        'before use.',
3472
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3473
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3474
 
    hidden=False,
3475
 
    experimental=True,
3476
 
    )
3477
 
format_registry.register_metadir('gc-chk255',
3478
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatPackGCCHK255',
3479
 
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3480
 
        'Please read '
3481
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3482
 
        'before use.',
3483
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3484
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3485
 
    hidden=False,
3486
 
    experimental=True,
3487
 
    )
3488
 
format_registry.register_metadir('gc-chk255-big',
3489
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatPackGCCHK255Big',
3490
 
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3491
 
        'Please read '
3492
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3493
 
        'before use.',
3494
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3495
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3496
 
    hidden=False,
3497
 
    experimental=True,
3498
 
    )
3499
 
 
3500
 
# The following format should be an alias for the rich root equivalent
 
4019
format_registry.register_metadir('development6-rich-root',
 
4020
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
 
4021
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
 
4022
        'Please read '
 
4023
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
4024
        'before use.',
 
4025
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
4026
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
4027
    hidden=True,
 
4028
    experimental=True,
 
4029
    )
 
4030
 
 
4031
format_registry.register_metadir('development7-rich-root',
 
4032
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
 
4033
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
 
4034
        'rich roots. Please read '
 
4035
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
4036
        'before use.',
 
4037
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
4038
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
4039
    hidden=True,
 
4040
    experimental=True,
 
4041
    )
 
4042
 
 
4043
format_registry.register_metadir('2a',
 
4044
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
 
4045
    help='First format for bzr 2.0 series.\n'
 
4046
        'Uses group-compress storage.\n'
 
4047
        'Provides rich roots which are a one-way transition.\n',
 
4048
        # 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
 
4049
        # 'rich roots. Supported by bzr 1.16 and later.',
 
4050
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
4051
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
4052
    experimental=True,
 
4053
    )
 
4054
 
 
4055
# The following format should be an alias for the rich root equivalent 
3501
4056
# of the default format
3502
4057
format_registry.register_metadir('default-rich-root',
3503
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3504
 
    help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3505
 
    branch_format='bzrlib.branch.BzrBranchFormat6',
3506
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
4058
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
 
4059
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
4060
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3507
4061
    alias=True,
3508
 
    )
 
4062
    hidden=True,
 
4063
    help='Same as 2a.')
 
4064
 
3509
4065
# The current format that is made on 'bzr init'.
3510
 
format_registry.set_default('pack-0.92')
 
4066
format_registry.set_default('2a')