/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Andrew Bennetts
  • Date: 2010-04-13 04:33:55 UTC
  • mfrom: (5147 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5149.
  • Revision ID: andrew.bennetts@canonical.com-20100413043355-lg3id0uwtju0k3zs
MergeĀ lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""BzrDir logic. The BzrDir is the basic control directory used by bzr.
18
18
 
29
29
 
30
30
import os
31
31
import sys
 
32
import warnings
32
33
 
33
34
from bzrlib.lazy_import import lazy_import
34
35
lazy_import(globals(), """
37
38
 
38
39
import bzrlib
39
40
from bzrlib import (
 
41
    branch,
40
42
    config,
41
43
    errors,
42
44
    graph,
44
46
    lockdir,
45
47
    osutils,
46
48
    remote,
 
49
    repository,
47
50
    revision as _mod_revision,
48
51
    ui,
49
52
    urlutils,
57
60
from bzrlib.osutils import (
58
61
    sha_string,
59
62
    )
 
63
from bzrlib.push import (
 
64
    PushResult,
 
65
    )
 
66
from bzrlib.repofmt import pack_repo
60
67
from bzrlib.smart.client import _SmartClient
61
68
from bzrlib.store.versioned import WeaveStore
62
69
from bzrlib.transactions import WriteTransaction
71
78
from bzrlib.trace import (
72
79
    mutter,
73
80
    note,
 
81
    warning,
74
82
    )
75
83
 
76
84
from bzrlib import (
 
85
    hooks,
77
86
    registry,
78
87
    symbol_versioning,
79
88
    )
81
90
 
82
91
class BzrDir(object):
83
92
    """A .bzr control diretory.
84
 
    
 
93
 
85
94
    BzrDir instances let you create or open any of the things that can be
86
95
    found within .bzr - checkouts, branches and repositories.
87
 
    
 
96
 
88
97
    :ivar transport:
89
98
        the transport which this bzr dir is rooted at (i.e. file:///.../.bzr/)
90
99
    :ivar root_transport:
92
101
        (i.e. the parent directory holding the .bzr directory).
93
102
 
94
103
    Everything in the bzrdir should have the same file permissions.
 
104
 
 
105
    :cvar hooks: An instance of BzrDirHooks.
95
106
    """
96
107
 
97
108
    def break_lock(self):
119
130
        return True
120
131
 
121
132
    def check_conversion_target(self, target_format):
 
133
        """Check that a bzrdir as a whole can be converted to a new format."""
 
134
        # The only current restriction is that the repository content can be 
 
135
        # fetched compatibly with the target.
122
136
        target_repo_format = target_format.repository_format
123
 
        source_repo_format = self._format.repository_format
124
 
        source_repo_format.check_conversion_target(target_repo_format)
 
137
        try:
 
138
            self.open_repository()._format.check_conversion_target(
 
139
                target_repo_format)
 
140
        except errors.NoRepositoryPresent:
 
141
            # No repo, no problem.
 
142
            pass
125
143
 
126
144
    @staticmethod
127
145
    def _check_supported(format, allow_unsupported,
129
147
        basedir=None):
130
148
        """Give an error or warning on old formats.
131
149
 
132
 
        :param format: may be any kind of format - workingtree, branch, 
 
150
        :param format: may be any kind of format - workingtree, branch,
133
151
        or repository.
134
152
 
135
 
        :param allow_unsupported: If true, allow opening 
136
 
        formats that are strongly deprecated, and which may 
 
153
        :param allow_unsupported: If true, allow opening
 
154
        formats that are strongly deprecated, and which may
137
155
        have limited functionality.
138
156
 
139
157
        :param recommend_upgrade: If true (default), warn
171
189
                                       preserve_stacking=preserve_stacking)
172
190
 
173
191
    def clone_on_transport(self, transport, revision_id=None,
174
 
                           force_new_repo=False, preserve_stacking=False,
175
 
                           stacked_on=None):
 
192
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
193
        create_prefix=False, use_existing_dir=True):
176
194
        """Clone this bzrdir and its contents to transport verbatim.
177
195
 
178
196
        :param transport: The transport for the location to produce the clone
184
202
                               even if one is available.
185
203
        :param preserve_stacking: When cloning a stacked branch, stack the
186
204
            new branch on top of the other branch's stacked-on branch.
 
205
        :param create_prefix: Create any missing directories leading up to
 
206
            to_transport.
 
207
        :param use_existing_dir: Use an existing directory if one exists.
187
208
        """
188
 
        transport.ensure_base()
 
209
        # Overview: put together a broad description of what we want to end up
 
210
        # with; then make as few api calls as possible to do it.
 
211
        
 
212
        # We may want to create a repo/branch/tree, if we do so what format
 
213
        # would we want for each:
189
214
        require_stacking = (stacked_on is not None)
190
 
        metadir = self.cloning_metadir(require_stacking)
191
 
        result = metadir.initialize_on_transport(transport)
192
 
        repository_policy = None
 
215
        format = self.cloning_metadir(require_stacking)
 
216
        
 
217
        # Figure out what objects we want:
193
218
        try:
194
219
            local_repo = self.find_repository()
195
220
        except errors.NoRepositoryPresent:
209
234
                        errors.UnstackableRepositoryFormat,
210
235
                        errors.NotStacked):
211
236
                    pass
212
 
 
 
237
        # Bug: We create a metadir without knowing if it can support stacking,
 
238
        # we should look up the policy needs first, or just use it as a hint,
 
239
        # or something.
213
240
        if local_repo:
214
 
            # may need to copy content in
215
 
            repository_policy = result.determine_repository_policy(
216
 
                force_new_repo, stacked_on, self.root_transport.base,
217
 
                require_stacking=require_stacking)
218
241
            make_working_trees = local_repo.make_working_trees()
219
 
            result_repo = repository_policy.acquire_repository(
220
 
                make_working_trees, local_repo.is_shared())
221
 
            result_repo.fetch(local_repo, revision_id=revision_id)
222
 
        else:
223
 
            result_repo = None
 
242
            want_shared = local_repo.is_shared()
 
243
            repo_format_name = format.repository_format.network_name()
 
244
        else:
 
245
            make_working_trees = False
 
246
            want_shared = False
 
247
            repo_format_name = None
 
248
 
 
249
        result_repo, result, require_stacking, repository_policy = \
 
250
            format.initialize_on_transport_ex(transport,
 
251
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
252
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
253
            stack_on_pwd=self.root_transport.base,
 
254
            repo_format_name=repo_format_name,
 
255
            make_working_trees=make_working_trees, shared_repo=want_shared)
 
256
        if repo_format_name:
 
257
            try:
 
258
                # If the result repository is in the same place as the
 
259
                # resulting bzr dir, it will have no content, further if the
 
260
                # result is not stacked then we know all content should be
 
261
                # copied, and finally if we are copying up to a specific
 
262
                # revision_id then we can use the pending-ancestry-result which
 
263
                # does not require traversing all of history to describe it.
 
264
                if (result_repo.bzrdir.root_transport.base ==
 
265
                    result.root_transport.base and not require_stacking and
 
266
                    revision_id is not None):
 
267
                    fetch_spec = graph.PendingAncestryResult(
 
268
                        [revision_id], local_repo)
 
269
                    result_repo.fetch(local_repo, fetch_spec=fetch_spec)
 
270
                else:
 
271
                    result_repo.fetch(local_repo, revision_id=revision_id)
 
272
            finally:
 
273
                result_repo.unlock()
 
274
        else:
 
275
            if result_repo is not None:
 
276
                raise AssertionError('result_repo not None(%r)' % result_repo)
224
277
        # 1 if there is a branch present
225
278
        #   make sure its content is available in the target repository
226
279
        #   clone it.
227
280
        if local_branch is not None:
228
 
            result_branch = local_branch.clone(result, revision_id=revision_id)
229
 
            if repository_policy is not None:
230
 
                repository_policy.configure_branch(result_branch)
231
 
        if result_repo is None or result_repo.make_working_trees():
232
 
            try:
 
281
            result_branch = local_branch.clone(result, revision_id=revision_id,
 
282
                repository_policy=repository_policy)
 
283
        try:
 
284
            # Cheaper to check if the target is not local, than to try making
 
285
            # the tree and fail.
 
286
            result.root_transport.local_abspath('.')
 
287
            if result_repo is None or result_repo.make_working_trees():
233
288
                self.open_workingtree().clone(result)
234
 
            except (errors.NoWorkingTree, errors.NotLocalUrl):
235
 
                pass
 
289
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
290
            pass
236
291
        return result
237
292
 
238
293
    # TODO: This should be given a Transport, and should chdir up; otherwise
244
299
    @classmethod
245
300
    def create(cls, base, format=None, possible_transports=None):
246
301
        """Create a new BzrDir at the url 'base'.
247
 
        
 
302
 
248
303
        :param format: If supplied, the format of branch to create.  If not
249
304
            supplied, the default is used.
250
 
        :param possible_transports: If supplied, a list of transports that 
 
305
        :param possible_transports: If supplied, a list of transports that
251
306
            can be reused to share a remote connection.
252
307
        """
253
308
        if cls is not BzrDir:
300
355
                for subdir in sorted(subdirs, reverse=True):
301
356
                    pending.append(current_transport.clone(subdir))
302
357
 
 
358
    def list_branches(self):
 
359
        """Return a sequence of all branches local to this control directory.
 
360
 
 
361
        """
 
362
        try:
 
363
            return [self.open_branch()]
 
364
        except errors.NotBranchError:
 
365
            return []
 
366
 
303
367
    @staticmethod
304
368
    def find_branches(transport):
305
369
        """Find all branches under a transport.
317
381
            except errors.NoRepositoryPresent:
318
382
                pass
319
383
            else:
320
 
                return False, (None, repository)
321
 
            try:
322
 
                branch = bzrdir.open_branch()
323
 
            except errors.NotBranchError:
324
 
                return True, (None, None)
325
 
            else:
326
 
                return True, (branch, None)
327
 
        branches = []
328
 
        for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
 
384
                return False, ([], repository)
 
385
            return True, (bzrdir.list_branches(), None)
 
386
        ret = []
 
387
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
388
                                                  evaluate=evaluate):
329
389
            if repo is not None:
330
 
                branches.extend(repo.find_branches())
331
 
            if branch is not None:
332
 
                branches.append(branch)
333
 
        return branches
 
390
                ret.extend(repo.find_branches())
 
391
            if branches is not None:
 
392
                ret.extend(branches)
 
393
        return ret
334
394
 
335
395
    def destroy_repository(self):
336
396
        """Destroy the repository in this BzrDir"""
337
397
        raise NotImplementedError(self.destroy_repository)
338
398
 
339
 
    def create_branch(self):
 
399
    def create_branch(self, name=None):
340
400
        """Create a branch in this BzrDir.
341
401
 
 
402
        :param name: Name of the colocated branch to create, None for
 
403
            the default branch.
 
404
 
342
405
        The bzrdir's format will control what branch format is created.
343
406
        For more control see BranchFormatXX.create(a_bzrdir).
344
407
        """
345
408
        raise NotImplementedError(self.create_branch)
346
409
 
347
 
    def destroy_branch(self):
348
 
        """Destroy the branch in this BzrDir"""
 
410
    def destroy_branch(self, name=None):
 
411
        """Destroy a branch in this BzrDir.
 
412
        
 
413
        :param name: Name of the branch to destroy, None for the default 
 
414
            branch.
 
415
        """
349
416
        raise NotImplementedError(self.destroy_branch)
350
417
 
351
418
    @staticmethod
353
420
        """Create a new BzrDir, Branch and Repository at the url 'base'.
354
421
 
355
422
        This will use the current default BzrDirFormat unless one is
356
 
        specified, and use whatever 
 
423
        specified, and use whatever
357
424
        repository format that that uses via bzrdir.create_branch and
358
425
        create_repository. If a shared repository is available that is used
359
426
        preferentially.
373
440
                                    stack_on_pwd=None, require_stacking=False):
374
441
        """Return an object representing a policy to use.
375
442
 
376
 
        This controls whether a new repository is created, or a shared
377
 
        repository used instead.
 
443
        This controls whether a new repository is created, and the format of
 
444
        that repository, or some existing shared repository used instead.
378
445
 
379
446
        If stack_on is supplied, will not seek a containing shared repo.
380
447
 
389
456
            stack_on_pwd = None
390
457
            config = found_bzrdir.get_config()
391
458
            stop = False
392
 
            if config is not None:
393
 
                stack_on = config.get_default_stack_on()
394
 
                if stack_on is not None:
395
 
                    stack_on_pwd = found_bzrdir.root_transport.base
396
 
                    stop = True
397
 
                    note('Using default stacking branch %s at %s', stack_on,
398
 
                         stack_on_pwd)
 
459
            stack_on = config.get_default_stack_on()
 
460
            if stack_on is not None:
 
461
                stack_on_pwd = found_bzrdir.root_transport.base
 
462
                stop = True
399
463
            # does it have a repository ?
400
464
            try:
401
465
                repository = found_bzrdir.open_repository()
404
468
            else:
405
469
                if ((found_bzrdir.root_transport.base !=
406
470
                     self.root_transport.base) and not repository.is_shared()):
 
471
                    # Don't look higher, can't use a higher shared repo.
407
472
                    repository = None
 
473
                    stop = True
408
474
                else:
409
475
                    stop = True
410
476
            if not stop:
434
500
    def _find_or_create_repository(self, force_new_repo):
435
501
        """Create a new repository if needed, returning the repository."""
436
502
        policy = self.determine_repository_policy(force_new_repo)
437
 
        return policy.acquire_repository()
 
503
        return policy.acquire_repository()[0]
438
504
 
439
505
    @staticmethod
440
506
    def create_branch_convenience(base, force_new_repo=False,
447
513
        not.
448
514
 
449
515
        This will use the current default BzrDirFormat unless one is
450
 
        specified, and use whatever 
 
516
        specified, and use whatever
451
517
        repository format that that uses via bzrdir.create_branch and
452
518
        create_repository. If a shared repository is available that is used
453
519
        preferentially. Whatever repository is used, its tree creation policy
455
521
 
456
522
        The created Branch object is returned.
457
523
        If a working tree cannot be made due to base not being a file:// url,
458
 
        no error is raised unless force_new_tree is True, in which case no 
 
524
        no error is raised unless force_new_tree is True, in which case no
459
525
        data is created on disk and NotLocalUrl is raised.
460
526
 
461
527
        :param base: The URL to create the branch at.
462
528
        :param force_new_repo: If True a new repository is always created.
463
 
        :param force_new_tree: If True or False force creation of a tree or 
 
529
        :param force_new_tree: If True or False force creation of a tree or
464
530
                               prevent such creation respectively.
465
531
        :param format: Override for the bzrdir format to create.
466
532
        :param possible_transports: An optional reusable transports list.
488
554
        'base' must be a local path or a file:// url.
489
555
 
490
556
        This will use the current default BzrDirFormat unless one is
491
 
        specified, and use whatever 
 
557
        specified, and use whatever
492
558
        repository format that that uses for bzrdirformat.create_workingtree,
493
559
        create_branch and create_repository.
494
560
 
506
572
    def create_workingtree(self, revision_id=None, from_branch=None,
507
573
        accelerator_tree=None, hardlink=False):
508
574
        """Create a working tree at this BzrDir.
