~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Robert Collins
  • Date: 2009-03-31 00:12:10 UTC
  • mto: This revision was merged to the branch mainline in revision 4219.
  • Revision ID: robertc@robertcollins.net-20090331001210-fufeq2heozx9jne0
Fix Tree.get_symlink_target to decode from the disk encoding to get a unicode encoded string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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
33
32
 
34
33
from bzrlib.lazy_import import lazy_import
35
34
lazy_import(globals(), """
36
35
from stat import S_ISDIR
 
36
import textwrap
37
37
 
38
38
import bzrlib
39
39
from bzrlib import (
40
 
    branch,
41
40
    config,
42
 
    controldir,
43
41
    errors,
44
42
    graph,
45
43
    lockable_files,
46
44
    lockdir,
47
45
    osutils,
48
46
    remote,
49
 
    repository,
50
47
    revision as _mod_revision,
51
48
    ui,
52
49
    urlutils,
60
57
from bzrlib.osutils import (
61
58
    sha_string,
62
59
    )
63
 
from bzrlib.push import (
64
 
    PushResult,
65
 
    )
66
 
from bzrlib.repofmt import pack_repo
67
60
from bzrlib.smart.client import _SmartClient
68
61
from bzrlib.store.versioned import WeaveStore
69
62
from bzrlib.transactions import WriteTransaction
71
64
    do_catching_redirections,
72
65
    get_transport,
73
66
    local,
 
67
    remote as remote_transport,
74
68
    )
75
69
from bzrlib.weave import Weave
76
70
""")
78
72
from bzrlib.trace import (
79
73
    mutter,
80
74
    note,
81
 
    warning,
82
75
    )
83
76
 
84
77
from bzrlib import (
88
81
    )
89
82
 
90
83
 
91
 
class BzrDir(controldir.ControlDir):
 
84
class BzrDir(object):
92
85
    """A .bzr control diretory.
93
86
 
94
87
    BzrDir instances let you create or open any of the things that can be
125
118
                    return
126
119
        thing_to_unlock.break_lock()
127
120
 
 
121
    def can_convert_format(self):
 
122
        """Return true if this bzrdir is one whose format we can convert from."""
 
123
        return True
 
124
 
128
125
    def check_conversion_target(self, target_format):
129
 
        """Check that a bzrdir as a whole can be converted to a new format."""
130
 
        # The only current restriction is that the repository content can be 
131
 
        # fetched compatibly with the target.
132
126
        target_repo_format = target_format.repository_format
133
 
        try:
134
 
            self.open_repository()._format.check_conversion_target(
135
 
                target_repo_format)
136
 
        except errors.NoRepositoryPresent:
137
 
            # No repo, no problem.
138
 
            pass
 
127
        source_repo_format = self._format.repository_format
 
128
        source_repo_format.check_conversion_target(target_repo_format)
139
129
 
140
130
    @staticmethod
141
131
    def _check_supported(format, allow_unsupported,
165
155
                format.get_format_description(),
166
156
                basedir)
167
157
 
 
158
    def clone(self, url, revision_id=None, force_new_repo=False,
 
159
              preserve_stacking=False):
 
160
        """Clone this bzrdir and its contents to url verbatim.
 
161
 
 
162
        :param url: The url create the clone at.  If url's last component does
 
163
            not exist, it will be created.
 
164
        :param revision_id: The tip revision-id to use for any branch or
 
165
            working tree.  If not None, then the clone operation may tune
 
166
            itself to download less data.
 
167
        :param force_new_repo: Do not use a shared repository for the target
 
168
                               even if one is available.
 
169
        :param preserve_stacking: When cloning a stacked branch, stack the
 
170
            new branch on top of the other branch's stacked-on branch.
 
171
        """
 
172
        return self.clone_on_transport(get_transport(url),
 
173
                                       revision_id=revision_id,
 
174
                                       force_new_repo=force_new_repo,
 
175
                                       preserve_stacking=preserve_stacking)
 
176
 
168
177
    def clone_on_transport(self, transport, revision_id=None,
169
 
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
170
 
        create_prefix=False, use_existing_dir=True):
 
178
                           force_new_repo=False, preserve_stacking=False,
 
179
                           stacked_on=None):
171
180
        """Clone this bzrdir and its contents to transport verbatim.
172
181
 
173
182
        :param transport: The transport for the location to produce the clone
179
188
                               even if one is available.
180
189
        :param preserve_stacking: When cloning a stacked branch, stack the
181
190
            new branch on top of the other branch's stacked-on branch.
182
 
        :param create_prefix: Create any missing directories leading up to
183
 
            to_transport.
184
 
        :param use_existing_dir: Use an existing directory if one exists.
185
191
        """
186
 
        # Overview: put together a broad description of what we want to end up
187
 
        # with; then make as few api calls as possible to do it.
188
 
 
189
 
        # We may want to create a repo/branch/tree, if we do so what format
190
 
        # would we want for each:
 
192
        transport.ensure_base()
191
193
        require_stacking = (stacked_on is not None)
192
194
        format = self.cloning_metadir(require_stacking)
193
 
 
194
 
        # Figure out what objects we want:
 
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
195
199
        try:
196
200
            local_repo = self.find_repository()
197
201
        except errors.NoRepositoryPresent:
211
215
                        errors.UnstackableRepositoryFormat,
212
216
                        errors.NotStacked):
213
217
                    pass
214
 
        # Bug: We create a metadir without knowing if it can support stacking,
215
 
        # we should look up the policy needs first, or just use it as a hint,
216
 
        # or something.
 
218
 
217
219
        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)
218
224
            make_working_trees = local_repo.make_working_trees()
219
 
            want_shared = local_repo.is_shared()
220
 
            repo_format_name = format.repository_format.network_name()
221
 
        else:
222
 
            make_working_trees = False
223
 
            want_shared = False
224
 
            repo_format_name = None
225
 
 
226
 
        result_repo, result, require_stacking, repository_policy = \
227
 
            format.initialize_on_transport_ex(transport,
228
 
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
229
 
            force_new_repo=force_new_repo, stacked_on=stacked_on,
230
 
            stack_on_pwd=self.root_transport.base,
231
 
            repo_format_name=repo_format_name,
232
 
            make_working_trees=make_working_trees, shared_repo=want_shared)
233
 
        if repo_format_name:
234
 
            try:
235
 
                # If the result repository is in the same place as the
236
 
                # resulting bzr dir, it will have no content, further if the
237
 
                # result is not stacked then we know all content should be
238
 
                # copied, and finally if we are copying up to a specific
239
 
                # revision_id then we can use the pending-ancestry-result which
240
 
                # does not require traversing all of history to describe it.
241
 
                if (result_repo.user_url == result.user_url
242
 
                    and not require_stacking and
243
 
                    revision_id is not None):
244
 
                    fetch_spec = graph.PendingAncestryResult(
245
 
                        [revision_id], local_repo)
246
 
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
247
 
                else:
248
 
                    result_repo.fetch(local_repo, revision_id=revision_id)
249
 
            finally:
250
 
                result_repo.unlock()
251
 
        else:
252
 
            if result_repo is not None:
253
 
                raise AssertionError('result_repo not None(%r)' % result_repo)
 
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
254
238
        # 1 if there is a branch present
255
239
        #   make sure its content is available in the target repository
256
240
        #   clone it.
273
257
        t = get_transport(url)
274
258
        t.ensure_base()
275
259
 
 
260
    @classmethod
 
261
    def create(cls, base, format=None, possible_transports=None):
 
262
        """Create a new BzrDir at the url 'base'.
 
263
 
 
264
        :param format: If supplied, the format of branch to create.  If not
 
265
            supplied, the default is used.
 
266
        :param possible_transports: If supplied, a list of transports that
 
267
            can be reused to share a remote connection.
 
268
        """
 
269
        if cls is not BzrDir:
 
270
            raise AssertionError("BzrDir.create always creates the default"
 
271
                " format, not one of %r" % cls)
 
272
        t = get_transport(base, possible_transports)
 
273
        t.ensure_base()
 
274
        if format is None:
 
275
            format = BzrDirFormat.get_default_format()
 
276
        return format.initialize_on_transport(t)
 
277
 
276
278
    @staticmethod
277
279
    def find_bzrdirs(transport, evaluate=None, list_current=None):
278
280
        """Find bzrdirs recursively from current location.
301
303
            recurse = True
302
304
            try:
303
305
                bzrdir = BzrDir.open_from_transport(current_transport)
304
 
            except (errors.NotBranchError, errors.PermissionDenied):
 
306
            except errors.NotBranchError:
305
307
                pass
306
308
            else:
307
309
                recurse, value = evaluate(bzrdir)
308
310
                yield value
309
311
            try:
310
312
                subdirs = list_current(current_transport)
311
 
            except (errors.NoSuchFile, errors.PermissionDenied):
 
313
            except errors.NoSuchFile:
312
314
                continue
313
315
            if recurse:
314
316
                for subdir in sorted(subdirs, reverse=True):
331
333
            except errors.NoRepositoryPresent:
332
334
                pass
333
335
            else:
334
 
                return False, ([], repository)
335
 
            return True, (bzrdir.list_branches(), None)
336
 
        ret = []
337
 
        for branches, repo in BzrDir.find_bzrdirs(transport,
338
 
                                                  evaluate=evaluate):
 
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):
339
345
            if repo is not None:
340
 
                ret.extend(repo.find_branches())
341
 
            if branches is not None:
342
 
                ret.extend(branches)
343
 
        return ret
 
346
                branches.extend(repo.find_branches())
 
347
            if branch is not None:
 
348
                branches.append(branch)
 
349
        return branches
 
350
 
 
351
    def destroy_repository(self):
 
352
        """Destroy the repository in this BzrDir"""
 
353
        raise NotImplementedError(self.destroy_repository)
 
354
 
 
355
    def create_branch(self):
 
356
        """Create a branch in this BzrDir.
 
357
 
 
358
        The bzrdir's format will control what branch format is created.
 
359
        For more control see BranchFormatXX.create(a_bzrdir).
 
360
        """
 
361
        raise NotImplementedError(self.create_branch)
 
362
 
 
363
    def destroy_branch(self):
 
364
        """Destroy the branch in this BzrDir"""
 
365
        raise NotImplementedError(self.destroy_branch)
344
366
 
345
367
    @staticmethod
346
368
    def create_branch_and_repo(base, force_new_repo=False, format=None):
383
405
            stack_on_pwd = None
384
406
            config = found_bzrdir.get_config()
385
407
            stop = False
386
 
            stack_on = config.get_default_stack_on()
387
 
            if stack_on is not None:
388
 
                stack_on_pwd = found_bzrdir.user_url
389
 
                stop = True
 
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
390
413
            # does it have a repository ?
391
414
            try:
392
415
                repository = found_bzrdir.open_repository()
393
416
            except errors.NoRepositoryPresent:
394
417
                repository = None
395
418
            else:
396
 
                if (found_bzrdir.user_url != self.user_url 
397
 
                    and not repository.is_shared()):
 
419
                if ((found_bzrdir.root_transport.base !=
 
420
                     self.root_transport.base) and not repository.is_shared()):
398
421
                    # Don't look higher, can't use a higher shared repo.
399
422
                    repository = None
400
423
                    stop = True
496
519
                                               format=format).bzrdir
497
520
        return bzrdir.create_workingtree()
498
521
 
499
 
    def generate_backup_name(self, base):
500
 
        """Generate a non-existing backup file name based on base."""
501
 
        counter = 1
502
 
        name = "%s.~%d~" % (base, counter)
503
 
        while self.root_transport.has(name):
504
 
            counter += 1
505
 
            name = "%s.~%d~" % (base, counter)
506
 
        return name
 
522
    def create_workingtree(self, revision_id=None, from_branch=None,
 
523
        accelerator_tree=None, hardlink=False):
 
524
        """Create a working tree at this BzrDir.
 
525
 
 
526
        :param revision_id: create it as of this revision id.
 
527
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
528
        :param accelerator_tree: A tree which can be used for retrieving file
 
529
            contents more quickly than the revision tree, i.e. a workingtree.
 
530
            The revision tree will be used for cases where accelerator_tree's
 
531
            content is different.
 
532
        """
 
533
        raise NotImplementedError(self.create_workingtree)
507
534
 
508
535
    def backup_bzrdir(self):
509
536
        """Backup this bzr control directory.
510
537
 
511
538
        :return: Tuple with old path name and new path name
512
539
        """
513
 
 
514
 
        backup_dir=self.generate_backup_name('backup.bzr')
515
540
        pb = ui.ui_factory.nested_progress_bar()
516
541
        try:
517
542
            # FIXME: bug 300001 -- the backup fails if the backup directory
518
543
            # already exists, but it should instead either remove it or make
519
544
            # a new backup directory.
520
545
            #
 
546
            # FIXME: bug 262450 -- the backup directory should have the same
 
547
            # permissions as the .bzr directory (probably a bug in copy_tree)
521
548
            old_path = self.root_transport.abspath('.bzr')
522
 
            new_path = self.root_transport.abspath(backup_dir)
523
 
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
524
 
            self.root_transport.copy_tree('.bzr', backup_dir)
 
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')
525
553
            return (old_path, new_path)
526
554
        finally:
527
555
            pb.finished()
551
579
                else:
552
580
                    pass
553
581
 
 
582
    def destroy_workingtree(self):
 
583
        """Destroy the working tree at this BzrDir.
 
584
 
 
585
        Formats that do not support this may raise UnsupportedOperation.
 
586
        """
 
