~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Bring the groupcompress plugin into the brisbane-core branch.

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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""BzrDir logic. The BzrDir is the basic control directory used by bzr.
18
18
 
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 (
85
 
    hooks,
86
78
    registry,
87
79
    symbol_versioning,
88
80
    )
89
81
 
90
82
 
91
 
class BzrDir(controldir.ControlDir):
 
83
class BzrDir(object):
92
84
    """A .bzr control diretory.
93
85
 
94
86
    BzrDir instances let you create or open any of the things that can be
101
93
        (i.e. the parent directory holding the .bzr directory).
102
94
 
103
95
    Everything in the bzrdir should have the same file permissions.
104
 
 
105
 
    :cvar hooks: An instance of BzrDirHooks.
106
96
    """
107
97
 
108
98
    def break_lock(self):
125
115
                    return
126
116
        thing_to_unlock.break_lock()
127
117
 
 
118
    def can_convert_format(self):
 
119
        """Return true if this bzrdir is one whose format we can convert from."""
 
120
        return True
 
121
 
128
122
    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
123
        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
 
124
        source_repo_format = self._format.repository_format
 
125
        source_repo_format.check_conversion_target(target_repo_format)
139
126
 
140
127
    @staticmethod
141
128
    def _check_supported(format, allow_unsupported,
185
172
                                       preserve_stacking=preserve_stacking)
186
173
 
187
174
    def clone_on_transport(self, transport, revision_id=None,
188
 
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
189
 
        create_prefix=False, use_existing_dir=True):
 
175
                           force_new_repo=False, preserve_stacking=False,
 
176
                           stacked_on=None):
190
177
        """Clone this bzrdir and its contents to transport verbatim.
191
178
 
192
179
        :param transport: The transport for the location to produce the clone
198
185
                               even if one is available.
199
186
        :param preserve_stacking: When cloning a stacked branch, stack the
200
187
            new branch on top of the other branch's stacked-on branch.
201
 
        :param create_prefix: Create any missing directories leading up to
202
 
            to_transport.
203
 
        :param use_existing_dir: Use an existing directory if one exists.
204
188
        """
205
 
        # Overview: put together a broad description of what we want to end up
206
 
        # with; then make as few api calls as possible to do it.
207
 
 
208
 
        # We may want to create a repo/branch/tree, if we do so what format
209
 
        # would we want for each:
 
189
        transport.ensure_base()
210
190
        require_stacking = (stacked_on is not None)
211
191
        format = self.cloning_metadir(require_stacking)
212
 
 
213
 
        # Figure out what objects we want:
 
192
        result = format.initialize_on_transport(transport)
 
193
        repository_policy = None
214
194
        try:
215
195
            local_repo = self.find_repository()
216
196
        except errors.NoRepositoryPresent:
230
210
                        errors.UnstackableRepositoryFormat,
231
211
                        errors.NotStacked):
232
212
                    pass
233
 
        # Bug: We create a metadir without knowing if it can support stacking,
234
 
        # we should look up the policy needs first, or just use it as a hint,
235
 
        # or something.
 
213
 
236
214
        if local_repo:
 
215
            # may need to copy content in
 
216
            repository_policy = result.determine_repository_policy(
 
217
                force_new_repo, stacked_on, self.root_transport.base,
 
218
                require_stacking=require_stacking)
237
219
            make_working_trees = local_repo.make_working_trees()
238
 
            want_shared = local_repo.is_shared()
239
 
            repo_format_name = format.repository_format.network_name()
240
 
        else:
241
 
            make_working_trees = False
242
 
            want_shared = False
243
 
            repo_format_name = None
244
 
 
245
 
        result_repo, result, require_stacking, repository_policy = \
246
 
            format.initialize_on_transport_ex(transport,
247
 
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
248
 
            force_new_repo=force_new_repo, stacked_on=stacked_on,
249
 
            stack_on_pwd=self.root_transport.base,
250
 
            repo_format_name=repo_format_name,
251
 
            make_working_trees=make_working_trees, shared_repo=want_shared)
252
 
        if repo_format_name:
253
 
            try:
254
 
                # If the result repository is in the same place as the
255
 
                # resulting bzr dir, it will have no content, further if the
256
 
                # result is not stacked then we know all content should be
257
 
                # copied, and finally if we are copying up to a specific
258
 
                # revision_id then we can use the pending-ancestry-result which
259
 
                # does not require traversing all of history to describe it.
260
 
                if (result_repo.user_url == result.user_url
261
 
                    and not require_stacking and
262
 
                    revision_id is not None):
263
 
                    fetch_spec = graph.PendingAncestryResult(
264
 
                        [revision_id], local_repo)
265
 
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
266
 
                else:
267
 
                    result_repo.fetch(local_repo, revision_id=revision_id)
268
 
            finally:
269
 
                result_repo.unlock()
270
 
        else:
271
 
            if result_repo is not None:
272
 
                raise AssertionError('result_repo not None(%r)' % result_repo)
 
220
            result_repo, is_new_repo = repository_policy.acquire_repository(
 
221
                make_working_trees, local_repo.is_shared())
 
222
            if not require_stacking and repository_policy._require_stacking:
 
223
                require_stacking = True
 
224
                result._format.require_stacking()
 
225
            if is_new_repo and not require_stacking and revision_id is not None:
 
226
                fetch_spec = graph.PendingAncestryResult(
 
227
                    [revision_id], local_repo)
 
228
                result_repo.fetch(local_repo, fetch_spec=fetch_spec)
 
229
            else:
 
230
                result_repo.fetch(local_repo, revision_id=revision_id)
 
231
        else:
 
232
            result_repo = None
273
233
        # 1 if there is a branch present
274
234
        #   make sure its content is available in the target repository
275
235
        #   clone it.
292
252
        t = get_transport(url)
293
253
        t.ensure_base()
294
254
 
 
255
    @classmethod
 
256
    def create(cls, base, format=None, possible_transports=None):
 
257
        """Create a new BzrDir at the url 'base'.
 
258
 
 
259
        :param format: If supplied, the format of branch to create.  If not
 
260
            supplied, the default is used.
 
261
        :param possible_transports: If supplied, a list of transports that
 
262
            can be reused to share a remote connection.
 
263
        """
 
264
        if cls is not BzrDir:
 
265
            raise AssertionError("BzrDir.create always creates the default"
 
266
                " format, not one of %r" % cls)
 
267
        t = get_transport(base, possible_transports)
 
268
        t.ensure_base()
 
269
        if format is None:
 
270
            format = BzrDirFormat.get_default_format()
 
271
        return format.initialize_on_transport(t)
 
272
 
295
273
    @staticmethod
296
274
    def find_bzrdirs(transport, evaluate=None, list_current=None):
297
275
        """Find bzrdirs recursively from current location.
320
298
            recurse = True
321
299
            try:
322
300
                bzrdir = BzrDir.open_from_transport(current_transport)
323
 
            except (errors.NotBranchError, errors.PermissionDenied):
 
301
            except errors.NotBranchError:
324
302
                pass
325
303
            else:
326
304
                recurse, value = evaluate(bzrdir)
327
305
                yield value
328
306
            try:
329
307
                subdirs = list_current(current_transport)
330
 
            except (errors.NoSuchFile, errors.PermissionDenied):
 
308
            except errors.NoSuchFile:
331
309
                continue
332
310
            if recurse:
333
311
                for subdir in sorted(subdirs, reverse=True):
350
328
            except errors.NoRepositoryPresent:
351
329
                pass
352
330
            else:
353
 
                return False, ([], repository)
354
 
            return True, (bzrdir.list_branches(), None)
355
 
        ret = []
356
 
        for branches, repo in BzrDir.find_bzrdirs(transport,
357
 
                                                  evaluate=evaluate):
 
331
                return False, (None, repository)
 
332
            try:
 
333
                branch = bzrdir.open_branch()
 
334
            except errors.NotBranchError:
 
335
                return True, (None, None)
 
336
            else:
 
337
                return True, (branch, None)
 
338
        branches = []
 
339
        for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
358
340
            if repo is not None:
359
 
                ret.extend(repo.find_branches())
360
 
            if branches is not None:
361
 
                ret.extend(branches)
362
 
        return ret
 
341
                branches.extend(repo.find_branches())
 
342
            if branch is not None:
 
343
                branches.append(branch)
 
344
        return branches
 
345
 
 
346
    def destroy_repository(self):
 
347
        """Destroy the repository in this BzrDir"""
 
348
        raise NotImplementedError(self.destroy_repository)
 
349
 
 
350
    def create_branch(self):
 
351
        """Create a branch in this BzrDir.
 
352
 
 
353
        The bzrdir's format will control what branch format is created.
 
354
        For more control see BranchFormatXX.create(a_bzrdir).
 
355
        """
 
356
        raise NotImplementedError(self.create_branch)
 
357
 
 
358
    def destroy_branch(self):
 
359
        """Destroy the branch in this BzrDir"""
 
360
        raise NotImplementedError(self.destroy_branch)
363
361
 
364
362
    @staticmethod
365
363
    def create_branch_and_repo(base, force_new_repo=False, format=None):
386
384
                                    stack_on_pwd=None, require_stacking=False):
387
385
        """Return an object representing a policy to use.
388
386
 
389
 
        This controls whether a new repository is created, and the format of
390
 
        that repository, or some existing shared repository used instead.
 
387
        This controls whether a new repository is created, or a shared
 
388
        repository used instead.
391
389
 
392
390
        If stack_on is supplied, will not seek a containing shared repo.
393
391
 
402
400
            stack_on_pwd = None
403
401
            config = found_bzrdir.get_config()
404
402
            stop = False
405
 
            stack_on = config.get_default_stack_on()
406
 
            if stack_on is not None:
407
 
                stack_on_pwd = found_bzrdir.user_url
408
 
                stop = True
 
403
            if config is not None:
 
404
                stack_on = config.get_default_stack_on()
 
405
                if stack_on is not None:
 
406
                    stack_on_pwd = found_bzrdir.root_transport.base
 
407
                    stop = True
 
408
                    note('Using default stacking branch %s at %s', stack_on,
 
409
                         stack_on_pwd)
409
410
            # does it have a repository ?
410
411
            try:
411
412
                repository = found_bzrdir.open_repository()
412
413
            except errors.NoRepositoryPresent:
413
414
                repository = None
414
415
            else:
415
 
                if (found_bzrdir.user_url != self.user_url 
416
 
                    and not repository.is_shared()):
417
 
                    # Don't look higher, can't use a higher shared repo.
 
416
                if ((found_bzrdir.root_transport.base !=
 
417
                     self.root_transport.base) and not repository.is_shared()):
418
418
                    repository = None
419
 
                    stop = True
420
419
                else:
421
420
                    stop = True
422
421
            if not stop:
515
514
                                               format=format).bzrdir
516
515
        return bzrdir.create_workingtree()
517
516
 
518
 
    def generate_backup_name(self, base):
519
 
        """Generate a non-existing backup file name based on base."""
520
 
        counter = 1
521
 
        name = "%s.~%d~" % (base, counter)
522
 
        while self.root_transport.has(name):
523
 
            counter += 1
524
 
            name = "%s.~%d~" % (base, counter)
525
 
        return name
 
517
    def create_workingtree(self, revision_id=None, from_branch=None,
 
518
        accelerator_tree=None, hardlink=False):
 
519
        """Create a working tree at this BzrDir.
 
520
 
 
521
        :param revision_id: create it as of this revision id.
 
522
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
523
        :param accelerator_tree: A tree which can be used for retrieving file
 
524
            contents more quickly than the revision tree, i.e. a workingtree.
 
525
            The revision tree will be used for cases where accelerator_tree's
 
526
            content is different.
 
527
        """
 
528
        raise NotImplementedError(self.create_workingtree)
526
529
 
527
530
    def backup_bzrdir(self):
528
531
        """Backup this bzr control directory.
529
532
 
530
533
        :return: Tuple with old path name and new path name
531
534
        """
532
 
 
533
 
        backup_dir=self.generate_backup_name('backup.bzr')
534
535
        pb = ui.ui_factory.nested_progress_bar()
535
536
        try:
536
537
            # FIXME: bug 300001 -- the backup fails if the backup directory
537
538
            # already exists, but it should instead either remove it or make
538
539
            # a new backup directory.
539
540
            #
 
541
            # FIXME: bug 262450 -- the backup directory should have the same
 
542
            # permissions as the .bzr directory (probably a bug in copy_tree)
540
543
            old_path = self.root_transport.abspath('.bzr')
541
 
            new_path = self.root_transport.abspath(backup_dir)
542
 
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
543
 
            self.root_transport.copy_tree('.bzr', backup_dir)
 
544
            new_path = self.root_transport.abspath('backup.bzr')
 
545
            pb.note('making backup of %s' % (old_path,))
 
546
            pb.note('  to %s' % (new_path,))
 
547
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
544
548
            return (old_path, new_path)
545
549
        finally:
546
550
            pb.finished()
570
574
                else:
571
575
                    pass
572
576
 
 
577
    def destroy_workingtree(self):
 
578
        """Destroy the working tree at this BzrDir.
 
579
 
 
580
        Formats that do not support this may raise UnsupportedOperation.
 
581
        """
 
582
        raise NotImplementedError(self.destroy_workingtree)
 
583
 
 
584
    def destroy_workingtree_metadata(self):
 
585
        """Destroy the control files for the working tree at this BzrDir.
 
586
 
 
587
        The contents of working tree files are not affected.
 
588
        Formats that do not support this may raise UnsupportedOperation.
 
589
        """
 
590
        raise NotImplementedError(self.destroy_workingtree_metadata)
 
591
 
573
592
    def _find_containing(self, evaluate):
574
593
        """Find something in a containing control directory.
575
594
 
589
608
            if stop:
590
609
                return result
591
610
            next_transport = found_bzrdir.root_transport.clone('..')
592
 
            if (found_bzrdir.user_url == next_transport.base):
 
611
            if (found_bzrdir.root_transport.base == next_transport.base):
593
612
                # top of the file system
594
613
                return None
595
614
            # find the next containing bzrdir
612
631
                repository = found_bzrdir.open_repository()
613
632
            except errors.NoRepositoryPresent:
614
633
                return None, False
615
 
            if found_bzrdir.user_url == self.user_url:
 
634
            if found_bzrdir.root_transport.base == self.root_transport.base:
616
635
                return repository, True
617
636
            elif repository.is_shared():
618
637
                return repository, True
624
643
            raise errors.NoRepositoryPresent(self)
625
644
        return found_repo
626
645
 
 
646
    def get_branch_reference(self):
 
647
        """Return the referenced URL for the branch in this bzrdir.
 
