~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/controldir.py

(gz) Fix deprecations of win32utils path function unicode wrappers (Martin
 Packman)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
"""
24
24
 
 
25
from __future__ import absolute_import
 
26
 
25
27
from bzrlib.lazy_import import lazy_import
26
28
lazy_import(globals(), """
27
29
import textwrap
28
30
 
29
31
from bzrlib import (
30
32
    errors,
 
33
    hooks,
31
34
    revision as _mod_revision,
32
35
    transport as _mod_transport,
 
36
    trace,
33
37
    ui,
 
38
    urlutils,
34
39
    )
 
40
from bzrlib.transport import local
35
41
from bzrlib.push import (
36
42
    PushResult,
37
43
    )
38
44
 
 
45
from bzrlib.i18n import gettext
39
46
""")
40
47
 
41
48
from bzrlib import registry
74
81
        return self.user_transport.base
75
82
 
76
83
 
77
 
 
78
84
class ControlDir(ControlComponent):
79
85
    """A control directory.
80
86
 
102
108
        """Return a sequence of all branches local to this control directory.
103
109
 
104
110
        """
 
111
        return self.get_branches().values()
 
112
 
 
113
    def get_branches(self):
 
114
        """Get all branches in this control directory, as a dictionary.
 
115
        
 
116
        :return: Dictionary mapping branch names to instances.
 
117
        """
105
118
        try:
106
 
            return [self.open_branch()]
 
119
           return { None: self.open_branch() }
107
120
        except (errors.NotBranchError, errors.NoRepositoryPresent):
108
 
            return []
 
121
           return {}
109
122
 
110
123
    def is_control_filename(self, filename):
111
124
        """True if filename is the name of a path which is reserved for
145
158
        """Destroy the repository in this ControlDir."""
146
159
        raise NotImplementedError(self.destroy_repository)
147
160
 
148
 
    def create_branch(self, name=None, repository=None):
 
161
    def create_branch(self, name=None, repository=None,
 
162
                      append_revisions_only=None):
149
163
        """Create a branch in this ControlDir.
150
164
 
151
165
        :param name: Name of the colocated branch to create, None for
152
166
            the default branch.
 
167
        :param append_revisions_only: Whether this branch should only allow
 
168
            appending new revisions to its history.
153
169
 
154
170
        The controldirs format will control what branch format is created.
155
171
        For more control see BranchFormatXX.create(a_controldir).
193
209
        """
194
210
        raise NotImplementedError(self.destroy_workingtree_metadata)
195
211
 
 
212
    def find_branch_format(self, name=None):
 
213
        """Find the branch 'format' for this controldir.
 
214
 
 
215
        This might be a synthetic object for e.g. RemoteBranch and SVN.
 
216
        """
 
217
        raise NotImplementedError(self.find_branch_format)
 
218
 
196
219
    def get_branch_reference(self, name=None):
197
220
        """Return the referenced URL for the branch in this controldir.
198
221
 
208
231
        return None
209
232
 
210
233
    def open_branch(self, name=None, unsupported=False,
211
 
                    ignore_fallbacks=False):
 
234
                    ignore_fallbacks=False, possible_transports=None):
212
235
        """Open the branch object at this ControlDir if one is present.
213
236
 
214
 
        If unsupported is True, then no longer supported branch formats can
215
 
        still be opened.
216
 
 
217
 
        TODO: static convenience version of this?
 
237
        :param unsupported: if True, then no longer supported branch formats can
 
238
            still be opened.
 
239
        :param ignore_fallbacks: Whether to open fallback repositories
 
240
        :param possible_transports: Transports to use for opening e.g.
 
241
            fallback repositories.
218
242
        """
219
243
        raise NotImplementedError(self.open_branch)
220
244
 
226
250
        get at a repository.
227
251
 
228
252
        :param _unsupported: a private parameter, not part of the api.
229
 
 
230
 
        TODO: static convenience version of this?
231
253
        """
232
254
        raise NotImplementedError(self.open_repository)
233
255
 
261
283
        branch and discards it, and that's somewhat expensive.)
262
284
        """
263
285
        try:
264
 
            self.open_branch(name)
 
286
            self.open_branch(name, ignore_fallbacks=True)
265
287
            return True
266
288
        except errors.NotBranchError:
267
289
            return False