587
        raise NotImplementedError(self.destroy_workingtree)
 
588
 
 
589
    def destroy_workingtree_metadata(self):
 
590
        """Destroy the control files for the working tree at this BzrDir.
 
591
 
 
592
        The contents of working tree files are not affected.
 
593
        Formats that do not support this may raise UnsupportedOperation.
 
594
        """
 
595
        raise NotImplementedError(self.destroy_workingtree_metadata)
 
596
 
554
597
    def _find_containing(self, evaluate):
555
598
        """Find something in a containing control directory.
556
599
 
570
613
            if stop:
571
614
                return result
572
615
            next_transport = found_bzrdir.root_transport.clone('..')
573
 
            if (found_bzrdir.user_url == next_transport.base):
 
616
            if (found_bzrdir.root_transport.base == next_transport.base):
574
617
                # top of the file system
575
618
                return None
576
619
            # find the next containing bzrdir
593
636
                repository = found_bzrdir.open_repository()
594
637
            except errors.NoRepositoryPresent:
595
638
                return None, False
596
 
            if found_bzrdir.user_url == self.user_url:
 
639
            if found_bzrdir.root_transport.base == self.root_transport.base:
597
640
                return repository, True
598
641
            elif repository.is_shared():
599
642
                return repository, True
605
648
            raise errors.NoRepositoryPresent(self)
606
649
        return found_repo
607
650
 
 
651
    def get_branch_reference(self):
 
652
        """Return the referenced URL for the branch in this bzrdir.
 
653
 
 
654
        :raises NotBranchError: If there is no Branch.
 
655
        :return: The URL the branch in this bzrdir references if it is a
 
656
            reference branch, or None for regular branches.
 
657
        """
 
658
        return None
 
659
 
 
660
    def get_branch_transport(self, branch_format):
 
661
        """Get the transport for use by branch format in this BzrDir.
 
662
 
 
663
        Note that bzr dirs that do not support format strings will raise
 
664
        IncompatibleFormat if the branch format they are given has
 
665
        a format string, and vice versa.
 
666
 
 
667
        If branch_format is None, the transport is returned with no
 
668
        checking. If it is not None, then the returned transport is
 
669
        guaranteed to point to an existing directory ready for use.
 
670
        """
 
671
        raise NotImplementedError(self.get_branch_transport)
 
672
 
608
673
    def _find_creation_modes(self):
609
674
        """Determine the appropriate modes for files and directories.
610
675
 
649
714
            self._find_creation_modes()
650
715
        return self._dir_mode
651
716
 
 
717
    def get_repository_transport(self, repository_format):
 
718
        """Get the transport for use by repository format in this BzrDir.
 
719
 
 
720
        Note that bzr dirs that do not support format strings will raise
 
721
        IncompatibleFormat if the repository format they are given has
 
722
        a format string, and vice versa.
 
723
 
 
724
        If repository_format is None, the transport is returned with no
 
725
        checking. If it is not None, then the returned transport is
 
726
        guaranteed to point to an existing directory ready for use.
 
727
        """
 
728
        raise NotImplementedError(self.get_repository_transport)
 
729
 
 
730
    def get_workingtree_transport(self, tree_format):
 
731
        """Get the transport for use by workingtree format in this BzrDir.
 
732
 
 
733
        Note that bzr dirs that do not support format strings will raise
 
734
        IncompatibleFormat if the workingtree format they are given has a
 
735
        format string, and vice versa.
 
736
 
 
737
        If workingtree_format is None, the transport is returned with no
 
738
        checking. If it is not None, then the returned transport is
 
739
        guaranteed to point to an existing directory ready for use.
 
740
        """
 
741
        raise NotImplementedError(self.get_workingtree_transport)
 
742
 
652
743
    def get_config(self):
653
 
        """Get configuration for this BzrDir."""
654
 
        return config.BzrDirConfig(self)
655
 
 
656
 
    def _get_config(self):
657
 
        """By default, no configuration is available."""
658
 
        return None
 
744
        if getattr(self, '_get_config', None) is None:
 
745
            return None
 
746
        return self._get_config()
659
747
 
660
748
    def __init__(self, _transport, _format):
661
749
        """Initialize a Bzr control dir object.
667
755
        :param _transport: the transport this dir is based at.
668
756
        """
669
757
        self._format = _format
670
 
        # these are also under the more standard names of 
671
 
        # control_transport and user_transport
672
758
        self.transport = _transport.clone('.bzr')
673
759
        self.root_transport = _transport
674
760
        self._mode_check_done = False
675
761
 
676
 
    @property 
677
 
    def user_transport(self):
678
 
        return self.root_transport
679
 
 
680
 
    @property
681
 
    def control_transport(self):
682
 
        return self.transport
683
 
 
684
762
    def is_control_filename(self, filename):
685
763
        """True if filename is the name of a path which is reserved for bzrdir's.
686
764
 
688
766
 
689
767
        This is true IF and ONLY IF the filename is part of the namespace reserved
690
768
        for bzr control dirs. Currently this is the '.bzr' directory in the root
691
 
        of the root_transport. 
 
769
        of the root_transport. it is expected that plugins will need to extend
 
770
        this in the future - for instance to make bzr talk with svn working
 
771
        trees.
692
772
        """
693
773
        # this might be better on the BzrDirFormat class because it refers to
694
774
        # all the possible bzrdir disk formats.
698
778
        # add new tests for it to the appropriate place.
699
779
        return filename == '.bzr' or filename.startswith('.bzr/')
700
780
 
 
781
    def needs_format_conversion(self, format=None):
 
782
        """Return true if this bzrdir needs convert_format run on it.
 
783
 
 
784
        For instance, if the repository format is out of date but the
 
785
        branch and working tree are not, this should return True.
 
786
 
 
787
        :param format: Optional parameter indicating a specific desired
 
788
                       format we plan to arrive at.
 
789
        """
 
790
        raise NotImplementedError(self.needs_format_conversion)
 
791
 
701
792
    @staticmethod
702
793
    def open_unsupported(base):
703
794
        """Open a branch which is not supported."""
726
817
        # the redirections.
727
818
        base = transport.base
728
819
        def find_format(transport):