648
 
 
649
        :raises NotBranchError: If there is no Branch.
 
650
        :return: The URL the branch in this bzrdir references if it is a
 
651
            reference branch, or None for regular branches.
 
652
        """
 
653
        return None
 
654
 
 
655
    def get_branch_transport(self, branch_format):
 
656
        """Get the transport for use by branch format in this BzrDir.
 
657
 
 
658
        Note that bzr dirs that do not support format strings will raise
 
659
        IncompatibleFormat if the branch format they are given has
 
660
        a format string, and vice versa.
 
661
 
 
662
        If branch_format is None, the transport is returned with no
 
663
        checking. If it is not None, then the returned transport is
 
664
        guaranteed to point to an existing directory ready for use.
 
665
        """
 
666
        raise NotImplementedError(self.get_branch_transport)
 
667
 
627
668
    def _find_creation_modes(self):
628
669
        """Determine the appropriate modes for files and directories.
629
670
 
668
709
            self._find_creation_modes()
669
710
        return self._dir_mode
670
711
 
 
712
    def get_repository_transport(self, repository_format):
 
713
        """Get the transport for use by repository format in this BzrDir.
 
714
 
 
715
        Note that bzr dirs that do not support format strings will raise
 
716
        IncompatibleFormat if the repository format they are given has
 
717
        a format string, and vice versa.
 
718
 
 
719
        If repository_format is None, the transport is returned with no
 
720
        checking. If it is not None, then the returned transport is
 
721
        guaranteed to point to an existing directory ready for use.
 
722
        """
 
723
        raise NotImplementedError(self.get_repository_transport)
 
724
 
 
725
    def get_workingtree_transport(self, tree_format):
 
726
        """Get the transport for use by workingtree format in this BzrDir.
 
727
 
 
728
        Note that bzr dirs that do not support format strings will raise
 
729
        IncompatibleFormat if the workingtree format they are given has a
 
730
        format string, and vice versa.
 
731
 
 
732
        If workingtree_format is None, the transport is returned with no
 
733
        checking. If it is not None, then the returned transport is
 
734
        guaranteed to point to an existing directory ready for use.
 
735
        """
 
736
        raise NotImplementedError(self.get_workingtree_transport)
 
737
 
671
738
    def get_config(self):
672
 
        """Get configuration for this BzrDir."""
673
 
        return config.BzrDirConfig(self)
674
 
 
675
 
    def _get_config(self):
676
 
        """By default, no configuration is available."""
677
 
        return None
 
739
        if getattr(self, '_get_config', None) is None:
 
740
            return None
 
741
        return self._get_config()
678
742
 
679
743
    def __init__(self, _transport, _format):
680
744
        """Initialize a Bzr control dir object.
686
750
        :param _transport: the transport this dir is based at.
687
751
        """
688
752
        self._format = _format
689
 
        # these are also under the more standard names of 
690
 
        # control_transport and user_transport
691
753
        self.transport = _transport.clone('.bzr')
692
754
        self.root_transport = _transport
693
755
        self._mode_check_done = False
694
756
 
695
 
    @property 
696
 
    def user_transport(self):
697
 
        return self.root_transport
698
 
 
699
 
    @property
700
 
    def control_transport(self):
701
 
        return self.transport
702
 
 
703
757
    def is_control_filename(self, filename):
704
758
        """True if filename is the name of a path which is reserved for bzrdir's.
705
759
 
707
761
 
708
762
        This is true IF and ONLY IF the filename is part of the namespace reserved
709
763
        for bzr control dirs. Currently this is the '.bzr' directory in the root
710
 
        of the root_transport. 
 
764
        of the root_transport. it is expected that plugins will need to extend
 
765
        this in the future - for instance to make bzr talk with svn working
 
766
        trees.
711
767
        """
712
768
        # this might be better on the BzrDirFormat class because it refers to
713
769
        # all the possible bzrdir disk formats.
717
773
        # add new tests for it to the appropriate place.
718
774
        return filename == '.bzr' or filename.startswith('.bzr/')
719
775
 
 
776
    def needs_format_conversion(self, format=None):
 
777
        """Return true if this bzrdir needs convert_format run on it.
 
778
 
 
779
        For instance, if the repository format is out of date but the
 
780
        branch and working tree are not, this should return True.
 
781
 
 
782
        :param format: Optional parameter indicating a specific desired
 
783
                       format we plan to arrive at.
 
784
        """
 
785
        raise NotImplementedError(self.needs_format_conversion)
 
786
 
720
787
    @staticmethod
721
788
    def open_unsupported(base):
722
789
        """Open a branch which is not supported."""
739
806
        :param transport: Transport containing the bzrdir.
740
807
        :param _unsupported: private.
741
808
        """
742
 
        for hook in BzrDir.hooks['pre_open']:
743
 
            hook(transport)
744
809
        # Keep initial base since 'transport' may be modified while following
745
810
        # the redirections.
746
811
        base = transport.base
747
812
        def find_format(transport):
748
 
            return transport, controldir.ControlDirFormat.find_format(
 
813
            return transport, BzrDirFormat.find_format(
749
814
                transport, _server_formats=_server_formats)
750
815
 
751
816
        def redirected(transport, e, redirection_notice):
766
831
        BzrDir._check_supported(format, _unsupported)
767
832
        return format.open(transport, _found=True)
768
833
 
 
834
    def open_branch(self, unsupported=False):
 
835
        """Open the branch object at this BzrDir if one is present.
 
836
 
 
837
        If unsupported is True, then no longer supported branch formats can
 
838
        still be opened.
 
839
 
 
840
        TODO: static convenience version of this?
 
841
        """
 
842
        raise NotImplementedError(self.open_branch)
 
843
 
769
844
    @staticmethod
770
845
    def open_containing(url, possible_transports=None):
771
846
        """Open an existing branch which contains url.
809
884
                raise errors.NotBranchError(path=url)
810
885
            a_transport = new_t
811
886
 
 
887
    def _get_tree_branch(self):
 
888
        """Return the branch and tree, if any, for this bzrdir.
 
889
 
 
890
        Return None for tree if not present or inaccessible.
 
891
        Raise NotBranchError if no branch is present.
 
892
        :return: (tree, branch)
 
893
        """
 
894
        try:
 
895
            tree = self.open_workingtree()
 
896
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
897
            tree = None
 
898
            branch = self.open_branch()
 
899
        else:
 
900
            branch = tree.branch
 
901
        return tree, branch
 
902
 
812
903
    @classmethod
813
904
    def open_tree_or_branch(klass, location):
814
905
        """Return the branch and working tree at a location.
860
951
                raise errors.NotBranchError(location)
861
952
        return tree, branch, branch.repository, relpath
862
953
 
 
954
    def open_repository(self, _unsupported=False):
 
955
        """Open the repository object at this BzrDir if one is present.
 
956
 
 
957
        This will not follow the Branch object pointer - it's strictly a direct
 
958
        open facility. Most client code should use open_branch().repository to
 
959
        get at a repository.
 
960
 
 
961
        :param _unsupported: a private parameter, not part of the api.
 
962
        TODO: static convenience version of this?
 
963
        """
 
964
        raise NotImplementedError(self.open_repository)
 
965
 
 
966
    def open_workingtree(self, _unsupported=False,
 
967
                         recommend_upgrade=True, from_branch=None):
 
968
        """Open the workingtree object at this BzrDir if one is present.
 
969
 
 
970
        :param recommend_upgrade: Optional keyword parameter, when True (the
 
971
            default), emit through the ui module a recommendation that the user
 
972
            upgrade the working tree when the workingtree being opened is old
 
973
            (but still fully supported).
 
974
        :param from_branch: override bzrdir branch (for lightweight checkouts)
 
975
        """
 
976
        raise NotImplementedError(self.open_workingtree)
 
977
 
 
978
    def has_branch(self):
 
979
        """Tell if this bzrdir contains a branch.
 
980
 
 
981
        Note: if you're going to open the branch, you should just go ahead
 
