~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/controldir.py

  • Committer: Martin Packman
  • Date: 2011-12-08 19:00:14 UTC
  • mto: This revision was merged to the branch mainline in revision 6359.
  • Revision ID: martin.packman@canonical.com-20111208190014-mi8jm6v7jygmhb0r
Use --include-duplicates for make update-pot which already combines multiple msgid strings prettily

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2010, 2011, 2012 Canonical Ltd
 
1
# Copyright (C) 2010, 2011 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
22
22
 
23
23
"""
24
24
 
25
 
from __future__ import absolute_import
26
 
 
27
25
from bzrlib.lazy_import import lazy_import
28
26
lazy_import(globals(), """
29
27
import textwrap
108
106
        """Return a sequence of all branches local to this control directory.
109
107
 
110
108
        """
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
 
        """
118
109
        try:
119
 
           return { "": self.open_branch() }
 
110
            return [self.open_branch()]
120
111
        except (errors.NotBranchError, errors.NoRepositoryPresent):
121
 
           return {}
 
112
            return []
122
113
 
123
114
    def is_control_filename(self, filename):
124
115
        """True if filename is the name of a path which is reserved for
163
154
        """Create a branch in this ControlDir.
164
155
 
165
156
        :param name: Name of the colocated branch to create, None for
166
 
            the user selected branch or "" for the active branch.
 
157
            the default branch.
167
158
        :param append_revisions_only: Whether this branch should only allow
168
159
            appending new revisions to its history.
169
160
 
175
166
    def destroy_branch(self, name=None):
176
167
        """Destroy a branch in this ControlDir.
177
168
 
178
 
        :param name: Name of the branch to destroy, None for the 
179
 
            user selected branch or "" for the active branch.
180
 
        :raise NotBranchError: When the branch does not exist
 
169
        :param name: Name of the branch to destroy, None for the default 
 
170
            branch.
181
171
        """
182
172
        raise NotImplementedError(self.destroy_branch)
183
173
 
231
221
            raise errors.NoColocatedBranchSupport(self)
232
222
        return None
233
223
 
234
 
    def set_branch_reference(self, target_branch, name=None):
235
 
        """Set the referenced URL for the branch in this controldir.
236
 
 
237
 
        :param name: Optional colocated branch name
238
 
        :param target_branch: Branch to reference
239
 
        :raises NoColocatedBranchSupport: If a branch name was specified
240
 
            but colocated branches are not supported.
241
 
        :return: The referencing branch
242
 
        """
243
 
        raise NotImplementedError(self.set_branch_reference)
244
 
 
245
224
    def open_branch(self, name=None, unsupported=False,
246
225
                    ignore_fallbacks=False, possible_transports=None):
247
226
        """Open the branch object at this ControlDir if one is present.
274
253
        """
275
254
        raise NotImplementedError(self.find_repository)
276
255
 
277
 
    def open_workingtree(self, unsupported=False,
 
256
    def open_workingtree(self, _unsupported=False,
278
257
                         recommend_upgrade=True, from_branch=None):
279
258
        """Open the workingtree object at this ControlDir if one is present.
280
259
 
303
282
    def _get_selected_branch(self):
304
283
        """Return the name of the branch selected by the user.
305
284
 
306
 
        :return: Name of the branch selected by the user, or "".
 
285
        :return: Name of the branch selected by the user, or None.
307
286
        """
308
287
        branch = self.root_transport.get_segment_parameters().get("branch")
309
 
        if branch is None:
310
 
            branch = ""
311
 
        return urlutils.unescape(branch)
 
288
        if branch is not None:
 
289
            branch = urlutils.unescape(branch)
 
290
        return branch
312
291
 
313
292
    def has_workingtree(self):
314
293
        """Tell if this controldir contains a working tree.
342
321
        raise NotImplementedError(self.cloning_metadir)
343
322
 
344
323
    def checkout_metadir(self):
345
 
        """Produce a metadir suitable for checkouts of this controldir.
346
 
 
347
 
        :returns: A ControlDirFormat with all component formats
348
 
            either set appropriately or set to None if that component
349
 
            should not be created.
350
 
        """
 
324
        """Produce a metadir suitable for checkouts of this controldir."""
351
325
        return self.cloning_metadir()
352
326
 
353
327
    def sprout(self, url, revision_id=None, force_new_repo=False,
406
380
            repository_to.fetch(source.repository, revision_id=revision_id)
407
381
            br_to = source.clone(self, revision_id=revision_id)
408
382
            if source.get_push_location() is None or remember:
409
 
                # FIXME: Should be done only if we succeed ? -- vila 2012-01-18
410
383
                source.set_push_location(br_to.base)
411
384
            push_result.stacked_on = None
412
385
            push_result.branch_push_result = None
418
391
        else:
419
392
            # We have successfully opened the branch, remember if necessary:
420
393
            if source.get_push_location() is None or remember:
421
 
                # FIXME: Should be done only if we succeed ? -- vila 2012-01-18
422
394
                source.set_push_location(br_to.base)
423
395
            try:
424
396
                tree_to = self.open_workingtree()
678
650
        return klass.open(base, _unsupported=True)
679
651
 
680
652
    @classmethod
681
 
    def open(klass, base, possible_transports=None, probers=None,
682
 
             _unsupported=False):
 
653
    def open(klass, base, _unsupported=False, possible_transports=None):
683
654
        """Open an existing controldir, rooted at 'base' (url).