268
290
 
 
291
    def _get_selected_branch(self):
 
292
        """Return the name of the branch selected by the user.
 
293
 
 
294
        :return: Name of the branch selected by the user, or None.
 
295
        """
 
296
        branch = self.root_transport.get_segment_parameters().get("branch")
 
297
        if branch is not None:
 
298
            branch = urlutils.unescape(branch)
 
299
        return branch
 
300
 
269
301
    def has_workingtree(self):
270
302
        """Tell if this controldir contains a working tree.
271
303
 
298
330
        raise NotImplementedError(self.cloning_metadir)
299
331
 
300
332
    def checkout_metadir(self):
301
 
        """Produce a metadir suitable for checkouts of this controldir."""
 
333
        """Produce a metadir suitable for checkouts of this controldir.
 
334
 
 
335
        :returns: A ControlDirFormat with all component formats
 
336
            either set appropriately or set to None if that component
 
337
            should not be created.
 
338
        """
302
339
        return self.cloning_metadir()
303
340
 
304
341
    def sprout(self, url, revision_id=None, force_new_repo=False,
395
432
        return push_result
396
433
 
397
434
    def _get_tree_branch(self, name=None):
398
 
        """Return the branch and tree, if any, for this bzrdir.
 
435
        """Return the branch and tree, if any, for this controldir.
399
436
 
400
437
        :param name: Name of colocated branch to open.
401
438
 
420
457
        raise NotImplementedError(self.get_config)
421
458
 
422
459
    def check_conversion_target(self, target_format):
423
 
        """Check that a bzrdir as a whole can be converted to a new format."""
 
460
        """Check that a controldir as a whole can be converted to a new format."""
424
461
        raise NotImplementedError(self.check_conversion_target)
425
462
 
426
463
    def clone(self, url, revision_id=None, force_new_repo=False,
427
464
              preserve_stacking=False):
428
 
        """Clone this bzrdir and its contents to url verbatim.
 
465
        """Clone this controldir and its contents to url verbatim.
429
466
 
430
467
        :param url: The url create the clone at.  If url's last component does
431
468
            not exist, it will be created.
445
482
    def clone_on_transport(self, transport, revision_id=None,
446
483
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
447
484
        create_prefix=False, use_existing_dir=True, no_tree=False):
448
 
        """Clone this bzrdir and its contents to transport verbatim.
 
485
        """Clone this controldir and its contents to transport verbatim.
449
486
 
450
487
        :param transport: The transport for the location to produce the clone
451
488
            at.  If the target directory does not exist, it will be created.
463
500
        """
464
501
        raise NotImplementedError(self.clone_on_transport)
465
502
 
 
503
    @classmethod
 
504
    def find_bzrdirs(klass, transport, evaluate=None, list_current=None):
 
505
        """Find control dirs recursively from current location.
 
506
 
 
507
        This is intended primarily as a building block for more sophisticated
 
508
        functionality, like finding trees under a directory, or finding
 
509
        branches that use a given repository.
 
510
 
 
511
        :param evaluate: An optional callable that yields recurse, value,
 
512
            where recurse controls whether this controldir is recursed into
 
513
            and value is the value to yield.  By default, all bzrdirs
 
514
            are recursed into, and the return value is the controldir.
 
515
        :param list_current: if supplied, use this function to list the current
 
516
            directory, instead of Transport.list_dir
 
517
        :return: a generator of found bzrdirs, or whatever evaluate returns.
 
518
        """
 
519
        if list_current is None:
 
520
            def list_current(transport):
 
521
                return transport.list_dir('')
 
522
        if evaluate is None:
 
523
            def evaluate(controldir):
 
524
                return True, controldir
 
525
 
 
526
        pending = [transport]
 
527
        while len(pending) > 0:
 
528
            current_transport = pending.pop()
 
529
            recurse = True
 
530
            try:
 
531
                controldir = klass.open_from_transport(current_transport)
 
532
            except (errors.NotBranchError, errors.PermissionDenied):
 
533
                pass
 
534
            else:
 
535
                recurse, value = evaluate(controldir)
 
536
                yield value
 
537
            try:
 
538
                subdirs = list_current(current_transport)
 
539
            except (errors.NoSuchFile, errors.PermissionDenied):
 
540
                continue
 
541
            if recurse:
 
542
                for subdir in sorted(subdirs, reverse=True):
 