982
        and try, and not ask permission first.  (This method just opens the
 
983
        branch and discards it, and that's somewhat expensive.)
 
984
        """
 
985
        try:
 
986
            self.open_branch()
 
987
            return True
 
988
        except errors.NotBranchError:
 
989
            return False
 
990
 
 
991
    def has_workingtree(self):
 
992
        """Tell if this bzrdir contains a working tree.
 
993
 
 
994
        This will still raise an exception if the bzrdir has a workingtree that
 
995
        is remote & inaccessible.
 
996
 
 
997
        Note: if you're going to open the working tree, you should just go ahead
 
998
        and try, and not ask permission first.  (This method just opens the
 
999
        workingtree and discards it, and that's somewhat expensive.)
 
1000
        """
 
1001
        try:
 
1002
            self.open_workingtree(recommend_upgrade=False)
 
1003
            return True
 
1004
        except errors.NoWorkingTree:
 
1005
            return False
 
1006
 
863
1007
    def _cloning_metadir(self):
864
1008
        """Produce a metadir suitable for cloning with.
865
1009
 
868
1012
        result_format = self._format.__class__()
869
1013
        try:
870
1014
            try:
871
 
                branch = self.open_branch(ignore_fallbacks=True)
 
1015
                branch = self.open_branch()
872
1016
                source_repository = branch.repository
873
1017
                result_format._branch_format = branch._format
874
1018
            except errors.NotBranchError:
911
1055
        """
912
1056
        format, repository = self._cloning_metadir()
913
1057
        if format._workingtree_format is None:
914
 
            # No tree in self.
915
1058
            if repository is None:
916
 
                # No repository either
917
1059
                return format
918
 
            # We have a repository, so set a working tree? (Why? This seems to
919
 
            # contradict the stated return value in the docstring).
920
1060
            tree_format = repository._format._matchingbzrdir.workingtree_format
921
1061
            format.workingtree_format = tree_format.__class__()
922
1062
        if require_stacking:
923
1063
            format.require_stacking()
924
1064
        return format
925
1065
 
926
 
    @classmethod
927
 
    def create(cls, base, format=None, possible_transports=None):
928
 
        """Create a new BzrDir at the url 'base'.
929
 
 
930
 
        :param format: If supplied, the format of branch to create.  If not
931
 
            supplied, the default is used.
932
 
        :param possible_transports: If supplied, a list of transports that
933
 
            can be reused to share a remote connection.
934
 
        """
935
 
        if cls is not BzrDir:
936
 
            raise AssertionError("BzrDir.create always creates the"
937
 
                "default format, not one of %r" % cls)
938
 
        t = get_transport(base, possible_transports)
939
 
        t.ensure_base()
940
 
        if format is None:
941
 
            format = controldir.ControlDirFormat.get_default_format()
942
 
        return format.initialize_on_transport(t)
943
 
 
944
 
 
945
 
 
946
 
class BzrDirHooks(hooks.Hooks):
947
 
    """Hooks for BzrDir operations."""
948
 
 
949
 
    def __init__(self):
950
 
        """Create the default hooks."""
951
 
        hooks.Hooks.__init__(self)
952
 
        self.create_hook(hooks.HookPoint('pre_open',
953
 
            "Invoked before attempting to open a BzrDir with the transport "
954
 
            "that the open will use.", (1, 14), None))
955
 
        self.create_hook(hooks.HookPoint('post_repo_init',
956
 
            "Invoked after a repository has been initialized. "
957
 
            "post_repo_init is called with a "
958
 
            "bzrlib.bzrdir.RepoInitHookParams.",
959
 
            (2, 2), None))
960
 
 
961
 
# install the default hooks
962
 
BzrDir.hooks = BzrDirHooks()
963
 
 
964
 
 
965
 
class RepoInitHookParams(object):
966
 
    """Object holding parameters passed to *_repo_init hooks.
967
 
 
968
 
    There are 4 fields that hooks may wish to access:
969
 
 
970
 
    :ivar repository: Repository created
971
 
    :ivar format: Repository format
972
 
    :ivar bzrdir: The bzrdir for the repository
973
 
    :ivar shared: The repository is shared
974
 
    """
975
 
 
976
 
    def __init__(self, repository, format, a_bzrdir, shared):
977
 
        """Create a group of RepoInitHook parameters.
978
 
 
979
 
        :param repository: Repository created
980
 
        :param format: Repository format
981
 
        :param bzrdir: The bzrdir for the repository
982
 
        :param shared: The repository is shared
983
 
        """
984
 
        self.repository = repository
985
 
        self.format = format
986
 
        self.bzrdir = a_bzrdir
987
 
        self.shared = shared
988
 
 
989
 
    def __eq__(self, other):
990
 
        return self.__dict__ == other.__dict__
991
 
 
992
 
    def __repr__(self):
993
 
        if self.repository:
994
 
            return "<%s for %s>" % (self.__class__.__name__,
995
 
                self.repository)
996
 
        else:
997
 
            return "<%s for %s>" % (self.__class__.__name__,
998
 
                self.bzrdir)
 
1066
    def checkout_metadir(self):
 
1067
        return self.cloning_metadir()
 
1068
 
 
1069
    def sprout(self, url, revision_id=None, force_new_repo=False,
 
1070
               recurse='down', possible_transports=None,
 
1071
               accelerator_tree=None, hardlink=False, stacked=False,
 
1072
               source_branch=None, create_tree_if_local=True):
 
1073
        """Create a copy of this bzrdir prepared for use as a new line of
 
1074
        development.
 
1075
 
 
1076
        If url's last component does not exist, it will be created.
 
1077
 
 
1078
        Attributes related to the identity of the source branch like
 
1079
        branch nickname will be cleaned, a working tree is created
 
1080
        whether one existed before or not; and a local branch is always
 
1081
        created.
 
1082
 
 
1083
        if revision_id is not None, then the clone operation may tune
 
1084
            itself to download less data.
 
1085
        :param accelerator_tree: A tree which can be used for retrieving file
 
1086
            contents more quickly than the revision tree, i.e. a workingtree.
 
1087
            The revision tree will be used for cases where accelerator_tree's
 
1088
            content is different.
 
1089
        :param hardlink: If true, hard-link files from accelerator_tree,
 
1090
            where possible.
 
1091
        :param stacked: If true, create a stacked branch referring to the
 
1092
            location of this control directory.
 
1093
        :param create_tree_if_local: If true, a working-tree will be created
 
1094
            when working locally.
 
1095
        """
 
1096
        target_transport = get_transport(url, possible_transports)
 
1097
        target_transport.ensure_base()
 
1098
        cloning_format = self.cloning_metadir(stacked)
 
1099
        # Create/update the result branch
 
1100
        result = cloning_format.initialize_on_transport(target_transport)
 
1101
        # if a stacked branch wasn't requested, we don't create one
 
1102
        # even if the origin was stacked
 
1103
        stacked_branch_url = None
 
1104
        if source_branch is not None:
 
1105
            if stacked:
 
1106
                stacked_branch_url = self.root_transport.base
 
1107
            source_repository = source_branch.repository
 
1108
        else:
 
1109
            try:
 
1110
                source_branch = self.open_branch()
 
1111
                source_repository = source_branch.repository
 
1112
                if stacked:
 
1113
                    stacked_branch_url = self.root_transport.base
 
1114
            except errors.NotBranchError:
 
1115
                source_branch = None
 
1116
                try:
 
1117
                    source_repository = self.open_repository()
 
1118
                except errors.NoRepositoryPresent:
 
1119
                    source_repository = None
 
1120
        repository_policy = result.determine_repository_policy(
 
1121
            force_new_repo, stacked_branch_url, require_stacking=stacked)
 
1122
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
1123
        if is_new_repo and revision_id is not None and not stacked:
 
1124
            fetch_spec = graph.PendingAncestryResult(
 
1125
                [revision_id], source_repository)
 
1126
        else:
 
1127
            fetch_spec = None
 
1128
        if source_repository is not None:
 
1129
            # Fetch while stacked to prevent unstacked fetch from
 
1130
            # Branch.sprout.
 
1131
            if fetch_spec is None:
 
1132
                result_repo.fetch(source_repository, revision_id=revision_id)
 
1133
            else:
 
1134
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
 
1135
 
 
1136
        if source_branch is None:
 
1137
            # this is for sprouting a bzrdir without a branch; is that
 
1138
            # actually useful?
 
1139
            # Not especially, but it's part of the contract.
 
1140
            result_branch = result.create_branch()
 
1141
        else:
 
1142
            result_branch = source_branch.sprout(result,
 
1143
                revision_id=revision_id, repository_policy=repository_policy)
 
1144
        mutter("created new branch %r" % (result_branch,))
 
1145
 
 
1146
        # Create/update the result working tree
 
1147
        if (create_tree_if_local and
 
1148
            isinstance(target_transport, local.LocalTransport) and
 
1149
            (result_repo is None or result_repo.make_working_trees())):
 
1150
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
 
1151
                hardlink=hardlink)
 
1152
            wt.lock_write()
 
1153
            try:
 
1154
                if wt.path2id('') is None:
 
1155
                    try:
 
1156
                        wt.set_root_id(self.open_workingtree.get_root_id())
 
1157
                    except errors.NoWorkingTree:
 
1158
                        pass
 
1159
            finally:
 
1160
                wt.unlock()
 
1161
        else:
 
1162
            wt = None
 
1163
        if recurse == 'down':
 
1164
            if wt is not None:
 
1165
                basis = wt.basis_tree()
 
1166
                basis.lock_read()
 
1167
                subtrees = basis.iter_references()
 
1168
            elif result_branch is not None:
 
1169
                basis = result_branch.basis_tree()
 
1170
                basis.lock_read()
 
1171
                subtrees = basis.iter_references()
 
1172
            elif source_branch is not None:
 
1173
                basis = source_branch.basis_tree()
 
1174
                basis.lock_read()
 
1175
                subtrees = basis.iter_references()
 
1176
            else:
 
1177
                subtrees = []
 
1178
                basis = None
 
1179
            try:
 
1180
                for path, file_id in subtrees:
 
1181
                    target = urlutils.join(url, urlutils.escape(path))
 
1182
                    sublocation = source_branch.reference_parent(file_id, path)
 
1183
                    sublocation.bzrdir.sprout(target,
 
1184
                        basis.get_reference_revision(file_id, path),
 
1185
                        force_new_repo=force_new_repo, recurse=recurse,
 
1186
                        stacked=stacked)
 
1187
            finally:
 
1188
                if basis is not None:
 
1189
                    basis.unlock()
 
1190
        return result
999
1191
 
1000
1192
 
1001
1193
class BzrDirPreSplitOut(BzrDir):
1016
1208
    def cloning_metadir(self, require_stacking=False):
1017
1209
        """Produce a metadir suitable for cloning with."""
1018
1210
        if require_stacking:
1019
 
            return controldir.format_registry.make_bzrdir('1.6')
 
1211
            return format_registry.make_bzrdir('1.6')
1020
1212
        return self._format.__class__()
1021
1213
 
1022
1214
    def clone(self, url, revision_id=None, force_new_repo=False,
1042
1234
            tree.clone(result)
1043
1235
        return result
1044
1236
 
1045
 
    def create_branch(self, name=None):
 
1237
    def create_branch(self):
1046
1238
        """See BzrDir.create_branch."""
1047
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1239
        return self._format.get_branch_format().initialize(self)
1048
1240
 
1049
 
    def destroy_branch(self, name=None):
 
1241
    def destroy_branch(self):
1050
1242
        """See BzrDir.destroy_branch."""
1051
1243
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1052
1244
 
1075
1267
        # that can do wonky stuff here, and that only
1076
1268
        # happens for creating checkouts, which cannot be
1077
1269
        # done on this format anyway. So - acceptable wart.
1078
 
        if hardlink:
1079
 
            warning("can't support hardlinked working trees in %r"
1080
 
                % (self,))
1081
1270
        try:
1082
1271
            result = self.open_workingtree(recommend_upgrade=False)
1083
1272
        except errors.NoSuchFile:
1108
1297
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1109
1298
                                          self)
1110
1299
 
1111
 
    def get_branch_transport(self, branch_format, name=None):
 
1300
    def get_branch_transport(self, branch_format):
1112
1301
        """See BzrDir.get_branch_transport()."""
1113
 
        if name is not None:
1114
 
            raise errors.NoColocatedBranchSupport(self)
1115
1302
        if branch_format is None:
1116
1303
            return self.transport
1117
1304
        try:
1150
1337
            format = BzrDirFormat.get_default_format()
1151
1338
        return not isinstance(self._format, format.__class__)
1152
1339
 
1153
 
    def open_branch(self, name=None, unsupported=False,
1154
 
                    ignore_fallbacks=False):
 
1340
    def open_branch(self, unsupported=False):
1155
1341
        """See BzrDir.open_branch."""
1156
1342
        from bzrlib.branch import BzrBranchFormat4
1157
1343
        format = BzrBranchFormat4()
1158
1344
        self._check_supported(format, unsupported)
1159
 
        return format.open(self, name, _found=True)
 
1345
        return format.open(self, _found=True)
1160
1346
 
1161
1347
    def sprout(self, url, revision_id=None, force_new_repo=False,
1162
1348
               possible_transports=None, accelerator_tree=None,
1223
1409
    This is a deprecated format and may be removed after sept 2006.
1224
1410
    """
1225
1411
 
1226
 
    def has_workingtree(self):
1227
 
        """See BzrDir.has_workingtree."""
1228
 
        return True
1229
 
    
1230
1412
    def open_repository(self):
1231
1413
        """See BzrDir.open_repository."""
1232
1414
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1248
1430
    This is a deprecated format and may be removed after sept 2006.
1249
1431
    """
1250
1432
 
1251
 
    def has_workingtree(self):
1252
 
        """See BzrDir.has_workingtree."""
1253
 
        return True
1254
 
    
1255
1433
    def open_repository(self):
1256
1434
        """See BzrDir.open_repository."""
1257
1435
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1279
1457
        """See BzrDir.can_convert_format()."""
1280
1458
        return True
1281
1459
 
1282
 
    def create_branch(self, name=None):
 
1460
    def create_branch(self):
1283
1461
        """See BzrDir.create_branch."""
1284
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1462
        return self._format.get_branch_format().initialize(self)
1285
1463
 
1286
 
    def destroy_branch(self, name=None):
 
1464
    def destroy_branch(self):
1287
1465
        """See BzrDir.create_branch."""
1288
 
        if name is not None:
1289
 
            raise errors.NoColocatedBranchSupport(self)
1290
1466
        self.transport.delete_tree('branch')
1291
1467
 
1292
1468
    def create_repository(self, shared=False):
1315
1491
    def destroy_workingtree_metadata(self):
1316
1492
        self.transport.delete_tree('checkout')
1317
1493
 
1318
 
    def find_branch_format(self, name=None):
 
1494
    def find_branch_format(self):
1319
1495
        """Find the branch 'format' for this bzrdir.
1320
1496
 
1321
1497
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1322
1498
        """
1323
1499
        from bzrlib.branch import BranchFormat
1324
 
        return BranchFormat.find_format(self, name=name)
 
1500
        return BranchFormat.find_format(self)
1325
1501
 
1326
1502
    def _get_mkdir_mode(self):
1327
1503
        """Figure out the mode to use when creating a bzrdir subdir."""
1329
1505
                                     lockable_files.TransportLock)
1330
1506
        return temp_control._dir_mode
1331
1507
 
1332
 
    def get_branch_reference(self, name=None):
 
1508
    def get_branch_reference(self):
1333
1509
        """See BzrDir.get_branch_reference()."""
1334
1510
        from bzrlib.branch import BranchFormat
1335
 
        format = BranchFormat.find_format(self, name=name)
1336
 
        return format.get_reference(self, name=name)
 
1511
        format = BranchFormat.find_format(self)
 
1512
        return format.get_reference(self)
1337
1513
 
1338
 
    def get_branch_transport(self, branch_format, name=None):
 
1514
    def get_branch_transport(self, branch_format):
1339
1515
        """See BzrDir.get_branch_transport()."""
1340
 
        if name is not None:
1341
 
            raise errors.NoColocatedBranchSupport(self)
1342
 
        # XXX: this shouldn't implicitly create the directory if it's just
1343
 
        # promising to get a transport -- mbp 20090727
1344
1516
        if branch_format is None:
1345
1517
            return self.transport.clone('branch')
1346
1518
        try:
1381
1553
            pass
1382
1554
        return self.transport.clone('checkout')
1383
1555
 
1384
 
    def has_workingtree(self):
1385
 
        """Tell if this bzrdir contains a working tree.
1386
 
 
1387
 
        This will still raise an exception if the bzrdir has a workingtree that
1388
 
        is remote & inaccessible.
1389
 
 
1390
 
        Note: if you're going to open the working tree, you should just go
1391
 
        ahead and try, and not ask permission first.
1392
 
        """
1393
 
        from bzrlib.workingtree import WorkingTreeFormat
1394
 
        try:
1395
 
            WorkingTreeFormat.find_format(self)
1396
 
        except errors.NoWorkingTree:
1397
 
            return False
1398
 
        return True
1399
 
 
1400
1556
    def needs_format_conversion(self, format=None):
1401
1557
        """See BzrDir.needs_format_conversion()."""
1402
1558
        if format is None:
1415
1571
                return True
1416
1572
        except errors.NoRepositoryPresent:
1417
1573
            pass
1418
 
        for branch in self.list_branches():
1419
 
            if not isinstance(branch._format,
 
1574
        try:
 
1575
            if not isinstance(self.open_branch()._format,
1420
1576
                              format.get_branch_format().__class__):
1421
1577
                # the branch needs an upgrade.
1422
1578
                return True
 
1579
        except errors.NotBranchError:
 
1580
            pass
1423
1581
        try:
1424
1582
            my_wt = self.open_workingtree(recommend_upgrade=False)
1425
1583
            if not isinstance(my_wt._format,
1430
1588
            pass
1431
1589
        return False
1432
1590
 
1433
 
    def open_branch(self, name=None, unsupported=False,
1434
 
                    ignore_fallbacks=False):
 
1591
    def open_branch(self, unsupported=False):
1435
1592
        """See BzrDir.open_branch."""
1436
 
        format = self.find_branch_format(name=name)
 
1593
        format = self.find_branch_format()
1437
1594
        self._check_supported(format, unsupported)
1438
 
        return format.open(self, name=name,
1439
 
            _found=True, ignore_fallbacks=ignore_fallbacks)
 
1595
        return format.open(self, _found=True)
1440
1596
 
1441
1597
    def open_repository(self, unsupported=False):
1442
1598
        """See BzrDir.open_repository."""
1456
1612
        return format.open(self, _found=True)
1457
1613
 
1458
1614
    def _get_config(self):
1459
 
        return config.TransportConfig(self.transport, 'control.conf')
1460
 
 
1461
 
 
1462
 
class BzrProber(controldir.Prober):
1463
 
    """Prober for formats that use a .bzr/ control directory."""
1464
 
 
1465
 
    _formats = {}
1466
 
    """The known .bzr formats."""
1467
 
 
1468
 
    @classmethod
1469
 
    def register_bzrdir_format(klass, format):
1470
 
        klass._formats[format.get_format_string()] = format
1471
 
 
1472
 
    @classmethod
1473
 
    def unregister_bzrdir_format(klass, format):
1474
 
        del klass._formats[format.get_format_string()]
1475
 
 
1476
 
    @classmethod
1477
 
    def probe_transport(klass, transport):
1478
 
        """Return the .bzrdir style format present in a directory."""
1479
 
        try:
1480
 
            format_string = transport.get_bytes(".bzr/branch-format")
1481
 
        except errors.NoSuchFile:
1482
 
            raise errors.NotBranchError(path=transport.base)
1483
 
        try:
1484
 
            return klass._formats[format_string]
1485
 
        except KeyError:
1486
 
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1487
 
 
1488
 
 
1489
 
controldir.ControlDirFormat.register_prober(BzrProber)
1490
 
 
1491
 
 
1492
 
class RemoteBzrProber(controldir.Prober):
1493
 
    """Prober for remote servers that provide a Bazaar smart server."""
1494
 
 
1495
 
    @classmethod
1496
 
    def probe_transport(klass, transport):
1497
 
        """Return a RemoteBzrDirFormat object if it looks possible."""
1498
 
        try:
1499
 
            medium = transport.get_smart_medium()
1500
 
        except (NotImplementedError, AttributeError,
1501
 
                errors.TransportNotPossible, errors.NoSmartMedium,
1502
 
                errors.SmartProtocolError):
1503
 
            # no smart server, so not a branch for this format type.
1504
 
            raise errors.NotBranchError(path=transport.base)
1505
 
        else:
1506
 
            # Decline to open it if the server doesn't support our required
1507
 
            # version (3) so that the VFS-based transport will do it.
1508
 
            if medium.should_probe():
1509
 
                try:
1510
 
                    server_version = medium.protocol_version()
1511
 
                except errors.SmartProtocolError:
1512
 
                    # Apparently there's no usable smart server there, even though
1513
 
                    # the medium supports the smart protocol.
1514
 
                    raise errors.NotBranchError(path=transport.base)
1515
 
                if server_version != '2':
1516
 
                    raise errors.NotBranchError(path=transport.base)
1517
 
            return RemoteBzrDirFormat()
1518
 
 
1519
 
 
1520
 
class BzrDirFormat(controldir.ControlDirFormat):
1521
 
    """ControlDirFormat base class for .bzr/ directories.
 
1615
        return config.BzrDirConfig(self.transport)
 
1616
 
 
1617
 
 
1618
class BzrDirFormat(object):
 
1619
    """An encapsulation of the initialization and open routines for a format.
 
1620
 
 
1621
    Formats provide three things:
 
1622
     * An initialization routine,
 
1623
     * a format string,
 
1624
     * an open routine.
1522
1625
 
1523
1626
    Formats are placed in a dict by their format string for reference
1524
1627
    during bzrdir opening. These should be subclasses of BzrDirFormat
1529
1632
    object will be created every system load.
1530
1633
    """
1531
1634
 
 
1635
    _default_format = None
 
1636
    """The default format used for new .bzr dirs."""
 
1637
 
 
1638
    _formats = {}
 
1639
    """The known formats."""
 
1640
 
 
1641
    _control_formats = []
 
1642
    """The registered control formats - .bzr, ....
 
1643
 
 
1644
    This is a list of BzrDirFormat objects.
 
1645
    """
 
1646
 
 
1647
    _control_server_formats = []
 
1648
    """The registered control server formats, e.g. RemoteBzrDirs.
 
1649
 
 
1650
    This is a list of BzrDirFormat objects.
 
1651
    """
 
1652
 
1532
1653
    _lock_file_name = 'branch-lock'
1533
1654
 
1534
1655
    # _lock_class must be set in subclasses to the lock type, typ.
1535
1656
    # TransportLock or LockDir
1536
1657
 
 
1658
    @classmethod
 
1659
    def find_format(klass, transport, _server_formats=True):
 
1660
        """Return the format present at transport."""
 
1661
        if _server_formats:
 
1662
            formats = klass._control_server_formats + klass._control_formats
 
1663
        else:
 
1664
            formats = klass._control_formats
 
1665
        for format in formats:
 
1666
            try:
 
1667
                return format.probe_transport(transport)
 
1668
            except errors.NotBranchError:
 
1669
                # this format does not find a control dir here.
 
1670
                pass
 
1671
        raise errors.NotBranchError(path=transport.base)
 
1672
 
 
1673
    @classmethod
 
1674
    def probe_transport(klass, transport):
 
1675
        """Return the .bzrdir style format present in a directory."""
 
1676
        try:
 
1677
            format_string = transport.get(".bzr/branch-format").read()
 
1678
        except errors.NoSuchFile:
 
1679
            raise errors.NotBranchError(path=transport.base)
 
1680
 
 
1681
        try:
 
1682
            return klass._formats[format_string]
 
1683
        except KeyError:
 
1684
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
 
1685
 
 
1686
    @classmethod
 
1687
    def get_default_format(klass):
 
1688
        """Return the current default format."""
 
1689
        return klass._default_format
 
1690
 
1537
1691
    def get_format_string(self):
1538
1692
        """Return the ASCII format string that identifies this format."""
1539
1693
        raise NotImplementedError(self.get_format_string)
1540
1694
 
 
1695
    def get_format_description(self):
 
1696
        """Return the short description for this format."""
 
1697
        raise NotImplementedError(self.get_format_description)
 
1698
 
 
1699
    def get_converter(self, format=None):
 
1700
        """Return the converter to use to convert bzrdirs needing converts.
 
1701
 
 
1702
        This returns a bzrlib.bzrdir.Converter object.
 
1703
 
 
1704
        This should return the best upgrader to step this format towards the
 
1705
        current default format. In the case of plugins we can/should provide
 
1706
        some means for them to extend the range of returnable converters.
 
1707
 
 
1708
        :param format: Optional format to override the default format of the
 
1709
                       library.
 
1710
        """
 
1711
        raise NotImplementedError(self.get_converter)
 
1712
 
 
1713
    def initialize(self, url, possible_transports=None):
 
1714
        """Create a bzr control dir at this url and return an opened copy.
 
1715
 
 
1716
        Subclasses should typically override initialize_on_transport
 
1717
        instead of this method.
 
1718
        """
 
1719
        return self.initialize_on_transport(get_transport(url,
 
1720
                                                          possible_transports))
 
1721
 
1541
1722
    def initialize_on_transport(self, transport):
1542
1723
        """Initialize a new bzrdir in the base directory of a Transport."""
1543
1724
        try:
1556
1737
            self._supply_sub_formats_to(remote_format)
1557
1738
            return remote_format.initialize_on_transport(transport)
1558
1739
 
1559
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1560
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
1561
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1562
 
        shared_repo=False, vfs_only=False):
1563
 
        """Create this format on transport.
1564
 
 
1565
 
        The directory to initialize will be created.
1566
 
 
1567
 
        :param force_new_repo: Do not use a shared repository for the target,
1568
 
                               even if one is available.
1569
 
        :param create_prefix: Create any missing directories leading up to
1570
 
            to_transport.
1571
 
        :param use_existing_dir: Use an existing directory if one exists.
1572
 
        :param stacked_on: A url to stack any created branch on, None to follow
1573
 
            any target stacking policy.
1574
 
        :param stack_on_pwd: If stack_on is relative, the location it is
1575
 
            relative to.
1576
 
        :param repo_format_name: If non-None, a repository will be
1577
 
            made-or-found. Should none be found, or if force_new_repo is True
1578
 
            the repo_format_name is used to select the format of repository to
1579
 
            create.
1580
 
        :param make_working_trees: Control the setting of make_working_trees
1581
 
            for a new shared repository when one is made. None to use whatever
1582
 
            default the format has.
1583
 
        :param shared_repo: Control whether made repositories are shared or
1584
 
            not.
1585
 
        :param vfs_only: If True do not attempt to use a smart server
1586
 
        :return: repo, bzrdir, require_stacking, repository_policy. repo is
1587
 
            None if none was created or found, bzrdir is always valid.
1588
 
            require_stacking is the result of examining the stacked_on
1589
 
            parameter and any stacking policy found for the target.
1590
 
        """
1591
 
        if not vfs_only:
1592
 
            # Try to hand off to a smart server 
1593
 
            try:
1594
 
                client_medium = transport.get_smart_medium()
1595
 
            except errors.NoSmartMedium:
1596
 
                pass
1597
 
            else:
1598
 
                # TODO: lookup the local format from a server hint.
1599
 
                remote_dir_format = RemoteBzrDirFormat()
1600
 
                remote_dir_format._network_name = self.network_name()
1601
 
                self._supply_sub_formats_to(remote_dir_format)
1602
 
                return remote_dir_format.initialize_on_transport_ex(transport,
1603
 
                    use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1604
 
                    force_new_repo=force_new_repo, stacked_on=stacked_on,
1605
 
                    stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1606
 
                    make_working_trees=make_working_trees, shared_repo=shared_repo)
1607
 
        # XXX: Refactor the create_prefix/no_create_prefix code into a
1608
 
        #      common helper function
1609
 
        # The destination may not exist - if so make it according to policy.
1610
 
        def make_directory(transport):
1611
 
            transport.mkdir('.')
1612
 
            return transport
1613
 
        def redirected(transport, e, redirection_notice):
1614
 
            note(redirection_notice)
1615
 
            return transport._redirected_to(e.source, e.target)
1616
 
        try:
1617
 
            transport = do_catching_redirections(make_directory, transport,
1618
 
                redirected)
1619
 
        except errors.FileExists:
1620
 
            if not use_existing_dir:
1621
 
                raise
1622
 
        except errors.NoSuchFile:
1623
 
            if not create_prefix:
1624
 
                raise
1625
 
            transport.create_prefix()
1626
 
 
1627
 
        require_stacking = (stacked_on is not None)
1628
 
        # Now the target directory exists, but doesn't have a .bzr
1629
 
        # directory. So we need to create it, along with any work to create
1630
 
        # all of the dependent branches, etc.
1631
 
 
1632
 
        result = self.initialize_on_transport(transport)
1633
 
        if repo_format_name:
1634
 
            try:
1635
 
                # use a custom format
1636
 
                result._format.repository_format = \
1637
 
                    repository.network_format_registry.get(repo_format_name)
1638
 
            except AttributeError:
1639
 
                # The format didn't permit it to be set.
1640
 
                pass
1641
 
            # A repository is desired, either in-place or shared.
1642
 
            repository_policy = result.determine_repository_policy(
1643
 
                force_new_repo, stacked_on, stack_on_pwd,
1644
 
                require_stacking=require_stacking)
1645
 
            result_repo, is_new_repo = repository_policy.acquire_repository(
1646
 
                make_working_trees, shared_repo)
1647
 
            if not require_stacking and repository_policy._require_stacking:
1648
 
                require_stacking = True
1649
 
                result._format.require_stacking()
1650
 
            result_repo.lock_write()
1651
 
        else:
1652
 
            result_repo = None
1653
 
            repository_policy = None
1654
 
        return result_repo, result, require_stacking, repository_policy
1655
 
 
1656
1740
    def _initialize_on_transport_vfs(self, transport):
1657
1741
        """Initialize a new bzrdir using VFS calls.
1658
1742
 
1691
1775
            control_files.unlock()
1692
1776
        return self.open(transport, _found=True)
1693
1777
 
 
1778
    def is_supported(self):
 
1779
        """Is this format supported?
 
1780
 
 
1781
        Supported formats must be initializable and openable.
 
1782
        Unsupported formats may not support initialization or committing or
 
1783
        some other features depending on the reason for not being supported.
 
1784
        """
 
1785
        return True
 
1786
 
 
1787
    def network_name(self):
 
1788
        """A simple byte string uniquely identifying this format for RPC calls.
 
1789
 
 
1790
        Bzr control formats use thir disk format string to identify the format
 
1791
        over the wire. Its possible that other control formats have more
 
1792
        complex detection requirements, so we permit them to use any unique and
 
1793
        immutable string they desire.
 
1794
        """
 
1795
        raise NotImplementedError(self.network_name)
 
1796
 
 
1797
    def same_model(self, target_format):
 
1798
        return (self.repository_format.rich_root_data ==
 
1799
            target_format.rich_root_data)
 
1800
 
 
1801
    @classmethod
 
1802
    def known_formats(klass):
 
1803
        """Return all the known formats.
 
1804
 
 
1805
        Concrete formats should override _known_formats.
 
1806
        """
 
1807
        # There is double indirection here to make sure that control
 
1808
        # formats used by more than one dir format will only be probed
 
1809
        # once. This can otherwise be quite expensive for remote connections.
 
1810
        result = set()
 
1811
        for format in klass._control_formats:
 
1812
            result.update(format._known_formats())
 
1813
        return result
 
1814
 
 
1815
    @classmethod
 
1816
    def _known_formats(klass):
 
1817
        """Return the known format instances for this control format."""
 
1818
        return set(klass._formats.values())
 
1819
 
1694
1820
    def open(self, transport, _found=False):
1695
1821
        """Return an instance of this format for the dir transport points at.
1696
1822
 
1697
1823
        _found is a private parameter, do not use it.
1698
1824
        """
1699
1825
        if not _found:
1700
 
            found_format = controldir.ControlDirFormat.find_format(transport)
 
1826
            found_format = BzrDirFormat.find_format(transport)
1701
1827
            if not isinstance(found_format, self.__class__):
1702
1828
                raise AssertionError("%s was asked to open %s, but it seems to need "
1703
1829
                        "format %s"
1717
1843
 
1718
1844
    @classmethod
1719
1845
    def register_format(klass, format):
1720
 
        BzrProber.register_bzrdir_format(format)
 
1846
        klass._formats[format.get_format_string()] = format
1721
1847
        # bzr native formats have a network name of their format string.
1722
1848
        network_format_registry.register(format.get_format_string(), format.__class__)
1723
 
        controldir.ControlDirFormat.register_format(format)
 
1849
 
 
1850
    @classmethod
 
1851
    def register_control_format(klass, format):
 
1852
        """Register a format that does not use '.bzr' for its control dir.
 
1853
 
 
1854
        TODO: This should be pulled up into a 'ControlDirFormat' base class
 
1855
        which BzrDirFormat can inherit from, and renamed to register_format
 
1856
        there. It has been done without that for now for simplicity of
 
1857
        implementation.
 
1858
        """
 
1859
        klass._control_formats.append(format)
 
1860
 
 
1861
    @classmethod
 
1862
    def register_control_server_format(klass, format):
 
1863
        """Register a control format for client-server environments.
 
1864
 
 
1865
        These formats will be tried before ones registered with
 
1866
        register_control_format.  This gives implementations that decide to the
 
1867
        chance to grab it before anything looks at the contents of the format
 
1868
        file.
 
1869
        """
 
1870
        klass._control_server_formats.append(format)
 
1871
 
 
1872
    @classmethod
 
1873
    def _set_default_format(klass, format):
 
1874
        """Set default format (for testing behavior of defaults only)"""
 
1875
        klass._default_format = format
 
1876
 
 
1877
    def __str__(self):
 
1878
        # Trim the newline
 
1879
        return self.get_format_description().rstrip()
1724
1880
 
1725
1881
    def _supply_sub_formats_to(self, other_format):
1726
1882
        """Give other_format the same values for sub formats as this has.
1736
1892
 
1737
1893
    @classmethod
1738
1894
    def unregister_format(klass, format):
1739
 
        BzrProber.unregister_bzrdir_format(format)
1740
 
        controldir.ControlDirFormat.unregister_format(format)
1741
 
        network_format_registry.remove(format.get_format_string())
 
1895
        del klass._formats[format.get_format_string()]
 
1896
 
 
1897
    @classmethod
 
1898
    def unregister_control_format(klass, format):
 
1899
        klass._control_formats.remove(format)
1742
1900
 
1743
1901
 
1744
1902
class BzrDirFormat4(BzrDirFormat):
1796
1954
    repository_format = property(__return_repository_format)
1797
1955
 
1798
1956
 
1799
 
class BzrDirFormatAllInOne(BzrDirFormat):
1800
 
    """Common class for formats before meta-dirs."""
1801
 
 
1802
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1803
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
1804
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1805
 
        shared_repo=False):