509
 
        
 
575
 
510
576
        :param revision_id: create it as of this revision id.
511
577
        :param from_branch: override bzrdir branch (for lightweight checkouts)
512
578
        :param accelerator_tree: A tree which can be used for retrieving file
516
582
        """
517
583
        raise NotImplementedError(self.create_workingtree)
518
584
 
 
585
    def backup_bzrdir(self):
 
586
        """Backup this bzr control directory.
 
587
 
 
588
        :return: Tuple with old path name and new path name
 
589
        """
 
590
        def name_gen(base='backup.bzr'):
 
591
            counter = 1
 
592
            name = "%s.~%d~" % (base, counter)
 
593
            while self.root_transport.has(name):
 
594
                counter += 1
 
595
                name = "%s.~%d~" % (base, counter)
 
596
            return name
 
597
 
 
598
        backup_dir=name_gen()
 
599
        pb = ui.ui_factory.nested_progress_bar()
 
600
        try:
 
601
            # FIXME: bug 300001 -- the backup fails if the backup directory
 
602
            # already exists, but it should instead either remove it or make
 
603
            # a new backup directory.
 
604
            #
 
605
            old_path = self.root_transport.abspath('.bzr')
 
606
            new_path = self.root_transport.abspath(backup_dir)
 
607
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
 
608
            self.root_transport.copy_tree('.bzr', backup_dir)
 
609
            return (old_path, new_path)
 
610
        finally:
 
611
            pb.finished()
 
612
 
519
613
    def retire_bzrdir(self, limit=10000):
520
614
        """Permanently disable the bzrdir.
521
615
 
619
713
        """
620
714
        return None
621
715
 
622
 
    def get_branch_transport(self, branch_format):
 
716
    def get_branch_transport(self, branch_format, name=None):
623
717
        """Get the transport for use by branch format in this BzrDir.
624
718
 
625
719
        Note that bzr dirs that do not support format strings will raise
626
720
        IncompatibleFormat if the branch format they are given has
627
721
        a format string, and vice versa.
628
722
 
629
 
        If branch_format is None, the transport is returned with no 
 
723
        If branch_format is None, the transport is returned with no
630
724
        checking. If it is not None, then the returned transport is
631
725
        guaranteed to point to an existing directory ready for use.
632
726
        """
675
769
        if not self._mode_check_done:
676
770
            self._find_creation_modes()
677
771
        return self._dir_mode
678
 
        
 
772
 
679
773
    def get_repository_transport(self, repository_format):
680
774
        """Get the transport for use by repository format in this BzrDir.
681
775
 
683
777
        IncompatibleFormat if the repository format they are given has
684
778
        a format string, and vice versa.
685
779
 
686
 
        If repository_format is None, the transport is returned with no 
 
780
        If repository_format is None, the transport is returned with no
687
781
        checking. If it is not None, then the returned transport is
688
782
        guaranteed to point to an existing directory ready for use.
689
783
        """
690
784
        raise NotImplementedError(self.get_repository_transport)
691
 
        
 
785
 
692
786
    def get_workingtree_transport(self, tree_format):
693
787
        """Get the transport for use by workingtree format in this BzrDir.
694
788
 
696
790
        IncompatibleFormat if the workingtree format they are given has a
697
791
        format string, and vice versa.
698
792
 
699
 
        If workingtree_format is None, the transport is returned with no 
 
793
        If workingtree_format is None, the transport is returned with no
700
794
        checking. If it is not None, then the returned transport is
701
795
        guaranteed to point to an existing directory ready for use.
702
796
        """
703
797
        raise NotImplementedError(self.get_workingtree_transport)
704
798
 
705
799
    def get_config(self):
706
 
        if getattr(self, '_get_config', None) is None:
707
 
            return None
708
 
        return self._get_config()
 
800
        """Get configuration for this BzrDir."""
 
801
        return config.BzrDirConfig(self)
 
802
 
 
803
    def _get_config(self):
 
804
        """By default, no configuration is available."""
 
805
        return None
709
806
 
710
807
    def __init__(self, _transport, _format):
711
808
        """Initialize a Bzr control dir object.
712
 
        
 
809
 
713
810
        Only really common logic should reside here, concrete classes should be
714
811
        made with varying behaviours.
715
812
 
723
820
 
724
821
    def is_control_filename(self, filename):
725
822
        """True if filename is the name of a path which is reserved for bzrdir's.
726
 
        
 
823
 
727
824
        :param filename: A filename within the root transport of this bzrdir.
728
825
 
729
826
        This is true IF and ONLY IF the filename is part of the namespace reserved
732
829
        this in the future - for instance to make bzr talk with svn working
733
830
        trees.
734
831
        """
735
 
        # this might be better on the BzrDirFormat class because it refers to 
736
 
        # all the possible bzrdir disk formats. 
737
 
        # This method is tested via the workingtree is_control_filename tests- 
 
832
        # this might be better on the BzrDirFormat class because it refers to
 
833
        # all the possible bzrdir disk formats.
 
834
        # This method is tested via the workingtree is_control_filename tests-
738
835
        # it was extracted from WorkingTree.is_control_filename. If the method's
739
836
        # contract is extended beyond the current trivial implementation, please
740
837
        # add new tests for it to the appropriate place.
742
839
 
743
840
    def needs_format_conversion(self, format=None):
744
841
        """Return true if this bzrdir needs convert_format run on it.
745
 
        
746
 
        For instance, if the repository format is out of date but the 
 
842
 
 
843
        For instance, if the repository format is out of date but the
747
844
        branch and working tree are not, this should return True.
748
845
 
749
846
        :param format: Optional parameter indicating a specific desired
755
852
    def open_unsupported(base):
756
853
        """Open a branch which is not supported."""
757
854
        return BzrDir.open(base, _unsupported=True)
758
 
        
 
855
 
759
856
    @staticmethod
760
857
    def open(base, _unsupported=False, possible_transports=None):
761
858
        """Open an existing bzrdir, rooted at 'base' (url).
762
 
        
 
859
 
763
860
        :param _unsupported: a private parameter to the BzrDir class.
764
861
        """
765
862
        t = get_transport(base, possible_transports=possible_transports)
773
870
        :param transport: Transport containing the bzrdir.
774
871
        :param _unsupported: private.
775
872
        """
 
873
        for hook in BzrDir.hooks['pre_open']:
 
874
            hook(transport)
 
875
        # Keep initial base since 'transport' may be modified while following
 
876
        # the redirections.
776
877
        base = transport.base
777
 
 
778
878
        def find_format(transport):
779
879
            return transport, BzrDirFormat.find_format(
780
880
                transport, _server_formats=_server_formats)
781
881
 
782
882
        def redirected(transport, e, redirection_notice):
783
 
            qualified_source = e.get_source_url()
784
 
            relpath = transport.relpath(qualified_source)
785
 
            if not e.target.endswith(relpath):
786
 
                # Not redirected to a branch-format, not a branch
787
 
                raise errors.NotBranchError(path=e.target)
788
 
            target = e.target[:-len(relpath)]
 
883
            redirected_transport = transport._redirected_to(e.source, e.target)
 
884
            if redirected_transport is None:
 
885
                raise errors.NotBranchError(base)
789
886
            note('%s is%s redirected to %s',
790
 
                 transport.base, e.permanently, target)
791
 
            # Let's try with a new transport
792
 
            # FIXME: If 'transport' has a qualifier, this should
793
 
            # be applied again to the new transport *iff* the
794
 
            # schemes used are the same. Uncomment this code
795
 
            # once the function (and tests) exist.
796
 
            # -- vila20070212
797
 
            #target = urlutils.copy_url_qualifiers(original, target)
798
 
            return get_transport(target)
 
887
                 transport.base, e.permanently, redirected_transport.base)
 
888
            return redirected_transport
799
889
 
800
890
        try:
801
891
            transport, format = do_catching_redirections(find_format,
807
897
        BzrDir._check_supported(format, _unsupported)
808
898
        return format.open(transport, _found=True)
809
899
 
810
 
    def open_branch(self, unsupported=False):
 
900
    def open_branch(self, name=None, unsupported=False,
 
901
                    ignore_fallbacks=False):
811
902
        """Open the branch object at this BzrDir if one is present.
812
903
 
813
904
        If unsupported is True, then no longer supported branch formats can
814
905
        still be opened.
815
 
        
 
906
 
816
907
        TODO: static convenience version of this?
817
908
        """
818
909
        raise NotImplementedError(self.open_branch)
820
911
    @staticmethod
821
912
    def open_containing(url, possible_transports=None):
822
913
        """Open an existing branch which contains url.
823
 
        
 
914
 
824
915
        :param url: url to search from.
825
916
        See open_containing_from_transport for more detail.
826
917
        """
827
918
        transport = get_transport(url, possible_transports)
828
919
        return BzrDir.open_containing_from_transport(transport)
829
 
    
 
920
 
830
921
    @staticmethod
831
922
    def open_containing_from_transport(a_transport):
832
923
        """Open an existing branch which contains a_transport.base.
835
926
 
836
927
        Basically we keep looking up until we find the control directory or
837
928
        run into the root.  If there isn't one, raises NotBranchError.
838
 
        If there is one and it is either an unrecognised format or an unsupported 
 
929
        If there is one and it is either an unrecognised format or an unsupported
839
930
        format, UnknownFormatError or UnsupportedFormatError are raised.
840
931
        If there is one, it is returned, along with the unused portion of url.
841
932
 
842
 
        :return: The BzrDir that contains the path, and a Unicode path 
 
933
        :return: The BzrDir that contains the path, and a Unicode path
843
934
                for the rest of the URL.
844
935
        """
845
936
        # this gets the normalised url back. I.e. '.' -> the full path.
951
1042
        """
952
1043
        raise NotImplementedError(self.open_workingtree)
953
1044
 
954
 
    def has_branch(self):
 
1045
    def has_branch(self, name=None):
955
1046
        """Tell if this bzrdir contains a branch.
956
 
        
 
1047
 
957
1048
        Note: if you're going to open the branch, you should just go ahead
958
 
        and try, and not ask permission first.  (This method just opens the 
959
 
        branch and discards it, and that's somewhat expensive.) 
 
1049
        and try, and not ask permission first.  (This method just opens the
 
1050
        branch and discards it, and that's somewhat expensive.)
960
1051
        """
961
1052
        try:
962
 
            self.open_branch()
 
1053
            self.open_branch(name)
963
1054
            return True
964
1055
        except errors.NotBranchError:
965
1056
            return False
969
1060
 
970
1061
        This will still raise an exception if the bzrdir has a workingtree that
971
1062
        is remote & inaccessible.
972
 
        
 
1063
 
973
1064
        Note: if you're going to open the working tree, you should just go ahead
974
 
        and try, and not ask permission first.  (This method just opens the 
975
 
        workingtree and discards it, and that's somewhat expensive.) 
 
1065
        and try, and not ask permission first.  (This method just opens the
 
1066
        workingtree and discards it, and that's somewhat expensive.)
976
1067
        """
977
1068
        try:
978
1069
            self.open_workingtree(recommend_upgrade=False)
982
1073
 
983
1074
    def _cloning_metadir(self):
984
1075
        """Produce a metadir suitable for cloning with.
985
 
        
 
1076
 
986
1077
        :returns: (destination_bzrdir_format, source_repository)
987
1078
        """
988
1079
        result_format = self._format.__class__()
989
1080
        try:
990
1081
            try:
991
 
                branch = self.open_branch()
 
1082
                branch = self.open_branch(ignore_fallbacks=True)
992
1083
                source_repository = branch.repository
993
1084
                result_format._branch_format = branch._format
994
1085
            except errors.NotBranchError:
1031
1122
        """
1032
1123
        format, repository = self._cloning_metadir()
1033
1124
        if format._workingtree_format is None:
 
1125
            # No tree in self.
1034
1126
            if repository is None:
 
1127
                # No repository either
1035
1128
                return format
 
1129
            # We have a repository, so set a working tree? (Why? This seems to
 
1130
            # contradict the stated return value in the docstring).
1036
1131
            tree_format = repository._format._matchingbzrdir.workingtree_format
1037
1132
            format.workingtree_format = tree_format.__class__()
1038
 
        if (require_stacking and not
1039
 
            format.get_branch_format().supports_stacking()):
1040
 
            # We need to make a stacked branch, but the default format for the
1041
 
            # target doesn't support stacking.  So force a branch that *can*
1042
 
            # support stacking.
1043
 
            from bzrlib.branch import BzrBranchFormat7
1044
 
            format._branch_format = BzrBranchFormat7()
1045
 
            mutter("using %r for stacking" % (format._branch_format,))
1046
 
            from bzrlib.repofmt import pack_repo
1047
 
            if format.repository_format.rich_root_data:
1048
 
                bzrdir_format_name = '1.6.1-rich-root'
1049
 
                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
1050
 
            else:
1051
 
                bzrdir_format_name = '1.6'
1052
 
                repo_format = pack_repo.RepositoryFormatKnitPack5()
1053
 
            note('Source format does not support stacking, using format:'
1054
 
                 ' \'%s\'\n  %s\n',
1055
 
                 bzrdir_format_name, repo_format.get_format_description())
1056
 
            format.repository_format = repo_format
 
1133
        if require_stacking:
 
1134
            format.require_stacking()
1057
1135
        return format
1058
1136
 
1059
1137
    def checkout_metadir(self):
1061
1139
 
1062
1140
    def sprout(self, url, revision_id=None, force_new_repo=False,
1063
1141
               recurse='down', possible_transports=None,
1064
 
               accelerator_tree=None, hardlink=False, stacked=False):
 
1142
               accelerator_tree=None, hardlink=False, stacked=False,
 
1143
               source_branch=None, create_tree_if_local=True):
1065
1144
        """Create a copy of this bzrdir prepared for use as a new line of
1066
1145
        development.
1067
1146
 
1082
1161
            where possible.
1083
1162
        :param stacked: If true, create a stacked branch referring to the
1084
1163
            location of this control directory.
 
1164
        :param create_tree_if_local: If true, a working-tree will be created
 
1165
            when working locally.
1085
1166
        """
1086
1167
        target_transport = get_transport(url, possible_transports)
1087
1168
        target_transport.ensure_base()
1088
1169
        cloning_format = self.cloning_metadir(stacked)
1089
1170
        # Create/update the result branch
1090
1171
        result = cloning_format.initialize_on_transport(target_transport)
1091
 
        try:
1092
 
            source_branch = self.open_branch()
1093
 
            source_repository = source_branch.repository
 
1172
        # if a stacked branch wasn't requested, we don't create one
 
1173
        # even if the origin was stacked
 
1174
        stacked_branch_url = None
 
1175
        if source_branch is not None:
1094
1176
            if stacked:
1095
1177
                stacked_branch_url = self.root_transport.base
1096
 
            else:
1097
 
                # if a stacked branch wasn't requested, we don't create one
1098
 
                # even if the origin was stacked
1099
 
                stacked_branch_url = None
1100
 
        except errors.NotBranchError:
1101
 
            source_branch = None
 
1178
            source_repository = source_branch.repository
 
1179
        else:
1102
1180
            try:
1103
 
                source_repository = self.open_repository()
1104
 
            except errors.NoRepositoryPresent:
1105
 
                source_repository = None
1106
 
            stacked_branch_url = None
 
1181
                source_branch = self.open_branch()
 
1182
                source_repository = source_branch.repository
 
1183
                if stacked:
 
1184
                    stacked_branch_url = self.root_transport.base
 
1185
            except errors.NotBranchError:
 
1186
                source_branch = None
 
1187
                try:
 
1188
                    source_repository = self.open_repository()
 
1189
                except errors.NoRepositoryPresent:
 
1190
                    source_repository = None
1107
1191
        repository_policy = result.determine_repository_policy(
1108
1192
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1109
 
        result_repo = repository_policy.acquire_repository()
 
1193
        result_repo, is_new_repo = repository_policy.acquire_repository()
 
1194
        if is_new_repo and revision_id is not None and not stacked:
 
1195
            fetch_spec = graph.PendingAncestryResult(
 
1196
                [revision_id], source_repository)
 
1197
        else:
 
1198
            fetch_spec = None
1110
1199
        if source_repository is not None:
1111
1200
            # Fetch while stacked to prevent unstacked fetch from
1112
1201
            # Branch.sprout.
1113
 
            result_repo.fetch(source_repository, revision_id=revision_id)
 
1202
            if fetch_spec is None:
 
1203
                result_repo.fetch(source_repository, revision_id=revision_id)
 
1204
            else:
 
1205
                result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1114
1206
 
1115
1207
        if source_branch is None:
1116
1208
            # this is for sprouting a bzrdir without a branch; is that
1118
1210
            # Not especially, but it's part of the contract.
1119
1211
            result_branch = result.create_branch()
1120
1212
        else:
1121
 
            # Force NULL revision to avoid using repository before stacking
1122
 
            # is configured.
1123
 
            result_branch = source_branch.sprout(
1124
 
                result, revision_id=_mod_revision.NULL_REVISION)
1125
 
            parent_location = result_branch.get_parent()
 
1213
            result_branch = source_branch.sprout(result,
 
1214
                revision_id=revision_id, repository_policy=repository_policy)
1126
1215
        mutter("created new branch %r" % (result_branch,))
1127
 
        repository_policy.configure_branch(result_branch)
1128
 
        if source_branch is not None:
1129
 
            source_branch.copy_content_into(result_branch, revision_id)
1130
 
            # Override copy_content_into
1131
 
            result_branch.set_parent(parent_location)
1132
1216
 
1133
1217
        # Create/update the result working tree
1134
 
        if isinstance(target_transport, local.LocalTransport) and (
1135
 
            result_repo is None or result_repo.make_working_trees()):
 
1218
        if (create_tree_if_local and
 
1219
            isinstance(target_transport, local.LocalTransport) and
 
1220
            (result_repo is None or result_repo.make_working_trees())):
1136
1221
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1137
1222
                hardlink=hardlink)
1138
1223
            wt.lock_write()
1175
1260
                    basis.unlock()
1176
1261
        return result
1177
1262
 
 
1263
    def push_branch(self, source, revision_id=None, overwrite=False, 
 
1264
        remember=False, create_prefix=False):
 
1265
        """Push the source branch into this BzrDir."""
 
1266
        br_to = None
 
1267
        # If we can open a branch, use its direct repository, otherwise see
 
1268
        # if there is a repository without a branch.
 
1269
        try:
 
1270
            br_to = self.open_branch()
 
1271
        except errors.NotBranchError:
 
1272
            # Didn't find a branch, can we find a repository?
 
1273
            repository_to = self.find_repository()
 
1274
        else:
 
1275
            # Found a branch, so we must have found a repository
 
1276
            repository_to = br_to.repository
 
1277
 
 
1278
        push_result = PushResult()
 
1279
        push_result.source_branch = source
 
1280
        if br_to is None:
 
1281
            # We have a repository but no branch, copy the revisions, and then
 
1282
            # create a branch.
 
1283
            repository_to.fetch(source.repository, revision_id=revision_id)
 
1284
            br_to = source.clone(self, revision_id=revision_id)
 
1285
            if source.get_push_location() is None or remember:
 
1286
                source.set_push_location(br_to.base)
 
1287
            push_result.stacked_on = None
 
1288
            push_result.branch_push_result = None
 
1289
            push_result.old_revno = None
 
1290
            push_result.old_revid = _mod_revision.NULL_REVISION
 
1291
            push_result.target_branch = br_to
 
1292
            push_result.master_branch = None
 
1293
            push_result.workingtree_updated = False
 
1294
        else:
 
1295
            # We have successfully opened the branch, remember if necessary:
 
1296
            if source.get_push_location() is None or remember:
 
1297
                source.set_push_location(br_to.base)
 
1298
            try:
 
1299
                tree_to = self.open_workingtree()
 
1300
            except errors.NotLocalUrl:
 
1301
                push_result.branch_push_result = source.push(br_to, 
 
1302
                    overwrite, stop_revision=revision_id)
 
1303
                push_result.workingtree_updated = False
 
1304
            except errors.NoWorkingTree:
 
1305
                push_result.branch_push_result = source.push(br_to,
 
1306
                    overwrite, stop_revision=revision_id)
 
1307
                push_result.workingtree_updated = None # Not applicable
 
1308
            else:
 
1309
                tree_to.lock_write()
 
1310
                try:
 
1311
                    push_result.branch_push_result = source.push(
 
1312
                        tree_to.branch, overwrite, stop_revision=revision_id)
 
1313
                    tree_to.update()
 
1314
                finally:
 
1315
                    tree_to.unlock()
 
1316
                push_result.workingtree_updated = True
 
1317
            push_result.old_revno = push_result.branch_push_result.old_revno
 
1318
            push_result.old_revid = push_result.branch_push_result.old_revid
 
1319
            push_result.target_branch = \
 
1320
                push_result.branch_push_result.target_branch
 
1321
        return push_result
 
1322
 
 
1323
 
 
1324
class BzrDirHooks(hooks.Hooks):
 
1325
    """Hooks for BzrDir operations."""
 
1326
 
 
1327
    def __init__(self):
 
1328
        """Create the default hooks."""
 
1329
        hooks.Hooks.__init__(self)
 
1330
        self.create_hook(hooks.HookPoint('pre_open',
 
1331
            "Invoked before attempting to open a BzrDir with the transport "
 
1332
            "that the open will use.", (1, 14), None))
 
1333
 
 
1334
# install the default hooks
 
1335
BzrDir.hooks = BzrDirHooks()
 
1336
 
1178
1337
 
1179
1338
class BzrDirPreSplitOut(BzrDir):
1180
1339
    """A common class for the all-in-one formats."""
1220
1379
            tree.clone(result)
1221
1380
        return result
1222
1381
 
1223
 
    def create_branch(self):
 
1382
    def create_branch(self, name=None):
1224
1383
        """See BzrDir.create_branch."""
1225
 
        return self._format.get_branch_format().initialize(self)
 
1384
        return self._format.get_branch_format().initialize(self, name=name)
1226
1385
 
1227
 
    def destroy_branch(self):
 
1386
    def destroy_branch(self, name=None):
1228
1387
        """See BzrDir.destroy_branch."""
1229
1388
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1230
1389
 
1251
1410
        # and that will have set it for us, its only
1252
1411
        # specific uses of create_workingtree in isolation
1253
1412
        # that can do wonky stuff here, and that only
1254
 
        # happens for creating checkouts, which cannot be 
 
1413
        # happens for creating checkouts, which cannot be
1255
1414
        # done on this format anyway. So - acceptable wart.
 
1415
        if hardlink:
 
1416
            warning("can't support hardlinked working trees in %r"
 
1417
                % (self,))
1256
1418
        try:
1257
1419
            result = self.open_workingtree(recommend_upgrade=False)
1258
1420
        except errors.NoSuchFile:
1280
1442
 
1281
1443
    def destroy_workingtree_metadata(self):
1282
1444
        """See BzrDir.destroy_workingtree_metadata."""
1283
 
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata, 
 
1445
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1284
1446
                                          self)
1285
1447
 
1286
 
    def get_branch_transport(self, branch_format):
 
1448
    def get_branch_transport(self, branch_format, name=None):
1287
1449
        """See BzrDir.get_branch_transport()."""
 
1450
        if name is not None:
 
1451
            raise errors.NoColocatedBranchSupport(self)
1288
1452
        if branch_format is None:
1289
1453
            return self.transport
1290
1454
        try:
1318
1482
        # if the format is not the same as the system default,
1319
1483
        # an upgrade is needed.
1320
1484
        if format is None:
 
1485
            symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
 
1486
                % 'needs_format_conversion(format=None)')
1321
1487
            format = BzrDirFormat.get_default_format()
1322
1488
        return not isinstance(self._format, format.__class__)
1323
1489
 
1324
 
    def open_branch(self, unsupported=False):
 
1490
    def open_branch(self, name=None, unsupported=False,
 
1491
                    ignore_fallbacks=False):
1325
1492
        """See BzrDir.open_branch."""
1326
1493
        from bzrlib.branch import BzrBranchFormat4
1327
1494
        format = BzrBranchFormat4()
1328
1495
        self._check_supported(format, unsupported)
1329
 
        return format.open(self, _found=True)
 
1496
        return format.open(self, name, _found=True)
1330
1497
 
1331
1498
    def sprout(self, url, revision_id=None, force_new_repo=False,
1332
1499
               possible_transports=None, accelerator_tree=None,
1333
 
               hardlink=False, stacked=False):
 
1500
               hardlink=False, stacked=False, create_tree_if_local=True,
 
1501
               source_branch=None):
1334
1502
        """See BzrDir.sprout()."""
 
1503
        if source_branch is not None:
 
1504
            my_branch = self.open_branch()
 
1505
            if source_branch.base != my_branch.base:
 
1506
                raise AssertionError(
 
1507
                    "source branch %r is not within %r with branch %r" %
 
1508
                    (source_branch, self, my_branch))
1335
1509
        if stacked:
1336
1510
            raise errors.UnstackableBranchFormat(
1337
1511
                self._format, self.root_transport.base)
 
1512
        if not create_tree_if_local:
 
1513
            raise errors.MustHaveWorkingTree(
 
1514
                self._format, self.root_transport.base)
1338
1515
        from bzrlib.workingtree import WorkingTreeFormat2
1339
1516
        self._make_tail(url)
1340
1517
        result = self._format._initialize_for_clone(url)
1346
1523
            self.open_branch().sprout(result, revision_id=revision_id)
1347
1524
        except errors.NotBranchError:
1348
1525
            pass
 
1526
 
1349
1527
        # we always want a working tree
1350
1528
        WorkingTreeFormat2().initialize(result,
1351
1529
                                        accelerator_tree=accelerator_tree,
1355
1533
 
1356
1534
class BzrDir4(BzrDirPreSplitOut):
1357
1535
    """A .bzr version 4 control object.
1358
 
    
 
1536
 
1359
1537
    This is a deprecated format and may be removed after sept 2006.
1360
1538
    """
1361
1539
 
1365
1543
 
1366
1544
    def needs_format_conversion(self, format=None):
1367
1545
        """Format 4 dirs are always in need of conversion."""
 
1546
        if format is None:
 
1547
            symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
 
1548
                % 'needs_format_conversion(format=None)')
1368
1549
        return True
1369
1550
 
1370
1551
    def open_repository(self):
1379
1560
    This is a deprecated format and may be removed after sept 2006.
1380
1561
    """
1381
1562
 
 
1563
    def has_workingtree(self):
 
1564
        """See BzrDir.has_workingtree."""
 
1565
        return True
 
1566
    
1382
1567
    def open_repository(self):
1383
1568
        """See BzrDir.open_repository."""
1384
1569
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1400
1585
    This is a deprecated format and may be removed after sept 2006.
1401
1586
    """
1402
1587
 
 
1588
    def has_workingtree(self):
 
1589
        """See BzrDir.has_workingtree."""
 
1590
        return True
 
1591
    
1403
1592
    def open_repository(self):
1404
1593
        """See BzrDir.open_repository."""
1405
1594
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1416
1605
 
1417
1606
class BzrDirMeta1(BzrDir):
1418
1607
    """A .bzr meta version 1 control object.
1419
 
    
1420
 
    This is the first control object where the 
 
1608
 
 
1609
    This is the first control object where the
1421
1610
    individual aspects are really split out: there are separate repository,
1422
1611
    workingtree and branch subdirectories and any subset of the three can be
1423
1612
    present within a BzrDir.
1427
1616
        """See BzrDir.can_convert_format()."""
1428
1617
        return True
1429
1618
 
1430
 
    def create_branch(self):
 
1619
    def create_branch(self, name=None):
1431
1620
        """See BzrDir.create_branch."""
1432
 
        return self._format.get_branch_format().initialize(self)
 
1621
        return self._format.get_branch_format().initialize(self, name=name)
1433
1622
 
1434
 
    def destroy_branch(self):
 
1623
    def destroy_branch(self, name=None):
1435
1624
        """See BzrDir.create_branch."""
 
1625
        if name is not None:
 
1626
            raise errors.NoColocatedBranchSupport(self)
1436
1627
        self.transport.delete_tree('branch')
1437
1628
 
1438
1629
    def create_repository(self, shared=False):
1481
1672
        format = BranchFormat.find_format(self)
1482
1673
        return format.get_reference(self)
1483
1674
 
1484
 
    def get_branch_transport(self, branch_format):
 
1675
    def get_branch_transport(self, branch_format, name=None):
1485
1676
        """See BzrDir.get_branch_transport()."""
 
1677
        if name is not None:
 
1678
            raise errors.NoColocatedBranchSupport(self)
 
1679
        # XXX: this shouldn't implicitly create the directory if it's just
 
1680
        # promising to get a transport -- mbp 20090727
1486
1681
        if branch_format is None:
1487
1682
            return self.transport.clone('branch')
1488
1683
        try:
1523
1718
            pass
1524
1719
        return self.transport.clone('checkout')
1525
1720
 
 
1721
    def has_workingtree(self):
 
1722
        """Tell if this bzrdir contains a working tree.
 
1723
 
 
1724
        This will still raise an exception if the bzrdir has a workingtree that
 
1725
        is remote & inaccessible.
 
1726
 
 
1727
        Note: if you're going to open the working tree, you should just go
 
1728
        ahead and try, and not ask permission first.
 
1729
        """
 
1730
        from bzrlib.workingtree import WorkingTreeFormat
 
1731
        try:
 
1732
            WorkingTreeFormat.find_format(self)
 
1733
        except errors.NoWorkingTree:
 
1734
            return False
 
1735
        return True
 
1736
 
1526
1737
    def needs_format_conversion(self, format=None):
1527
1738
        """See BzrDir.needs_format_conversion()."""
1528
1739
        if format is None:
 
1740
            symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
 
1741
                % 'needs_format_conversion(format=None)')
 
1742
        if format is None:
1529
1743
            format = BzrDirFormat.get_default_format()
1530
1744
        if not isinstance(self._format, format.__class__):
1531
1745
            # it is not a meta dir format, conversion is needed.
1538
1752
                return True
1539
1753
        except errors.NoRepositoryPresent:
1540
1754
            pass
1541
 
        try:
1542
 
            if not isinstance(self.open_branch()._format,
 
1755
        for branch in self.list_branches():
 
1756
            if not isinstance(branch._format,
1543
1757
                              format.get_branch_format().__class__):
1544
1758
                # the branch needs an upgrade.
1545
1759
                return True
1546
 
        except errors.NotBranchError:
1547
 
            pass
1548
1760
        try:
1549
1761
            my_wt = self.open_workingtree(recommend_upgrade=False)
1550
1762
            if not isinstance(my_wt._format,
1555
1767
            pass
1556
1768
        return False
1557
1769
 
1558
 
    def open_branch(self, unsupported=False):
 
1770
    def open_branch(self, name=None, unsupported=False,
 
1771
                    ignore_fallbacks=False):
1559
1772
        """See BzrDir.open_branch."""
1560
1773
        format = self.find_branch_format()
1561
1774
        self._check_supported(format, unsupported)
1562
 
        return format.open(self, _found=True)
 
1775
        return format.open(self, name=name,
 
1776
            _found=True, ignore_fallbacks=ignore_fallbacks)
1563
1777
 
1564
1778
    def open_repository(self, unsupported=False):
1565
1779
        """See BzrDir.open_repository."""
1579
1793
        return format.open(self, _found=True)
1580
1794
 
1581
1795
    def _get_config(self):
1582
 
        return config.BzrDirConfig(self.transport)
 
1796
        return config.TransportConfig(self.transport, 'control.conf')
1583
1797
 
1584
1798
 
1585
1799
class BzrDirFormat(object):
1590
1804
     * a format string,
1591
1805
     * an open routine.
1592
1806
 
1593
 
    Formats are placed in a dict by their format string for reference 
 
1807
    Formats are placed in a dict by their format string for reference
1594
1808
    during bzrdir opening. These should be subclasses of BzrDirFormat
1595
1809
    for consistency.
1596
1810
 
1597
1811
    Once a format is deprecated, just deprecate the initialize and open
1598
 
    methods on the format class. Do not deprecate the object, as the 
 
1812
    methods on the format class. Do not deprecate the object, as the
1599
1813
    object will be created every system load.
 
1814
 
 
1815
    :cvar colocated_branches: Whether this formats supports colocated branches.
1600
1816
    """
1601
1817
 
1602
1818
    _default_format = None
1607
1823
 
1608
1824
    _control_formats = []
1609
1825
    """The registered control formats - .bzr, ....
1610
 
    
 
1826
 
1611
1827
    This is a list of BzrDirFormat objects.
1612
1828
    """
1613
1829
 
1619
1835
 
1620
1836
    _lock_file_name = 'branch-lock'
1621
1837
 
 
1838
    colocated_branches = False
 
1839
    """Whether co-located branches are supported for this control dir format.
 
1840
    """
 
1841
 
1622
1842
    # _lock_class must be set in subclasses to the lock type, typ.
1623
1843
    # TransportLock or LockDir
1624
1844
 
1641
1861
    def probe_transport(klass, transport):
1642
1862
        """Return the .bzrdir style format present in a directory."""
1643
1863
        try:
1644
 
            format_string = transport.get(".bzr/branch-format").read()
 
1864
            format_string = transport.get_bytes(".bzr/branch-format")
1645
1865
        except errors.NoSuchFile:
1646
1866
            raise errors.NotBranchError(path=transport.base)
1647
1867
 
1672
1892
        current default format. In the case of plugins we can/should provide
1673
1893
        some means for them to extend the range of returnable converters.
1674
1894
 
1675
 
        :param format: Optional format to override the default format of the 
 
1895
        :param format: Optional format to override the default format of the
1676
1896
                       library.
1677
1897
        """
1678
1898
        raise NotImplementedError(self.get_converter)
1679
1899
 
1680
1900
    def initialize(self, url, possible_transports=None):
1681
1901
        """Create a bzr control dir at this url and return an opened copy.
1682
 
        
 
1902
 
 
1903
        While not deprecated, this method is very specific and its use will
 
1904
        lead to many round trips to setup a working environment. See
 
1905
        initialize_on_transport_ex for a [nearly] all-in-one method.
 
1906
 
1683
1907
        Subclasses should typically override initialize_on_transport
1684
1908
        instead of this method.
1685
1909
        """
1688
1912
 
1689
1913
    def initialize_on_transport(self, transport):
1690
1914
        """Initialize a new bzrdir in the base directory of a Transport."""
1691
 
        # Since we don't have a .bzr directory, inherit the
 
1915
        try:
 
1916
            # can we hand off the request to the smart server rather than using
 
1917
            # vfs calls?
 
1918
            client_medium = transport.get_smart_medium()
 
1919
        except errors.NoSmartMedium:
 
1920
            return self._initialize_on_transport_vfs(transport)
 
1921
        else:
 
1922
            # Current RPC's only know how to create bzr metadir1 instances, so
 
1923
            # we still delegate to vfs methods if the requested format is not a
 
1924
            # metadir1
 
1925
            if type(self) != BzrDirMetaFormat1:
 
1926
                return self._initialize_on_transport_vfs(transport)
 
1927
            remote_format = RemoteBzrDirFormat()
 
1928
            self._supply_sub_formats_to(remote_format)
 
1929
            return remote_format.initialize_on_transport(transport)
 
1930
 
 
1931
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
1932
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
1933
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
1934
        shared_repo=False, vfs_only=False):
 
1935
        """Create this format on transport.
 
1936
 
 
1937
        The directory to initialize will be created.
 
1938
 
 
1939
        :param force_new_repo: Do not use a shared repository for the target,
 
1940
                               even if one is available.
 
1941
        :param create_prefix: Create any missing directories leading up to
 
1942
            to_transport.
 
1943
        :param use_existing_dir: Use an existing directory if one exists.
 
1944
        :param stacked_on: A url to stack any created branch on, None to follow
 
1945
            any target stacking policy.
 
1946
        :param stack_on_pwd: If stack_on is relative, the location it is
 
1947
            relative to.
 
1948
        :param repo_format_name: If non-None, a repository will be
 
1949
            made-or-found. Should none be found, or if force_new_repo is True
 
1950
            the repo_format_name is used to select the format of repository to
 
1951
            create.
 
1952
        :param make_working_trees: Control the setting of make_working_trees
 
1953
            for a new shared repository when one is made. None to use whatever
 
1954
            default the format has.
 
1955
        :param shared_repo: Control whether made repositories are shared or
 
1956
            not.
 
1957
        :param vfs_only: If True do not attempt to use a smart server
 
1958
        :return: repo, bzrdir, require_stacking, repository_policy. repo is
 
1959
            None if none was created or found, bzrdir is always valid.
 
1960
            require_stacking is the result of examining the stacked_on
 
1961
            parameter and any stacking policy found for the target.
 
1962
        """
 
1963
        if not vfs_only:
 
1964
            # Try to hand off to a smart server 
 
1965
            try:
 
1966
                client_medium = transport.get_smart_medium()
 
1967
            except errors.NoSmartMedium:
 
1968
                pass
 
1969
            else:
 
1970
                # TODO: lookup the local format from a server hint.
 
1971
                remote_dir_format = RemoteBzrDirFormat()
 
1972
                remote_dir_format._network_name = self.network_name()
 
1973
                self._supply_sub_formats_to(remote_dir_format)
 
1974
                return remote_dir_format.initialize_on_transport_ex(transport,
 
1975
                    use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
1976
                    force_new_repo=force_new_repo, stacked_on=stacked_on,
 
1977
                    stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
1978
                    make_working_trees=make_working_trees, shared_repo=shared_repo)
 
1979
        # XXX: Refactor the create_prefix/no_create_prefix code into a
 
1980
        #      common helper function
 
1981
        # The destination may not exist - if so make it according to policy.
 
1982
        def make_directory(transport):
 
1983
            transport.mkdir('.')
 
1984
            return transport
 
1985
        def redirected(transport, e, redirection_notice):
 
1986
            note(redirection_notice)
 
1987
            return transport._redirected_to(e.source, e.target)
 
1988
        try:
 
1989
            transport = do_catching_redirections(make_directory, transport,
 
1990
                redirected)
 
1991
        except errors.FileExists:
 
1992
            if not use_existing_dir:
 
1993
                raise
 
1994
        except errors.NoSuchFile:
 
1995
            if not create_prefix:
 
1996
                raise
 
1997
            transport.create_prefix()
 
1998
 
 
1999
        require_stacking = (stacked_on is not None)
 
2000
        # Now the target directory exists, but doesn't have a .bzr
 
2001
        # directory. So we need to create it, along with any work to create
 
2002
        # all of the dependent branches, etc.
 
2003
 
 
2004
        result = self.initialize_on_transport(transport)
 
2005
        if repo_format_name:
 
2006
            try:
 
2007
                # use a custom format
 
2008
                result._format.repository_format = \
 
2009
                    repository.network_format_registry.get(repo_format_name)
 
2010
            except AttributeError:
 
2011
                # The format didn't permit it to be set.
 
2012
                pass
 
2013
            # A repository is desired, either in-place or shared.
 
2014
            repository_policy = result.determine_repository_policy(
 
2015
                force_new_repo, stacked_on, stack_on_pwd,
 
2016
                require_stacking=require_stacking)
 
2017
            result_repo, is_new_repo = repository_policy.acquire_repository(
 
2018
                make_working_trees, shared_repo)
 
2019
            if not require_stacking and repository_policy._require_stacking:
 
2020
                require_stacking = True
 
2021
                result._format.require_stacking()
 
2022
            result_repo.lock_write()
 
2023
        else:
 
2024
            result_repo = None
 
2025
            repository_policy = None
 
2026
        return result_repo, result, require_stacking, repository_policy
 
2027
 
 
2028
    def _initialize_on_transport_vfs(self, transport):
 
2029
        """Initialize a new bzrdir using VFS calls.
 
2030
 
 
2031
        :param transport: The transport to create the .bzr directory in.
 
2032
        :return: A
 
2033
        """
 
2034
        # Since we are creating a .bzr directory, inherit the
1692
2035
        # mode from the root directory
1693
2036
        temp_control = lockable_files.LockableFiles(transport,
1694
2037
                            '', lockable_files.TransportLock)
1724
2067
        """Is this format supported?
1725
2068
 
1726
2069
        Supported formats must be initializable and openable.
1727
 
        Unsupported formats may not support initialization or committing or 
 
2070
        Unsupported formats may not support initialization or committing or
1728
2071
        some other features depending on the reason for not being supported.
1729
2072
        """
1730
2073
        return True
1731
2074
 
 
2075
    def network_name(self):
 
2076
        """A simple byte string uniquely identifying this format for RPC calls.
 
2077
 
 
2078
        Bzr control formats use thir disk format string to identify the format
 
2079
        over the wire. Its possible that other control formats have more
 
2080
        complex detection requirements, so we permit them to use any unique and
 
2081
        immutable string they desire.
 
2082
        """
 
2083
        raise NotImplementedError(self.network_name)
 
2084
 
1732
2085
    def same_model(self, target_format):
1733
 
        return (self.repository_format.rich_root_data == 
 
2086
        return (self.repository_format.rich_root_data ==
1734
2087
            target_format.rich_root_data)
1735
2088
 
1736
2089
    @classmethod
1737
2090
    def known_formats(klass):
1738
2091
        """Return all the known formats.
1739
 
        
 
2092
 
1740
2093
        Concrete formats should override _known_formats.
1741
2094
        """
1742
 
        # There is double indirection here to make sure that control 
1743
 
        # formats used by more than one dir format will only be probed 
 
2095
        # There is double indirection here to make sure that control
 
2096
        # formats used by more than one dir format will only be probed
1744
2097
        # once. This can otherwise be quite expensive for remote connections.
1745
2098
        result = set()
1746
2099
        for format in klass._control_formats:
1747
2100
            result.update(format._known_formats())
1748
2101
        return result
1749
 
    
 
2102
 
1750
2103
    @classmethod
1751
2104
    def _known_formats(klass):
1752
2105
        """Return the known format instances for this control format."""
1754
2107
 
1755
2108
    def open(self, transport, _found=False):
1756
2109
        """Return an instance of this format for the dir transport points at.
1757
 
        
 
2110
 
1758
2111
        _found is a private parameter, do not use it.
1759
2112
        """
1760
2113
        if not _found:
1761
2114
            found_format = BzrDirFormat.find_format(transport)
1762
2115
            if not isinstance(found_format, self.__class__):
1763
2116
                raise AssertionError("%s was asked to open %s, but it seems to need "
1764
 
                        "format %s" 
 
2117
                        "format %s"
1765
2118
                        % (self, transport, found_format))
 
2119
            # Allow subclasses - use the found format.
 
2120
            self._supply_sub_formats_to(found_format)
 
2121
            return found_format._open(transport)
1766
2122
        return self._open(transport)
1767
2123
 
1768
2124
    def _open(self, transport):
1776
2132
    @classmethod
1777
2133
    def register_format(klass, format):
1778
2134
        klass._formats[format.get_format_string()] = format
 
2135
        # bzr native formats have a network name of their format string.
 
2136
        network_format_registry.register(format.get_format_string(), format.__class__)
1779
2137
 
1780
2138
    @classmethod
1781
2139
    def register_control_format(klass, format):
1782
2140
        """Register a format that does not use '.bzr' for its control dir.
1783
2141
 
1784
2142
        TODO: This should be pulled up into a 'ControlDirFormat' base class
1785
 
        which BzrDirFormat can inherit from, and renamed to register_format 
 
2143
        which BzrDirFormat can inherit from, and renamed to register_format
1786
2144
        there. It has been done without that for now for simplicity of
1787
2145
        implementation.
1788
2146
        """
1806
2164
 
1807
2165
    def __str__(self):
1808
2166
        # Trim the newline
1809
 
        return self.get_format_string().rstrip()
 
2167
        return self.get_format_description().rstrip()
 
2168
 
 
2169
    def _supply_sub_formats_to(self, other_format):
 
2170
        """Give other_format the same values for sub formats as this has.
 
2171
 
 
2172
        This method is expected to be used when parameterising a
 
2173
        RemoteBzrDirFormat instance with the parameters from a
 
2174
        BzrDirMetaFormat1 instance.
 
2175
 
 
2176
        :param other_format: other_format is a format which should be
 
2177
            compatible with whatever sub formats are supported by self.
 
2178
        :return: None.
 
2179
        """
1810
2180
 
1811
2181
    @classmethod
1812
2182
    def unregister_format(klass, format):
1844
2214
        """See BzrDirFormat.get_converter()."""
1845
2215
        # there is one and only one upgrade path here.
1846
2216
        return ConvertBzrDir4To5()
1847
 
        
 
2217
 
1848
2218
    def initialize_on_transport(self, transport):
1849
2219
        """Format 4 branches cannot be created."""
1850
2220
        raise errors.UninitializableFormat(self)
1853
2223
        """Format 4 is not supported.
1854
2224
 
1855
2225
        It is not supported because the model changed from 4 to 5 and the
1856
 
        conversion logic is expensive - so doing it on the fly was not 
 
2226
        conversion logic is expensive - so doing it on the fly was not
1857
2227
        feasible.
1858
2228
        """
1859
2229
        return False
1860
2230
 
 
2231
    def network_name(self):
 
2232
        return self.get_format_string()
 
2233
 
1861
2234
    def _open(self, transport):
1862
2235
        """See BzrDirFormat._open."""
1863
2236
        return BzrDir4(transport, self)
1869
2242
    repository_format = property(__return_repository_format)
1870
2243
 
1871
2244
 
1872
 
class BzrDirFormat5(BzrDirFormat):
 
2245
class BzrDirFormatAllInOne(BzrDirFormat):
 
2246
    """Common class for formats before meta-dirs."""
 
2247
 
 
2248
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
2249
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
2250
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
2251
        shared_repo=False):
 
2252
        """See BzrDirFormat.initialize_on_transport_ex."""
 
2253
        require_stacking = (stacked_on is not None)
 
2254
        # Format 5 cannot stack, but we've been asked to - actually init
 
2255
        # a Meta1Dir
 
2256
        if require_stacking:
 
2257
            format = BzrDirMetaFormat1()
 
2258
            return format.initialize_on_transport_ex(transport,
 
2259
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
2260
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
2261
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
2262
                make_working_trees=make_working_trees, shared_repo=shared_repo)
 
2263
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
 
2264
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
2265
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
2266
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
2267
            make_working_trees=make_working_trees, shared_repo=shared_repo)
 
2268
 
 
2269
 
 
2270
class BzrDirFormat5(BzrDirFormatAllInOne):
1873
2271
    """Bzr control format 5.
1874
2272
 
1875
2273
    This format is a combined format for working tree, branch and repository.
1876
2274
    It has:
1877
 
     - Format 2 working trees [always] 
1878
 
     - Format 4 branches [always] 
 
2275
     - Format 2 working trees [always]
 
2276
     - Format 4 branches [always]
1879
2277
     - Format 5 repositories [always]
1880
2278
       Unhashed stores in the repository.
1881
2279
    """
1901
2299
 
1902
2300
    def _initialize_for_clone(self, url):
1903
2301
        return self.initialize_on_transport(get_transport(url), _cloning=True)
1904
 
        
 
2302
 
1905
2303
    def initialize_on_transport(self, transport, _cloning=False):
1906
2304
        """Format 5 dirs always have working tree, branch and repository.
1907
 
        
 
2305
 
1908
2306
        Except when they are being cloned.
1909
2307
        """
1910
2308
        from bzrlib.branch import BzrBranchFormat4
1916
2314
            result._init_workingtree()
1917
2315
        return result
1918
2316
 
 
2317
    def network_name(self):
 
2318
        return self.get_format_string()
 
2319
 
1919
2320
    def _open(self, transport):
1920
2321
        """See BzrDirFormat._open."""
1921
2322
        return BzrDir5(transport, self)
1927
2328
    repository_format = property(__return_repository_format)
1928
2329
 
1929
2330
 
1930
 
class BzrDirFormat6(BzrDirFormat):
 
2331
class BzrDirFormat6(BzrDirFormatAllInOne):
1931
2332
    """Bzr control format 6.
1932
2333
 
1933
2334
    This format is a combined format for working tree, branch and repository.
1934
2335
    It has:
1935
 
     - Format 2 working trees [always] 
1936
 
     - Format 4 branches [always] 
 
2336
     - Format 2 working trees [always]
 
2337
     - Format 4 branches [always]
1937
2338
     - Format 6 repositories [always]
1938
2339
    """
1939
2340
 
1955
2356
        """See BzrDirFormat.get_converter()."""
1956
2357
        # there is one and only one upgrade path here.
1957
2358
        return ConvertBzrDir6ToMeta()
1958
 
        
 
2359
 
1959
2360
    def _initialize_for_clone(self, url):
1960
2361
        return self.initialize_on_transport(get_transport(url), _cloning=True)
1961
2362
 
1962
2363
    def initialize_on_transport(self, transport, _cloning=False):
1963
2364
        """Format 6 dirs always have working tree, branch and repository.
1964
 
        
 
2365
 
1965
2366
        Except when they are being cloned.
1966
2367
        """
1967
2368
        from bzrlib.branch import BzrBranchFormat4
1973
2374
            result._init_workingtree()
1974
2375
        return result
1975
2376
 
 
2377
    def network_name(self):
 
2378
        return self.get_format_string()
 
2379
 
1976
2380
    def _open(self, transport):
1977
2381
        """See BzrDirFormat._open."""
1978
2382
        return BzrDir6(transport, self)
2000
2404
    def __init__(self):
2001
2405
        self._workingtree_format = None
2002
2406
        self._branch_format = None
 
2407
        self._repository_format = None
2003
2408
 
2004
2409
    def __eq__(self, other):
2005
2410
        if other.__class__ is not self.__class__:
2022
2427
    def set_branch_format(self, format):
2023
2428
        self._branch_format = format
2024
2429
 
 
2430
    def require_stacking(self, stack_on=None, possible_transports=None,
 
2431
            _skip_repo=False):
 
2432
        """We have a request to stack, try to ensure the formats support it.
 
2433
 
 
2434
        :param stack_on: If supplied, it is the URL to a branch that we want to
 
2435
            stack on. Check to see if that format supports stacking before
 
2436
            forcing an upgrade.
 
2437
        """
 
2438
        # Stacking is desired. requested by the target, but does the place it
 
2439
        # points at support stacking? If it doesn't then we should
 
2440
        # not implicitly upgrade. We check this here.
 
2441
        new_repo_format = None
 
2442
        new_branch_format = None
 
2443
 
 
2444
        # a bit of state for get_target_branch so that we don't try to open it
 
2445
        # 2 times, for both repo *and* branch
 
2446
        target = [None, False, None] # target_branch, checked, upgrade anyway
 
2447
        def get_target_branch():
 
2448
            if target[1]:
 
2449
                # We've checked, don't check again
 
2450
                return target
 
2451
            if stack_on is None:
 
2452
                # No target format, that means we want to force upgrading
 
2453
                target[:] = [None, True, True]
 
2454
                return target
 
2455
            try:
 
2456
                target_dir = BzrDir.open(stack_on,
 
2457
                    possible_transports=possible_transports)
 
2458
            except errors.NotBranchError:
 
2459
                # Nothing there, don't change formats
 
2460
                target[:] = [None, True, False]
 
2461
                return target
 
2462
            except errors.JailBreak:
 
2463
                # JailBreak, JFDI and upgrade anyway
 
2464
                target[:] = [None, True, True]
 
2465
                return target
 
2466
            try:
 
2467
                target_branch = target_dir.open_branch()
 
2468
            except errors.NotBranchError:
 
2469
                # No branch, don't upgrade formats
 
2470
                target[:] = [None, True, False]
 
2471
                return target
 
2472
            target[:] = [target_branch, True, False]
 
2473
            return target
 
2474
 
 
2475
        if (not _skip_repo and
 
2476
                 not self.repository_format.supports_external_lookups):
 
2477
            # We need to upgrade the Repository.
 
2478
            target_branch, _, do_upgrade = get_target_branch()
 
2479
            if target_branch is None:
 
2480
                # We don't have a target branch, should we upgrade anyway?
 
2481
                if do_upgrade:
 
2482
                    # stack_on is inaccessible, JFDI.
 
2483
                    # TODO: bad monkey, hard-coded formats...
 
2484
                    if self.repository_format.rich_root_data:
 
2485
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
 
2486
                    else:
 
2487
                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
 
2488
            else:
 
2489
                # If the target already supports stacking, then we know the
 
2490
                # project is already able to use stacking, so auto-upgrade
 
2491
                # for them
 
2492
                new_repo_format = target_branch.repository._format
 
2493
                if not new_repo_format.supports_external_lookups:
 
2494
                    # target doesn't, source doesn't, so don't auto upgrade
 
2495
                    # repo
 
2496
                    new_repo_format = None
 
2497
            if new_repo_format is not None:
 
2498
                self.repository_format = new_repo_format
 
2499
                note('Source repository format does not support stacking,'
 
2500
                     ' using format:\n  %s',
 
2501
                     new_repo_format.get_format_description())
 
2502
 
 
2503
        if not self.get_branch_format().supports_stacking():
 
2504
            # We just checked the repo, now lets check if we need to
 
2505
            # upgrade the branch format
 
2506
            target_branch, _, do_upgrade = get_target_branch()
 
2507
            if target_branch is None:
 
2508
                if do_upgrade:
 
2509
                    # TODO: bad monkey, hard-coded formats...
 
2510
                    new_branch_format = branch.BzrBranchFormat7()
 
2511
            else:
 
2512
                new_branch_format = target_branch._format
 
2513
                if not new_branch_format.supports_stacking():
 
2514
                    new_branch_format = None
 
2515
            if new_branch_format is not None:
 
2516
                # Does support stacking, use its format.
 
2517
                self.set_branch_format(new_branch_format)
 
2518
                note('Source branch format does not support stacking,'
 
2519
                     ' using format:\n  %s',
 
2520
                     new_branch_format.get_format_description())
 
2521
 
2025
2522
    def get_converter(self, format=None):
2026
2523
        """See BzrDirFormat.get_converter()."""
2027
2524
        if format is None:
2039
2536
        """See BzrDirFormat.get_format_description()."""
2040
2537
        return "Meta directory format 1"
2041
2538
 
 
2539
    def network_name(self):
 
2540
        return self.get_format_string()
 
2541
 
2042
2542
    def _open(self, transport):
2043
2543
        """See BzrDirFormat._open."""
2044
 
        return BzrDirMeta1(transport, self)
 
2544
        # Create a new format instance because otherwise initialisation of new
 
2545
        # metadirs share the global default format object leading to alias
 
2546
        # problems.
 
2547
        format = BzrDirMetaFormat1()
 
2548
        self._supply_sub_formats_to(format)
 
2549
        return BzrDirMeta1(transport, format)
2045
2550
 
2046
2551
    def __return_repository_format(self):
2047
2552
        """Circular import protection."""
2048
 
        if getattr(self, '_repository_format', None):
 
2553
        if self._repository_format:
2049
2554
            return self._repository_format
2050
2555
        from bzrlib.repository import RepositoryFormat
2051
2556
        return RepositoryFormat.get_default_format()
2052
2557
 
2053
 
    def __set_repository_format(self, value):
 
2558
    def _set_repository_format(self, value):
2054
2559
        """Allow changing the repository format for metadir formats."""
2055
2560
        self._repository_format = value
2056
2561
 
2057
 
    repository_format = property(__return_repository_format, __set_repository_format)
 
2562
    repository_format = property(__return_repository_format,
 
2563
        _set_repository_format)
 
2564
 
 
2565
    def _supply_sub_formats_to(self, other_format):
 
2566
        """Give other_format the same values for sub formats as this has.
 
2567
 
 
2568
        This method is expected to be used when parameterising a
 
2569
        RemoteBzrDirFormat instance with the parameters from a
 
2570
        BzrDirMetaFormat1 instance.
 
2571
 
 
2572
        :param other_format: other_format is a format which should be
 
2573
            compatible with whatever sub formats are supported by self.
 
2574
        :return: None.
 
2575
        """
 
2576
        if getattr(self, '_repository_format', None) is not None:
 
2577
            other_format.repository_format = self.repository_format
 
2578
        if self._branch_format is not None:
 
2579
            other_format._branch_format = self._branch_format
 
2580
        if self._workingtree_format is not None:
 
2581
            other_format.workingtree_format = self.workingtree_format
2058
2582
 
2059
2583
    def __get_workingtree_format(self):
2060
2584
        if self._workingtree_format is None:
2069
2593
                                  __set_workingtree_format)
2070
2594
 
2071
2595
 
 
2596
network_format_registry = registry.FormatRegistry()
 
2597
"""Registry of formats indexed by their network name.
 
2598
 
 
2599
The network name for a BzrDirFormat is an identifier that can be used when
 
2600
referring to formats with smart server operations. See
 
2601
BzrDirFormat.network_name() for more detail.
 
2602
"""
 
2603
 
 
2604
 
2072
2605
# Register bzr control format
2073
2606
BzrDirFormat.register_control_format(BzrDirFormat)
2074
2607
 
2106
2639
        self.absent_revisions = set()
2107
2640
        self.text_count = 0
2108
2641
        self.revisions = {}
2109
 
        
 
2642
 
2110
2643
    def convert(self, to_convert, pb):
2111
2644
        """See Converter.convert()."""
2112
2645
        self.bzrdir = to_convert
2113
 
        self.pb = pb
2114
 
        self.pb.note('starting upgrade from format 4 to 5')
2115
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2116
 
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2117
 
        self._convert_to_weaves()
2118
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2646
        if pb is not None:
 
2647
            warnings.warn("pb parameter to convert() is deprecated")
 
2648
        self.pb = ui.ui_factory.nested_progress_bar()
 
2649
        try:
 
2650
            ui.ui_factory.note('starting upgrade from format 4 to 5')
 
2651
            if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2652
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2653
            self._convert_to_weaves()
 
2654
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2655
        finally:
 
2656
            self.pb.finished()
2119
2657
 
2120
2658
    def _convert_to_weaves(self):
2121
 
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
 
2659
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2122
2660
        try:
2123
2661
            # TODO permissions
2124
2662
            stat = self.bzrdir.transport.stat('weaves')
2152
2690
        self.pb.clear()
2153
2691
        self._write_all_weaves()
2154
2692
        self._write_all_revs()
2155
 
        self.pb.note('upgraded to weaves:')
2156
 
        self.pb.note('  %6d revisions and inventories', len(self.revisions))
2157
 
        self.pb.note('  %6d revisions not present', len(self.absent_revisions))
2158
 
        self.pb.note('  %6d texts', self.text_count)
 
2693
        ui.ui_factory.note('upgraded to weaves:')
 
2694
        ui.ui_factory.note('  %6d revisions and inventories' % len(self.revisions))
 
2695
        ui.ui_factory.note('  %6d revisions not present' % len(self.absent_revisions))
 
2696
        ui.ui_factory.note('  %6d texts' % self.text_count)
2159
2697
        self._cleanup_spare_files_after_format4()
2160
2698
        self.branch._transport.put_bytes(
2161
2699
            'branch-format',
2218
2756
                revision_store.add_lines(key, None, osutils.split_lines(text))
2219
2757
        finally:
2220
2758
            self.pb.clear()
2221
 
            
 
2759
 
2222
2760
    def _load_one_rev(self, rev_id):
2223
2761
        """Load a revision object into memory.
2224
2762
 
2229
2767
                       len(self.known_revisions))
2230
2768
        if not self.branch.repository.has_revision(rev_id):
2231
2769
            self.pb.clear()
2232
 
            self.pb.note('revision {%s} not present in branch; '
2233
 
                         'will be converted as a ghost',
 
2770
            ui.ui_factory.note('revision {%s} not present in branch; '
 
2771
                         'will be converted as a ghost' %
2234
2772
                         rev_id)
2235
2773
            self.absent_revisions.add(rev_id)
2236
2774
        else:
2298
2836
        text_changed = False
2299
2837
        parent_candiate_entries = ie.parent_candidates(parent_invs)
2300
2838
        heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2301
 
        # XXX: Note that this is unordered - and this is tolerable because 
 
2839
        # XXX: Note that this is unordered - and this is tolerable because
2302
2840
        # the previous code was also unordered.
2303
2841
        previous_entries = dict((head, parent_candiate_entries[head]) for head
2304
2842
            in heads)
2305
2843
        self.snapshot_ie(previous_entries, ie, w, rev_id)
2306
2844
        del ie.text_id
2307
2845
 
2308
 
    @symbol_versioning.deprecated_method(symbol_versioning.one_one)
2309
 
    def get_parents(self, revision_ids):
2310
 
        for revision_id in revision_ids:
2311
 
            yield self.revisions[revision_id].parent_ids
2312
 
 
2313
2846
    def get_parent_map(self, revision_ids):
2314
 
        """See graph._StackedParentsProvider.get_parent_map"""
 
2847
        """See graph.StackedParentsProvider.get_parent_map"""
2315
2848
        return dict((revision_id, self.revisions[revision_id])
2316
2849
                    for revision_id in revision_ids
2317
2850
                     if revision_id in self.revisions)
2321
2854
        # a call to:. This needs the path figured out. rather than a work_tree
2322
2855
        # a v4 revision_tree can be given, or something that looks enough like
2323
2856
        # one to give the file content to the entry if it needs it.
2324
 
        # and we need something that looks like a weave store for snapshot to 
 
2857
        # and we need something that looks like a weave store for snapshot to
2325
2858
        # save against.
2326
2859
        #ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2327
2860
        if len(previous_revisions) == 1:
2367
2900
    def convert(self, to_convert, pb):
2368
2901
        """See Converter.convert()."""
2369
2902
        self.bzrdir = to_convert
2370
 
        self.pb = pb
2371
 
        self.pb.note('starting upgrade from format 5 to 6')
2372
 
        self._convert_to_prefixed()
2373
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2903
        pb = ui.ui_factory.nested_progress_bar()
 
2904
        try:
 
2905
            ui.ui_factory.note('starting upgrade from format 5 to 6')
 
2906
            self._convert_to_prefixed()
 
2907
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2908
        finally:
 
2909
            pb.finished()
2374
2910
 
2375
2911
    def _convert_to_prefixed(self):
2376
2912
        from bzrlib.store import TransportStore
2377
2913
        self.bzrdir.transport.delete('branch-format')
2378
2914
        for store_name in ["weaves", "revision-store"]:
2379
 
            self.pb.note("adding prefixes to %s" % store_name)
 
2915
            ui.ui_factory.note("adding prefixes to %s" % store_name)
2380
2916
            store_transport = self.bzrdir.transport.clone(store_name)
2381
2917
            store = TransportStore(store_transport, prefixed=True)
2382
2918
            for urlfilename in store_transport.list_dir('.'):
2409
2945
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2410
2946
        from bzrlib.branch import BzrBranchFormat5
2411
2947
        self.bzrdir = to_convert
2412
 
        self.pb = pb
 
2948
        self.pb = ui.ui_factory.nested_progress_bar()
2413
2949
        self.count = 0
2414
2950
        self.total = 20 # the steps we know about
2415
2951
        self.garbage_inventories = []
2416
2952
        self.dir_mode = self.bzrdir._get_dir_mode()
2417
2953
        self.file_mode = self.bzrdir._get_file_mode()
2418
2954
 
2419
 
        self.pb.note('starting upgrade from format 6 to metadir')
 
2955
        ui.ui_factory.note('starting upgrade from format 6 to metadir')
2420
2956
        self.bzrdir.transport.put_bytes(
2421
2957
                'branch-format',
2422
2958
                "Converting to format 6",
2443
2979
        self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2444
2980
        self.make_lock('repository')
2445
2981
        # we hard code the formats here because we are converting into
2446
 
        # the meta format. The meta format upgrader can take this to a 
 
2982
        # the meta format. The meta format upgrader can take this to a
2447
2983
        # future format within each component.
2448
2984
        self.put_format('repository', RepositoryFormat7())
2449
2985
        for entry in repository_names:
2472
3008
        else:
2473
3009
            has_checkout = True
2474
3010
        if not has_checkout:
2475
 
            self.pb.note('No working tree.')
 
3011
            ui.ui_factory.note('No working tree.')
2476
3012
            # If some checkout files are there, we may as well get rid of them.
2477
3013
            for name, mandatory in checkout_files:
2478
3014
                if name in bzrcontents:
2495
3031
            'branch-format',
2496
3032
            BzrDirMetaFormat1().get_format_string(),
2497
3033
            mode=self.file_mode)
 
3034
        self.pb.finished()
2498
3035
        return BzrDir.open(self.bzrdir.root_transport.base)
2499
3036
 
2500
3037
    def make_lock(self, name):
2536
3073
    def convert(self, to_convert, pb):
2537
3074
        """See Converter.convert()."""
2538
3075
        self.bzrdir = to_convert
2539
 
        self.pb = pb
 
3076
        self.pb = ui.ui_factory.nested_progress_bar()
2540
3077
        self.count = 0
2541
3078
        self.total = 1
2542
3079
        self.step('checking repository format')
2547
3084
        else:
2548
3085
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
2549
3086
                from bzrlib.repository import CopyConverter
2550
 
                self.pb.note('starting repository conversion')
 
3087
                ui.ui_factory.note('starting repository conversion')
2551
3088
                converter = CopyConverter(self.target_format.repository_format)
2552
3089
                converter.convert(repo, pb)
2553
 
        try:
2554
 
            branch = self.bzrdir.open_branch()
2555
 
        except errors.NotBranchError:
2556
 
            pass
2557
 
        else:
 
3090
        for branch in self.bzrdir.list_branches():
2558
3091
            # TODO: conversions of Branch and Tree should be done by
2559
3092
            # InterXFormat lookups/some sort of registry.
2560
3093
            # Avoid circular imports
2564
3097
            while old != new:
2565
3098
                if (old == _mod_branch.BzrBranchFormat5 and
2566
3099
                    new in (_mod_branch.BzrBranchFormat6,
2567
 
                        _mod_branch.BzrBranchFormat7)):
 
3100
                        _mod_branch.BzrBranchFormat7,
 
3101
                        _mod_branch.BzrBranchFormat8)):
2568
3102
                    branch_converter = _mod_branch.Converter5to6()
2569
3103
                elif (old == _mod_branch.BzrBranchFormat6 and
2570
 
                    new == _mod_branch.BzrBranchFormat7):
 
3104
                    new in (_mod_branch.BzrBranchFormat7,
 
3105
                            _mod_branch.BzrBranchFormat8)):
2571
3106
                    branch_converter = _mod_branch.Converter6to7()
 
3107
                elif (old == _mod_branch.BzrBranchFormat7 and
 
3108
                      new is _mod_branch.BzrBranchFormat8):
 
3109
                    branch_converter = _mod_branch.Converter7to8()
2572
3110
                else:
2573
 
                    raise errors.BadConversionTarget("No converter", new)
 
3111
                    raise errors.BadConversionTarget("No converter", new,
 
3112
                        branch._format)
2574
3113
                branch_converter.convert(branch)
2575
3114
                branch = self.bzrdir.open_branch()
2576
3115
                old = branch._format.__class__
2582
3121
            # TODO: conversions of Branch and Tree should be done by
2583
3122
            # InterXFormat lookups
2584
3123
            if (isinstance(tree, workingtree.WorkingTree3) and
2585
 
                not isinstance(tree, workingtree_4.WorkingTree4) and
 
3124
                not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2586
3125
                isinstance(self.target_format.workingtree_format,
2587
 
                    workingtree_4.WorkingTreeFormat4)):
 
3126
                    workingtree_4.DirStateWorkingTreeFormat)):
2588
3127
                workingtree_4.Converter3to4().convert(tree)
 
3128
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
3129
                not isinstance(tree, workingtree_4.WorkingTree5) and
 
3130
                isinstance(self.target_format.workingtree_format,
 
3131
                    workingtree_4.WorkingTreeFormat5)):
 
3132
                workingtree_4.Converter4to5().convert(tree)
 
3133
            if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
 
3134
                not isinstance(tree, workingtree_4.WorkingTree6) and
 
3135
                isinstance(self.target_format.workingtree_format,
 
3136
                    workingtree_4.WorkingTreeFormat6)):
 
3137
                workingtree_4.Converter4or5to6().convert(tree)
 
3138
        self.pb.finished()
2589
3139
        return to_convert
2590
3140
 
2591
3141
 
2592
 
# This is not in remote.py because it's small, and needs to be registered.
2593
 
# Putting it in remote.py creates a circular import problem.
 
3142
# This is not in remote.py because it's relatively small, and needs to be
 
3143
# registered. Putting it in remote.py creates a circular import problem.
2594
3144
# we can make it a lazy object if the control formats is turned into something
2595
3145
# like a registry.
2596
3146
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2597
3147
    """Format representing bzrdirs accessed via a smart server"""
2598
3148
 
 
3149
    def __init__(self):
 
3150
        BzrDirMetaFormat1.__init__(self)
 
3151
        # XXX: It's a bit ugly that the network name is here, because we'd
 
3152
        # like to believe that format objects are stateless or at least
 
3153
        # immutable,  However, we do at least avoid mutating the name after
 
3154
        # it's returned.  See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
 
3155
        self._network_name = None
 
3156
 
 
3157
    def __repr__(self):
 
3158
        return "%s(_network_name=%r)" % (self.__class__.__name__,
 
3159
            self._network_name)
 
3160
 
2599
3161
    def get_format_description(self):
 
3162
        if self._network_name:
 
3163
            real_format = network_format_registry.get(self._network_name)
 
3164
            return 'Remote: ' + real_format.get_format_description()
2600
3165
        return 'bzr remote bzrdir'
2601
 
    
 
3166
 
 
3167
    def get_format_string(self):
 
3168
        raise NotImplementedError(self.get_format_string)
 
3169
 
 
3170
    def network_name(self):
 
3171
        if self._network_name:
 
3172
            return self._network_name
 
3173
        else:
 
3174
            raise AssertionError("No network name set.")
 
3175
 
2602
3176
    @classmethod
2603
3177
    def probe_transport(klass, transport):
2604
3178
        """Return a RemoteBzrDirFormat object if it looks possible."""
2633
3207
            return local_dir_format.initialize_on_transport(transport)
2634
3208
        client = _SmartClient(client_medium)
2635
3209
        path = client.remote_path_from_transport(transport)
2636
 
        response = client.call('BzrDirFormat.initialize', path)
 
3210
        try:
 
3211
            response = client.call('BzrDirFormat.initialize', path)
 
3212
        except errors.ErrorFromSmartServer, err:
 
3213
            remote._translate_error(err, path=path)
2637
3214
        if response[0] != 'ok':
2638
3215
            raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2639
 
        return remote.RemoteBzrDir(transport)
 
3216
        format = RemoteBzrDirFormat()
 
3217
        self._supply_sub_formats_to(format)
 
3218
        return remote.RemoteBzrDir(transport, format)
 
3219
 
 
3220
    def parse_NoneTrueFalse(self, arg):
 
3221
        if not arg:
 
3222
            return None
 
3223
        if arg == 'False':
 
3224
            return False
 
3225
        if arg == 'True':
 
3226
            return True
 
3227
        raise AssertionError("invalid arg %r" % arg)
 
3228
 
 
3229
    def _serialize_NoneTrueFalse(self, arg):
 
3230
        if arg is False:
 
3231
            return 'False'
 
3232
        if arg:
 
3233
            return 'True'
 
3234
        return ''
 
3235
 
 
3236
    def _serialize_NoneString(self, arg):
 
3237
        return arg or ''
 
3238
 
 
3239
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
 
3240
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
3241
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
3242
        shared_repo=False):
 
3243
        try:
 
3244
            # hand off the request to the smart server
 
3245
            client_medium = transport.get_smart_medium()
 
3246
        except errors.NoSmartMedium:
 
3247
            do_vfs = True
 
3248
        else:
 
3249
            # Decline to open it if the server doesn't support our required
 
3250
            # version (3) so that the VFS-based transport will do it.
 
3251
            if client_medium.should_probe():
 
3252
                try:
 
3253
                    server_version = client_medium.protocol_version()
 
3254
                    if server_version != '2':
 
3255
                        do_vfs = True
 
3256
                    else:
 
3257
                        do_vfs = False
 
3258
                except errors.SmartProtocolError:
 
3259
                    # Apparently there's no usable smart server there, even though
 
3260
                    # the medium supports the smart protocol.
 
3261
                    do_vfs = True
 
3262
            else:
 
3263
                do_vfs = False
 
3264
        if not do_vfs:
 
3265
            client = _SmartClient(client_medium)
 
3266
            path = client.remote_path_from_transport(transport)
 
3267
            if client_medium._is_remote_before((1, 16)):
 
3268
                do_vfs = True
 
3269
        if do_vfs:
 
3270
            # TODO: lookup the local format from a server hint.
 
3271
            local_dir_format = BzrDirMetaFormat1()
 
3272
            self._supply_sub_formats_to(local_dir_format)
 
3273
            return local_dir_format.initialize_on_transport_ex(transport,
 
3274
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
3275
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
3276
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
3277
                make_working_trees=make_working_trees, shared_repo=shared_repo,
 
3278
                vfs_only=True)
 
3279
        return self._initialize_on_transport_ex_rpc(client, path, transport,
 
3280
            use_existing_dir, create_prefix, force_new_repo, stacked_on,
 
3281
            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
 
3282
 
 
3283
    def _initialize_on_transport_ex_rpc(self, client, path, transport,
 
3284
        use_existing_dir, create_prefix, force_new_repo, stacked_on,
 
3285
        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
 
3286
        args = []
 
3287
        args.append(self._serialize_NoneTrueFalse(use_existing_dir))
 
3288
        args.append(self._serialize_NoneTrueFalse(create_prefix))
 
3289
        args.append(self._serialize_NoneTrueFalse(force_new_repo))
 
3290
        args.append(self._serialize_NoneString(stacked_on))
 
3291
        # stack_on_pwd is often/usually our transport
 
3292
        if stack_on_pwd:
 
3293
            try:
 
3294
                stack_on_pwd = transport.relpath(stack_on_pwd)
 
3295
                if not stack_on_pwd:
 
3296
                    stack_on_pwd = '.'
 
3297
            except errors.PathNotChild:
 
3298
                pass
 
3299
        args.append(self._serialize_NoneString(stack_on_pwd))
 
3300
        args.append(self._serialize_NoneString(repo_format_name))
 
3301
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
 
3302
        args.append(self._serialize_NoneTrueFalse(shared_repo))
 
3303
        request_network_name = self._network_name or \
 
3304
            BzrDirFormat.get_default_format().network_name()
 
3305
        try:
 
3306
            response = client.call('BzrDirFormat.initialize_ex_1.16',
 
3307
                request_network_name, path, *args)
 
3308
        except errors.UnknownSmartMethod:
 
3309
            client._medium._remember_remote_is_before((1,16))
 
3310
            local_dir_format = BzrDirMetaFormat1()
 
3311
            self._supply_sub_formats_to(local_dir_format)
 
3312
            return local_dir_format.initialize_on_transport_ex(transport,
 
3313
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
3314
                force_new_repo=force_new_repo, stacked_on=stacked_on,
 
3315
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
3316
                make_working_trees=make_working_trees, shared_repo=shared_repo,
 
3317
                vfs_only=True)
 
3318
        except errors.ErrorFromSmartServer, err:
 
3319
            remote._translate_error(err, path=path)
 
3320
        repo_path = response[0]
 
3321
        bzrdir_name = response[6]
 
3322
        require_stacking = response[7]
 
3323
        require_stacking = self.parse_NoneTrueFalse(require_stacking)
 
3324
        format = RemoteBzrDirFormat()
 
3325
        format._network_name = bzrdir_name
 
3326
        self._supply_sub_formats_to(format)
 
3327
        bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
 
3328
        if repo_path:
 
3329
            repo_format = remote.response_tuple_to_repo_format(response[1:])
 
3330
            if repo_path == '.':
 
3331
                repo_path = ''
 
3332
            if repo_path:
 
3333
                repo_bzrdir_format = RemoteBzrDirFormat()
 
3334
                repo_bzrdir_format._network_name = response[5]
 
3335
                repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
 
3336
                    repo_bzrdir_format)
 
3337
            else:
 
3338
                repo_bzr = bzrdir
 
3339
            final_stack = response[8] or None
 
3340
            final_stack_pwd = response[9] or None
 
3341
            if final_stack_pwd:
 
3342
                final_stack_pwd = urlutils.join(
 
3343
                    transport.base, final_stack_pwd)
 
3344
            remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
 
3345
            if len(response) > 10:
 
3346
                # Updated server verb that locks remotely.
 
3347
                repo_lock_token = response[10] or None
 
3348
                remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
 
3349
                if repo_lock_token:
 
3350
                    remote_repo.dont_leave_lock_in_place()
 
3351
            else:
 
3352
                remote_repo.lock_write()
 
3353
            policy = UseExistingRepository(remote_repo, final_stack,
 
3354
                final_stack_pwd, require_stacking)
 
3355
            policy.acquire_repository()
 
3356
        else:
 
3357
            remote_repo = None
 
3358
            policy = None
 
3359
        bzrdir._format.set_branch_format(self.get_branch_format())
 
3360
        if require_stacking:
 
3361
            # The repo has already been created, but we need to make sure that
 
3362
            # we'll make a stackable branch.
 
3363
            bzrdir._format.require_stacking(_skip_repo=True)
 
3364
        return remote_repo, bzrdir, require_stacking, policy
2640
3365
 
2641
3366
    def _open(self, transport):
2642
 
        return remote.RemoteBzrDir(transport)
 
3367
        return remote.RemoteBzrDir(transport, self)
2643
3368
 
2644
3369
    def __eq__(self, other):
2645
3370
        if not isinstance(other, RemoteBzrDirFormat):
2646
3371
            return False
2647
3372
        return self.get_format_description() == other.get_format_description()
2648
3373
 
 
3374
    def __return_repository_format(self):
 
3375
        # Always return a RemoteRepositoryFormat object, but if a specific bzr
 
3376
        # repository format has been asked for, tell the RemoteRepositoryFormat
 
3377
        # that it should use that for init() etc.
 
3378
        result = remote.RemoteRepositoryFormat()
 
3379
        custom_format = getattr(self, '_repository_format', None)
 
3380
        if custom_format:
 
3381
            if isinstance(custom_format, remote.RemoteRepositoryFormat):
 
3382
                return custom_format
 
3383
            else:
 
3384
                # We will use the custom format to create repositories over the
 
3385
                # wire; expose its details like rich_root_data for code to
 
3386
                # query
 
3387
                result._custom_format = custom_format
 
3388
        return result
 
3389
 
 
3390
    def get_branch_format(self):
 
3391
        result = BzrDirMetaFormat1.get_branch_format(self)
 
3392
        if not isinstance(result, remote.RemoteBranchFormat):
 
3393
            new_result = remote.RemoteBranchFormat()
 
3394
            new_result._custom_format = result
 
3395
            # cache the result
 
3396
            self.set_branch_format(new_result)
 
3397
            result = new_result
 
3398
        return result
 
3399
 
 
3400
    repository_format = property(__return_repository_format,
 
3401
        BzrDirMetaFormat1._set_repository_format) #.im_func)
 
3402
 
2649
3403
 
2650
3404
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2651
3405
 
2661
3415
 
2662
3416
class BzrDirFormatRegistry(registry.Registry):
2663
3417
    """Registry of user-selectable BzrDir subformats.
2664
 
    
 
3418
 
2665
3419
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2666
3420
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
2667
3421
    """
2669
3423
    def __init__(self):
2670
3424
        """Create a BzrDirFormatRegistry."""
2671
3425
        self._aliases = set()
 
3426
        self._registration_order = list()
2672
3427
        super(BzrDirFormatRegistry, self).__init__()
2673
3428
 
2674
3429
    def aliases(self):
2685
3440
        """Register a metadir subformat.
2686
3441
 
2687
3442
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2688
 
        by the Repository format.
 
3443
        by the Repository/Branch/WorkingTreeformats.
2689
3444
 
2690
3445
        :param repository_format: The fully-qualified repository format class
2691
3446
            name as a string.
2725
3480
    def register(self, key, factory, help, native=True, deprecated=False,
2726
3481
                 hidden=False, experimental=False, alias=False):
2727
3482
        """Register a BzrDirFormat factory.
2728
 
        
 
3483
 
2729
3484
        The factory must be a callable that takes one parameter: the key.
2730
3485
        It must produce an instance of the BzrDirFormat when called.
2731
3486
 
2736
3491
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
2737
3492
        if alias:
2738
3493
            self._aliases.add(key)
 
3494
        self._registration_order.append(key)
2739
3495
 
2740
3496
    def register_lazy(self, key, module_name, member_name, help, native=True,
2741
3497
        deprecated=False, hidden=False, experimental=False, alias=False):
2743
3499
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
2744
3500
        if alias:
2745
3501
            self._aliases.add(key)
 
3502
        self._registration_order.append(key)
2746
3503
 
2747
3504
    def set_default(self, key):
2748
3505
        """Set the 'default' key to be a clone of the supplied key.
2749
 
        
 
3506
 
2750
3507
        This method must be called once and only once.
2751
3508
        """
2752
3509
        registry.Registry.register(self, 'default', self.get(key),
2755
3512
 
2756
3513
    def set_default_repository(self, key):
2757
3514
        """Set the FormatRegistry default and Repository default.
2758
 
        
 
3515
 
2759
3516
        This is a transitional method while Repository.set_default_format
2760
3517
        is deprecated.
2761
3518
        """
2768
3525
        return self.get(key)()
2769
3526
 
2770
3527
    def help_topic(self, topic):
2771
 
        output = textwrap.dedent("""\
2772
 
            These formats can be used for creating branches, working trees, and
2773
 
            repositories.
2774
 
 
2775
 
            """)
 
3528
        output = ""
2776
3529
        default_realkey = None
2777
3530
        default_help = self.get_help('default')
2778
3531
        help_pairs = []
2779
 
        for key in self.keys():
 
3532
        for key in self._registration_order:
2780
3533
            if key == 'default':
2781
3534
                continue
2782
3535
            help = self.get_help(key)
2788
3541
        def wrapped(key, help, info):
2789
3542
            if info.native:
2790
3543
                help = '(native) ' + help
2791
 
            return ':%s:\n%s\n\n' % (key, 
2792
 
                    textwrap.fill(help, initial_indent='    ', 
2793
 
                    subsequent_indent='    '))
 
3544
            return ':%s:\n%s\n\n' % (key,
 
3545
                textwrap.fill(help, initial_indent='    ',
 
3546
                    subsequent_indent='    ',
 
3547
                    break_long_words=False))
2794
3548
        if default_realkey is not None:
2795
3549
            output += wrapped(default_realkey, '(default) %s' % default_help,
2796
3550
                              self.get_info('default'))
2806
3560
                experimental_pairs.append((key, help))
2807
3561
            else:
2808
3562
                output += wrapped(key, help, info)
 
3563
        output += "\nSee :doc:`formats-help` for more about storage formats."
 
3564
        other_output = ""
2809
3565
        if len(experimental_pairs) > 0:
2810
 
            output += "Experimental formats are shown below.\n\n"
 
3566
            other_output += "Experimental formats are shown below.\n\n"
2811
3567
            for key, help in experimental_pairs:
2812
3568
                info = self.get_info(key)
2813
 
                output += wrapped(key, help, info)
 
3569
                other_output += wrapped(key, help, info)
 
3570
        else:
 
3571
            other_output += \
 
3572
                "No experimental formats are available.\n\n"
2814
3573
        if len(deprecated_pairs) > 0:
2815
 
            output += "Deprecated formats are shown below.\n\n"
 
3574
            other_output += "\nDeprecated formats are shown below.\n\n"
2816
3575
            for key, help in deprecated_pairs:
2817
3576
                info = self.get_info(key)
2818
 
                output += wrapped(key, help, info)
 
3577
                other_output += wrapped(key, help, info)
 
3578
        else:
 
3579
            other_output += \
 
3580
                "\nNo deprecated formats are available.\n\n"
 
3581
        other_output += \
 
3582
                "\nSee :doc:`formats-help` for more about storage formats."
2819
3583
 
2820
 
        return output
 
3584
        if topic == 'other-formats':
 
3585
            return other_output
 
3586
        else:
 
3587
            return output
2821
3588
 
2822
3589
 
2823
3590
class RepositoryAcquisitionPolicy(object):
2857
3624
                stack_on = self._get_full_stack_on()
2858
3625
        try:
2859
3626
            branch.set_stacked_on_url(stack_on)
2860
 
        except errors.UnstackableBranchFormat:
 
3627
        except (errors.UnstackableBranchFormat,
 
3628
                errors.UnstackableRepositoryFormat):
2861
3629
            if self._require_stacking:
2862
3630
                raise
2863
3631
 
 
3632
    def requires_stacking(self):
 
3633
        """Return True if this policy requires stacking."""
 
3634
        return self._stack_on is not None and self._require_stacking
 
3635
 
2864
3636
    def _get_full_stack_on(self):
2865
3637
        """Get a fully-qualified URL for the stack_on location."""
2866
3638
        if self._stack_on is None:
2870
3642
        else:
2871
3643
            return urlutils.join(self._stack_on_pwd, self._stack_on)
2872
3644
 
2873
 
    def _add_fallback(self, repository):
 
3645
    def _add_fallback(self, repository, possible_transports=None):
2874
3646
        """Add a fallback to the supplied repository, if stacking is set."""
2875
3647
        stack_on = self._get_full_stack_on()
2876
3648
        if stack_on is None:
2877
3649
            return
2878
 
        stacked_dir = BzrDir.open(stack_on)
 
3650
        try:
 
3651
            stacked_dir = BzrDir.open(stack_on,
 
3652
                                      possible_transports=possible_transports)
 
3653
        except errors.JailBreak:
 
3654
            # We keep the stacking details, but we are in the server code so
 
3655
            # actually stacking is not needed.
 
3656
            return
2879
3657
        try:
2880
3658
            stacked_repo = stacked_dir.open_branch().repository
2881
3659
        except errors.NotBranchError:
2885
3663
        except errors.UnstackableRepositoryFormat:
2886
3664
            if self._require_stacking:
2887
3665
                raise
 
3666
        else:
 
3667
            self._require_stacking = True
2888
3668
 
2889
3669
    def acquire_repository(self, make_working_trees=None, shared=False):
2890
3670
        """Acquire a repository for this bzrdir.
2894
3674
        :param make_working_trees: If creating a repository, set
2895
3675
            make_working_trees to this value (if non-None)
2896
3676
        :param shared: If creating a repository, make it shared if True
2897
 
        :return: A repository
 
3677
        :return: A repository, is_new_flag (True if the repository was
 
3678
            created).
2898
3679
        """
2899
3680
        raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2900
3681
 
2920
3701
 
2921
3702
        Creates the desired repository in the bzrdir we already have.
2922
3703
        """
 
3704
        stack_on = self._get_full_stack_on()
 
3705
        if stack_on:
 
3706
            format = self._bzrdir._format
 
3707
            format.require_stacking(stack_on=stack_on,
 
3708
                                    possible_transports=[self._bzrdir.root_transport])
 
3709
            if not self._require_stacking:
 
3710
                # We have picked up automatic stacking somewhere.
 
3711
                note('Using default stacking branch %s at %s', self._stack_on,
 
3712
                    self._stack_on_pwd)
2923
3713
        repository = self._bzrdir.create_repository(shared=shared)
2924
 
        self._add_fallback(repository)
 
3714
        self._add_fallback(repository,
 
3715
                           possible_transports=[self._bzrdir.transport])
2925
3716
        if make_working_trees is not None:
2926
3717
            repository.set_make_working_trees(make_working_trees)
2927
 
        return repository
 
3718
        return repository, True
2928
3719
 
2929
3720
 
2930
3721
class UseExistingRepository(RepositoryAcquisitionPolicy):
2946
3737
    def acquire_repository(self, make_working_trees=None, shared=False):
2947
3738
        """Implementation of RepositoryAcquisitionPolicy.acquire_repository
2948
3739
 
2949
 
        Returns an existing repository to use
 
3740
        Returns an existing repository to use.
2950
3741
        """
2951
 
        self._add_fallback(self._repository)
2952
 
        return self._repository
2953
 
 
2954
 
 
 
3742
        self._add_fallback(self._repository,
 
3743
                       possible_transports=[self._repository.bzrdir.transport])
 
3744
        return self._repository, False
 
3745
 
 
3746
 
 
3747
# Please register new formats after old formats so that formats
 
3748
# appear in chronological order and format descriptions can build
 
3749
# on previous ones.
2955
3750
format_registry = BzrDirFormatRegistry()
 
3751
# The pre-0.8 formats have their repository format network name registered in
 
3752
# repository.py. MetaDir formats have their repository format network name
 
3753
# inferred from their disk format string.
2956
3754
format_registry.register('weave', BzrDirFormat6,
2957
3755
    'Pre-0.8 format.  Slower than knit and does not'
2958
3756
    ' support checkouts or shared repositories.',
 
3757
    hidden=True,
2959
3758
    deprecated=True)
2960
 
format_registry.register_metadir('knit',
2961
 
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2962
 
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
2963
 
    branch_format='bzrlib.branch.BzrBranchFormat5',
2964
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2965
3759
format_registry.register_metadir('metaweave',
2966
3760
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2967
3761
    'Transitional format in 0.8.  Slower than knit.',
2968
3762
    branch_format='bzrlib.branch.BzrBranchFormat5',
2969
3763
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3764
    hidden=True,
 
3765
    deprecated=True)
 
3766
format_registry.register_metadir('knit',
 
3767
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
3768
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
 
3769
    branch_format='bzrlib.branch.BzrBranchFormat5',
 
3770
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3771
    hidden=True,
2970
3772
    deprecated=True)
2971
3773
format_registry.register_metadir('dirstate',
2972
3774
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2976
3778
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2977
3779
    # directly from workingtree_4 triggers a circular import.
2978
3780
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2979
 
    )
 
3781
    hidden=True,
 
3782
    deprecated=True)
2980
3783
format_registry.register_metadir('dirstate-tags',
2981
3784
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2982
3785
    help='New in 0.15: Fast local operations and improved scaling for '
2984
3787
        ' Incompatible with bzr < 0.15.',
2985
3788
    branch_format='bzrlib.branch.BzrBranchFormat6',
2986
3789
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2987
 
    )
 
3790
    hidden=True,
 
3791
    deprecated=True)
2988
3792
format_registry.register_metadir('rich-root',
2989
3793
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2990
3794
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
2991
 
        ' bzr < 1.0',
 
3795
        ' bzr < 1.0.',
2992
3796
    branch_format='bzrlib.branch.BzrBranchFormat6',
2993
3797
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2994
 
    )
 
3798
    hidden=True,
 
3799
    deprecated=True)