543
                    pending.append(current_transport.clone(subdir))
 
544
 
 
545
    @classmethod
 
546
    def find_branches(klass, transport):
 
547
        """Find all branches under a transport.
 
548
 
 
549
        This will find all branches below the transport, including branches
 
550
        inside other branches.  Where possible, it will use
 
551
        Repository.find_branches.
 
552
 
 
553
        To list all the branches that use a particular Repository, see
 
554
        Repository.find_branches
 
555
        """
 
556
        def evaluate(controldir):
 
557
            try:
 
558
                repository = controldir.open_repository()
 
559
            except errors.NoRepositoryPresent:
 
560
                pass
 
561
            else:
 
562
                return False, ([], repository)
 
563
            return True, (controldir.list_branches(), None)
 
564
        ret = []
 
565
        for branches, repo in klass.find_bzrdirs(
 
566
                transport, evaluate=evaluate):
 
567
            if repo is not None:
 
568
                ret.extend(repo.find_branches())
 
569
            if branches is not None:
 
570
                ret.extend(branches)
 
571
        return ret
 
572
 
 
573
    @classmethod
 
574
    def create_branch_and_repo(klass, base, force_new_repo=False, format=None):
 
575
        """Create a new ControlDir, Branch and Repository at the url 'base'.
 
576
 
 
577
        This will use the current default ControlDirFormat unless one is
 
578
        specified, and use whatever
 
579
        repository format that that uses via controldir.create_branch and
 
580
        create_repository. If a shared repository is available that is used
 
581
        preferentially.
 
582
 
 
583
        The created Branch object is returned.
 
584
 
 
585
        :param base: The URL to create the branch at.
 
586
        :param force_new_repo: If True a new repository is always created.
 
587
        :param format: If supplied, the format of branch to create.  If not
 
588
            supplied, the default is used.
 
589
        """
 
590
        controldir = klass.create(base, format)
 
591
        controldir._find_or_create_repository(force_new_repo)
 
592
        return controldir.create_branch()
 
593
 
 
594
    @classmethod
 
595
    def create_branch_convenience(klass, base, force_new_repo=False,
 
596
                                  force_new_tree=None, format=None,
 
597
                                  possible_transports=None):
 
598
        """Create a new ControlDir, Branch and Repository at the url 'base'.
 
599
 
 
600
        This is a convenience function - it will use an existing repository
 
601
        if possible, can be told explicitly whether to create a working tree or
 
602
        not.
 
603
 
 
604
        This will use the current default ControlDirFormat unless one is
 
605
        specified, and use whatever
 
606
        repository format that that uses via ControlDir.create_branch and
 
607
        create_repository. If a shared repository is available that is used
 
608
        preferentially. Whatever repository is used, its tree creation policy
 
609
        is followed.
 
610
 
 
611
        The created Branch object is returned.
 
612
        If a working tree cannot be made due to base not being a file:// url,
 
613
        no error is raised unless force_new_tree is True, in which case no
 
614
        data is created on disk and NotLocalUrl is raised.
 
615
 
 
616
        :param base: The URL to create the branch at.
 
617
        :param force_new_repo: If True a new repository is always created.
 
618
        :param force_new_tree: If True or False force creation of a tree or
 
619
                               prevent such creation respectively.
 
620
        :param format: Override for the controldir format to create.
 
621
        :param possible_transports: An optional reusable transports list.
 
622
        """
 
623
        if force_new_tree:
 
624
            # check for non local urls
 
625
            t = _mod_transport.get_transport(base, possible_transports)
 
626
            if not isinstance(t, local.LocalTransport):
 
627
                raise errors.NotLocalUrl(base)
 
628
        controldir = klass.create(base, format, possible_transports)
 
629
        repo = controldir._find_or_create_repository(force_new_repo)
 
630
        result = controldir.create_branch()
 
631
        if force_new_tree or (repo.make_working_trees() and
 
632
                              force_new_tree is None):
 
633
            try:
 
634
                controldir.create_workingtree()
 
635
            except errors.NotLocalUrl:
 
636
                pass
 
637
        return result
 
638
 
 
639
    @classmethod
 
640
    def create_standalone_workingtree(klass, base, format=None):
 