1806
 
        """See BzrDirFormat.initialize_on_transport_ex."""
1807
 
        require_stacking = (stacked_on is not None)
1808
 
        # Format 5 cannot stack, but we've been asked to - actually init
1809
 
        # a Meta1Dir
1810
 
        if require_stacking:
1811
 
            format = BzrDirMetaFormat1()
1812
 
            return format.initialize_on_transport_ex(transport,
1813
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1814
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
1815
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1816
 
                make_working_trees=make_working_trees, shared_repo=shared_repo)
1817
 
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
1818
 
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1819
 
            force_new_repo=force_new_repo, stacked_on=stacked_on,
1820
 
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1821
 
            make_working_trees=make_working_trees, shared_repo=shared_repo)
1822
 
 
1823
 
 
1824
 
class BzrDirFormat5(BzrDirFormatAllInOne):
 
1957
class BzrDirFormat5(BzrDirFormat):
1825
1958
    """Bzr control format 5.
1826
1959
 
1827
1960
    This format is a combined format for working tree, branch and repository.
1882
2015
    repository_format = property(__return_repository_format)
1883
2016
 
1884
2017
 
1885
 
class BzrDirFormat6(BzrDirFormatAllInOne):
 
2018
class BzrDirFormat6(BzrDirFormat):
1886
2019
    """Bzr control format 6.