2995
3800
format_registry.register_metadir('dirstate-with-subtree',
2996
3801
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2997
3802
    help='New in 0.15: Fast local operations and improved scaling for '
3007
3812
    help='New in 0.92: Pack-based format with data compatible with '
3008
3813
        'dirstate-tags format repositories. Interoperates with '
3009
3814
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3010
 
        'Previously called knitpack-experimental.  '
3011
 
        'For more information, see '
3012
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3815
        ,
3013
3816
    branch_format='bzrlib.branch.BzrBranchFormat6',
3014
3817
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3015
3818
    )
3018
3821
    help='New in 0.92: Pack-based format with data compatible with '
3019
3822
        'dirstate-with-subtree format repositories. Interoperates with '
3020
3823
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3021
 
        'Previously called knitpack-experimental.  '
3022
 
        'For more information, see '
3023
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3824
        ,
3024
3825
    branch_format='bzrlib.branch.BzrBranchFormat6',
3025
3826
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3026
3827
    hidden=True,
3028
3829
    )
3029
3830
format_registry.register_metadir('rich-root-pack',
3030
3831
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3031
 
    help='New in 1.0: Pack-based format with data compatible with '
3032
 
        'rich-root format repositories. Incompatible with'
3033
 
        ' bzr < 1.0',
 
3832
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
 
3833
         '(needed for bzr-svn and bzr-git).',
3034
3834
    branch_format='bzrlib.branch.BzrBranchFormat6',
3035
3835
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3836
    hidden=True,
3036
3837
    )