729
 
            return transport, controldir.ControlDirFormat.find_format(
 
820
            return transport, BzrDirFormat.find_format(
730
821
                transport, _server_formats=_server_formats)
731
822
 
732
823
        def redirected(transport, e, redirection_notice):
747
838
        BzrDir._check_supported(format, _unsupported)
748
839
        return format.open(transport, _found=True)
749
840
 
 
841
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
842
        """Open the branch object at this BzrDir if one is present.
 
843
 
 
844
        If unsupported is True, then no longer supported branch formats can
 
845
        still be opened.
 
846
 
 
847
        TODO: static convenience version of this?
 
848
        """
 
849
        raise NotImplementedError(self.open_branch)
 
850
 
750
851
    @staticmethod
751
852
    def open_containing(url, possible_transports=None):
752
853
        """Open an existing branch which contains url.
790
891
                raise errors.NotBranchError(path=url)
791
892
            a_transport = new_t
792
893
 
 
894
    def _get_tree_branch(self):
 
895
        """Return the branch and tree, if any, for this bzrdir.
 
896
 
 
897
        Return None for tree if not present or inaccessible.
 
898
        Raise NotBranchError if no branch is present.
 
899
        :return: (tree, branch)
 
900
        """
 
901
        try:
 
902
            tree = self.open_workingtree()
 
903
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
904
            tree = None
 
905
            branch = self.open_branch()
 
906
        else:
 
907
            branch = tree.branch
 
908
        return tree, branch
 
909
 
793
910
    @classmethod
794
911
    def open_tree_or_branch(klass, location):
795
912
        """Return the branch and working tree at a location.
841
958
                raise errors.NotBranchError(location)
842
959
        return tree, branch, branch.repository, relpath
843
960
 
 
961
    def open_repository(self, _unsupported=False):
 
962
        """Open the repository object at this BzrDir if one is present.
 
963
 
 
964
        This will not follow the Branch object pointer - it's strictly a direct
 
965
        open facility. Most client code should use open_branch().repository to
 
966
        get at a repository.
 
967
 
 
968
        :param _unsupported: a private parameter, not part of the api.
 
969
        TODO: static convenience version of this?
 
970
        """
 
971
        raise NotImplementedError(self.open_repository)
 
972
 
 
973
    def open_workingtree(self, _unsupported=False,
 
974
                         recommend_upgrade=True, from_branch=None):
 
975
        """Open the workingtree object at this BzrDir if one is present.
 
976
 
 
977
        :param recommend_upgrade: Optional keyword parameter, when True (the
 
978
            default), emit through the ui module a recommendation that the user
 
979
            upgrade the working tree when the workingtree being opened is old
 
980
            (but still fully supported).
 
981
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
982
        """
 
983
        raise NotImplementedError(self.open_workingtree)
 
984
 
 
985
    def has_branch(self):
 
986
        """Tell if this bzrdir contains a branch.
 
987
 
 
988
        Note: if you're going to open the branch, you should just go ahead
 
989
        and try, and not ask permission first.  (This method just opens the
 
990
        branch and discards it, and that's somewhat expensive.)
 
991
        """
 
992
        try:
 
993
            self.open_branch()
 
994
            return True
 
995
        except errors.NotBranchError:
 
996
            return False
 
997
 
 
998
    def has_workingtree(self):
 
999
        """Tell if this bzrdir contains a working tree.
 
1000
 
 
1001
        This will still raise an exception if the bzrdir has a workingtree that
 
1002
        is remote & inaccessible.
 
1003
 
 
1004
        Note: if you're going to open the working tree, you should just go ahead
 
1005
        and try, and not ask permission first.  (This method just opens the
 
1006
        workingtree and discards it, and that's somewhat expensive.)
 
1007
        """
 
1008
        try:
 
1009
            self.open_workingtree(recommend_upgrade=False)
 
1010
            return True
 
1011
        except errors.NoWorkingTree:
 
1012
            return False
 
1013
 
844
1014
    def _cloning_metadir(self):
845
1015
        """Produce a metadir suitable for cloning with.
846
1016
 
892
1062
        """
893
1063
        format, repository = self._cloning_metadir()
894
1064
        if format._workingtree_format is None:
895
 
            # No tree in self.
896
1065
            if repository is None:
897
 
                # No repository either
898
1066
                return format
899
 
            # We have a repository, so set a working tree? (Why? This seems to
900
 
            # contradict the stated return value in the docstring).
901
1067
            tree_format = repository._format._matchingbzrdir.workingtree_format
902
1068
            format.workingtree_format = tree_format.__class__()
903
1069
        if require_stacking:
904
1070
            format.require_stacking()
905
1071
        return format
906
1072
 
907
 
    @classmethod
908
 
    def create(cls, base, format=None, possible_transports=None):
909
 
        """Create a new BzrDir at the url 'base'.
910
 
 
911
 
        :param format: If supplied, the format of branch to create.  If not
912
 
            supplied, the default is used.
913
 
        :param possible_transports: If supplied, a list of transports that
914
 
            can be reused to share a remote connection.
 
1073
    def checkout_metadir(self):
 
1074
        return self.cloning_metadir()
 
1075
 
 
1076
    def sprout(self, url, revision_id=None, force_new_repo=False,
 
1077
               recurse='down', possible_transports=None,
 
1078
               accelerator_tree=None, hardlink=False, stacked=False,
 
1079
               source_branch=None, create_tree_if_local=True):
 
1080
        """Create a copy of this bzrdir prepared for use as a new line of
 
1081
        development.
 
1082
 
 
1083
        If url's last component does not exist, it will be created.
 
1084
 
 
1085
        Attributes related to the identity of the source branch like
 
1086
        branch nickname will be cleaned, a working tree is created
 
1087
        whether one existed before or not; and a local branch is always
 
1088
        created.
 
1089
 
 
1090
        if revision_id is not None, then the clone operation may tune
 
1091
            itself to download less data.
 
1092
        :param accelerator_tree: A tree which can be used for retrieving file
 
1093
            contents more quickly than the revision tree, i.e. a workingtree.
 
1094
            The revision tree will be used for cases where accelerator_tree's
 
1095
            content is different.
 
1096
        :param hardlink: If true, hard-link files from accelerator_tree,
 
1097
            where possible.
 
1098
        :param stacked: If true, create a stacked branch referring to the
 
1099
            location of this control directory.
 
1100
        :param create_tree_if_local: If true, a working-tree will be created
 
1101
            when working locally.
915
1102
        """
916
 
        if cls is not BzrDir:
917
 
            raise AssertionError("BzrDir.create always creates the"
918
 
                "default format, not one of %r" % cls)
919
 
        t = get_transport(base, possible_transports)
920
 
        t.ensure_base()
921
 
        if format is None:
922
 
            format = controldir.ControlDirFormat.get_default_format()
923
 
        return format.initialize_on_transport(t)
924
 
 
 
1103
        target_transport = get_transport(url, possible_transports)
 
1104
        target_transport.ensure_base()
 
1105
        cloning_format = self.cloning_metadir(stacked)
 
1106
        # Create/update the result branch
 
1107
        result = cloning_format.initialize_on_transport(target_transport)
 
1108
        # if a stacked branch wasn't requested, we don't create one
 
1109
        # even if the origin was stacked
 
1110
        stacked_branch_url = None
 
1111
        if source_branch is not None:
 
1112
            if stacked:
 
1113
                stacked_branch_url = self.root_transport.base
 
1114
            source_repository = source_branch.repository
 
1115
        else:
 
1116
            try:
 
1117
                source_branch = self.open_branch()
 
1118
                source_repository = source_branch.repository
 
1119
                if stacked:
 
1120
                    stacked_branch_url = self.root_transport.base
 
1121
            except errors.NotBranchError:
 
1122
                source_branch = None
 
1123
                try:
 
1124
                    source_repository = self.open_repository()
 
1125
                except errors.NoRepositoryPresent:
 
1126
                    source_repository = None
 
1127
        repository_policy = result.determine_repository_policy(
 
1128
            force_new_repo, stacked_branch_url, require_stacking=stacked)
 
1129
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
1130
        if is_new_repo and revision_id is not None and not stacked:
 
1131
            fetch_spec = graph.PendingAncestryResult(
 
1132
                [revision_id], source_repository)
 
1133
        else:
 
1134
            fetch_spec = None
 
1135
        if source_repository is not None:
 
1136
            # Fetch while stacked to prevent unstacked fetch from
 
1137
            # Branch.sprout.
 
1138
            if fetch_spec is None:
 
1139
                result_repo.fetch(source_repository, revision_id=revision_id)
 
1140
            else:
 
1141
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
1142
 
 
1143
        if source_branch is None:
 
1144
            # this is for sprouting a bzrdir without a branch; is that
 
1145
            # actually useful?
 
1146
            # Not especially, but it's part of the contract.
 
1147
            result_branch = result.create_branch()
 
1148
        else:
 
1149
            result_branch = source_branch.sprout(result,
 
1150
                revision_id=revision_id, repository_policy=repository_policy)
 
1151
        mutter("created new branch %r" % (result_branch,))
 
1152
 
 
1153
        # Create/update the result working tree
 
1154
        if (create_tree_if_local and
 
1155
            isinstance(target_transport, local.LocalTransport) and
 
1156
            (result_repo is None or result_repo.make_working_trees())):
 
1157
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
 
1158
                hardlink=hardlink)
 
1159
            wt.lock_write()
 
1160
            try:
 
1161
                if wt.path2id('') is None:
 
1162
                    try:
 
1163
                        wt.set_root_id(self.open_workingtree.get_root_id())
 
1164
                    except errors.NoWorkingTree:
 
1165
                        pass
 
1166
            finally:
 
1167
                wt.unlock()
 
1168
        else:
 
1169
            wt = None
 
1170
        if recurse == 'down':
 
1171
            if wt is not None:
 
1172
                basis = wt.basis_tree()
 
1173
                basis.lock_read()
 
1174
                subtrees = basis.iter_references()
 
1175
            elif result_branch is not None:
 
1176
                basis = result_branch.basis_tree()
 
1177
                basis.lock_read()
 
1178
                subtrees = basis.iter_references()
 
1179
            elif source_branch is not None:
 
1180
                basis = source_branch.basis_tree()
 
1181
                basis.lock_read()
 
1182
                subtrees = basis.iter_references()
 
1183
            else:
 
1184
                subtrees = []
 
1185
                basis = None
 
1186
            try:
 
1187
                for path, file_id in subtrees:
 
1188
                    target = urlutils.join(url, urlutils.escape(path))
 
1189
                    sublocation = source_branch.reference_parent(file_id, path)
 
1190
                    sublocation.bzrdir.sprout(target,
 
1191
                        basis.get_reference_revision(file_id, path),
 
1192
                        force_new_repo=force_new_repo, recurse=recurse,
 
1193
                        stacked=stacked)
 
1194
            finally:
 
1195
                if basis is not None:
 
1196
                    basis.unlock()
 
1197
        return result
925
1198
 
926
1199
 
927
1200
class BzrDirHooks(hooks.Hooks):
933
1206
        self.create_hook(hooks.HookPoint('pre_open',
934
1207
            "Invoked before attempting to open a BzrDir with the transport "
935
1208
            "that the open will use.", (1, 14), None))
936
 
        self.create_hook(hooks.HookPoint('post_repo_init',
937
 
            "Invoked after a repository has been initialized. "
938
 
            "post_repo_init is called with a "
939
 
            "bzrlib.bzrdir.RepoInitHookParams.",
940
 
            (2, 2), None))
941
1209
 
942
1210
# install the default hooks
943
1211
BzrDir.hooks = BzrDirHooks()
944
1212
 
945
1213
 
946
 
class RepoInitHookParams(object):
947
 
    """Object holding parameters passed to *_repo_init hooks.
948
 
 
949
 
    There are 4 fields that hooks may wish to access:
950
 
 
951
 
    :ivar repository: Repository created
952
 
    :ivar format: Repository format
953
 
    :ivar bzrdir: The bzrdir for the repository
954
 
    :ivar shared: The repository is shared
955
 
    """
956
 
 
957
 
    def __init__(self, repository, format, a_bzrdir, shared):
958
 
        """Create a group of RepoInitHook parameters.
959
 
 
960
 
        :param repository: Repository created
961
 
        :param format: Repository format
962
 
        :param bzrdir: The bzrdir for the repository
963
 
        :param shared: The repository is shared
964
 
        """
965
 
        self.repository = repository
966
 
        self.format = format
967
 
        self.bzrdir = a_bzrdir
968
 
        self.shared = shared
969
 
 
970
 
    def __eq__(self, other):
971
 
        return self.__dict__ == other.__dict__
972
 
 
973
 
    def __repr__(self):
974
 
        if self.repository:
975
 
            return "<%s for %s>" % (self.__class__.__name__,
976
 
                self.repository)
977
 
        else:
978
 
            return "<%s for %s>" % (self.__class__.__name__,
979
 
                self.bzrdir)
980
 
 
981
 
 
982
1214
class BzrDirPreSplitOut(BzrDir):
983
1215
    """A common class for the all-in-one formats."""
984
1216
 
997
1229
    def cloning_metadir(self, require_stacking=False):
998
1230
        """Produce a metadir suitable for cloning with."""
999
1231
        if require_stacking:
1000
 
            return controldir.format_registry.make_bzrdir('1.6')
 
1232
            return format_registry.make_bzrdir('1.6')
1001
1233
        return self._format.__class__()
1002
1234
 
1003
1235
    def clone(self, url, revision_id=None, force_new_repo=False,
1023
1255
            tree.clone(result)
1024
1256
        return result
1025
1257
 
1026
 
    def create_branch(self, name=None):
 
1258
    def create_branch(self):
1027
1259
        """See BzrDir.create_branch."""
1028
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1260
        return self._format.get_branch_format().initialize(self)
1029
1261
 
1030
 
    def destroy_branch(self, name=None):
 
1262
    def destroy_branch(self):
1031
1263
        """See BzrDir.destroy_branch."""
1032
1264
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1033
1265
 
1056
1288
        # that can do wonky stuff here, and that only
1057
1289
        # happens for creating checkouts, which cannot be
1058
1290
        # done on this format anyway. So - acceptable wart.
1059
 
        if hardlink:
1060
 
            warning("can't support hardlinked working trees in %r"
1061
 
                % (self,))
1062
1291
        try:
1063
1292
            result = self.open_workingtree(recommend_upgrade=False)
1064
1293
        except errors.NoSuchFile:
1089
1318
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1090
1319
                                          self)
1091
1320
 
1092
 
    def get_branch_transport(self, branch_format, name=None):
 
1321
    def get_branch_transport(self, branch_format):
1093
1322
        """See BzrDir.get_branch_transport()."""
1094
 
        if name is not None:
1095
 
            raise errors.NoColocatedBranchSupport(self)
1096
1323
        if branch_format is None:
1097
1324
            return self.transport
1098
1325
        try:
1131
1358
            format = BzrDirFormat.get_default_format()
1132
1359
        return not isinstance(self._format, format.__class__)
1133
1360
 
1134
 
    def open_branch(self, name=None, unsupported=False,
1135
 
                    ignore_fallbacks=False):
 
1361
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
1136
1362
        """See BzrDir.open_branch."""
1137
1363
        from bzrlib.branch import BzrBranchFormat4
1138
1364
        format = BzrBranchFormat4()
1139
1365
        self._check_supported(format, unsupported)
1140
 
        return format.open(self, name, _found=True)
 
1366
        return format.open(self, _found=True)
1141
1367
 
1142
1368
    def sprout(self, url, revision_id=None, force_new_repo=False,
1143
1369
               possible_transports=None, accelerator_tree=None,
1204
1430
    This is a deprecated format and may be removed after sept 2006.
1205
1431
    """
1206
1432
 
1207
 
    def has_workingtree(self):
1208
 
        """See BzrDir.has_workingtree."""
1209
 
        return True
1210
 
    
1211
1433
    def open_repository(self):
1212
1434
        """See BzrDir.open_repository."""
1213
1435
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1229
1451
    This is a deprecated format and may be removed after sept 2006.
1230
1452
    """
1231
1453
 
1232
 
    def has_workingtree(self):
1233
 
        """See BzrDir.has_workingtree."""
1234
 
        return True
1235
 
    
1236
1454
    def open_repository(self):
1237
1455
        """See BzrDir.open_repository."""
1238
1456
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1260
1478
        """See BzrDir.can_convert_format()."""
1261
1479
        return True
1262
1480
 
1263
 
    def create_branch(self, name=None):
 
1481
    def create_branch(self):
1264
1482
        """See BzrDir.create_branch."""
1265
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1483
        return self._format.get_branch_format().initialize(self)
1266
1484
 
1267
 
    def destroy_branch(self, name=None):
 
1485
    def destroy_branch(self):
1268
1486
        """See BzrDir.create_branch."""
1269
 
        if name is not None:
1270
 
            raise errors.NoColocatedBranchSupport(self)
1271
1487
        self.transport.delete_tree('branch')
1272
1488
 
1273
1489
    def create_repository(self, shared=False):
1296
1512
    def destroy_workingtree_metadata(self):
1297
1513
        self.transport.delete_tree('checkout')
1298
1514
 
1299
 
    def find_branch_format(self, name=None):
 
1515
    def find_branch_format(self):
1300
1516
        """Find the branch 'format' for this bzrdir.
1301
1517
 
1302
1518
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1303
1519
        """
1304
1520
        from bzrlib.branch import BranchFormat
1305
 
        return BranchFormat.find_format(self, name=name)
 
1521
        return BranchFormat.find_format(self)
1306
1522
 
1307
1523
    def _get_mkdir_mode(self):
1308
1524
        """Figure out the mode to use when creating a bzrdir subdir."""
1310
1526
                                     lockable_files.TransportLock)
1311
1527
        return temp_control._dir_mode
1312
1528
 
1313
 
    def get_branch_reference(self, name=None):
 
1529
    def get_branch_reference(self):
1314
1530
        """See BzrDir.get_branch_reference()."""
1315
1531
        from bzrlib.branch import BranchFormat
1316
 
        format = BranchFormat.find_format(self, name=name)
1317
 
        return format.get_reference(self, name=name)
 
1532
        format = BranchFormat.find_format(self)
 
1533
        return format.get_reference(self)
1318
1534
 
1319
 
    def get_branch_transport(self, branch_format, name=None):
 
1535
    def get_branch_transport(self, branch_format):
1320
1536
        """See BzrDir.get_branch_transport()."""
1321
 
        if name is not None:
1322
 
            raise errors.NoColocatedBranchSupport(self)
1323
 
        # XXX: this shouldn't implicitly create the directory if it's just
1324
 
        # promising to get a transport -- mbp 20090727
1325
1537
        if branch_format is None:
1326
1538
            return self.transport.clone('branch')
1327
1539
        try:
1362
1574
            pass
1363
1575
        return self.transport.clone('checkout')
1364
1576
 
1365
 
    def has_workingtree(self):
1366
 
        """Tell if this bzrdir contains a working tree.
1367
 
 
1368
 
        This will still raise an exception if the bzrdir has a workingtree that
1369
 
        is remote & inaccessible.
1370
 
 
1371
 
        Note: if you're going to open the working tree, you should just go
1372
 
        ahead and try, and not ask permission first.
1373
 
        """
1374
 
        from bzrlib.workingtree import WorkingTreeFormat
1375
 
        try:
1376
 
            WorkingTreeFormat.find_format(self)
1377
 
        except errors.NoWorkingTree:
1378
 
            return False
1379
 
        return True
1380
 
 
1381
1577
    def needs_format_conversion(self, format=None):
1382
1578
        """See BzrDir.needs_format_conversion()."""
1383
1579
        if format is None:
1396
1592
                return True
1397
1593
        except errors.NoRepositoryPresent:
1398
1594
            pass
1399
 
        for branch in self.list_branches():
1400
 
            if not isinstance(branch._format,
 
1595
        try:
 
1596
            if not isinstance(self.open_branch()._format,
1401
1597
                              format.get_branch_format().__class__):
1402
1598
                # the branch needs an upgrade.
1403
1599
                return True
 
1600
        except errors.NotBranchError:
 
1601
            pass
1404
1602
        try:
1405
1603
            my_wt = self.open_workingtree(recommend_upgrade=False)
1406
1604
            if not isinstance(my_wt._format,
1411
1609
            pass
1412
1610
        return False
1413
1611
 
1414
 
    def open_branch(self, name=None, unsupported=False,
1415
 
                    ignore_fallbacks=False):
 
1612
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
1416
1613
        """See BzrDir.open_branch."""
1417
 
        format = self.find_branch_format(name=name)
 
1614
        format = self.find_branch_format()
1418
1615
        self._check_supported(format, unsupported)
1419
 
        return format.open(self, name=name,
1420
 
            _found=True, ignore_fallbacks=ignore_fallbacks)
 
1616
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1421
1617
 
1422
1618
    def open_repository(self, unsupported=False):
1423
1619
        """See BzrDir.open_repository."""
1437
1633
        return format.open(self, _found=True)
1438
1634
 
1439
1635
    def _get_config(self):
1440
 
        return config.TransportConfig(self.transport, 'control.conf')
1441
 
 
1442
 
 
1443
 
class BzrProber(controldir.Prober):
1444
 
    """Prober for formats that use a .bzr/ control directory."""
1445
 
 
1446
 
    _formats = {}
1447
 
    """The known .bzr formats."""
1448
 
 
1449
 
    @classmethod
1450
 
    def register_bzrdir_format(klass, format):
1451
 
        klass._formats[format.get_format_string()] = format
1452
 
 
1453
 
    @classmethod
1454
 
    def unregister_bzrdir_format(klass, format):
1455
 
        del klass._formats[format.get_format_string()]
1456
 
 
1457
 
    @classmethod
1458
 
    def probe_transport(klass, transport):
1459
 
        """Return the .bzrdir style format present in a directory."""
1460
 
        try:
1461
 
            format_string = transport.get_bytes(".bzr/branch-format")
1462
 
        except errors.NoSuchFile:
1463
 
            raise errors.NotBranchError(path=transport.base)
1464
 
        try:
1465
 
            return klass._formats[format_string]
1466
 
        except KeyError:
1467
 
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1468
 
 
1469
 
 
1470
 
controldir.ControlDirFormat.register_prober(BzrProber)
1471
 
 
1472
 
 
1473
 
class RemoteBzrProber(controldir.Prober):
1474
 
    """Prober for remote servers that provide a Bazaar smart server."""
1475
 
 
1476
 
    @classmethod
1477
 
    def probe_transport(klass, transport):
1478
 
        """Return a RemoteBzrDirFormat object if it looks possible."""
1479
 
        try:
1480
 
            medium = transport.get_smart_medium()
1481
 
        except (NotImplementedError, AttributeError,
1482
 
                errors.TransportNotPossible, errors.NoSmartMedium,
1483
 
                errors.SmartProtocolError):
1484
 
            # no smart server, so not a branch for this format type.
1485
 
            raise errors.NotBranchError(path=transport.base)
1486
 
        else:
1487
 
            # Decline to open it if the server doesn't support our required
1488
 
            # version (3) so that the VFS-based transport will do it.
1489
 
            if medium.should_probe():
1490
 
                try:
1491
 
                    server_version = medium.protocol_version()
1492
 
                except errors.SmartProtocolError:
1493
 
                    # Apparently there's no usable smart server there, even though
1494
 
                    # the medium supports the smart protocol.
1495
 
                    raise errors.NotBranchError(path=transport.base)
1496
 
                if server_version != '2':
1497
 
                    raise errors.NotBranchError(path=transport.base)
1498
 
            return RemoteBzrDirFormat()
1499
 
 
1500
 
 
1501
 
class BzrDirFormat(controldir.ControlDirFormat):
1502
 
    """ControlDirFormat base class for .bzr/ directories.
 
1636
        return config.BzrDirConfig(self.transport)
 
1637
 
 
1638
 
 
1639
class BzrDirFormat(object):
 
1640
    """An encapsulation of the initialization and open routines for a format.
 
1641
 
 
1642
    Formats provide three things:
 
1643
     * An initialization routine,
 
1644
     * a format string,
 
1645
     * an open routine.
1503
1646
 
1504
1647
    Formats are placed in a dict by their format string for reference
1505
1648
    during bzrdir opening. These should be subclasses of BzrDirFormat
1510
1653
    object will be created every system load.
1511
1654
    """
1512
1655
 
 
1656
    _default_format = None
 
1657
    """The default format used for new .bzr dirs."""
 
1658
 
 
1659
    _formats = {}
 
1660
    """The known formats."""
 
1661
 
 
1662
    _control_formats = []
 
1663
    """The registered control formats - .bzr, ....
 
1664
 
 
1665
    This is a list of BzrDirFormat objects.
 
1666
    """
 
1667
 
 
1668
    _control_server_formats = []
 
1669
    """The registered control server formats, e.g. RemoteBzrDirs.
 
1670
 
 
1671
    This is a list of BzrDirFormat objects.
 
1672
    """
 
1673
 
1513
1674
    _lock_file_name = 'branch-lock'
1514
1675
 
1515
1676
    # _lock_class must be set in subclasses to the lock type, typ.
1516
1677
    # TransportLock or LockDir
1517
1678
 
 
1679
    @classmethod
 
1680
    def find_format(klass, transport, _server_formats=True):
 
1681
        """Return the format present at transport."""
 
1682
        if _server_formats:
 
1683
            formats = klass._control_server_formats + klass._control_formats
 
1684
        else:
 
1685
            formats = klass._control_formats
 
1686
        for format in formats:
 
1687
            try:
 
1688
                return format.probe_transport(transport)
 
1689
            except errors.NotBranchError:
 
1690
                # this format does not find a control dir here.
 
1691
                pass
 
1692
        raise errors.NotBranchError(path=transport.base)
 
1693
 
 
1694
    @classmethod
 
1695
    def probe_transport(klass, transport):
 
1696
        """Return the .bzrdir style format present in a directory."""
 
1697
        try:
 
1698
            format_string = transport.get(".bzr/branch-format").read()
 
1699
        except errors.NoSuchFile:
 
1700
            raise errors.NotBranchError(path=transport.base)
 
1701
 
 
1702
        try:
 
1703
            return klass._formats[format_string]
 
1704
        except KeyError:
 
1705
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
 
1706
 
 
1707
    @classmethod
 
1708
    def get_default_format(klass):
 
1709
        """Return the current default format."""
 
1710
        return klass._default_format
 
1711
 
1518
1712
    def get_format_string(self):
1519
1713
        """Return the ASCII format string that identifies this format."""
1520
1714
        raise NotImplementedError(self.get_format_string)
1521
1715
 
 
1716
    def get_format_description(self):
 
1717
        """Return the short description for this format."""
 
1718
        raise NotImplementedError(self.get_format_description)
 
1719
 
 
1720
    def get_converter(self, format=None):
 
1721
        """Return the converter to use to convert bzrdirs needing converts.
 
1722
 
 
1723
        This returns a bzrlib.bzrdir.Converter object.
 
1724
 
 
1725
        This should return the best upgrader to step this format towards the
 
1726
        current default format. In the case of plugins we can/should provide
 
1727
        some means for them to extend the range of returnable converters.
 
1728
 
 
1729
        :param format: Optional format to override the default format of the
 
1730
                       library.
 
1731
        """
 
1732
        raise NotImplementedError(self.get_converter)
 
1733
 
 
1734
    def initialize(self, url, possible_transports=None):
 
1735
        """Create a bzr control dir at this url and return an opened copy.
 
1736
 
 
1737
        Subclasses should typically override initialize_on_transport
 
1738
        instead of this method.
 
1739
        """
 
1740
        return self.initialize_on_transport(get_transport(url,
 
1741
                                                          possible_transports))
 
1742
 
1522
1743
    def initialize_on_transport(self, transport):
1523
1744
        """Initialize a new bzrdir in the base directory of a Transport."""
1524
1745
        try:
1537
1758
            self._supply_sub_formats_to(remote_format)
1538
1759
            return remote_format.initialize_on_transport(transport)
1539
1760
 
1540
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1541
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
1542
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1543
 
        shared_repo=False, vfs_only=False):