1887
2020
 
1888
2021
    This format is a combined format for working tree, branch and repository.
1981
2114
    def set_branch_format(self, format):
1982
2115
        self._branch_format = format
1983
2116
 
1984
 
    def require_stacking(self, stack_on=None, possible_transports=None,
1985
 
            _skip_repo=False):
1986
 
        """We have a request to stack, try to ensure the formats support it.
1987
 
 
1988
 
        :param stack_on: If supplied, it is the URL to a branch that we want to
1989
 
            stack on. Check to see if that format supports stacking before
1990
 
            forcing an upgrade.
1991
 
        """
1992
 
        # Stacking is desired. requested by the target, but does the place it
1993
 
        # points at support stacking? If it doesn't then we should
1994
 
        # not implicitly upgrade. We check this here.
1995
 
        new_repo_format = None
1996
 
        new_branch_format = None
1997
 
 
1998
 
        # a bit of state for get_target_branch so that we don't try to open it
1999
 
        # 2 times, for both repo *and* branch
2000
 
        target = [None, False, None] # target_branch, checked, upgrade anyway
2001
 
        def get_target_branch():
2002
 
            if target[1]:
2003
 
                # We've checked, don't check again
2004
 
                return target
2005
 
            if stack_on is None:
2006
 
                # No target format, that means we want to force upgrading
2007
 
                target[:] = [None, True, True]
2008
 
                return target
2009
 
            try:
2010
 
                target_dir = BzrDir.open(stack_on,
2011
 
                    possible_transports=possible_transports)
2012
 
            except errors.NotBranchError:
2013
 
                # Nothing there, don't change formats
2014
 
                target[:] = [None, True, False]
2015
 
                return target
2016
 
            except errors.JailBreak:
2017
 
                # JailBreak, JFDI and upgrade anyway
2018
 
                target[:] = [None, True, True]
2019
 
                return target
2020
 
            try:
2021
 
                target_branch = target_dir.open_branch()
2022
 
            except errors.NotBranchError:
2023
 
                # No branch, don't upgrade formats
2024
 
                target[:] = [None, True, False]
2025
 
                return target
2026
 
            target[:] = [target_branch, True, False]
2027
 
            return target
2028
 
 
2029
 
        if (not _skip_repo and
2030
 
                 not self.repository_format.supports_external_lookups):
2031
 
            # We need to upgrade the Repository.
2032
 
            target_branch, _, do_upgrade = get_target_branch()
2033
 
            if target_branch is None:
2034
 
                # We don't have a target branch, should we upgrade anyway?
2035
 
                if do_upgrade:
2036
 
                    # stack_on is inaccessible, JFDI.
2037
 
                    # TODO: bad monkey, hard-coded formats...
2038
 
                    if self.repository_format.rich_root_data:
2039
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2040
 
                    else:
2041
 
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
2042
 
            else:
2043
 
                # If the target already supports stacking, then we know the
2044
 
                # project is already able to use stacking, so auto-upgrade
2045
 
                # for them
2046
 
                new_repo_format = target_branch.repository._format
2047
 
                if not new_repo_format.supports_external_lookups:
2048
 
                    # target doesn't, source doesn't, so don't auto upgrade
2049
 
                    # repo
2050
 
                    new_repo_format = None
2051
 
            if new_repo_format is not None:
2052
 
                self.repository_format = new_repo_format
2053
 
                note('Source repository format does not support stacking,'
2054
 
                     ' using format:\n  %s',
2055
 
                     new_repo_format.get_format_description())
2056
 
 
 
2117
    def require_stacking(self):
2057
2118
        if not self.get_branch_format().supports_stacking():
2058
 
            # We just checked the repo, now lets check if we need to
2059
 
            # upgrade the branch format
2060
 
            target_branch, _, do_upgrade = get_target_branch()
2061
 
            if target_branch is None:
2062
 
                if do_upgrade:
2063
 
                    # TODO: bad monkey, hard-coded formats...
2064
 
                    new_branch_format = branch.BzrBranchFormat7()
 
2119
            # We need to make a stacked branch, but the default format for the
 
2120
            # target doesn't support stacking.  So force a branch that *can*
 
2121
            # support stacking.
 
2122
            from bzrlib.branch import BzrBranchFormat7
 
2123
            branch_format = BzrBranchFormat7()
 
2124
            self.set_branch_format(branch_format)
 
2125
            mutter("using %r for stacking" % (branch_format,))
 
2126
            from bzrlib.repofmt import pack_repo
 
2127
            if self.repository_format.rich_root_data:
 
2128
                bzrdir_format_name = '1.6.1-rich-root'
 
2129
                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2065
2130
            else:
2066
 
                new_branch_format = target_branch._format
2067
 
                if not new_branch_format.supports_stacking():
2068
 
                    new_branch_format = None
2069
 
            if new_branch_format is not None:
2070
 
                # Does support stacking, use its format.
2071
 
                self.set_branch_format(new_branch_format)
2072
 
                note('Source branch format does not support stacking,'
2073
 
                     ' using format:\n  %s',
2074
 
                     new_branch_format.get_format_description())
 
2131
                bzrdir_format_name = '1.6'
 
2132
                repo_format = pack_repo.RepositoryFormatKnitPack5()
 
2133
            note('Source format does not support stacking, using format:'
 
2134
                 ' \'%s\'\n  %s\n',
 
2135
                 bzrdir_format_name, repo_format.get_format_description())
 
2136
            self.repository_format = repo_format
2075
2137
 
2076
2138
    def get_converter(self, format=None):
2077
2139
        """See BzrDirFormat.get_converter()."""
2095
2157
 
2096
2158
    def _open(self, transport):
2097
2159
        """See BzrDirFormat._open."""
2098
 
        # Create a new format instance because otherwise initialisation of new
2099
 
        # metadirs share the global default format object leading to alias
2100
 
        # problems.
2101
 
        format = BzrDirMetaFormat1()
2102
 
        self._supply_sub_formats_to(format)
2103
 
        return BzrDirMeta1(transport, format)
 
2160
        return BzrDirMeta1(transport, self)
2104
2161
 
2105
2162
    def __return_repository_format(self):
2106
2163
        """Circular import protection."""