641
        """Create a new ControlDir, WorkingTree, Branch and Repository at 'base'.
 
642
 
 
643
        'base' must be a local path or a file:// url.
 
644
 
 
645
        This will use the current default ControlDirFormat unless one is
 
646
        specified, and use whatever
 
647
        repository format that that uses for bzrdirformat.create_workingtree,
 
648
        create_branch and create_repository.
 
649
 
 
650
        :param format: Override for the controldir format to create.
 
651
        :return: The WorkingTree object.
 
652
        """
 
653
        t = _mod_transport.get_transport(base)
 
654
        if not isinstance(t, local.LocalTransport):
 
655
            raise errors.NotLocalUrl(base)
 
656
        controldir = klass.create_branch_and_repo(base,
 
657
                                               force_new_repo=True,
 
658
                                               format=format).bzrdir
 
659
        return controldir.create_workingtree()
 
660
 
 
661
    @classmethod
 
662
    def open_unsupported(klass, base):
 
663
        """Open a branch which is not supported."""
 
664
        return klass.open(base, _unsupported=True)
 
665
 
 
666
    @classmethod
 
667
    def open(klass, base, _unsupported=False, possible_transports=None):
 
668
        """Open an existing controldir, rooted at 'base' (url).
 
669
 
 
670
        :param _unsupported: a private parameter to the ControlDir class.
 
671
        """
 
672
        t = _mod_transport.get_transport(base, possible_transports)
 
673
        return klass.open_from_transport(t, _unsupported=_unsupported)
 
674
 
 
675
    @classmethod
 
676
    def open_from_transport(klass, transport, _unsupported=False,
 
677
                            _server_formats=True):
 
678
        """Open a controldir within a particular directory.
 
679
 
 
680
        :param transport: Transport containing the controldir.
 
681
        :param _unsupported: private.
 
682
        """
 
683
        for hook in klass.hooks['pre_open']:
 
684
            hook(transport)
 
685
        # Keep initial base since 'transport' may be modified while following
 
686
        # the redirections.
 
687
        base = transport.base
 
688
        def find_format(transport):
 
689
            return transport, ControlDirFormat.find_format(
 
690
                transport, _server_formats=_server_formats)
 
691
 
 
692
        def redirected(transport, e, redirection_notice):
 
693
            redirected_transport = transport._redirected_to(e.source, e.target)
 
694
            if redirected_transport is None:
 
695
                raise errors.NotBranchError(base)
 
696
            trace.note(gettext('{0} is{1} redirected to {2}').format(
 
697
                 transport.base, e.permanently, redirected_transport.base))
 
698
            return redirected_transport
 
699
 
 
700
        try:
 
701
            transport, format = _mod_transport.do_catching_redirections(
 
702
                find_format, transport, redirected)
 
703
        except errors.TooManyRedirections:
 
704
            raise errors.NotBranchError(base)
 
705
 
 
706
        format.check_support_status(_unsupported)
 
707
        return format.open(transport, _found=True)
 
708
 
 
709
    @classmethod
 
710
    def open_containing(klass, url, possible_transports=None):
 
711
        """Open an existing branch which contains url.
 
712
 
 
713
        :param url: url to search from.
 
714
 
 
715
        See open_containing_from_transport for more detail.
 
716
        """
 
717
        transport = _mod_transport.get_transport(url, possible_transports)
 
718
        return klass.open_containing_from_transport(transport)
 
719
 
 
720
    @classmethod
 
721
    def open_containing_from_transport(klass, a_transport):
 
722
        """Open an existing branch which contains a_transport.base.
 
723
 
 
724
        This probes for a branch at a_transport, and searches upwards from there.
 
725
 
 
726
        Basically we keep looking up until we find the control directory or
 
727
        run into the root.  If there isn't one, raises NotBranchError.
 
728
        If there is one and it is either an unrecognised format or an unsupported
 
729
        format, UnknownFormatError or UnsupportedFormatError are raised.
 
730
        If there is one, it is returned, along with the unused portion of url.
 
731
 
 
732
        :return: The ControlDir that contains the path, and a Unicode path
 
733
                for the rest of the URL.
 
734
        """
 
735
        # this gets the normalised url back. I.e. '.' -> the full path.
 
736
        url = a_transport.base
 
737
        while True:
 
738
            try:
 
739
                result = klass.open_from_transport(a_transport)
 
740
                return result, urlutils.unescape(a_transport.relpath(url))
 