1544
 
        """Create this format on transport.
1545
 
 
1546
 
        The directory to initialize will be created.
1547
 
 
1548
 
        :param force_new_repo: Do not use a shared repository for the target,
1549
 
                               even if one is available.
1550
 
        :param create_prefix: Create any missing directories leading up to
1551
 
            to_transport.
1552
 
        :param use_existing_dir: Use an existing directory if one exists.
1553
 
        :param stacked_on: A url to stack any created branch on, None to follow
1554
 
            any target stacking policy.
1555
 
        :param stack_on_pwd: If stack_on is relative, the location it is
1556
 
            relative to.
1557
 
        :param repo_format_name: If non-None, a repository will be
1558
 
            made-or-found. Should none be found, or if force_new_repo is True
1559
 
            the repo_format_name is used to select the format of repository to
1560
 
            create.
1561
 
        :param make_working_trees: Control the setting of make_working_trees
1562
 
            for a new shared repository when one is made. None to use whatever
1563
 
            default the format has.
1564
 
        :param shared_repo: Control whether made repositories are shared or
1565
 
            not.
1566
 
        :param vfs_only: If True do not attempt to use a smart server
1567
 
        :return: repo, bzrdir, require_stacking, repository_policy. repo is
1568
 
            None if none was created or found, bzrdir is always valid.
1569
 
            require_stacking is the result of examining the stacked_on
1570
 
            parameter and any stacking policy found for the target.
1571
 
        """
1572
 
        if not vfs_only:
1573
 
            # Try to hand off to a smart server 
1574
 
            try:
1575
 
                client_medium = transport.get_smart_medium()
1576
 
            except errors.NoSmartMedium:
1577
 
                pass
1578
 
            else:
1579
 
                # TODO: lookup the local format from a server hint.
1580
 
                remote_dir_format = RemoteBzrDirFormat()
1581
 
                remote_dir_format._network_name = self.network_name()
1582
 
                self._supply_sub_formats_to(remote_dir_format)
1583
 
                return remote_dir_format.initialize_on_transport_ex(transport,
1584
 
                    use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1585
 
                    force_new_repo=force_new_repo, stacked_on=stacked_on,
1586
 
                    stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1587
 
                    make_working_trees=make_working_trees, shared_repo=shared_repo)
1588
 
        # XXX: Refactor the create_prefix/no_create_prefix code into a
1589
 
        #      common helper function
1590
 
        # The destination may not exist - if so make it according to policy.
1591
 
        def make_directory(transport):
1592
 
            transport.mkdir('.')
1593
 
            return transport
1594
 
        def redirected(transport, e, redirection_notice):
1595
 
            note(redirection_notice)
1596
 
            return transport._redirected_to(e.source, e.target)
1597
 
        try:
1598
 
            transport = do_catching_redirections(make_directory, transport,
1599
 
                redirected)
1600
 
        except errors.FileExists:
1601
 
            if not use_existing_dir:
1602
 
                raise
1603
 
        except errors.NoSuchFile:
1604
 
            if not create_prefix:
1605
 
                raise
1606
 
            transport.create_prefix()
1607
 
 
1608
 
        require_stacking = (stacked_on is not None)
1609
 
        # Now the target directory exists, but doesn't have a .bzr
1610
 
        # directory. So we need to create it, along with any work to create
1611
 
        # all of the dependent branches, etc.
1612
 
 
1613
 
        result = self.initialize_on_transport(transport)
1614
 
        if repo_format_name:
1615
 
            try:
1616
 
                # use a custom format
1617
 
                result._format.repository_format = \
1618
 
                    repository.network_format_registry.get(repo_format_name)
1619
 
            except AttributeError:
1620
 
                # The format didn't permit it to be set.
1621
 
                pass
1622
 
            # A repository is desired, either in-place or shared.
1623
 
            repository_policy = result.determine_repository_policy(
1624
 
                force_new_repo, stacked_on, stack_on_pwd,
1625
 
                require_stacking=require_stacking)
1626
 
            result_repo, is_new_repo = repository_policy.acquire_repository(
1627
 
                make_working_trees, shared_repo)
1628
 
            if not require_stacking and repository_policy._require_stacking:
1629
 
                require_stacking = True
1630
 
                result._format.require_stacking()
1631
 
            result_repo.lock_write()
1632
 
        else:
1633
 
            result_repo = None
1634
 
            repository_policy = None
1635
 
        return result_repo, result, require_stacking, repository_policy
1636
 
 
1637
1761
    def _initialize_on_transport_vfs(self, transport):
1638
1762
        """Initialize a new bzrdir using VFS calls.
1639
1763
 
1672
1796
            control_files.unlock()
1673
1797
        return self.open(transport, _found=True)
1674
1798
 
 
1799
    def is_supported(self):
 
1800
        """Is this format supported?
 
1801
 
 
1802
        Supported formats must be initializable and openable.
 
1803
        Unsupported formats may not support initialization or committing or
 
1804
        some other features depending on the reason for not being supported.
 
1805
        """
 
1806
        return True
 
1807
 
 
1808
    def network_name(self):
 
1809
        """A simple byte string uniquely identifying this format for RPC calls.
 
1810
 
 
1811
        Bzr control formats use thir disk format string to identify the format
 
1812
        over the wire. Its possible that other control formats have more
 
1813
        complex detection requirements, so we permit them to use any unique and
 
1814
        immutable string they desire.
 
1815
        """
 
1816
        raise NotImplementedError(self.network_name)
 
1817
 
 
1818
    def same_model(self, target_format):
 
1819
        return (self.repository_format.rich_root_data ==
 
1820
            target_format.rich_root_data)
 
1821
 
 
1822
    @classmethod
 
1823
    def known_formats(klass):
 
1824
        """Return all the known formats.
 
1825
 
 
1826
        Concrete formats should override _known_formats.
 
