/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 __init__.py

  • Committer: Jelmer Vernooij
  • Date: 2008-11-10 16:14:20 UTC
  • mto: (0.219.2 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20081110161420-bax1raw5jkm1p67h
Import fixes from bzr-svn.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
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
 
16
 
 
17
"""Foreign branch utilities."""
 
18
 
 
19
from bzrlib import errors, registry
 
20
from bzrlib.branch import Branch
 
21
from bzrlib.commands import Command, Option
 
22
from bzrlib.trace import info
 
23
 
 
24
 
 
25
class VcsMapping(object):
 
26
    """Describes the mapping between the semantics of Bazaar and a foreign vcs.
 
27
 
 
28
    """
 
29
    experimental = False
 
30
    roundtripping = False
 
31
    revid_prefix = None
 
32
 
 
33
    def revision_id_bzr_to_foreign(self, bzr_revid):
 
34
        """Parse a bzr revision id and convert it to a foreign revid.
 
35
 
 
36
        :param bzr_revid: The bzr revision id (a string).
 
37
        :return: A foreign revision id, can be any sort of object.
 
38
        """
 
39
        raise NotImplementedError(self.revision_id_bzr_to_foreign)
 
40
 
 
41
    def revision_id_foreign_to_bzr(self, foreign_revid):
 
42
        """Parse a foreign revision id and convert it to a bzr revid.
 
43
 
 
44
        :param foreign_revid: Foreign revision id, can be any sort of object.
 
45
        :return: A bzr revision id.
 
46
        """
 
47
        raise NotImplementedError(self.revision_id_foreign_to_bzr)
 
48
 
 
49
 
 
50
class VcsMappingRegistry(registry.Registry):
 
51
    """Registry for Bazaar<->foreign VCS mappings.
 
52
    
 
53
    There should be one instance of this registry for every foreign VCS.
 
54
    """
 
55
 
 
56
    def register(self, key, factory, help):
 
57
        """Register a mapping between Bazaar and foreign VCS semantics.
 
58
 
 
59
        The factory must be a callable that takes one parameter: the key.
 
60
        It must produce an instance of VcsMapping when called.
 
61
        """
 
62
        registry.Registry.register(self, key, factory, help)
 
63
 
 
64
    def set_default(self, key):
 
65
        """Set the 'default' key to be a clone of the supplied key.
 
66
 
 
67
        This method must be called once and only once.
 
68
        """
 
69
        self._set_default_key(key)
 
70
 
 
71
    def get_default(self):
 
72
        """Convenience function for obtaining the default mapping to use."""
 
73
        return self.get(self._get_default_key())
 
74
 
 
75
 
 
76
class ForeignBranch(Branch):
 
77
 
 
78
    def __init__(self, mapping):
 
79
        super(ForeignBranch, self).__init__()
 
80
        self.mapping = mapping
 
81
 
 
82
    def dpull(self, source, stop_revision=None):
 
83
        raise NotImplementedError(self.pull)
 
84
 
 
85
 
 
86
class FakeControlFiles(object):
 
87
    """Dummy implementation of ControlFiles.
 
88
    
 
89
    This is required as some code relies on controlfiles being 
 
90
    available."""
 
91
    def get_utf8(self, name):
 
92
        raise errors.NoSuchFile(name)
 
93
 
 
94
    def get(self, name):
 
95
        raise errors.NoSuchFile(name)
 
96
 
 
97
    def break_lock(self):
 
98
        pass
 
99
 
 
100
 
 
101
class cmd_dpush(Command):
 
102
    """Push diffs into a foreign version control system without any 
 
103
    Bazaar-specific metadata.
 
104
 
 
105
    This will afterwards rebase the local Bazaar branch on the remote
 
106
    branch unless the --no-rebase option is used, in which case 
 
107
    the two branches will be out of sync. 
 
108
    """
 
109
    takes_args = ['location?']
 
110
    takes_options = ['remember', Option('directory',
 
111
            help='Branch to push from, '
 
112
                 'rather than the one containing the working directory.',
 
113
            short_name='d',
 
114
            type=unicode,
 
115
            ),
 
116
            Option('no-rebase', help="Don't rebase after push")]
 
117
 
 
118
    def run(self, location=None, remember=False, directory=None, 
 
119
            no_rebase=False):
 
120
        from bzrlib import urlutils
 
121
        from bzrlib.bzrdir import BzrDir
 
122
        from bzrlib.branch import Branch
 
123
        from bzrlib.errors import BzrCommandError, NoWorkingTree
 
124
        from bzrlib.workingtree import WorkingTree
 
125
 
 
126
        if directory is None:
 
127
            directory = "."
 
128
        try:
 
129
            source_wt = WorkingTree.open_containing(directory)[0]
 
130
            source_branch = source_wt.branch
 
131
        except NoWorkingTree:
 
132
            source_branch = Branch.open_containing(directory)[0]
 
133
            source_wt = None
 
134
        stored_loc = source_branch.get_push_location()
 
135
        if location is None:
 
136
            if stored_loc is None:
 
137
                raise BzrCommandError("No push location known or specified.")
 
138
            else:
 
139
                display_url = urlutils.unescape_for_display(stored_loc,
 
140
                        self.outf.encoding)
 
141
                self.outf.write("Using saved location: %s\n" % display_url)
 
142
                location = stored_loc
 
143
 
 
144
        bzrdir = BzrDir.open(location)
 
145
        target_branch = bzrdir.open_branch()
 
146
        target_branch.lock_write()
 
147
        if not isinstance(target_branch, ForeignBranch):
 
148
            info("target branch is not a foreign branch, using regular push.")
 
149
            target_branch.pull(source_branch)
 
150
            no_rebase = True
 
151
        else:
 
152
            revid_map = target_branch.dpull(source_branch)
 
153
        # We successfully created the target, remember it
 
154
        if source_branch.get_push_location() is None or remember:
 
155
            source_branch.set_push_location(target_branch.base)
 
156
        if not no_rebase:
 
157
            _, old_last_revid = source_branch.last_revision_info()
 
158
            new_last_revid = revid_map[old_last_revid]
 
159
            if source_wt is not None:
 
160
                source_wt.pull(target_branch, overwrite=True, 
 
161
                               stop_revision=new_last_revid)
 
162
            else:
 
163
                source_branch.pull(target_branch, overwrite=True, 
 
164
                                   stop_revision=new_last_revid)
 
165
 
 
166
def test_suite():
 
167
    from unittest import TestSuite
 
168
    from bzrlib.tests import TestUtil
 
169
    loader = TestUtil.TestLoader()
 
170
    suite = TestSuite()
 
171
    import test_versionedfiles
 
172
    testmod_names = ['test_versionedfiles',]
 
173
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
 
174
    return suite
 
175
 
 
176
def escape_commit_message(message):
 
177
    """Replace xml-incompatible control characters."""
 
178
    if message is None:
 
179
        return None
 
180
    import re
 
181
    # FIXME: RBC 20060419 this should be done by the revision
 
182
    # serialiser not by commit. Then we can also add an unescaper
 
183
    # in the deserializer and start roundtripping revision messages
 
184
    # precisely. See repository_implementations/test_repository.py
 
185
    
 
186
    # Python strings can include characters that can't be
 
187
    # represented in well-formed XML; escape characters that
 
188
    # aren't listed in the XML specification
 
189
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
 
190
    message, _ = re.subn(
 
191
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
 
192
        lambda match: match.group(0).encode('unicode_escape'),
 
193
        message)
 
194
    return message
 
195
 
 
196
 
 
197