3037
3838
format_registry.register_metadir('1.6',
3038
3839
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3039
 
    help='A branch and pack based repository that supports stacking. ',
 
3840
    help='A format that allows a branch to indicate that there is another '
 
3841
         '(stacked) repository that should be used to access data that is '
 
3842
         'not present locally.',
3040
3843
    branch_format='bzrlib.branch.BzrBranchFormat7',
3041
3844
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3845
    hidden=True,
3042
3846
    )
3043
3847
format_registry.register_metadir('1.6.1-rich-root',
3044
3848
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3045
 
    help='A branch and pack based repository that supports stacking '
3046
 
         'and rich root data (needed for bzr-svn). ',
3047
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3048
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3049
 
    )
3050
 
# The following two formats should always just be aliases.
3051
 
format_registry.register_metadir('development',
3052
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3053
 
    help='Current development format. Can convert data to and from pack-0.92 '
3054
 
        '(and anything compatible with pack-0.92) format repositories. '
3055
 
        'Repositories and branches in this format can only be read by bzr.dev. '
3056
 
        'Please read '
3057
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3849
    help='A variant of 1.6 that supports rich-root data '
 
3850
         '(needed for bzr-svn and bzr-git).',
 
3851
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3852
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3853
    hidden=True,
 
3854
    )
 