1827
        """
 
1828
        # There is double indirection here to make sure that control
 
1829
        # formats used by more than one dir format will only be probed
 
1830
        # once. This can otherwise be quite expensive for remote connections.
 
1831
        result = set()
 
1832
        for format in klass._control_formats:
 
1833
            result.update(format._known_formats())
 
1834
        return result
 
1835
 
 
1836
    @classmethod
 
1837
    def _known_formats(klass):
 
1838
        """Return the known format instances for this control format."""
 
1839
        return set(klass._formats.values())
 
1840
 
1675
1841
    def open(self, transport, _found=False):
1676
1842
        """Return an instance of this format for the dir transport points at.
1677
1843
 
1678
1844
        _found is a private parameter, do not use it.
1679
1845
        """
1680
1846
        if not _found:
1681
 
            found_format = controldir.ControlDirFormat.find_format(transport)
 
1847
            found_format = BzrDirFormat.find_format(transport)
1682
1848
            if not isinstance(found_format, self.__class__):
1683
1849
                raise AssertionError("%s was asked to open %s, but it seems to need "
1684
1850
                        "format %s"
1698
1864
 
1699
1865
    @classmethod
1700
1866
    def register_format(klass, format):
1701
 
        BzrProber.register_bzrdir_format(format)
 
1867
        klass._formats[format.get_format_string()] = format
1702
1868
        # bzr native formats have a network name of their format string.
1703
 
        controldir.network_format_registry.register(format.get_format_string(), format.__class__)
1704
 
        controldir.ControlDirFormat.register_format(format)
 
1869
        network_format_registry.register(format.get_format_string(), format.__class__)
 
1870
 
 
1871
    @classmethod
 
1872
    def register_control_format(klass, format):
 
1873
        """Register a format that does not use '.bzr' for its control dir.
 
1874
 
 
1875
        TODO: This should be pulled up into a 'ControlDirFormat' base class
 
1876
        which BzrDirFormat can inherit from, and renamed to register_format
 
1877
        there. It has been done without that for now for simplicity of
 
1878
        implementation.
 
1879
        """
 
1880
        klass._control_formats.append(format)
 
1881
 
 
1882
    @classmethod
 
1883
    def register_control_server_format(klass, format):
 
1884
        """Register a control format for client-server environments.
 
1885
 
 
1886
        These formats will be tried before ones registered with
 
1887
        register_control_format.  This gives implementations that decide to the
 
1888
        chance to grab it before anything looks at the contents of the format
 
1889
        file.
 
1890
        """
 
1891
        klass._control_server_formats.append(format)
 
1892
 
 
1893
    @classmethod
 
1894
    def _set_default_format(klass, format):
 
1895
        """Set default format (for testing behavior of defaults only)"""
 
1896
        klass._default_format = format
 
1897
 
 
1898
    def __str__(self):
 
1899
        # Trim the newline
 
1900
        return self.get_format_description().rstrip()
1705
1901
 
1706
1902
    def _supply_sub_formats_to(self, other_format):
1707
1903
        """Give other_format the same values for sub formats as this has.
1717
1913
 
1718
1914
    @classmethod
1719
1915
    def unregister_format(klass, format):
1720
 
        BzrProber.unregister_bzrdir_format(format)
1721
 
        controldir.ControlDirFormat.unregister_format(format)
1722
 
        controldir.network_format_registry.remove(format.get_format_string())
 
1916
        del klass._formats[format.get_format_string()]
 
1917
 
 
1918
    @classmethod
 
1919
    def unregister_control_format(klass, format):
 
1920
        klass._control_formats.remove(format)
1723
1921
 
1724
1922
 
1725
1923
class BzrDirFormat4(BzrDirFormat):
1777
1975
    repository_format = property(__return_repository_format)
1778
1976
 
1779
1977
 
1780
 
class BzrDirFormatAllInOne(BzrDirFormat):
1781
 
    """Common class for formats before meta-dirs."""
1782
 
 
1783
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1784
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
1785
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1786
 
        shared_repo=False):
1787
 
        """See BzrDirFormat.initialize_on_transport_ex."""
1788
 
        require_stacking = (stacked_on is not None)
1789
 
        # Format 5 cannot stack, but we've been asked to - actually init
1790
 
        # a Meta1Dir
1791
 
        if require_stacking:
1792
 
            format = BzrDirMetaFormat1()
1793
 
            return format.initialize_on_transport_ex(transport,
1794
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1795
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
1796
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1797
 
                make_working_trees=make_working_trees, shared_repo=shared_repo)
1798
 
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
1799
 
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1800
 
            force_new_repo=force_new_repo, stacked_on=stacked_on,
1801
 
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1802
 
            make_working_trees=make_working_trees, shared_repo=shared_repo)
1803
 
 
1804
 
 
1805
 
class BzrDirFormat5(BzrDirFormatAllInOne):
 
1978
class BzrDirFormat5(BzrDirFormat):
1806
1979
    """Bzr control format 5.
1807
1980
 
1808
1981
    This format is a combined format for working tree, branch and repository.
1863
2036
    repository_format = property(__return_repository_format)
1864
2037
 
1865
2038
 
1866
 
class BzrDirFormat6(BzrDirFormatAllInOne):
 
2039
class BzrDirFormat6(BzrDirFormat):
1867
2040
    """Bzr control format 6.
1868
2041
 
1869
2042
    This format is a combined format for working tree, branch and repository.
1962
2135
    def set_branch_format(self, format):
1963
2136
        self._branch_format = format
1964
2137
 
1965
 
    def require_stacking(self, stack_on=None, possible_transports=None,
1966
 
            _skip_repo=False):
1967
 
        """We have a request to stack, try to ensure the formats support it.
1968
 
 
1969
 
        :param stack_on: If supplied, it is the URL to a branch that we want to
1970
 
            stack on. Check to see if that format supports stacking before
1971
 
            forcing an upgrade.
1972
 
        """
1973
 
        # Stacking is desired. requested by the target, but does the place it
1974
 
        # points at support stacking? If it doesn't then we should
1975
 
        # not implicitly upgrade. We check this here.
1976
 
        new_repo_format = None
1977
 
        new_branch_format = None
1978
 
 
1979
 
        # a bit of state for get_target_branch so that we don't try to open it
1980
 
        # 2 times, for both repo *and* branch
1981
 
        target = [None, False, None] # target_branch, checked, upgrade anyway
1982
 
        def get_target_branch():
1983
 
            if target[1]:
1984
 
                # We've checked, don't check again
1985
 
                return target
1986
 
            if stack_on is None:
1987
 
                # No target format, that means we want to force upgrading
1988
 
                target[:] = [None, True, True]
1989
 
                return target
1990
 
            try:
1991
 
                target_dir = BzrDir.open(stack_on,
1992
 
                    possible_transports=possible_transports)
1993
 
            except errors.NotBranchError:
1994
 
                # Nothing there, don't change formats
1995
 
                target[:] = [None, True, False]
1996
 
                return target
1997
 
            except errors.JailBreak:
1998
 
                # JailBreak, JFDI and upgrade anyway
1999
 
                target[:] = [None, True, True]
2000
 
                return target
2001
 
            try:
2002
 
                target_branch = target_dir.open_branch()
2003
 
            except errors.NotBranchError:
2004
 
                # No branch, don't upgrade formats
2005
 
                target[:] = [None, True, False]
2006
 
                return target
2007
 
            target[:] = [target_branch, True, False]
2008
 
            return target
2009
 
 
2010
 
        if (not _skip_repo and
2011
 
                 not self.repository_format.supports_external_lookups):
2012
 
            # We need to upgrade the Repository.
2013
 
            target_branch, _, do_upgrade = get_target_branch()
2014
 
            if target_branch is None:
2015
 
                # We don't have a target branch, should we upgrade anyway?
2016
 
                if do_upgrade:
2017
 
                    # stack_on is inaccessible, JFDI.
2018
 
                    # TODO: bad monkey, hard-coded formats...
2019
 
                    if self.repository_format.rich_root_data:
2020
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2021
 
                    else:
2022
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
2023
 
            else:
2024
 
                # If the target already supports stacking, then we know the
2025
 
                # project is already able to use stacking, so auto-upgrade
2026
 
                # for them
2027
 
                new_repo_format = target_branch.repository._format
2028
 
                if not new_repo_format.supports_external_lookups:
2029
 
                    # target doesn't, source doesn't, so don't auto upgrade
2030
 
                    # repo
2031
 
                    new_repo_format = None
2032
 
            if new_repo_format is not None:
2033
 
                self.repository_format = new_repo_format
2034
 
                note('Source repository format does not support stacking,'
2035
 
                     ' using format:\n  %s',
2036
 
                     new_repo_format.get_format_description())
2037
 
 
 
2138
    def require_stacking(self):
2038
2139
        if not self.get_branch_format().supports_stacking():
2039
 
            # We just checked the repo, now lets check if we need to
2040
 
            # upgrade the branch format
2041
 
            target_branch, _, do_upgrade = get_target_branch()
2042
 
            if target_branch is None:
2043
 
                if do_upgrade:
2044
 
                    # TODO: bad monkey, hard-coded formats...
2045
 
                    new_branch_format = branch.BzrBranchFormat7()
 
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()
2046
2151
            else:
2047
 
                new_branch_format = target_branch._format
2048
 
                if not new_branch_format.supports_stacking():
2049
 
                    new_branch_format = None
2050
 
            if new_branch_format is not None:
2051
 
                # Does support stacking, use its format.
2052
 
                self.set_branch_format(new_branch_format)
2053
 
                note('Source branch format does not support stacking,'
2054
 
                     ' using format:\n  %s',
2055
 
                     new_branch_format.get_format_description())
 
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
2056
2158
 
2057
2159
    def get_converter(self, format=None):
2058
2160
        """See BzrDirFormat.get_converter()."""
2076
2178
 
2077
2179
    def _open(self, transport):
2078
2180
        """See BzrDirFormat._open."""
2079
 
        # Create a new format instance because otherwise initialisation of new
2080
 
        # metadirs share the global default format object leading to alias
2081
 
        # problems.
2082
 
        format = BzrDirMetaFormat1()
2083
 
        self._supply_sub_formats_to(format)
2084
 
        return BzrDirMeta1(transport, format)
 
2181
        return BzrDirMeta1(transport, self)
2085
2182
 
2086
2183
    def __return_repository_format(self):
2087
2184
        """Circular import protection."""
2128
2225
                                  __set_workingtree_format)
2129
2226
 
2130
2227
 
 
2228
network_format_registry = registry.FormatRegistry()
 
2229
"""Registry of formats indexed by their network name.
 
2230
 
 
2231
The network name for a BzrDirFormat is an identifier that can be used when
 
2232
referring to formats with smart server operations. See
 
2233
BzrDirFormat.network_name() for more detail.
 
2234
"""
 
2235
 
 
2236
 
 
2237
# Register bzr control format
 
2238
BzrDirFormat.register_control_format(BzrDirFormat)
 
2239
 
2131
2240
# Register bzr formats
2132
2241
BzrDirFormat.register_format(BzrDirFormat4())
2133
2242
BzrDirFormat.register_format(BzrDirFormat5())
2134
2243
BzrDirFormat.register_format(BzrDirFormat6())
2135
2244
__default_format = BzrDirMetaFormat1()
2136
2245
BzrDirFormat.register_format(__default_format)
2137
 
controldir.ControlDirFormat._default_format = __default_format
 
2246
BzrDirFormat._default_format = __default_format
2138
2247
 
2139
2248
 
2140
2249
class Converter(object):
2166
2275
    def convert(self, to_convert, pb):
2167
2276
        """See Converter.convert()."""
2168
2277
        self.bzrdir = to_convert
2169
 
        if pb is not None:
2170
 
            warnings.warn("pb parameter to convert() is deprecated")
2171
 
        self.pb = ui.ui_factory.nested_progress_bar()
2172
 
        try:
2173
 
            ui.ui_factory.note('starting upgrade from format 4 to 5')
2174
 
            if isinstance(self.bzrdir.transport, local.LocalTransport):
2175
 
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2176
 
            self._convert_to_weaves()
2177
 
            return BzrDir.open(self.bzrdir.user_url)
2178
 
        finally:
2179
 
            self.pb.finished()
 
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)
2180
2284
 
2181
2285
    def _convert_to_weaves(self):
2182
 
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
 
2286
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2183
2287
        try:
2184
2288
            # TODO permissions
2185
2289
            stat = self.bzrdir.transport.stat('weaves')
2213
2317
        self.pb.clear()
2214
2318
        self._write_all_weaves()
2215
2319
        self._write_all_revs()
2216
 
        ui.ui_factory.note('upgraded to weaves:')
2217
 
        ui.ui_factory.note('  %6d revisions and inventories' % len(self.revisions))
2218
 
        ui.ui_factory.note('  %6d revisions not present' % len(self.absent_revisions))
2219
 
        ui.ui_factory.note('  %6d texts' % self.text_count)
 
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)
2220
2324
        self._cleanup_spare_files_after_format4()
2221
2325
        self.branch._transport.put_bytes(
2222
2326
            'branch-format',
2290
2394
                       len(self.known_revisions))
2291
2395
        if not self.branch.repository.has_revision(rev_id):
2292
2396
            self.pb.clear()
2293
 
            ui.ui_factory.note('revision {%s} not present in branch; '
2294
 
                         'will be converted as a ghost' %
 
2397
            self.pb.note('revision {%s} not present in branch; '
 
2398
                         'will be converted as a ghost',
2295
2399
                         rev_id)
2296
2400
            self.absent_revisions.add(rev_id)
2297
2401
        else:
2302
2406
            self.revisions[rev_id] = rev
2303
2407
 
2304
2408
    def _load_old_inventory(self, rev_id):
2305
 
        f = self.branch.repository.inventory_store.get(rev_id)
2306
 
        try:
2307
 
            old_inv_xml = f.read()
2308
 
        finally:
2309
 
            f.close()
 
2409
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2310
2410
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2311
2411
        inv.revision_id = rev_id
2312
2412
        rev = self.revisions[rev_id]
2368
2468
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2369
2469
            in heads)