741
            except errors.NotBranchError, e:
 
742
                pass
 
743
            except errors.PermissionDenied:
 
744
                pass
 
745
            try:
 
746
                new_t = a_transport.clone('..')
 
747
            except errors.InvalidURLJoin:
 
748
                # reached the root, whatever that may be
 
749
                raise errors.NotBranchError(path=url)
 
750
            if new_t.base == a_transport.base:
 
751
                # reached the root, whatever that may be
 
752
                raise errors.NotBranchError(path=url)
 
753
            a_transport = new_t
 
754
 
 
755
    @classmethod
 
756
    def open_tree_or_branch(klass, location):
 
757
        """Return the branch and working tree at a location.
 
758
 
 
759
        If there is no tree at the location, tree will be None.
 
760
        If there is no branch at the location, an exception will be
 
761
        raised
 
762
        :return: (tree, branch)
 
763
        """
 
764
        controldir = klass.open(location)
 
765
        return controldir._get_tree_branch()
 
766
 
 
767
    @classmethod
 
768
    def open_containing_tree_or_branch(klass, location):
 
769
        """Return the branch and working tree contained by a location.
 
770
 
 
771
        Returns (tree, branch, relpath).
 
772
        If there is no tree at containing the location, tree will be None.
 
773
        If there is no branch containing the location, an exception will be
 
774
        raised
 
775
        relpath is the portion of the path that is contained by the branch.
 
776
        """
 
777
        controldir, relpath = klass.open_containing(location)
 
778
        tree, branch = controldir._get_tree_branch()
 
779
        return tree, branch, relpath
 
780
 
 
781
    @classmethod
 
782
    def open_containing_tree_branch_or_repository(klass, location):
 
783
        """Return the working tree, branch and repo contained by a location.
 
784
 
 
785
        Returns (tree, branch, repository, relpath).
 
786
        If there is no tree containing the location, tree will be None.
 
787
        If there is no branch containing the location, branch will be None.
 
788
        If there is no repository containing the location, repository will be
 
789
        None.
 
790
        relpath is the portion of the path that is contained by the innermost
 
791
        ControlDir.
 
792
 
 
793
        If no tree, branch or repository is found, a NotBranchError is raised.
 
794
        """
 
795
        controldir, relpath = klass.open_containing(location)
 
796
        try:
 
797
            tree, branch = controldir._get_tree_branch()
 
798
        except errors.NotBranchError:
 
799
            try:
 
800
                repo = controldir.find_repository()
 
801
                return None, None, repo, relpath
 
802
            except (errors.NoRepositoryPresent):
 
803
                raise errors.NotBranchError(location)
 
804
        return tree, branch, branch.repository, relpath
 
805
 
 
806
    @classmethod
 
807
    def create(klass, base, format=None, possible_transports=None):
 
808
        """Create a new ControlDir at the url 'base'.
 
809
 
 
810
        :param format: If supplied, the format of branch to create.  If not
 
811
            supplied, the default is used.
 
812
        :param possible_transports: If supplied, a list of transports that
 
813
            can be reused to share a remote connection.
 
814
        """
 
815
        if klass is not ControlDir:
 
816
            raise AssertionError("ControlDir.create always creates the"
 
817
                "default format, not one of %r" % klass)
 
818
        t = _mod_transport.get_transport(base, possible_transports)
 
819
        t.ensure_base()
 
820
        if format is None:
 
821
            format = ControlDirFormat.get_default_format()
 
822
        return format.initialize_on_transport(t)
 
823
 
 
824
 
 
825
class ControlDirHooks(hooks.Hooks):
 
826
    """Hooks for ControlDir operations."""
 
827
 
 
828
    def __init__(self):
 
829
        """Create the default hooks."""
 
830
        hooks.Hooks.__init__(self, "bzrlib.controldir", "ControlDir.hooks")
 
831
        self.add_hook('pre_open',
 
832
            "Invoked before attempting to open a ControlDir with the transport "
 
833
            "that the open will use.", (1, 14))
 
834
        self.add_hook('post_repo_init',
 
835
            "Invoked after a repository has been initialized. "
 
836
            "post_repo_init is called with a "
 
837
            "bzrlib.controldir.RepoInitHookParams.",
 
838
            (2, 2))
 
839
 
 
840
# install the default hooks
 
