~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2009-04-06 02:54:14 UTC
  • mfrom: (4253 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4255.
  • Revision ID: jelmer@samba.org-20090406025414-65tpjwcmjp5wa5oj
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

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