2370
2470
        self.snapshot_ie(previous_entries, ie, w, rev_id)
 
2471
        del ie.text_id
2371
2472
 
2372
2473
    def get_parent_map(self, revision_ids):
2373
 
        """See graph.StackedParentsProvider.get_parent_map"""
 
2474
        """See graph._StackedParentsProvider.get_parent_map"""
2374
2475
        return dict((revision_id, self.revisions[revision_id])
2375
2476
                    for revision_id in revision_ids
2376
2477
                     if revision_id in self.revisions)
2389
2490
                ie.revision = previous_ie.revision
2390
2491
                return
2391
2492
        if ie.has_text():
2392
 
            f = self.branch.repository._text_store.get(ie.text_id)
2393
 
            try:
2394
 
                file_lines = f.readlines()
2395
 
            finally:
2396
 
                f.close()
 
2493
            text = self.branch.repository._text_store.get(ie.text_id)
 
2494
            file_lines = text.readlines()
2397
2495
            w.add_lines(rev_id, previous_revisions, file_lines)
2398
2496
            self.text_count += 1
2399
2497
        else:
2429
2527
    def convert(self, to_convert, pb):
2430
2528
        """See Converter.convert()."""
2431
2529
        self.bzrdir = to_convert
2432
 
        pb = ui.ui_factory.nested_progress_bar()
2433
 
        try:
2434
 
            ui.ui_factory.note('starting upgrade from format 5 to 6')
2435
 
            self._convert_to_prefixed()
2436
 
            return BzrDir.open(self.bzrdir.user_url)
2437
 
        finally:
2438
 
            pb.finished()
 
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)
2439
2534
 
2440
2535
    def _convert_to_prefixed(self):
2441
2536
        from bzrlib.store import TransportStore
2442
2537
        self.bzrdir.transport.delete('branch-format')
2443
2538
        for store_name in ["weaves", "revision-store"]:
2444
 
            ui.ui_factory.note("adding prefixes to %s" % store_name)
 
2539
            self.pb.note("adding prefixes to %s" % store_name)
2445
2540
            store_transport = self.bzrdir.transport.clone(store_name)
2446
2541
            store = TransportStore(store_transport, prefixed=True)
2447
2542
            for urlfilename in store_transport.list_dir('.'):
2474
2569
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2475
2570
        from bzrlib.branch import BzrBranchFormat5
2476
2571
        self.bzrdir = to_convert
2477
 
        self.pb = ui.ui_factory.nested_progress_bar()
 
2572
        self.pb = pb
2478
2573
        self.count = 0
2479
2574
        self.total = 20 # the steps we know about
2480
2575
        self.garbage_inventories = []
2481
2576
        self.dir_mode = self.bzrdir._get_dir_mode()
2482
2577
        self.file_mode = self.bzrdir._get_file_mode()
2483
2578
 
2484
 
        ui.ui_factory.note('starting upgrade from format 6 to metadir')
 
2579
        self.pb.note('starting upgrade from format 6 to metadir')
2485
2580
        self.bzrdir.transport.put_bytes(
2486
2581
                'branch-format',
2487
2582
                "Converting to format 6",
2537
2632
        else:
2538
2633
            has_checkout = True
2539
2634
        if not has_checkout:
2540
 
            ui.ui_factory.note('No working tree.')
 
2635
            self.pb.note('No working tree.')
2541
2636
            # If some checkout files are there, we may as well get rid of them.
2542
2637
            for name, mandatory in checkout_files:
2543
2638
                if name in bzrcontents:
2560
2655
            'branch-format',
2561
2656
            BzrDirMetaFormat1().get_format_string(),
2562
2657
            mode=self.file_mode)
2563
 
        self.pb.finished()
2564
 
        return BzrDir.open(self.bzrdir.user_url)
 
2658
        return BzrDir.open(self.bzrdir.root_transport.base)
2565
2659
 
2566
2660
    def make_lock(self, name):
2567
2661
        """Make a lock for the new control dir name."""
2602
2696
    def convert(self, to_convert, pb):
2603
2697
        """See Converter.convert()."""
2604
2698
        self.bzrdir = to_convert
2605
 
        self.pb = ui.ui_factory.nested_progress_bar()
 
2699
        self.pb = pb
2606
2700
        self.count = 0
2607
2701
        self.total = 1
2608
2702
        self.step('checking repository format')
2613
2707
        else:
2614
2708
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
2615
2709
                from bzrlib.repository import CopyConverter
2616
 
                ui.ui_factory.note('starting repository conversion')
 
2710
                self.pb.note('starting repository conversion')
2617
2711
                converter = CopyConverter(self.target_format.repository_format)
2618
2712
                converter.convert(repo, pb)
2619
 
        for branch in self.bzrdir.list_branches():
 
2713
        try:
 
2714
            branch = self.bzrdir.open_branch()
 
2715
        except errors.NotBranchError:
 
2716
            pass
 
2717
        else:
2620
2718
            # TODO: conversions of Branch and Tree should be done by
2621
2719
            # InterXFormat lookups/some sort of registry.
2622
2720
            # Avoid circular imports
2626
2724
            while old != new:
2627
2725
                if (old == _mod_branch.BzrBranchFormat5 and
2628
2726
                    new in (_mod_branch.BzrBranchFormat6,
2629
 
                        _mod_branch.BzrBranchFormat7,
2630
 
                        _mod_branch.BzrBranchFormat8)):
 
2727
                        _mod_branch.BzrBranchFormat7)):
2631
2728
                    branch_converter = _mod_branch.Converter5to6()
2632
2729
                elif (old == _mod_branch.BzrBranchFormat6 and
2633
 
                    new in (_mod_branch.BzrBranchFormat7,
2634
 
                            _mod_branch.BzrBranchFormat8)):
 
2730
                    new == _mod_branch.BzrBranchFormat7):
2635
2731
                    branch_converter = _mod_branch.Converter6to7()
2636
 
                elif (old == _mod_branch.BzrBranchFormat7 and
2637
 
                      new is _mod_branch.BzrBranchFormat8):
2638
 
                    branch_converter = _mod_branch.Converter7to8()
2639
2732
                else:
2640
 
                    raise errors.BadConversionTarget("No converter", new,
2641
 
                        branch._format)
 
2733
                    raise errors.BadConversionTarget("No converter", new)
2642
2734
                branch_converter.convert(branch)
2643
2735
                branch = self.bzrdir.open_branch()
2644
2736
                old = branch._format.__class__
2659
2751
                isinstance(self.target_format.workingtree_format,
2660
2752
                    workingtree_4.WorkingTreeFormat5)):
2661
2753
                workingtree_4.Converter4to5().convert(tree)
2662
 
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2663
 
                not isinstance(tree, workingtree_4.WorkingTree6) and
2664
 
                isinstance(self.target_format.workingtree_format,
2665
 
                    workingtree_4.WorkingTreeFormat6)):
2666
 
                workingtree_4.Converter4or5to6().convert(tree)
2667
 
        self.pb.finished()
2668
2754
        return to_convert
2669
2755
 
2670
2756
 
2671
 
# This is not in remote.py because it's relatively small, and needs to be
2672
 
# registered. Putting it in remote.py creates a circular import problem.
 
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.
2673
2759
# we can make it a lazy object if the control formats is turned into something
2674
2760
# like a registry.
2675
2761
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2676
2762
    """Format representing bzrdirs accessed via a smart server"""
2677
2763
 
2678
 
    supports_workingtrees = False
2679
 
 
2680
2764
    def __init__(self):
2681
2765
        BzrDirMetaFormat1.__init__(self)
2682
 
        # XXX: It's a bit ugly that the network name is here, because we'd
2683
 
        # like to believe that format objects are stateless or at least
2684
 
        # immutable,  However, we do at least avoid mutating the name after
2685
 
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
2686
2766
        self._network_name = None
2687
2767
 
2688
 
    def __repr__(self):
2689
 
        return "%s(_network_name=%r)" % (self.__class__.__name__,
2690
 
            self._network_name)
2691
 
 
2692
2768
    def get_format_description(self):
2693
 
        if self._network_name:
2694
 
            real_format = controldir.network_format_registry.get(self._network_name)
2695
 
            return 'Remote: ' + real_format.get_format_description()
2696
2769
        return 'bzr remote bzrdir'
2697
2770
 
2698
2771
    def get_format_string(self):
2704
2777
        else:
2705
2778
            raise AssertionError("No network name set.")
2706
2779
 
 
2780
    @classmethod
 
2781
    def probe_transport(klass, transport):
 
2782
        """Return a RemoteBzrDirFormat object if it looks possible."""
 
2783
        try:
 
2784
            medium = transport.get_smart_medium()
 
2785
        except (NotImplementedError, AttributeError,
 
2786
                errors.TransportNotPossible, errors.NoSmartMedium,
 
2787
                errors.SmartProtocolError):
 
2788
            # no smart server, so not a branch for this format type.
 
2789
            raise errors.NotBranchError(path=transport.base)
 
2790
        else:
 
2791
            # Decline to open it if the server doesn't support our required
 
2792
            # version (3) so that the VFS-based transport will do it.
 
2793
            if medium.should_probe():
 
2794
                try:
 
2795
                    server_version = medium.protocol_version()
 
2796
                except errors.SmartProtocolError:
 
2797
                    # Apparently there's no usable smart server there, even though
 
2798
                    # the medium supports the smart protocol.
 
2799
                    raise errors.NotBranchError(path=transport.base)
 
2800
                if server_version != '2':
 
2801
                    raise errors.NotBranchError(path=transport.base)
 
2802
            return klass()
 
2803
 
2707
2804
    def initialize_on_transport(self, transport):
2708
2805
        try:
2709
2806
            # hand off the request to the smart server
2714
2811
            return local_dir_format.initialize_on_transport(transport)
2715
2812
        client = _SmartClient(client_medium)
2716
2813
        path = client.remote_path_from_transport(transport)
2717
 
        try:
2718
 
            response = client.call('BzrDirFormat.initialize', path)
2719
 
        except errors.ErrorFromSmartServer, err:
2720
 
            remote._translate_error(err, path=path)
 
2814
        response = client.call('BzrDirFormat.initialize', path)
2721
2815
        if response[0] != 'ok':
2722
2816
            raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2723
2817
        format = RemoteBzrDirFormat()
2724
2818
        self._supply_sub_formats_to(format)
2725
2819
        return remote.RemoteBzrDir(transport, format)
2726
2820
 
2727
 
    def parse_NoneTrueFalse(self, arg):
2728
 
        if not arg:
2729
 
            return None
2730
 
        if arg == 'False':
2731
 
            return False
2732
 
        if arg == 'True':
2733
 
            return True
2734
 
        raise AssertionError("invalid arg %r" % arg)
2735
 
 
2736
 
    def _serialize_NoneTrueFalse(self, arg):
2737
 
        if arg is False:
2738
 
            return 'False'
2739
 
        if arg:
2740
 
            return 'True'
2741
 
        return ''
2742
 
 
2743
 
    def _serialize_NoneString(self, arg):
2744
 
        return arg or ''
2745
 
 
2746
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2747
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
2748
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2749
 
        shared_repo=False):
2750
 
        try:
2751
 
            # hand off the request to the smart server
2752
 
            client_medium = transport.get_smart_medium()
2753
 
        except errors.NoSmartMedium:
2754
 
            do_vfs = True
2755
 
        else:
2756
 
            # Decline to open it if the server doesn't support our required
2757
 
            # version (3) so that the VFS-based transport will do it.
2758
 
            if client_medium.should_probe():
2759
 
                try:
2760
 
                    server_version = client_medium.protocol_version()
2761
 
                    if server_version != '2':
2762
 
                        do_vfs = True
2763
 
                    else:
2764
 
                        do_vfs = False
2765
 
                except errors.SmartProtocolError:
2766
 
                    # Apparently there's no usable smart server there, even though
2767
 
                    # the medium supports the smart protocol.
2768
 
                    do_vfs = True
2769
 
            else:
2770
 
                do_vfs = False
2771
 
        if not do_vfs:
2772
 
            client = _SmartClient(client_medium)
2773
 
            path = client.remote_path_from_transport(transport)
2774
 
            if client_medium._is_remote_before((1, 16)):
2775
 
                do_vfs = True
2776
 
        if do_vfs:
2777
 
            # TODO: lookup the local format from a server hint.
2778
 
            local_dir_format = BzrDirMetaFormat1()
2779
 
            self._supply_sub_formats_to(local_dir_format)
2780
 
            return local_dir_format.initialize_on_transport_ex(transport,
2781
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2782
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
2783
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2784
 
                make_working_trees=make_working_trees, shared_repo=shared_repo,
2785
 
                vfs_only=True)