3855
format_registry.register_metadir('1.9',
 
3856
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
 
3857
    help='A repository format using B+tree indexes. These indexes '
 
3858
         'are smaller in size, have smarter caching and provide faster '
 
3859
         'performance for most operations.',
 
3860
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3861
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3862
    hidden=True,
 
3863
    )
 
3864
format_registry.register_metadir('1.9-rich-root',
 
3865
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
 
3866
    help='A variant of 1.9 that supports rich-root data '
 
3867
         '(needed for bzr-svn and bzr-git).',
 
3868
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3869
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3870
    hidden=True,
 
3871
    )
 
3872
format_registry.register_metadir('1.14',
 
3873
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
 
3874
    help='A working-tree format that supports content filtering.',
 
3875
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3876
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3877
    )
 
3878
format_registry.register_metadir('1.14-rich-root',
 
3879
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
 
3880
    help='A variant of 1.14 that supports rich-root data '
 
3881
         '(needed for bzr-svn and bzr-git).',
 
3882
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3883
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
 
3884
    )
 
3885
# The following un-numbered 'development' formats should always just be aliases.
 
3886
format_registry.register_metadir('development-rich-root',
 
3887
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
 
3888
    help='Current development format. Supports rich roots. Can convert data '
 
3889
        'to and from rich-root-pack (and anything compatible with '
 
3890
        'rich-root-pack) format repositories. Repositories and branches in '
 
3891
        'this format can only be read by bzr.dev. Please read '
 
3892
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3058
3893
        'before use.',
3059
3894
    branch_format='bzrlib.branch.BzrBranchFormat7',
3060
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3895
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3061
3896
    experimental=True,
3062
3897
    alias=True,
 
3898
    hidden=True,
3063
3899
    )