841
ControlDir.hooks = ControlDirHooks()
 
842
 
466
843
 
467
844
class ControlComponentFormat(object):
468
845
    """A component that can live inside of a .bzr meta directory."""
469
846
 
470
847
    upgrade_recommended = False
471
848
 
472
 
    def get_format_string(self):
473
 
        """Return the format of this format, if usable in meta directories."""
474
 
        raise NotImplementedError(self.get_format_string)
475
 
 
476
849
    def get_format_description(self):
477
850
        """Return the short description for this format."""
478
851
        raise NotImplementedError(self.get_format_description)
505
878
            ui.ui_factory.recommend_upgrade(
506
879
                self.get_format_description(), basedir)
507
880
 
 
881
    @classmethod
 
882
    def get_format_string(cls):
 
883
        raise NotImplementedError(cls.get_format_string)
 
884
 
508
885
 
509
886
class ControlComponentFormatRegistry(registry.FormatRegistry):
510
887
    """A registry for control components (branch, workingtree, repository)."""
661
1038
    def is_supported(self):
662
1039
        """Is this format supported?
663
1040
 
664
 
        Supported formats must be initializable and openable.
 
1041
        Supported formats must be openable.
665
1042
        Unsupported formats may not support initialization or committing or
666
1043
        some other features depending on the reason for not being supported.
667
1044
        """
668
1045
        return True
669
1046
 
 
1047
    def is_initializable(self):
 
1048
        """Whether new control directories of this format can be initialized.
 
1049
        """
 
1050
        return self.is_supported()
 
1051
 
670
1052
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
671
1053
        basedir=None):
672
1054
        """Give an error or warning on old formats.
828
1210
        """Return the current default format."""
829
1211
        return klass._default_format
830
1212
 
 
1213
    def supports_transport(self, transport):
 
1214
        """Check if this format can be opened over a particular transport.
 
1215
        """
 
1216
        raise NotImplementedError(self.supports_transport)
 
1217
 
831
1218
 
832
1219
class Prober(object):
833
1220
    """Abstract class that can be used to detect a particular kind of
856
1243
        raise NotImplementedError(self.probe_transport)
857
1244
 
858
1245
    @classmethod
859
 
    def known_formats(cls):
 
1246
    def known_formats(klass):
860
1247
        """Return the control dir formats known by this prober.
861
1248
 
862
1249
        Multiple probers can return the same formats, so this should
864
1251
 
865
1252
        :return: A set of known formats.
866
1253
        """
867
 
        raise NotImplementedError(cls.known_formats)
 
1254
        raise NotImplementedError(klass.known_formats)
868
1255
 
869
1256
 
870
1257
class ControlDirFormatInfo(object):
1003
1390
            return output
1004
1391
 
1005
1392
 
 
1393
class RepoInitHookParams(object):
 
1394
    """Object holding parameters passed to `*_repo_init` hooks.
 
1395
 
 
1396
    There are 4 fields that hooks may wish to access:
 
1397
 
 
1398
    :ivar repository: Repository created
 
1399
    :ivar format: Repository format
 
1400
    :ivar bzrdir: The controldir for the repository
 
1401
    :ivar shared: The repository is shared
 
1402
    """
 
1403
 
 
1404
    def __init__(self, repository, format, controldir, shared):
 
1405
        """Create a group of RepoInitHook parameters.
 
1406
 
 
1407
        :param repository: Repository created
 
1408
        :param format: Repository format
 
1409
        :param controldir: The controldir for the repository
 
1410
        :param shared: The repository is shared
 
1411
        """
 
1412
        self.repository = repository
 
1413
        self.format = format
 
1414
        self.bzrdir = controldir
 
1415
        self.shared = shared
 
1416
 
 
1417
    def __eq__(self, other):
 
1418
        return self.__dict__ == other.__dict__
 
1419
 
 
1420
    def __repr__(self):
 
1421
        if self.repository:
 
1422
            return "<%s for %s>" % (self.__class__.__name__,
 
1423
                self.repository)
 
1424
        else:
 
1425
            return "<%s for %s>" % (self.__class__.__name__,
 
1426
                self.bzrdir)
 
1427
 
 
1428
 
1006
1429
# Please register new formats after old formats so that formats
1007
1430
# appear in chronological order and format descriptions can build
1008
1431
# on previous ones.