2786
 
        return self._initialize_on_transport_ex_rpc(client, path, transport,
2787
 
            use_existing_dir, create_prefix, force_new_repo, stacked_on,
2788
 
            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2789
 
 
2790
 
    def _initialize_on_transport_ex_rpc(self, client, path, transport,
2791
 
        use_existing_dir, create_prefix, force_new_repo, stacked_on,
2792
 
        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2793
 
        args = []
2794
 
        args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2795
 
        args.append(self._serialize_NoneTrueFalse(create_prefix))
2796
 
        args.append(self._serialize_NoneTrueFalse(force_new_repo))
2797
 
        args.append(self._serialize_NoneString(stacked_on))
2798
 
        # stack_on_pwd is often/usually our transport
2799
 
        if stack_on_pwd:
2800
 
            try:
2801
 
                stack_on_pwd = transport.relpath(stack_on_pwd)
2802
 
                if not stack_on_pwd:
2803
 
                    stack_on_pwd = '.'
2804
 
            except errors.PathNotChild:
2805
 
                pass
2806
 
        args.append(self._serialize_NoneString(stack_on_pwd))
2807
 
        args.append(self._serialize_NoneString(repo_format_name))
2808
 
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
2809
 
        args.append(self._serialize_NoneTrueFalse(shared_repo))
2810
 
        request_network_name = self._network_name or \
2811
 
            BzrDirFormat.get_default_format().network_name()
2812
 
        try:
2813
 
            response = client.call('BzrDirFormat.initialize_ex_1.16',
2814
 
                request_network_name, path, *args)
2815
 
        except errors.UnknownSmartMethod:
2816
 
            client._medium._remember_remote_is_before((1,16))
2817
 
            local_dir_format = BzrDirMetaFormat1()
2818
 
            self._supply_sub_formats_to(local_dir_format)
2819
 
            return local_dir_format.initialize_on_transport_ex(transport,
2820
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2821
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
2822
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2823
 
                make_working_trees=make_working_trees, shared_repo=shared_repo,
2824
 
                vfs_only=True)
2825
 
        except errors.ErrorFromSmartServer, err:
2826
 
            remote._translate_error(err, path=path)
2827
 
        repo_path = response[0]
2828
 
        bzrdir_name = response[6]
2829
 
        require_stacking = response[7]
2830
 
        require_stacking = self.parse_NoneTrueFalse(require_stacking)
2831
 
        format = RemoteBzrDirFormat()
2832
 
        format._network_name = bzrdir_name
2833
 
        self._supply_sub_formats_to(format)
2834
 
        bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2835
 
        if repo_path:
2836
 
            repo_format = remote.response_tuple_to_repo_format(response[1:])
2837
 
            if repo_path == '.':
2838
 
                repo_path = ''
2839
 
            if repo_path:
2840
 
                repo_bzrdir_format = RemoteBzrDirFormat()
2841
 
                repo_bzrdir_format._network_name = response[5]
2842
 
                repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2843
 
                    repo_bzrdir_format)
2844
 
            else:
2845
 
                repo_bzr = bzrdir
2846
 
            final_stack = response[8] or None
2847
 
            final_stack_pwd = response[9] or None
2848
 
            if final_stack_pwd:
2849
 
                final_stack_pwd = urlutils.join(
2850
 
                    transport.base, final_stack_pwd)
2851
 
            remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2852
 
            if len(response) > 10:
2853
 
                # Updated server verb that locks remotely.
2854
 
                repo_lock_token = response[10] or None
2855
 
                remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2856
 
                if repo_lock_token:
2857
 
                    remote_repo.dont_leave_lock_in_place()
2858
 
            else:
2859
 
                remote_repo.lock_write()
2860
 
            policy = UseExistingRepository(remote_repo, final_stack,
2861
 
                final_stack_pwd, require_stacking)
2862
 
            policy.acquire_repository()
2863
 
        else:
2864
 
            remote_repo = None
2865
 
            policy = None
2866
 
        bzrdir._format.set_branch_format(self.get_branch_format())
2867
 
        if require_stacking:
2868
 
            # The repo has already been created, but we need to make sure that
2869
 
            # we'll make a stackable branch.
2870
 
            bzrdir._format.require_stacking(_skip_repo=True)
2871
 
        return remote_repo, bzrdir, require_stacking, policy
2872
 
 
2873
2821
    def _open(self, transport):
2874
2822
        return remote.RemoteBzrDir(transport, self)
2875
2823
 
2908
2856
        BzrDirMetaFormat1._set_repository_format) #.im_func)
2909
2857
 
2910
2858
 
2911
 
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
 
2859
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
 
2860
 
 
2861
 
 
2862
class BzrDirFormatInfo(object):
 
2863
 
 
2864
    def __init__(self, native, deprecated, hidden, experimental):
 
2865
        self.deprecated = deprecated
 
2866
        self.native = native
 
2867
        self.hidden = hidden
 
2868
        self.experimental = experimental
 
2869
 
 
2870
 
 
2871
class BzrDirFormatRegistry(registry.Registry):
 
2872
    """Registry of user-selectable BzrDir subformats.
 
2873
 
 
2874
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
 
2875
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
 
2876
    """
 
2877
 
 
2878
    def __init__(self):
 
2879
        """Create a BzrDirFormatRegistry."""
 
2880
        self._aliases = set()
 
2881
        self._registration_order = list()
 
2882
        super(BzrDirFormatRegistry, self).__init__()
 
2883
 
 
2884
    def aliases(self):
 
2885
        """Return a set of the format names which are aliases."""
 
2886
        return frozenset(self._aliases)
 
2887
 
 
2888
    def register_metadir(self, key,
 
2889
             repository_format, help, native=True, deprecated=False,
 
2890
             branch_format=None,
 
2891
             tree_format=None,
 
2892
             hidden=False,
 
2893
             experimental=False,
 
2894
             alias=False):
 
2895
        """Register a metadir subformat.
 
2896
 
 
2897
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
2898
        by the Repository/Branch/WorkingTreeformats.
 
2899
 
 
2900
        :param repository_format: The fully-qualified repository format class
 
2901
            name as a string.
 
2902
        :param branch_format: Fully-qualified branch format class name as
 
2903
            a string.
 
2904
        :param tree_format: Fully-qualified tree format class name as
 
2905
            a string.
 
2906
        """
 
2907
        # This should be expanded to support setting WorkingTree and Branch
 
2908
        # formats, once BzrDirMetaFormat1 supports that.
 
2909
        def _load(full_name):
 
2910
            mod_name, factory_name = full_name.rsplit('.', 1)
 
2911
            try:
 
2912
                mod = __import__(mod_name, globals(), locals(),
 
2913
                        [factory_name])
 
2914
            except ImportError, e:
 
2915
                raise ImportError('failed to load %s: %s' % (full_name, e))
 
2916
            try:
 
2917
                factory = getattr(mod, factory_name)
 
2918
            except AttributeError:
 
2919
                raise AttributeError('no factory %s in module %r'
 
2920
                    % (full_name, mod))
 
2921
            return factory()
 
2922
 
 
2923
        def helper():
 
2924
            bd = BzrDirMetaFormat1()
 
2925
            if branch_format is not None:
 
2926
                bd.set_branch_format(_load(branch_format))
 
2927
            if tree_format is not None:
 
2928
                bd.workingtree_format = _load(tree_format)
 
2929
            if repository_format is not None:
 
2930
                bd.repository_format = _load(repository_format)
 
2931
            return bd
 
2932
        self.register(key, helper, help, native, deprecated, hidden,
 
2933
            experimental, alias)
 
2934
 
 
2935
    def register(self, key, factory, help, native=True, deprecated=False,
 
2936
                 hidden=False, experimental=False, alias=False):
 
2937
        """Register a BzrDirFormat factory.
 
2938
 
 
2939
        The factory must be a callable that takes one parameter: the key.
 
2940
        It must produce an instance of the BzrDirFormat when called.
 
2941
 
 
2942
        This function mainly exists to prevent the info object from being
 
2943
        supplied directly.
 
2944
        """
 