3064
3900
format_registry.register_metadir('development-subtree',
3065
3901
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3067
3903
        'from pack-0.92-subtree (and anything compatible with '
3068
3904
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3069
3905
        'this format can only be read by bzr.dev. Please read '
3070
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3906
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3071
3907
        'before use.',
3072
3908
    branch_format='bzrlib.branch.BzrBranchFormat7',
3073
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3909
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3074
3910
    experimental=True,
3075
 
    alias=True,
 
3911
    hidden=True,
 
3912
    alias=False, # Restore to being an alias when an actual development subtree format is added
 
3913
                 # This current non-alias status is simply because we did not introduce a
 
3914
                 # chk based subtree format.
3076
3915
    )
 
3916
 
3077
3917
# And the development formats above will have aliased one of the following:
3078
 
format_registry.register_metadir('development2',
3079
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3080
 
    help='1.6.1 with B+Tree based index. '
3081
 
        'Please read '
3082
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3083
 
        'before use.',
3084
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3085
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3086
 
    hidden=True,
3087
 
    experimental=True,
3088
 
    )
3089
 
format_registry.register_metadir('development2-subtree',
3090
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3091
 
    help='1.6.1-subtree with B+Tree based index. '
3092
 
        'Please read '
3093
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3094
 
        'before use.',
3095
 
    branch_format='bzrlib.branch.BzrBranchFormat7',
3096
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3097
 
    hidden=True,
3098
 
    experimental=True,
3099
 
    )
 