684
655
 
685
656
        :param _unsupported: a private parameter to the ControlDir class.
686
657
        """
687
658
        t = _mod_transport.get_transport(base, possible_transports)
688
 
        return klass.open_from_transport(t, probers=probers,
689
 
                _unsupported=_unsupported)
 
659
        return klass.open_from_transport(t, _unsupported=_unsupported)
690
660
 
691
661
    @classmethod
692
662
    def open_from_transport(klass, transport, _unsupported=False,
693
 
                            probers=None):
 
663
                            _server_formats=True):
694
664
        """Open a controldir within a particular directory.
695
665
 
696
666
        :param transport: Transport containing the controldir.
702
672
        # the redirections.
703
673
        base = transport.base
704
674
        def find_format(transport):
705
 
            return transport, ControlDirFormat.find_format(transport,
706
 
                probers=probers)
 
675
            return transport, ControlDirFormat.find_format(
 
676
                transport, _server_formats=_server_formats)
707
677
 
708
678
        def redirected(transport, e, redirection_notice):
709
679
            redirected_transport = transport._redirected_to(e.source, e.target)
756
726
                return result, urlutils.unescape(a_transport.relpath(url))
757
727
            except errors.NotBranchError, e:
758
728
                pass
759
 
            except errors.PermissionDenied:
760
 
                pass
761
729
            try:
762
730
                new_t = a_transport.clone('..')
763
731
            except errors.InvalidURLJoin:
781
749
        return controldir._get_tree_branch()
782
750
 
783
751
    @classmethod
784
 
    def open_containing_tree_or_branch(klass, location,
785
 
            possible_transports=None):
 
752
    def open_containing_tree_or_branch(klass, location):
786
753
        """Return the branch and working tree contained by a location.
787
754
 
788
755
        Returns (tree, branch, relpath).
791
758
        raised
792
759
        relpath is the portion of the path that is contained by the branch.
793
760
        """
794
 
        controldir, relpath = klass.open_containing(location,
795
 
            possible_transports=possible_transports)
 
761
        controldir, relpath = klass.open_containing(location)
796
762
        tree, branch = controldir._get_tree_branch()
797
763
        return tree, branch, relpath
798
764
 
860
826
 
861
827
 
862
828
class ControlComponentFormat(object):
863
 
    """A component that can live inside of a control directory."""
 
829
    """A component that can live inside of a .bzr meta directory."""
864
830
 
865
831
    upgrade_recommended = False
866
832
 
 
833
    def get_format_string(self):
 
834
        """Return the format of this format, if usable in meta directories."""
 
835
        raise NotImplementedError(self.get_format_string)
 
836
 
867
837
    def get_format_description(self):
868
838
        """Return the short description for this format."""
869
839
        raise NotImplementedError(self.get_format_description)
896
866
            ui.ui_factory.recommend_upgrade(
897
867
                self.get_format_description(), basedir)
898
868
 
899
 
    @classmethod
900
 
    def get_format_string(cls):
901
 
        raise NotImplementedError(cls.get_format_string)
902
 
 
903
869
 
904
870
class ControlComponentFormatRegistry(registry.FormatRegistry):
905
871
    """A registry for control components (branch, workingtree, repository)."""
1128
1094
        return self.get_format_description().rstrip()
1129
1095
 
1130
1096
    @classmethod
1131
 
    def all_probers(klass):
1132
 
        return klass._server_probers + klass._probers
1133
 
 
1134
 
    @classmethod
1135
1097
    def known_formats(klass):
1136
1098
        """Return all the known formats.
1137
1099
        """
1138
1100
        result = set()
1139
 
        for prober_kls in klass.all_probers():
 
1101
        for prober_kls in klass._probers + klass._server_probers:
1140
1102
            result.update(prober_kls.known_formats())
1141
1103
        return result
1142
1104
 
1143
1105
    @classmethod
1144
 
    def find_format(klass, transport, probers=None):
 
1106
    def find_format(klass, transport, _server_formats=True):
1145
1107
        """Return the format present at transport."""
1146
 
        if probers is None:
1147
 
            probers = klass.all_probers()
1148
 
        for prober_kls in probers:
 
1108
        if _server_formats:
 
1109
            _probers = klass._server_probers + klass._probers
 
1110
        else:
 
1111
            _probers = klass._probers
 
1112
        for prober_kls in _probers:
1149
1113
            prober = prober_kls()
1150
1114
            try:
1151
1115
                return prober.probe_transport(transport)