2945
        registry.Registry.register(self, key, factory, help,
 
2946
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
2947
        if alias:
 
2948
            self._aliases.add(key)
 
2949
        self._registration_order.append(key)
 
2950
 
 
2951
    def register_lazy(self, key, module_name, member_name, help, native=True,
 
2952
        deprecated=False, hidden=False, experimental=False, alias=False):
 
2953
        registry.Registry.register_lazy(self, key, module_name, member_name,
 
2954
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
2955
        if alias:
 
2956
            self._aliases.add(key)
 
2957
        self._registration_order.append(key)
 
2958
 
 
2959
    def set_default(self, key):
 
2960
        """Set the 'default' key to be a clone of the supplied key.
 
2961
 
 
2962
        This method must be called once and only once.
 
2963
        """
 
2964
        registry.Registry.register(self, 'default', self.get(key),
 
2965
            self.get_help(key), info=self.get_info(key))
 
2966
        self._aliases.add('default')
 
2967
 
 
2968
    def set_default_repository(self, key):
 
2969
        """Set the FormatRegistry default and Repository default.
 
2970
 
 
2971
        This is a transitional method while Repository.set_default_format
 
2972
        is deprecated.
 
2973
        """
 
2974
        if 'default' in self:
 
2975
            self.remove('default')
 
2976
        self.set_default(key)
 
2977
        format = self.get('default')()
 
2978
 
 
2979
    def make_bzrdir(self, key):
 
2980
        return self.get(key)()
 
2981
 
 
2982
    def help_topic(self, topic):
 
2983
        output = ""
 
2984
        default_realkey = None
 
2985
        default_help = self.get_help('default')
 
2986
        help_pairs = []
 
2987
        for key in self._registration_order:
 
2988
            if key == 'default':
 
2989
                continue
 
2990
            help = self.get_help(key)
 
2991
            if help == default_help:
 
2992
                default_realkey = key
 
2993
            else:
 
2994
                help_pairs.append((key, help))
 
2995
 
 
2996
        def wrapped(key, help, info):
 
2997
            if info.native:
 
2998
                help = '(native) ' + help
 
2999
            return ':%s:\n%s\n\n' % (key,
 
3000
                    textwrap.fill(help, initial_indent='    ',
 
3001
                    subsequent_indent='    '))
 
3002
        if default_realkey is not None:
 
3003
            output += wrapped(default_realkey, '(default) %s' % default_help,
 
3004
                              self.get_info('default'))
 
3005
        deprecated_pairs = []
 
3006
        experimental_pairs = []
 
3007
        for key, help in help_pairs:
 
3008
            info = self.get_info(key)
 
3009
            if info.hidden:
 
3010
                continue
 
3011
            elif info.deprecated:
 
3012
                deprecated_pairs.append((key, help))
 
3013
            elif info.experimental:
 
3014
                experimental_pairs.append((key, help))
 
3015
            else:
 
3016
                output += wrapped(key, help, info)
 
3017
        output += "\nSee ``bzr help formats`` for more about storage formats."
 
3018
        other_output = ""
 
3019
        if len(experimental_pairs) > 0:
 
3020
            other_output += "Experimental formats are shown below.\n\n"
 
3021
            for key, help in experimental_pairs:
 
3022
                info = self.get_info(key)
 
3023
                other_output += wrapped(key, help, info)
 
3024
        else:
 
3025
            other_output += \
 
3026
                "No experimental formats are available.\n\n"
 
3027
        if len(deprecated_pairs) > 0:
 
3028
            other_output += "\nDeprecated formats are shown below.\n\n"
 
3029
            for key, help in deprecated_pairs:
 
3030
                info = self.get_info(key)
 
3031
                other_output += wrapped(key, help, info)
 
3032
        else:
 
3033
            other_output += \
 
3034
                "\nNo deprecated formats are available.\n\n"
 
3035
        other_output += \
 
3036
            "\nSee ``bzr help formats`` for more about storage formats."
 
3037
 
 
3038
        if topic == 'other-formats':
 
3039
            return other_output
 
3040
        else:
 
3041
            return output
2912
3042
 
2913
3043
 
2914
3044
class RepositoryAcquisitionPolicy(object):
2943
3073
            try:
2944
3074
                stack_on = urlutils.rebase_url(self._stack_on,
2945
3075
                    self._stack_on_pwd,
2946
 
                    branch.user_url)
 
3076
                    branch.bzrdir.root_transport.base)
2947
3077
            except errors.InvalidRebaseURLs:
2948
3078
                stack_on = self._get_full_stack_on()
2949
3079
        try:
2953
3083
            if self._require_stacking:
2954
3084
                raise
2955
3085
 
2956
 
    def requires_stacking(self):
2957
 
        """Return True if this policy requires stacking."""
2958
 
        return self._stack_on is not None and self._require_stacking
2959
 
 
2960
3086
    def _get_full_stack_on(self):
2961
3087
        """Get a fully-qualified URL for the stack_on location."""
2962
3088
        if self._stack_on is None:
2971
3097
        stack_on = self._get_full_stack_on()
2972
3098
        if stack_on is None:
2973
3099
            return
2974
 
        try:
2975
 
            stacked_dir = BzrDir.open(stack_on,
2976
 
                                      possible_transports=possible_transports)
2977
 
        except errors.JailBreak:
2978
 
            # We keep the stacking details, but we are in the server code so
2979
 
            # actually stacking is not needed.
2980
 
            return
 
3100
        stacked_dir = BzrDir.open(stack_on,
 
3101
                                  possible_transports=possible_transports)
2981
3102
        try:
2982
3103
            stacked_repo = stacked_dir.open_branch().repository
2983
3104
        except errors.NotBranchError:
3027
3148
        """
3028
3149
        stack_on = self._get_full_stack_on()
3029
3150
        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.
3030
3154
            format = self._bzrdir._format
3031
 
            format.require_stacking(stack_on=stack_on,
3032
 
                                    possible_transports=[self._bzrdir.root_transport])
 
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())
3033
3189
            if not self._require_stacking:
3034
3190
                # We have picked up automatic stacking somewhere.
3035
3191
                note('Using default stacking branch %s at %s', self._stack_on,
3068
3224
        return self._repository, False
3069
3225
 
3070
3226
 
3071
 
def register_metadir(registry, key,
3072
 
         repository_format, help, native=True, deprecated=False,
3073
 
         branch_format=None,
3074
 
         tree_format=None,
3075
 
         hidden=False,
3076
 
         experimental=False,
3077
 
         alias=False):
3078
 
    """Register a metadir subformat.
3079
 
 
3080
 
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3081
 
    by the Repository/Branch/WorkingTreeformats.
3082
 
 
3083
 
    :param repository_format: The fully-qualified repository format class
3084
 
        name as a string.
3085
 
    :param branch_format: Fully-qualified branch format class name as
3086
 
        a string.
3087
 
    :param tree_format: Fully-qualified tree format class name as
3088
 
        a string.
3089
 
    """
3090
 
    # This should be expanded to support setting WorkingTree and Branch
3091
 
    # formats, once BzrDirMetaFormat1 supports that.
3092
 
    def _load(full_name):
3093
 
        mod_name, factory_name = full_name.rsplit('.', 1)
3094
 
        try:
3095
 
            mod = __import__(mod_name, globals(), locals(),
3096
 
                    [factory_name])
3097
 
        except ImportError, e:
3098
 
            raise ImportError('failed to load %s: %s' % (full_name, e))
3099
 
        try:
3100
 
            factory = getattr(mod, factory_name)
3101
 
        except AttributeError:
3102
 
            raise AttributeError('no factory %s in module %r'
3103
 
                % (full_name, mod))
3104
 
        return factory()
3105
 
 
3106
 
    def helper():
3107
 
        bd = BzrDirMetaFormat1()
3108
 
        if branch_format is not None:
3109
 
            bd.set_branch_format(_load(branch_format))
3110
 
        if tree_format is not None:
3111
 
            bd.workingtree_format = _load(tree_format)
3112
 
        if repository_format is not None:
3113
 
            bd.repository_format = _load(repository_format)
3114
 
        return bd
3115
 
    registry.register(key, helper, help, native, deprecated, hidden,
3116
 
        experimental, alias)
3117
 
 
 
3227
# Please register new formats after old formats so that formats
 
3228
# appear in chronological order and format descriptions can build
 
3229
# on previous ones.
 
3230
format_registry = BzrDirFormatRegistry()
3118
3231
# The pre-0.8 formats have their repository format network name registered in
3119
3232
# repository.py. MetaDir formats have their repository format network name
3120
3233
# inferred from their disk format string.
3121
 
controldir.format_registry.register('weave', BzrDirFormat6,
 
3234
format_registry.register('weave', BzrDirFormat6,
3122
3235
    'Pre-0.8 format.  Slower than knit and does not'
3123
3236
    ' support checkouts or shared repositories.',
3124
 
    hidden=True,
3125
3237
    deprecated=True)
3126
 
register_metadir(controldir.format_registry, 'metaweave',
 
3238
format_registry.register_metadir('metaweave',
3127
3239
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3128
3240
    'Transitional format in 0.8.  Slower than knit.',
3129
3241
    branch_format='bzrlib.branch.BzrBranchFormat5',
3130
3242
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3131
 
    hidden=True,
3132
3243
    deprecated=True)
3133
 
register_metadir(controldir.format_registry, 'knit',
 
3244
format_registry.register_metadir('knit',
3134
3245
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3135
3246
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3136
3247
    branch_format='bzrlib.branch.BzrBranchFormat5',
3137
3248
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3138
 
    hidden=True,
3139
3249
    deprecated=True)
3140
 
register_metadir(controldir.format_registry, 'dirstate',
 
3250
format_registry.register_metadir('dirstate',
3141
3251
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3142
3252
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3143
3253
        'above when accessed over the network.',
3145
3255
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3146
3256
    # directly from workingtree_4 triggers a circular import.
3147
3257
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3148
 
    hidden=True,
3149
3258
    deprecated=True)
3150
 
register_metadir(controldir.format_registry, 'dirstate-tags',
 
3259
format_registry.register_metadir('dirstate-tags',
3151
3260
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3152
3261
    help='New in 0.15: Fast local operations and improved scaling for '
3153
3262
        'network operations. Additionally adds support for tags.'
3154
3263
        ' Incompatible with bzr < 0.15.',
3155
3264
    branch_format='bzrlib.branch.BzrBranchFormat6',
3156
3265
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3157
 
    hidden=True,
3158
3266
    deprecated=True)
3159
 
register_metadir(controldir.format_registry, 'rich-root',
 
3267
format_registry.register_metadir('rich-root',
3160
3268
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3161
3269
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3162
3270
        ' bzr < 1.0.',
3163
3271
    branch_format='bzrlib.branch.BzrBranchFormat6',
3164
3272
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3165
 
    hidden=True,
3166
3273
    deprecated=True)
3167
 
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
 
3274
format_registry.register_metadir('dirstate-with-subtree',
3168
3275
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3169
3276
    help='New in 0.15: Fast local operations and improved scaling for '
3170
3277
        'network operations. Additionally adds support for versioning nested '
3174
3281
    experimental=True,
3175
3282
    hidden=True,
3176
3283
    )
3177
 
register_metadir(controldir.format_registry, 'pack-0.92',
 
3284
format_registry.register_metadir('pack-0.92',
3178
3285
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3179
3286
    help='New in 0.92: Pack-based format with data compatible with '
3180
3287
        'dirstate-tags format repositories. Interoperates with '
3181
3288
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3182
 
        ,
 
3289
        'Previously called knitpack-experimental.  '
 
3290
        'For more information, see '
 
3291
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3183
3292
    branch_format='bzrlib.branch.BzrBranchFormat6',
3184
3293
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3185
3294
    )
3186
 
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
 
3295
format_registry.register_metadir('pack-0.92-subtree',
3187
3296
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3188
3297
    help='New in 0.92: Pack-based format with data compatible with '
3189
3298
        'dirstate-with-subtree format repositories. Interoperates with '
3190
3299
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3191
 
        ,
 
3300
        'Previously called knitpack-experimental.  '
 
3301
        'For more information, see '
 
3302
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3192
3303
    branch_format='bzrlib.branch.BzrBranchFormat6',
3193
3304
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3194
3305
    hidden=True,
3195
3306
    experimental=True,
3196
3307
    )
3197
 
register_metadir(controldir.format_registry, 'rich-root-pack',
 
3308
format_registry.register_metadir('rich-root-pack',
3198
3309
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3199
3310
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3200
3311
         '(needed for bzr-svn and bzr-git).',
3201
3312
    branch_format='bzrlib.branch.BzrBranchFormat6',
3202
3313
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3203
 
    hidden=True,
3204
3314
    )
3205
 
register_metadir(controldir.format_registry, '1.6',
 
3315
format_registry.register_metadir('1.6',
3206
3316
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3207
3317
    help='A format that allows a branch to indicate that there is another '
3208
3318
         '(stacked) repository that should be used to access data that is '
3209
3319
         'not present locally.',
3210
3320
    branch_format='bzrlib.branch.BzrBranchFormat7',
3211
3321
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3212
 
    hidden=True,
3213
3322
    )
3214
 
register_metadir(controldir.format_registry, '1.6.1-rich-root',
 
3323
format_registry.register_metadir('1.6.1-rich-root',
3215
3324
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3216
3325
    help='A variant of 1.6 that supports rich-root data '
3217
3326
         '(needed for bzr-svn and bzr-git).',
3218
3327
    branch_format='bzrlib.branch.BzrBranchFormat7',
3219
3328
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3220
 
    hidden=True,
3221
3329
    )
3222
 
register_metadir(controldir.format_registry, '1.9',
 
3330
format_registry.register_metadir('1.9',
3223
3331
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3224
3332
    help='A repository format using B+tree indexes. These indexes '
3225
3333
         'are smaller in size, have smarter caching and provide faster '
3226
3334
         'performance for most operations.',
3227
3335
    branch_format='bzrlib.branch.BzrBranchFormat7',
3228
3336
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3229
 
    hidden=True,
3230
3337
    )
3231
 
register_metadir(controldir.format_registry, '1.9-rich-root',
 
3338
format_registry.register_metadir('1.9-rich-root',
3232
3339
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3233
3340
    help='A variant of 1.9 that supports rich-root data '
3234
3341
         '(needed for bzr-svn and bzr-git).',
3235
3342
    branch_format='bzrlib.branch.BzrBranchFormat7',
3236
3343
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3237
 
    hidden=True,
3238
3344
    )
3239
 
register_metadir(controldir.format_registry, '1.14',
 
3345
format_registry.register_metadir('development-wt5',
3240
3346
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3241
 
    help='A working-tree format that supports content filtering.',
 
3347
    help='A working-tree format that supports views and content filtering.',
3242
3348
    branch_format='bzrlib.branch.BzrBranchFormat7',
3243
3349
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3350
    experimental=True,
3244
3351
    )
3245
 
register_metadir(controldir.format_registry, '1.14-rich-root',
 
3352
format_registry.register_metadir('development-wt5-rich-root',
3246
3353
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3247
 
    help='A variant of 1.14 that supports rich-root data '
 
3354
    help='A variant of development-wt5 that supports rich-root data '
3248
3355
         '(needed for bzr-svn and bzr-git).',
3249
3356
    branch_format='bzrlib.branch.BzrBranchFormat7',
3250
3357
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3358
    experimental=True,
3251
3359
    )
3252
 
# The following un-numbered 'development' formats should always just be aliases.
3253
 
register_metadir(controldir.format_registry, 'development-rich-root',
3254
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3255
 
    help='Current development format. Supports rich roots. Can convert data '
3256
 
        'to and from rich-root-pack (and anything compatible with '
3257
 
        'rich-root-pack) format repositories. Repositories and branches in '
3258
 
        'this format can only be read by bzr.dev. Please read '
3259
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
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 '
3260
3368
        'before use.',
3261
3369
    branch_format='bzrlib.branch.BzrBranchFormat7',
3262
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3370
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3263
3371
    experimental=True,
3264
3372
    alias=True,
3265
 
    hidden=True,
3266
3373
    )
3267
 
register_metadir(controldir.format_registry, 'development5-subtree',
 
3374
format_registry.register_metadir('development-subtree',
3268
3375
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3269
 
    help='Development format, subtree variant. Can convert data to and '
3270
 
        'from pack-0.92-subtree (and anything compatible with '
3271
 
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3272
 
        'this format can only be read by bzr.dev. Please read '
3273
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3274
 
        'before use.',
3275
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3276
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3277
 
    experimental=True,
3278
 
    hidden=True,
3279
 
    alias=False,
3280
 
    )
3281
 
 
3282
 
 
3283
 
register_metadir(controldir.format_registry, 'development-subtree',
3284
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
3285
3376
    help='Current development format, subtree variant. Can convert data to and '
3286
3377
        'from pack-0.92-subtree (and anything compatible with '
3287
3378
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3288
3379
        'this format can only be read by bzr.dev. Please read '
3289
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3380
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3290
3381
        'before use.',
3291
3382
    branch_format='bzrlib.branch.BzrBranchFormat7',
3292
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3383
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3293
3384
    experimental=True,
3294
 
    hidden=True,
3295
 
    alias=False, # Restore to being an alias when an actual development subtree format is added
3296
 
                 # This current non-alias status is simply because we did not introduce a
3297
 
                 # chk based subtree format.
 
3385
    alias=True,
3298
3386
    )
3299
 
 
3300
3387
# And the development formats above will have aliased one of the following:
3301
 
register_metadir(controldir.format_registry, 'development6-rich-root',
3302
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3303
 
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3304
 
        'Please read '
3305
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3306
 
        'before use.',
3307
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3308
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3309
 
    hidden=True,
3310
 
    experimental=True,
3311
 
    )
3312
 
 
3313
 
register_metadir(controldir.format_registry, 'development7-rich-root',
3314
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3315
 
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3316
 
        'rich roots. Please read '
3317
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3318
 
        'before use.',
3319
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3320
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3321
 
    hidden=True,
3322
 
    experimental=True,
3323
 
    )
3324
 
 
3325
 
register_metadir(controldir.format_registry, '2a',
3326
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3327
 
    help='First format for bzr 2.0 series.\n'
3328
 
        'Uses group-compress storage.\n'
3329
 
        'Provides rich roots which are a one-way transition.\n',
3330
 
        # 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
3331
 
        # 'rich roots. Supported by bzr 1.16 and later.',
3332
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3333
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3334
 
    experimental=False,
3335
 
    )
3336
 
 
 
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
    )
3337
3410
# The following format should be an alias for the rich root equivalent 
3338
3411
# of the default format
3339
 
register_metadir(controldir.format_registry, 'default-rich-root',
3340
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3341
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3342
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3412
format_registry.register_metadir('default-rich-root',
 
3413
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
 
3414
    help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
 
3415
    branch_format='bzrlib.branch.BzrBranchFormat6',
 
3416
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3343
3417
    alias=True,
3344
 
    hidden=True,
3345
 
    help='Same as 2a.')
3346
 
 
 
3418
    )
3347
3419
# The current format that is made on 'bzr init'.
3348
 
controldir.format_registry.set_default('2a')
3349
 
 
3350
 
# XXX 2010-08-20 JRV: There is still a lot of code relying on
3351
 
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
3352
 
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
3353
 
format_registry = controldir.format_registry
 
3420
format_registry.set_default('pack-0.92')