2156
2213
"""
2157
2214
 
2158
2215
 
 
2216
# Register bzr control format
 
2217
BzrDirFormat.register_control_format(BzrDirFormat)
 
2218
 
2159
2219
# Register bzr formats
2160
2220
BzrDirFormat.register_format(BzrDirFormat4())
2161
2221
BzrDirFormat.register_format(BzrDirFormat5())
2162
2222
BzrDirFormat.register_format(BzrDirFormat6())
2163
2223
__default_format = BzrDirMetaFormat1()
2164
2224
BzrDirFormat.register_format(__default_format)
2165
 
controldir.ControlDirFormat._default_format = __default_format
 
2225
BzrDirFormat._default_format = __default_format
2166
2226
 
2167
2227
 
2168
2228
class Converter(object):
2194
2254
    def convert(self, to_convert, pb):
2195
2255
        """See Converter.convert()."""
2196
2256
        self.bzrdir = to_convert
2197
 
        if pb is not None:
2198
 
            warnings.warn("pb parameter to convert() is deprecated")
2199
 
        self.pb = ui.ui_factory.nested_progress_bar()
2200
 
        try:
2201
 
            ui.ui_factory.note('starting upgrade from format 4 to 5')
2202
 
            if isinstance(self.bzrdir.transport, local.LocalTransport):
2203
 
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2204
 
            self._convert_to_weaves()
2205
 
            return BzrDir.open(self.bzrdir.user_url)
2206
 
        finally:
2207
 
            self.pb.finished()
 
2257
        self.pb = pb
 
2258
        self.pb.note('starting upgrade from format 4 to 5')
 
2259
        if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2260
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2261
        self._convert_to_weaves()
 
2262
        return BzrDir.open(self.bzrdir.root_transport.base)
2208
2263
 
2209
2264
    def _convert_to_weaves(self):
2210
 
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
 
2265
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2211
2266
        try:
2212
2267
            # TODO permissions
2213
2268
            stat = self.bzrdir.transport.stat('weaves')
2241
2296
        self.pb.clear()
2242
2297
        self._write_all_weaves()
2243
2298
        self._write_all_revs()
2244
 
        ui.ui_factory.note('upgraded to weaves:')
2245
 
        ui.ui_factory.note('  %6d revisions and inventories' % len(self.revisions))
2246
 
        ui.ui_factory.note('  %6d revisions not present' % len(self.absent_revisions))
2247
 
        ui.ui_factory.note('  %6d texts' % self.text_count)
 
2299
        self.pb.note('upgraded to weaves:')
 
2300
        self.pb.note('  %6d revisions and inventories', len(self.revisions))
 
2301
        self.pb.note('  %6d revisions not present', len(self.absent_revisions))
 
2302
        self.pb.note('  %6d texts', self.text_count)
2248
2303
        self._cleanup_spare_files_after_format4()
2249
2304
        self.branch._transport.put_bytes(
2250
2305
            'branch-format',
2318
2373
                       len(self.known_revisions))
2319
2374
        if not self.branch.repository.has_revision(rev_id):
2320
2375
            self.pb.clear()
2321
 
            ui.ui_factory.note('revision {%s} not present in branch; '
2322
 
                         'will be converted as a ghost' %
 
2376
            self.pb.note('revision {%s} not present in branch; '
 
2377
                         'will be converted as a ghost',
2323
2378
                         rev_id)
2324
2379
            self.absent_revisions.add(rev_id)
2325
2380
        else:
2330
2385
            self.revisions[rev_id] = rev
2331
2386
 
2332
2387
    def _load_old_inventory(self, rev_id):
2333
 
        f = self.branch.repository.inventory_store.get(rev_id)
2334
 
        try:
2335
 
            old_inv_xml = f.read()
2336
 
        finally:
2337
 
            f.close()
 
2388
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2338
2389
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2339
2390
        inv.revision_id = rev_id
2340
2391
        rev = self.revisions[rev_id]
2396
2447
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2397
2448
            in heads)
2398
2449
        self.snapshot_ie(previous_entries, ie, w, rev_id)
 
2450
        del ie.text_id
 
2451
 
 
2452
    @symbol_versioning.deprecated_method(symbol_versioning.one_one)
 
2453
    def get_parents(self, revision_ids):
 
2454
        for revision_id in revision_ids:
 
2455
            yield self.revisions[revision_id].parent_ids
2399
2456
 
2400
2457
    def get_parent_map(self, revision_ids):
2401
 
        """See graph.StackedParentsProvider.get_parent_map"""
 
2458
        """See graph._StackedParentsProvider.get_parent_map"""
2402
2459
        return dict((revision_id, self.revisions[revision_id])
2403
2460
                    for revision_id in revision_ids
2404
2461
                     if revision_id in self.revisions)
2417
2474
                ie.revision = previous_ie.revision
2418
2475
                return
2419
2476
        if ie.has_text():
2420
 
            f = self.branch.repository._text_store.get(ie.text_id)
2421
 
            try:
2422
 
                file_lines = f.readlines()
2423
 
            finally:
2424
 
                f.close()
 
2477
            text = self.branch.repository._text_store.get(ie.text_id)
 
2478
            file_lines = text.readlines()
2425
2479
            w.add_lines(rev_id, previous_revisions, file_lines)
2426
2480
            self.text_count += 1
2427
2481
        else:
2457
2511
    def convert(self, to_convert, pb):
2458
2512
        """See Converter.convert()."""
2459
2513
        self.bzrdir = to_convert
2460
 
        pb = ui.ui_factory.nested_progress_bar()
2461
 
        try:
2462
 
            ui.ui_factory.note('starting upgrade from format 5 to 6')
2463
 
            self._convert_to_prefixed()
2464
 
            return BzrDir.open(self.bzrdir.user_url)
2465
 
        finally:
2466
 
            pb.finished()
 
2514
        self.pb = pb
 
2515
        self.pb.note('starting upgrade from format 5 to 6')
 
2516
        self._convert_to_prefixed()
 
2517
        return BzrDir.open(self.bzrdir.root_transport.base)
2467
2518
 
2468
2519
    def _convert_to_prefixed(self):
2469
2520
        from bzrlib.store import TransportStore
2470
2521
        self.bzrdir.transport.delete('branch-format')
2471
2522
        for store_name in ["weaves", "revision-store"]:
2472
 
            ui.ui_factory.note("adding prefixes to %s" % store_name)
 
2523
            self.pb.note("adding prefixes to %s" % store_name)
2473
2524
            store_transport = self.bzrdir.transport.clone(store_name)
2474
2525
            store = TransportStore(store_transport, prefixed=True)
2475
2526
            for urlfilename in store_transport.list_dir('.'):
2502
2553
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2503
2554
        from bzrlib.branch import BzrBranchFormat5
2504
2555
        self.bzrdir = to_convert
2505
 
        self.pb = ui.ui_factory.nested_progress_bar()
 
2556
        self.pb = pb
2506
2557
        self.count = 0
2507
2558
        self.total = 20 # the steps we know about
2508
2559
        self.garbage_inventories = []
2509
2560
        self.dir_mode = self.bzrdir._get_dir_mode()
2510
2561
        self.file_mode = self.bzrdir._get_file_mode()
2511
2562
 
2512
 
        ui.ui_factory.note('starting upgrade from format 6 to metadir')
 
2563
        self.pb.note('starting upgrade from format 6 to metadir')
2513
2564
        self.bzrdir.transport.put_bytes(
2514
2565
                'branch-format',
2515
2566
                "Converting to format 6",
2565
2616
        else:
2566
2617
            has_checkout = True
2567
2618
        if not has_checkout:
2568
 
            ui.ui_factory.note('No working tree.')
 
2619
            self.pb.note('No working tree.')
2569
2620
            # If some checkout files are there, we may as well get rid of them.
2570
2621
            for name, mandatory in checkout_files:
2571
2622
                if name in bzrcontents:
2588
2639
            'branch-format',
2589
2640
            BzrDirMetaFormat1().get_format_string(),
2590
2641
            mode=self.file_mode)
2591
 
        self.pb.finished()
2592
 
        return BzrDir.open(self.bzrdir.user_url)
 
2642
        return BzrDir.open(self.bzrdir.root_transport.base)
2593
2643
 
2594
2644
    def make_lock(self, name):
2595
2645
        """Make a lock for the new control dir name."""
2630
2680
    def convert(self, to_convert, pb):
2631
2681
        """See Converter.convert()."""
2632
2682
        self.bzrdir = to_convert
2633
 
        self.pb = ui.ui_factory.nested_progress_bar()
 
2683
        self.pb = pb
2634
2684
        self.count = 0
2635
2685
        self.total = 1
2636
2686
        self.step('checking repository format')
2641
2691
        else:
2642
2692
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
2643
2693
                from bzrlib.repository import CopyConverter
2644
 
                ui.ui_factory.note('starting repository conversion')
 
2694
                self.pb.note('starting repository conversion')
2645
2695
                converter = CopyConverter(self.target_format.repository_format)
2646
2696
                converter.convert(repo, pb)
2647
 
        for branch in self.bzrdir.list_branches():
 
2697
        try:
 
2698
            branch = self.bzrdir.open_branch()
 
2699
        except errors.NotBranchError:
 
2700
            pass
 
2701
        else:
2648
2702
            # TODO: conversions of Branch and Tree should be done by
2649
2703
            # InterXFormat lookups/some sort of registry.
2650
2704
            # Avoid circular imports
2654
2708
            while old != new:
2655
2709
                if (old == _mod_branch.BzrBranchFormat5 and
2656
2710
                    new in (_mod_branch.BzrBranchFormat6,
2657
 
                        _mod_branch.BzrBranchFormat7,
2658
 
                        _mod_branch.BzrBranchFormat8)):
 
2711
                        _mod_branch.BzrBranchFormat7)):
2659
2712
                    branch_converter = _mod_branch.Converter5to6()
2660
2713
                elif (old == _mod_branch.BzrBranchFormat6 and
2661
 
                    new in (_mod_branch.BzrBranchFormat7,
2662
 
                            _mod_branch.BzrBranchFormat8)):
 
2714
                    new == _mod_branch.BzrBranchFormat7):
2663
2715
                    branch_converter = _mod_branch.Converter6to7()
2664
 
                elif (old == _mod_branch.BzrBranchFormat7 and
2665
 
                      new is _mod_branch.BzrBranchFormat8):
2666
 
                    branch_converter = _mod_branch.Converter7to8()
2667
2716
                else:
2668
 
                    raise errors.BadConversionTarget("No converter", new,
2669
 
                        branch._format)
 
2717
                    raise errors.BadConversionTarget("No converter", new)
2670
2718
                branch_converter.convert(branch)
2671
2719
                branch = self.bzrdir.open_branch()
2672
2720
                old = branch._format.__class__
2687
2735
                isinstance(self.target_format.workingtree_format,
2688
2736
                    workingtree_4.WorkingTreeFormat5)):
2689
2737
                workingtree_4.Converter4to5().convert(tree)
2690
 
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2691
 
                not isinstance(tree, workingtree_4.WorkingTree6) and
2692
 
                isinstance(self.target_format.workingtree_format,
2693
 
                    workingtree_4.WorkingTreeFormat6)):
2694
 
                workingtree_4.Converter4or5to6().convert(tree)
2695
 
        self.pb.finished()
2696
2738
        return to_convert
2697
2739
 
2698
2740
 
2699
 
# This is not in remote.py because it's relatively small, and needs to be
2700
 
# registered. Putting it in remote.py creates a circular import problem.
 
2741
# This is not in remote.py because it's small, and needs to be registered.
 
2742
# Putting it in remote.py creates a circular import problem.
2701
2743
# we can make it a lazy object if the control formats is turned into something
2702
2744
# like a registry.
2703
2745
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2705
2747
 
2706
2748
    def __init__(self):
2707
2749
        BzrDirMetaFormat1.__init__(self)
2708
 
        # XXX: It's a bit ugly that the network name is here, because we'd
2709
 
        # like to believe that format objects are stateless or at least
2710
 
        # immutable,  However, we do at least avoid mutating the name after
2711
 
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
2712
2750
        self._network_name = None
2713
2751
 
2714
 
    def __repr__(self):
2715
 
        return "%s(_network_name=%r)" % (self.__class__.__name__,
2716
 
            self._network_name)
2717
 
 
2718
2752
    def get_format_description(self):
2719
 
        if self._network_name:
2720
 
            real_format = network_format_registry.get(self._network_name)
2721
 
            return 'Remote: ' + real_format.get_format_description()
2722
2753
        return 'bzr remote bzrdir'
2723
2754
 
2724
2755
    def get_format_string(self):
2730
2761
        else:
2731
2762
            raise AssertionError("No network name set.")
2732
2763
 
 
2764
    @classmethod
 
2765
    def probe_transport(klass, transport):
 
2766
        """Return a RemoteBzrDirFormat object if it looks possible."""
 
2767
        try:
 
2768
            medium = transport.get_smart_medium()
 
2769
        except (NotImplementedError, AttributeError,
 
2770
                errors.TransportNotPossible, errors.NoSmartMedium,
 
2771
                errors.SmartProtocolError):
 
2772
            # no smart server, so not a branch for this format type.
 
2773
            raise errors.NotBranchError(path=transport.base)
 
2774
        else:
 
2775
            # Decline to open it if the server doesn't support our required
 
2776
            # version (3) so that the VFS-based transport will do it.
 
2777
            if medium.should_probe():
 
2778
                try:
 
2779
                    server_version = medium.protocol_version()
 
2780
                except errors.SmartProtocolError:
 
2781
                    # Apparently there's no usable smart server there, even though
 
2782
                    # the medium supports the smart protocol.
 
2783
                    raise errors.NotBranchError(path=transport.base)
 
2784
                if server_version != '2':
 
2785
                    raise errors.NotBranchError(path=transport.base)
 
2786
            return klass()
 
2787
 
2733
2788
    def initialize_on_transport(self, transport):
2734
2789
        try:
2735
2790
            # hand off the request to the smart server
2740
2795
            return local_dir_format.initialize_on_transport(transport)
2741
2796
        client = _SmartClient(client_medium)
2742
2797
        path = client.remote_path_from_transport(transport)
2743
 
        try:
2744
 
            response = client.call('BzrDirFormat.initialize', path)
2745
 
        except errors.ErrorFromSmartServer, err:
2746
 
            remote._translate_error(err, path=path)
 
2798
        response = client.call('BzrDirFormat.initialize', path)
2747
2799
        if response[0] != 'ok':
2748
2800
            raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2749
2801
        format = RemoteBzrDirFormat()
2750
2802
        self._supply_sub_formats_to(format)
2751
2803
        return remote.RemoteBzrDir(transport, format)
2752
2804
 
2753
 
    def parse_NoneTrueFalse(self, arg):
2754
 
        if not arg:
2755
 
            return None
2756
 
        if arg == 'False':
2757
 
            return False
2758
 
        if arg == 'True':
2759
 
            return True
2760
 
        raise AssertionError("invalid arg %r" % arg)
2761
 
 
2762
 
    def _serialize_NoneTrueFalse(self, arg):
2763
 
        if arg is False:
2764
 
            return 'False'
2765
 
        if arg:
2766
 
            return 'True'
2767
 
        return ''
2768
 
 
2769
 
    def _serialize_NoneString(self, arg):
2770
 
        return arg or ''
2771
 
 
2772
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2773
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
2774
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2775
 
        shared_repo=False):
2776
 
        try:
2777
 
            # hand off the request to the smart server
2778
 
            client_medium = transport.get_smart_medium()
2779
 
        except errors.NoSmartMedium:
2780
 
            do_vfs = True
2781
 
        else:
2782
 
            # Decline to open it if the server doesn't support our required
2783
 
            # version (3) so that the VFS-based transport will do it.
2784
 
            if client_medium.should_probe():
2785
 
                try:
2786
 
                    server_version = client_medium.protocol_version()
2787
 
                    if server_version != '2':
2788
 
                        do_vfs = True
2789
 
                    else:
2790
 
                        do_vfs = False
2791
 
                except errors.SmartProtocolError:
2792
 
                    # Apparently there's no usable smart server there, even though
2793
 
                    # the medium supports the smart protocol.
2794
 
                    do_vfs = True
2795
 
            else:
2796
 
                do_vfs = False
2797
 
        if not do_vfs:
2798
 
            client = _SmartClient(client_medium)
2799
 
            path = client.remote_path_from_transport(transport)
2800
 
            if client_medium._is_remote_before((1, 16)):
2801
 
                do_vfs = True
2802
 
        if do_vfs:
2803
 
            # TODO: lookup the local format from a server hint.
2804
 
            local_dir_format = BzrDirMetaFormat1()
2805
 
            self._supply_sub_formats_to(local_dir_format)
2806
 
            return local_dir_format.initialize_on_transport_ex(transport,
2807
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2808
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
2809
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2810
 
                make_working_trees=make_working_trees, shared_repo=shared_repo,
2811
 
                vfs_only=True)
2812
 
        return self._initialize_on_transport_ex_rpc(client, path, transport,
2813
 
            use_existing_dir, create_prefix, force_new_repo, stacked_on,
2814
 
            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2815
 
 
2816
 
    def _initialize_on_transport_ex_rpc(self, client, path, transport,
2817
 
        use_existing_dir, create_prefix, force_new_repo, stacked_on,
2818
 
        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2819
 
        args = []
2820
 
        args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2821
 
        args.append(self._serialize_NoneTrueFalse(create_prefix))
2822
 
        args.append(self._serialize_NoneTrueFalse(force_new_repo))
2823
 
        args.append(self._serialize_NoneString(stacked_on))
2824
 
        # stack_on_pwd is often/usually our transport
2825
 
        if stack_on_pwd:
2826
 
            try:
2827
 
                stack_on_pwd = transport.relpath(stack_on_pwd)
2828
 
                if not stack_on_pwd:
2829
 
                    stack_on_pwd = '.'
2830
 
            except errors.PathNotChild:
2831
 
                pass
2832
 
        args.append(self._serialize_NoneString(stack_on_pwd))
2833
 
        args.append(self._serialize_NoneString(repo_format_name))
2834
 
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
2835
 
        args.append(self._serialize_NoneTrueFalse(shared_repo))
2836
 
        request_network_name = self._network_name or \
2837
 
            BzrDirFormat.get_default_format().network_name()
2838
 
        try:
2839
 
            response = client.call('BzrDirFormat.initialize_ex_1.16',
2840
 
                request_network_name, path, *args)
2841
 
        except errors.UnknownSmartMethod:
2842
 
            client._medium._remember_remote_is_before((1,16))
2843
 
            local_dir_format = BzrDirMetaFormat1()
2844
 
            self._supply_sub_formats_to(local_dir_format)
2845
 
            return local_dir_format.initialize_on_transport_ex(transport,
2846
 
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2847
 
                force_new_repo=force_new_repo, stacked_on=stacked_on,
2848
 
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2849
 
                make_working_trees=make_working_trees, shared_repo=shared_repo,
2850
 
                vfs_only=True)
2851
 
        except errors.ErrorFromSmartServer, err:
2852
 
            remote._translate_error(err, path=path)
2853
 
        repo_path = response[0]
2854
 
        bzrdir_name = response[6]
2855
 
        require_stacking = response[7]
2856
 
        require_stacking = self.parse_NoneTrueFalse(require_stacking)
2857
 
        format = RemoteBzrDirFormat()
2858
 
        format._network_name = bzrdir_name
2859
 
        self._supply_sub_formats_to(format)
2860
 
        bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2861
 
        if repo_path:
2862
 
            repo_format = remote.response_tuple_to_repo_format(response[1:])
2863
 
            if repo_path == '.':
2864
 
                repo_path = ''
2865
 
            if repo_path:
2866
 
                repo_bzrdir_format = RemoteBzrDirFormat()
2867
 
                repo_bzrdir_format._network_name = response[5]
2868
 
                repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2869
 
                    repo_bzrdir_format)
2870
 
            else:
2871
 
                repo_bzr = bzrdir
2872
 
            final_stack = response[8] or None
2873
 
            final_stack_pwd = response[9] or None
2874
 
            if final_stack_pwd:
2875
 
                final_stack_pwd = urlutils.join(
2876
 
                    transport.base, final_stack_pwd)
2877
 
            remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2878
 
            if len(response) > 10:
2879
 
                # Updated server verb that locks remotely.
2880
 
                repo_lock_token = response[10] or None
2881
 
                remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2882
 
                if repo_lock_token:
2883
 
                    remote_repo.dont_leave_lock_in_place()
2884
 
            else:
2885
 
                remote_repo.lock_write()
2886
 
            policy = UseExistingRepository(remote_repo, final_stack,
2887
 
                final_stack_pwd, require_stacking)
2888
 
            policy.acquire_repository()
2889
 
        else:
2890
 
            remote_repo = None
2891
 
            policy = None
2892
 
        bzrdir._format.set_branch_format(self.get_branch_format())
2893
 
        if require_stacking:
2894
 
            # The repo has already been created, but we need to make sure that
2895
 
            # we'll make a stackable branch.
2896
 
            bzrdir._format.require_stacking(_skip_repo=True)
2897
 
        return remote_repo, bzrdir, require_stacking, policy
2898
 
 
2899
2805
    def _open(self, transport):
2900
2806
        return remote.RemoteBzrDir(transport, self)
2901
2807
 
2908
2814
        # Always return a RemoteRepositoryFormat object, but if a specific bzr
2909
2815
        # repository format has been asked for, tell the RemoteRepositoryFormat
2910
2816
        # that it should use that for init() etc.
2911
 
        result = remote.RemoteRepositoryFormat()
 
2817
        result =  remote.RemoteRepositoryFormat()
2912
2818
        custom_format = getattr(self, '_repository_format', None)
2913
2819
        if custom_format:
 
2820
            # We will use the custom format to create repositories over the
 
2821
            # wire; expose its details like rich_root_data for code to query
2914
2822
            if isinstance(custom_format, remote.RemoteRepositoryFormat):
2915
 
                return custom_format
 
2823
                result._custom_format = custom_format._custom_format
2916
2824
            else:
2917
 
                # We will use the custom format to create repositories over the
2918
 
                # wire; expose its details like rich_root_data for code to
2919
 
                # query
2920
2825
                result._custom_format = custom_format
 
2826
            result.rich_root_data = custom_format.rich_root_data
2921
2827
        return result
2922
2828
 
2923
2829
    def get_branch_format(self):
2934
2840
        BzrDirMetaFormat1._set_repository_format) #.im_func)
2935
2841
 
2936
2842
 
2937
 
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
 
2843
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
 
2844
 
 
2845
 
 
2846
class BzrDirFormatInfo(object):
 
2847
 
 
2848
    def __init__(self, native, deprecated, hidden, experimental):
 
2849
        self.deprecated = deprecated
 
2850
        self.native = native
 
2851
        self.hidden = hidden
 
2852
        self.experimental = experimental
 
2853
 
 
2854
 
 
2855
class BzrDirFormatRegistry(registry.Registry):
 
2856
    """Registry of user-selectable BzrDir subformats.
 