3918
format_registry.register_metadir('development6-rich-root',
 
3919
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
 
3920
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
 
3921
        'Please read '
 
3922
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3923
        'before use.',
 
3924
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3925
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3926
    hidden=True,
 
3927
    experimental=True,
 
3928
    )
 
3929
 
 
3930
format_registry.register_metadir('development7-rich-root',
 
3931
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
 
3932
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
 
3933
        'rich roots. Please read '
 
3934
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
 
3935
        'before use.',
 
3936
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3937
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3938
    hidden=True,
 
3939
    experimental=True,
 
3940
    )
 
3941
 
 
3942
format_registry.register_metadir('2a',
 
3943
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
 
3944
    help='First format for bzr 2.0 series.\n'
 
3945
        'Uses group-compress storage.\n'
 
3946
        'Provides rich roots which are a one-way transition.\n',
 
3947
        # 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
 
3948
        # 'rich roots. Supported by bzr 1.16 and later.',
 
3949
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3950
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3951
    experimental=True,
 
3952
    )
 
3953
 
 
3954
# The following format should be an alias for the rich root equivalent 
 
3955
# of the default format
 
3956
format_registry.register_metadir('default-rich-root',
 
3957
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
 
3958
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3959
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
 
3960
    alias=True,
 
3961
    hidden=True,
 
3962
    help='Same as 2a.')
 
3963
 
3100
3964
# The current format that is made on 'bzr init'.
3101
 
format_registry.set_default('pack-0.92')
 
3965
format_registry.set_default('2a')