2857
 
 
2858
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
 
2859
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
 
2860
    """
 
2861
 
 
2862
    def __init__(self):
 
2863
        """Create a BzrDirFormatRegistry."""
 
2864
        self._aliases = set()
 
2865
        self._registration_order = list()
 
2866
        super(BzrDirFormatRegistry, self).__init__()
 
2867
 
 
2868
    def aliases(self):
 
2869
        """Return a set of the format names which are aliases."""
 
2870
        return frozenset(self._aliases)
 
2871
 
 
2872
    def register_metadir(self, key,
 
2873
             repository_format, help, native=True, deprecated=False,
 
2874
             branch_format=None,
 
2875
             tree_format=None,
 
2876
             hidden=False,
 
2877
             experimental=False,
 
2878
             alias=False):
 
2879
        """Register a metadir subformat.
 
2880
 
 
2881
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
2882
        by the Repository/Branch/WorkingTreeformats.
 
2883
 
 
2884
        :param repository_format: The fully-qualified repository format class
 
2885
            name as a string.
 
2886
        :param branch_format: Fully-qualified branch format class name as
 
2887
            a string.
 
2888
        :param tree_format: Fully-qualified tree format class name as
 
2889
            a string.
 
2890
        """
 
2891
        # This should be expanded to support setting WorkingTree and Branch
 
2892
        # formats, once BzrDirMetaFormat1 supports that.
 
2893
        def _load(full_name):
 
2894
            mod_name, factory_name = full_name.rsplit('.', 1)
 
2895
            try:
 
2896
                mod = __import__(mod_name, globals(), locals(),
 
2897
                        [factory_name])
 
2898
            except ImportError, e:
 
2899
                raise ImportError('failed to load %s: %s' % (full_name, e))
 
2900
            try:
 
2901
                factory = getattr(mod, factory_name)
 
2902
            except AttributeError:
 
2903
                raise AttributeError('no factory %s in module %r'
 
2904
                    % (full_name, mod))
 
2905
            return factory()
 
2906
 
 
2907
        def helper():
 
2908
            bd = BzrDirMetaFormat1()
 
2909
            if branch_format is not None:
 
2910
                bd.set_branch_format(_load(branch_format))
 
2911
            if tree_format is not None:
 
2912
                bd.workingtree_format = _load(tree_format)
 
2913
            if repository_format is not None:
 
2914
                bd.repository_format = _load(repository_format)
 
2915
            return bd
 
2916
        self.register(key, helper, help, native, deprecated, hidden,
 
2917
            experimental, alias)
 
2918
 
 
2919
    def register(self, key, factory, help, native=True, deprecated=False,
 
2920
                 hidden=False, experimental=False, alias=False):
 
2921
        """Register a BzrDirFormat factory.
 
2922
 
 
2923
        The factory must be a callable that takes one parameter: the key.
 
2924
        It must produce an instance of the BzrDirFormat when called.
 
2925
 
 
2926
        This function mainly exists to prevent the info object from being
 
2927
        supplied directly.
 
2928
        """
 
2929
        registry.Registry.register(self, key, factory, help,
 
2930
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
2931
        if alias:
 
2932
            self._aliases.add(key)
 
2933
        self._registration_order.append(key)
 
2934
 
 
2935
    def register_lazy(self, key, module_name, member_name, help, native=True,
 
2936
        deprecated=False, hidden=False, experimental=False, alias=False):
 
2937
        registry.Registry.register_lazy(self, key, module_name, member_name,
 
2938
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
 
2939
        if alias:
 
2940
            self._aliases.add(key)
 
2941
        self._registration_order.append(key)
 
2942
 
 
2943
    def set_default(self, key):
 
2944
        """Set the 'default' key to be a clone of the supplied key.
 
2945
 
 
2946
        This method must be called once and only once.
 
2947
        """
 
2948
        registry.Registry.register(self, 'default', self.get(key),
 
2949
            self.get_help(key), info=self.get_info(key))
 
2950
        self._aliases.add('default')
 
2951
 
 
2952
    def set_default_repository(self, key):
 
2953
        """Set the FormatRegistry default and Repository default.
 
2954
 
 
2955
        This is a transitional method while Repository.set_default_format
 
2956
        is deprecated.
 
2957
        """
 
2958
        if 'default' in self:
 
2959
            self.remove('default')
 
2960
        self.set_default(key)
 
2961
        format = self.get('default')()
 
2962
 
 
2963
    def make_bzrdir(self, key):
 
2964
        return self.get(key)()
 
2965
 
 
2966
    def help_topic(self, topic):
 
2967
        output = ""
 
2968
        default_realkey = None
 
2969
        default_help = self.get_help('default')
 
2970
        help_pairs = []
 
2971
        for key in self._registration_order:
 
2972
            if key == 'default':
 
2973
                continue
 
2974
            help = self.get_help(key)
 
2975
            if help == default_help:
 
2976
                default_realkey = key
 
2977
            else:
 
2978
                help_pairs.append((key, help))
 
2979
 
 
2980
        def wrapped(key, help, info):
 
2981
            if info.native:
 
2982
                help = '(native) ' + help
 
2983
            return ':%s:\n%s\n\n' % (key,
 
2984
                    textwrap.fill(help, initial_indent='    ',
 
2985
                    subsequent_indent='    '))
 
2986
        if default_realkey is not None:
 
2987
            output += wrapped(default_realkey, '(default) %s' % default_help,
 
2988
                              self.get_info('default'))
 
2989
        deprecated_pairs = []
 
2990
        experimental_pairs = []
 
2991
        for key, help in help_pairs:
 
2992
            info = self.get_info(key)
 
2993
            if info.hidden:
 
2994
                continue
 
2995
            elif info.deprecated:
 
2996
                deprecated_pairs.append((key, help))
 
2997
            elif info.experimental:
 
2998
                experimental_pairs.append((key, help))
 
2999
            else:
 
3000
                output += wrapped(key, help, info)
 
3001
        output += "\nSee ``bzr help formats`` for more about storage formats."
 
3002
        other_output = ""
 
3003
        if len(experimental_pairs) > 0:
 
3004
            other_output += "Experimental formats are shown below.\n\n"
 
3005
            for key, help in experimental_pairs:
 
3006
                info = self.get_info(key)
 
3007
                other_output += wrapped(key, help, info)
 
3008
        else:
 
3009
            other_output += \
 
3010
                "No experimental formats are available.\n\n"
 
3011
        if len(deprecated_pairs) > 0:
 
3012
            other_output += "\nDeprecated formats are shown below.\n\n"
 
3013
            for key, help in deprecated_pairs:
 
3014
                info = self.get_info(key)
 
3015
                other_output += wrapped(key, help, info)
 
3016
        else:
 
3017
            other_output += \
 
3018
                "\nNo deprecated formats are available.\n\n"
 
3019
        other_output += \
 
3020
            "\nSee ``bzr help formats`` for more about storage formats."
 
3021
 
 
3022
        if topic == 'other-formats':
 
3023
            return other_output
 
3024
        else:
 
3025
            return output
2938
3026
 
2939
3027
 
2940
3028
class RepositoryAcquisitionPolicy(object):
2969
3057
            try:
2970
3058
                stack_on = urlutils.rebase_url(self._stack_on,
2971
3059
                    self._stack_on_pwd,
2972
 
                    branch.user_url)
 
3060
                    branch.bzrdir.root_transport.base)
2973
3061
            except errors.InvalidRebaseURLs:
2974
3062
                stack_on = self._get_full_stack_on()
2975
3063
        try:
2976
3064
            branch.set_stacked_on_url(stack_on)
2977
 
        except (errors.UnstackableBranchFormat,
2978
 
                errors.UnstackableRepositoryFormat):
 
3065
        except errors.UnstackableBranchFormat:
2979
3066
            if self._require_stacking:
2980
3067
                raise
2981
3068
 
2982
 
    def requires_stacking(self):
2983
 
        """Return True if this policy requires stacking."""
2984
 
        return self._stack_on is not None and self._require_stacking
2985
 
 
2986
3069
    def _get_full_stack_on(self):
2987
3070
        """Get a fully-qualified URL for the stack_on location."""
2988
3071
        if self._stack_on is None:
2997
3080
        stack_on = self._get_full_stack_on()
2998
3081
        if stack_on is None:
2999
3082
            return
3000
 
        try:
3001
 
            stacked_dir = BzrDir.open(stack_on,
3002
 
                                      possible_transports=possible_transports)
3003
 
        except errors.JailBreak:
3004
 
            # We keep the stacking details, but we are in the server code so
3005
 
            # actually stacking is not needed.
3006
 
            return
 
3083
        stacked_dir = BzrDir.open(stack_on,
 
3084
                                  possible_transports=possible_transports)
3007
3085
        try:
3008
3086
            stacked_repo = stacked_dir.open_branch().repository
3009
3087
        except errors.NotBranchError:
3051
3129
 
3052
3130
        Creates the desired repository in the bzrdir we already have.
3053
3131
        """
3054
 
        stack_on = self._get_full_stack_on()
3055
 
        if stack_on:
3056
 
            format = self._bzrdir._format
3057
 
            format.require_stacking(stack_on=stack_on,
3058
 
                                    possible_transports=[self._bzrdir.root_transport])
3059
 
            if not self._require_stacking:
3060
 
                # We have picked up automatic stacking somewhere.
3061
 
                note('Using default stacking branch %s at %s', self._stack_on,
3062
 
                    self._stack_on_pwd)
3063
3132
        repository = self._bzrdir.create_repository(shared=shared)
3064
3133
        self._add_fallback(repository,
3065
3134
                           possible_transports=[self._bzrdir.transport])
3094
3163
        return self._repository, False
3095
3164
 
3096
3165
 
3097
 
def register_metadir(registry, key,
3098
 
         repository_format, help, native=True, deprecated=False,
3099
 
         branch_format=None,
3100
 
         tree_format=None,
3101
 
         hidden=False,
3102
 
         experimental=False,
3103
 
         alias=False):
3104
 
    """Register a metadir subformat.
3105
 
 
3106
 
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3107
 
    by the Repository/Branch/WorkingTreeformats.
3108
 
 
3109
 
    :param repository_format: The fully-qualified repository format class
3110
 
        name as a string.
3111
 
    :param branch_format: Fully-qualified branch format class name as
3112
 
        a string.
3113
 
    :param tree_format: Fully-qualified tree format class name as
3114
 
        a string.
3115
 
    """
3116
 
    # This should be expanded to support setting WorkingTree and Branch
3117
 
    # formats, once BzrDirMetaFormat1 supports that.
3118
 
    def _load(full_name):
3119
 
        mod_name, factory_name = full_name.rsplit('.', 1)
3120
 
        try:
3121
 
            mod = __import__(mod_name, globals(), locals(),
3122
 
                    [factory_name])
3123
 
        except ImportError, e:
3124
 
            raise ImportError('failed to load %s: %s' % (full_name, e))
3125
 
        try:
3126
 
            factory = getattr(mod, factory_name)
3127
 
        except AttributeError:
3128
 
            raise AttributeError('no factory %s in module %r'
3129
 
                % (full_name, mod))
3130
 
        return factory()
3131
 
 
3132
 
    def helper():
3133
 
        bd = BzrDirMetaFormat1()
3134
 
        if branch_format is not None:
3135
 
            bd.set_branch_format(_load(branch_format))
3136
 
        if tree_format is not None:
3137
 
            bd.workingtree_format = _load(tree_format)
3138
 
        if repository_format is not None:
3139
 
            bd.repository_format = _load(repository_format)
3140
 
        return bd
3141
 
    registry.register(key, helper, help, native, deprecated, hidden,
3142
 
        experimental, alias)
3143
 
 
 
3166
# Please register new formats after old formats so that formats
 
3167
# appear in chronological order and format descriptions can build
 
3168
# on previous ones.
 
3169
format_registry = BzrDirFormatRegistry()
3144
3170
# The pre-0.8 formats have their repository format network name registered in
3145
3171
# repository.py. MetaDir formats have their repository format network name
3146
3172
# inferred from their disk format string.
3147
 
controldir.format_registry.register('weave', BzrDirFormat6,
 
3173
format_registry.register('weave', BzrDirFormat6,
3148
3174
    'Pre-0.8 format.  Slower than knit and does not'
3149
3175
    ' support checkouts or shared repositories.',
3150
 
    hidden=True,
3151
3176
    deprecated=True)
3152
 
register_metadir(controldir.format_registry, 'metaweave',
 
3177
format_registry.register_metadir('metaweave',
3153
3178
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3154
3179
    'Transitional format in 0.8.  Slower than knit.',
3155
3180
    branch_format='bzrlib.branch.BzrBranchFormat5',
3156
3181
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3157
 
    hidden=True,
3158
3182
    deprecated=True)
3159
 
register_metadir(controldir.format_registry, 'knit',
 
3183
format_registry.register_metadir('knit',
3160
3184
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3161
3185
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3162
3186
    branch_format='bzrlib.branch.BzrBranchFormat5',
3163
3187
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3164
 
    hidden=True,
3165
3188
    deprecated=True)
3166
 
register_metadir(controldir.format_registry, 'dirstate',
 
3189
format_registry.register_metadir('dirstate',
3167
3190
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3168
3191
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3169
3192
        'above when accessed over the network.',
3171
3194
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3172
3195
    # directly from workingtree_4 triggers a circular import.
3173
3196
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3174
 
    hidden=True,
3175
3197
    deprecated=True)
3176
 
register_metadir(controldir.format_registry, 'dirstate-tags',
 
3198
format_registry.register_metadir('dirstate-tags',
3177
3199
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3178
3200
    help='New in 0.15: Fast local operations and improved scaling for '
3179
3201
        'network operations. Additionally adds support for tags.'
3180
3202
        ' Incompatible with bzr < 0.15.',
3181
3203
    branch_format='bzrlib.branch.BzrBranchFormat6',
3182
3204
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3183
 
    hidden=True,
3184
3205
    deprecated=True)
3185
 
register_metadir(controldir.format_registry, 'rich-root',
 
3206
format_registry.register_metadir('rich-root',
3186
3207
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3187
3208
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3188
3209
        ' bzr < 1.0.',
3189
3210
    branch_format='bzrlib.branch.BzrBranchFormat6',
3190
3211
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3191
 
    hidden=True,
3192
3212
    deprecated=True)
3193
 
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
 
3213
format_registry.register_metadir('dirstate-with-subtree',
3194
3214
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3195
3215
    help='New in 0.15: Fast local operations and improved scaling for '
3196
3216
        'network operations. Additionally adds support for versioning nested '
3200
3220
    experimental=True,
3201
3221
    hidden=True,
3202
3222
    )
3203
 
register_metadir(controldir.format_registry, 'pack-0.92',
 
3223
format_registry.register_metadir('pack-0.92',
3204
3224
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3205
3225
    help='New in 0.92: Pack-based format with data compatible with '
3206
3226
        'dirstate-tags format repositories. Interoperates with '
3207
3227
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3208
 
        ,
 
3228
        'Previously called knitpack-experimental.  '
 
3229
        'For more information, see '
 
3230
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3209
3231
    branch_format='bzrlib.branch.BzrBranchFormat6',
3210
3232
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3211
3233
    )
3212
 
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
 
3234
format_registry.register_metadir('pack-0.92-subtree',
3213
3235
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3214
3236
    help='New in 0.92: Pack-based format with data compatible with '
3215
3237
        'dirstate-with-subtree format repositories. Interoperates with '
3216
3238
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3217
 
        ,
 
3239
        'Previously called knitpack-experimental.  '
 
3240
        'For more information, see '
 
3241
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3218
3242
    branch_format='bzrlib.branch.BzrBranchFormat6',
3219
3243
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3220
3244
    hidden=True,
3221
3245
    experimental=True,
3222
3246
    )
3223
 
register_metadir(controldir.format_registry, 'rich-root-pack',
 
3247
format_registry.register_metadir('rich-root-pack',
3224
3248
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3225
3249
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3226
 
         '(needed for bzr-svn and bzr-git).',
 
3250
         '(needed for bzr-svn).',
3227
3251
    branch_format='bzrlib.branch.BzrBranchFormat6',
3228
3252
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3229
 
    hidden=True,
3230
3253
    )
3231
 
register_metadir(controldir.format_registry, '1.6',
 
3254
format_registry.register_metadir('1.6',
3232
3255
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3233
3256
    help='A format that allows a branch to indicate that there is another '
3234
3257
         '(stacked) repository that should be used to access data that is '
3235
3258
         'not present locally.',
3236
3259
    branch_format='bzrlib.branch.BzrBranchFormat7',
3237
3260
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3238
 
    hidden=True,
3239
3261
    )
3240
 
register_metadir(controldir.format_registry, '1.6.1-rich-root',
 
3262
format_registry.register_metadir('1.6.1-rich-root',
3241
3263
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3242
3264
    help='A variant of 1.6 that supports rich-root data '
3243
 
         '(needed for bzr-svn and bzr-git).',
 
3265
         '(needed for bzr-svn).',
3244
3266
    branch_format='bzrlib.branch.BzrBranchFormat7',
3245
3267
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3246
 
    hidden=True,
3247
3268
    )
3248
 
register_metadir(controldir.format_registry, '1.9',
 
3269
format_registry.register_metadir('1.9',
3249
3270
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3250
3271
    help='A repository format using B+tree indexes. These indexes '
3251
3272
         'are smaller in size, have smarter caching and provide faster '
3252
3273
         'performance for most operations.',
3253
3274
    branch_format='bzrlib.branch.BzrBranchFormat7',
3254
3275
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3255
 
    hidden=True,
3256
3276
    )
3257
 
register_metadir(controldir.format_registry, '1.9-rich-root',
 
3277
format_registry.register_metadir('1.9-rich-root',
3258
3278
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3259
3279
    help='A variant of 1.9 that supports rich-root data '
3260
 
         '(needed for bzr-svn and bzr-git).',
 
3280
         '(needed for bzr-svn).',
3261
3281
    branch_format='bzrlib.branch.BzrBranchFormat7',
3262
3282
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3263
 
    hidden=True,
3264
3283
    )
3265
 
register_metadir(controldir.format_registry, '1.14',
 
3284
format_registry.register_metadir('development-wt5',
3266
3285
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3267
 
    help='A working-tree format that supports content filtering.',
 
3286
    help='A working-tree format that supports views and content filtering.',
3268
3287
    branch_format='bzrlib.branch.BzrBranchFormat7',
3269
3288
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3289
    experimental=True,
3270
3290
    )
3271
 
register_metadir(controldir.format_registry, '1.14-rich-root',
 
3291
format_registry.register_metadir('development-wt5-rich-root',
3272
3292
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3273
 
    help='A variant of 1.14 that supports rich-root data '
3274
 
         '(needed for bzr-svn and bzr-git).',
 
3293
    help='A variant of development-wt5 that supports rich-root data '
 
3294
         '(needed for bzr-svn).',
3275
3295
    branch_format='bzrlib.branch.BzrBranchFormat7',
3276
3296
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3297
    experimental=True,
3277
3298
    )
3278
 
# The following un-numbered 'development' formats should always just be aliases.
3279
 
register_metadir(controldir.format_registry, 'development-rich-root',
3280
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3281
 
    help='Current development format. Supports rich roots. Can convert data '
3282
 
        'to and from rich-root-pack (and anything compatible with '
3283
 
        'rich-root-pack) format repositories. Repositories and branches in '
3284
 
        'this format can only be read by bzr.dev. Please read '
3285
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3299
# The following two formats should always just be aliases.
 
3300
format_registry.register_metadir('development',
 
3301
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
 
3302
    help='Current development format. Can convert data to and from pack-0.92 '
 
3303
        '(and anything compatible with pack-0.92) format repositories. '
 
3304
        'Repositories and branches in this format can only be read by bzr.dev. '
 
3305
        'Please read '
 
3306
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3286
3307
        'before use.',
3287
3308
    branch_format='bzrlib.branch.BzrBranchFormat7',
3288
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3309
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3289
3310
    experimental=True,
3290
3311
    alias=True,
3291
 
    hidden=True,
3292
3312
    )
3293
 
register_metadir(controldir.format_registry, 'development-subtree',
 
3313
format_registry.register_metadir('development-subtree',
3294
3314
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3295
3315
    help='Current development format, subtree variant. Can convert data to and '
3296
3316
        'from pack-0.92-subtree (and anything compatible with '
3297
3317
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3298
3318
        'this format can only be read by bzr.dev. Please read '
3299
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3319
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3300
3320
        'before use.',
3301
3321
    branch_format='bzrlib.branch.BzrBranchFormat7',
3302
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3322
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3303
3323
    experimental=True,
3304
 
    hidden=True,
3305
 
    alias=False, # Restore to being an alias when an actual development subtree format is added
3306
 
                 # This current non-alias status is simply because we did not introduce a
3307
 
                 # chk based subtree format.
 
3324
    alias=True,
3308
3325
    )
3309
 
 
3310
3326
# And the development formats above will have aliased one of the following:
3311
 
register_metadir(controldir.format_registry, 'development6-rich-root',
3312
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3313
 
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3314
 
        'Please read '
3315
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3316
 
        'before use.',
3317
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3318
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3319
 
    hidden=True,
3320
 
    experimental=True,
3321
 
    )
3322
 
 
3323
 
register_metadir(controldir.format_registry, 'development7-rich-root',
3324
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3325
 
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3326
 
        'rich roots. Please read '
3327
 
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3328
 
        'before use.',
3329
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3330
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3331
 
    hidden=True,
3332
 
    experimental=True,
3333
 
    )
3334
 
 
3335
 
register_metadir(controldir.format_registry, '2a',
3336
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3337
 
    help='First format for bzr 2.0 series.\n'
3338
 
        'Uses group-compress storage.\n'
3339
 
        'Provides rich roots which are a one-way transition.\n',
3340
 
        # 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
3341
 
        # 'rich roots. Supported by bzr 1.16 and later.',
3342
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3343
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3344
 
    experimental=True,
3345
 
    )
3346
 
 
3347
 
# The following format should be an alias for the rich root equivalent 
3348
 
# of the default format
3349
 
register_metadir(controldir.format_registry, 'default-rich-root',
3350
 
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3351
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3352
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3353
 
    alias=True,
3354
 
    hidden=True,
3355
 
    help='Same as 2a.')
 
3327
format_registry.register_metadir('development2',
 
3328
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
 
3329
    help='1.6.1 with B+Tree based index. '
 
3330
        'Please read '
 
3331
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3332
        'before use.',
 
3333
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3334
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3335
    hidden=True,
 
3336
    experimental=True,
 
3337
    )
 
3338
format_registry.register_metadir('development2-subtree',
 
3339
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
3340
    help='1.6.1-subtree with B+Tree based index. '
 
3341
        'Please read '
 
3342
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3343
        'before use.',
 
3344
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3345
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3346
    hidden=True,
 
3347
    experimental=True,
 
3348
    )
 
3349
format_registry.register_metadir('development5',
 
3350
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5',
 
3351
    help='1.9 with CHK inventories with parent_id index. '
 
3352
        'Please read '
 
3353
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3354
        'before use.',
 
3355
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3356
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3357
    hidden=True,
 
3358
    experimental=True,
 
3359
    )
 
3360
format_registry.register_metadir('development5-subtree',
 
3361
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Subtree',
 
3362
    help='1.9-subtree with CHK Inventories with parent_id index. '
 
3363
        'Please read '
 
3364
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3365
        'before use.',
 
3366
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3367
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3368
    hidden=True,
 
3369
    experimental=True,
 
3370
    )
 
3371
format_registry.register_metadir('development5-hash16',
 
3372
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Hash16',
 
3373
    help='1.9 with CHK inventories with parent_id index and 16-way hash trie. '
 
3374
        'Please read '
 
3375
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3376
        'before use.',
 
3377
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3378
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3379
    hidden=True,
 
3380
    experimental=True,
 
3381
    )
 
3382
format_registry.register_metadir('development5-hash255',
 
3383
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment5Hash255',
 
3384
    help='1.9 with CHK inventories with parent_id index and 255-way hash trie. '
 
3385
        'Please read '
 
3386
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3387
        'before use.',
 
3388
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3389
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3390
    hidden=True,
 
3391
    experimental=True,
 
3392
    )
 
3393
format_registry.register_metadir('gc-no-rich-root',
 
3394
    'bzrlib.repofmt.gc_repo.RepositoryFormatPackGCPlain',
 
3395
    help='pack-1.9 with xml inv, group compress '
 
3396
        'Please read '
 
3397
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3398
        'before use.',
 
3399
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3400
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3401
    hidden=False,
 
3402
    experimental=True,
 
3403
    )
 
3404
format_registry.register_metadir('gc-chk16',
 
3405
    'bzrlib.repofmt.gc_repo.RepositoryFormatPackGCCHK16',
 
3406
    help='pack-1.9 with 16-way hashed CHK inv, group compress, rich roots. '
 
3407
        'Please read '
 
3408
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3409
        'before use.',
 
3410
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3411
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3412
    hidden=False,
 
3413
    experimental=True,
 
3414
    )
 
3415
format_registry.register_metadir('gc-chk255',
 
3416
    'bzrlib.repofmt.gc_repo.RepositoryFormatPackGCCHK255',
 
3417
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
 
3418
        'Please read '
 
3419
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3420
        'before use.',
 
3421
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3422
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3423
    hidden=False,
 
3424
    experimental=True,
 
3425
    )
 
3426
format_registry.register_metadir('gc-chk255-big',
 
3427
    'bzrlib.repofmt.gc_repo.RepositoryFormatPackGCCHK255Big',
 
3428
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
 
3429
        'Please read '
 
3430
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3431
        'before use.',
 
3432
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3433
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3434
    hidden=False,
 
3435
    experimental=True,
 
3436
    )
3356
3437
 
3357
3438
# The current format that is made on 'bzr init'.
3358
 
controldir.format_registry.set_default('2a')
3359
 
 
3360
 
# XXX 2010-08-20 JRV: There is still a lot of code relying on
3361
 
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
3362
 
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
3363
 
format_registry = controldir.format_registry
 
3439
format_registry.set_default('pack-0.92')