/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
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
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
19
from bzrlib import errors, log, registry
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
20
from bzrlib.branch import Branch
0.205.7 by Jelmer Vernooij
Import dpush.
21
from bzrlib.commands import Command, Option
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
22
from bzrlib.errors import InvalidRevisionId
23
from bzrlib.revision import Revision
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
24
from bzrlib.trace import info
0.205.3 by Jelmer Vernooij
Fix import.
25
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
26
class VcsMapping(object):
27
    """Describes the mapping between the semantics of Bazaar and a foreign vcs.
28
29
    """
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
30
    # Whether this is an experimental mapping that is still open to changes.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
31
    experimental = False
0.205.18 by Jelmer Vernooij
Add docstrings.
32
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
33
    # Whether this mapping supports exporting and importing all bzr semantics.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
34
    roundtripping = False
0.205.18 by Jelmer Vernooij
Add docstrings.
35
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
36
    # Prefix used when importing native foreign revisions (not roundtripped) 
37
    # using this mapping.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
38
    revid_prefix = None
39
0.205.9 by Jelmer Vernooij
Add abstract functions for converting revision ids between bzr and foreign vcses.
40
    def revision_id_bzr_to_foreign(self, bzr_revid):
41
        """Parse a bzr revision id and convert it to a foreign revid.
42
43
        :param bzr_revid: The bzr revision id (a string).
44
        :return: A foreign revision id, can be any sort of object.
45
        """
46
        raise NotImplementedError(self.revision_id_bzr_to_foreign)
47
48
    def revision_id_foreign_to_bzr(self, foreign_revid):
49
        """Parse a foreign revision id and convert it to a bzr revid.
50
51
        :param foreign_revid: Foreign revision id, can be any sort of object.
52
        :return: A bzr revision id.
53
        """
54
        raise NotImplementedError(self.revision_id_foreign_to_bzr)
55
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
56
    def show_foreign_revid(self, foreign_revid):
57
        """Prepare a foreign revision id for formatting using bzr log.
58
        
59
        :param foreign_revid: Foreign revision id.
60
        :return: Dictionary mapping string keys to string values.
61
        """
62
        return { }
63
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
64
65
class VcsMappingRegistry(registry.Registry):
66
    """Registry for Bazaar<->foreign VCS mappings.
67
    
68
    There should be one instance of this registry for every foreign VCS.
69
    """
70
71
    def register(self, key, factory, help):
72
        """Register a mapping between Bazaar and foreign VCS semantics.
73
74
        The factory must be a callable that takes one parameter: the key.
75
        It must produce an instance of VcsMapping when called.
76
        """
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
77
        if ":" in key:
78
            raise ValueError("mapping name can not contain colon (:)")
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
79
        registry.Registry.register(self, key, factory, help)
80
81
    def set_default(self, key):
82
        """Set the 'default' key to be a clone of the supplied key.
83
84
        This method must be called once and only once.
85
        """
86
        self._set_default_key(key)
87
88
    def get_default(self):
89
        """Convenience function for obtaining the default mapping to use."""
90
        return self.get(self._get_default_key())
91
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
92
    def revision_id_bzr_to_foreign(self, revid):
93
        """Convert a bzr revision id to a foreign revid."""
94
        raise NotImplementedError(self.revision_id_bzr_to_foreign)
95
96
97
class ForeignVcs(object):
98
    """A foreign version control system."""
99
100
    def __init__(self, mapping_registry):
101
        self.mapping_registry = mapping_registry
102
103
104
class ForeignVcsRegistry(registry.Registry):
105
    """Registry for Foreign VCSes.
106
    
107
    """
108
109
    def register(self, key, foreign_vcs, help):
110
        """Register a foreign VCS.
111
112
        """
113
        if ":" in key or "-" in key:
114
            raise ValueError("vcs name can not contain : or -")
115
        registry.Registry.register(self, key, foreign_vcs, help)
116
117
    def parse_revision_id(self, revid):
118
        if not "-" in revid:
119
            raise InvalidRevisionId(revid, None)
120
        try:
121
            foreign_vcs = self.get(revid.split("-")[0])
122
        except KeyError:
123
            raise InvalidRevisionId(revid, None)
124
        return foreign_vcs.mapping_registry.revision_id_bzr_to_foreign(revid)
125
0.205.6 by Jelmer Vernooij
Import FakeControlFiles.
126
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
127
class ForeignBranch(Branch):
0.205.18 by Jelmer Vernooij
Add docstrings.
128
    """Branch that exists in a foreign version control system."""
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
129
130
    def __init__(self, mapping):
131
        super(ForeignBranch, self).__init__()
132
        self.mapping = mapping
133
134
    def dpull(self, source, stop_revision=None):
0.205.18 by Jelmer Vernooij
Add docstrings.
135
        """Pull deltas from another branch.
136
137
        :note: This does not, like pull, retain the revision ids from 
138
        the source branch.
139
140
        :param source: Source branch
141
        :param stop_revision: Revision to pull, defaults to last revision.
142
        """
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
143
        raise NotImplementedError(self.pull)
144
145
0.205.6 by Jelmer Vernooij
Import FakeControlFiles.
146
class FakeControlFiles(object):
147
    """Dummy implementation of ControlFiles.
148
    
149
    This is required as some code relies on controlfiles being 
150
    available."""
151
    def get_utf8(self, name):
152
        raise errors.NoSuchFile(name)
153
154
    def get(self, name):
155
        raise errors.NoSuchFile(name)
156
157
    def break_lock(self):
158
        pass
159
0.205.7 by Jelmer Vernooij
Import dpush.
160
161
class cmd_dpush(Command):
0.205.8 by Jelmer Vernooij
Remove references to svn.
162
    """Push diffs into a foreign version control system without any 
163
    Bazaar-specific metadata.
0.205.7 by Jelmer Vernooij
Import dpush.
164
0.205.8 by Jelmer Vernooij
Remove references to svn.
165
    This will afterwards rebase the local Bazaar branch on the remote
0.205.7 by Jelmer Vernooij
Import dpush.
166
    branch unless the --no-rebase option is used, in which case 
167
    the two branches will be out of sync. 
168
    """
169
    takes_args = ['location?']
170
    takes_options = ['remember', Option('directory',
171
            help='Branch to push from, '
172
                 'rather than the one containing the working directory.',
173
            short_name='d',
174
            type=unicode,
175
            ),
176
            Option('no-rebase', help="Don't rebase after push")]
177
178
    def run(self, location=None, remember=False, directory=None, 
179
            no_rebase=False):
180
        from bzrlib import urlutils
181
        from bzrlib.bzrdir import BzrDir
182
        from bzrlib.errors import BzrCommandError, NoWorkingTree
183
        from bzrlib.workingtree import WorkingTree
184
185
        if directory is None:
186
            directory = "."
187
        try:
188
            source_wt = WorkingTree.open_containing(directory)[0]
189
            source_branch = source_wt.branch
190
        except NoWorkingTree:
191
            source_branch = Branch.open_containing(directory)[0]
192
            source_wt = None
193
        stored_loc = source_branch.get_push_location()
194
        if location is None:
195
            if stored_loc is None:
196
                raise BzrCommandError("No push location known or specified.")
197
            else:
198
                display_url = urlutils.unescape_for_display(stored_loc,
199
                        self.outf.encoding)
200
                self.outf.write("Using saved location: %s\n" % display_url)
201
                location = stored_loc
202
203
        bzrdir = BzrDir.open(location)
204
        target_branch = bzrdir.open_branch()
205
        target_branch.lock_write()
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
206
        if not isinstance(target_branch, ForeignBranch):
207
            info("target branch is not a foreign branch, using regular push.")
208
            target_branch.pull(source_branch)
209
            no_rebase = True
210
        else:
211
            revid_map = target_branch.dpull(source_branch)
0.205.7 by Jelmer Vernooij
Import dpush.
212
        # We successfully created the target, remember it
213
        if source_branch.get_push_location() is None or remember:
214
            source_branch.set_push_location(target_branch.base)
215
        if not no_rebase:
216
            _, old_last_revid = source_branch.last_revision_info()
217
            new_last_revid = revid_map[old_last_revid]
218
            if source_wt is not None:
219
                source_wt.pull(target_branch, overwrite=True, 
220
                               stop_revision=new_last_revid)
221
            else:
222
                source_branch.pull(target_branch, overwrite=True, 
223
                                   stop_revision=new_last_revid)
224
0.205.15 by Jelmer Vernooij
Add test_suite function.
225
def test_suite():
226
    from unittest import TestSuite
227
    from bzrlib.tests import TestUtil
228
    loader = TestUtil.TestLoader()
229
    suite = TestSuite()
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
230
    testmod_names = ['test_versionedfiles', ]
0.205.15 by Jelmer Vernooij
Add test_suite function.
231
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
232
    return suite
0.205.7 by Jelmer Vernooij
Import dpush.
233
0.205.18 by Jelmer Vernooij
Add docstrings.
234
0.207.2 by Jelmer Vernooij
Import escape commit message function.
235
def escape_commit_message(message):
236
    """Replace xml-incompatible control characters."""
237
    if message is None:
238
        return None
239
    import re
240
    # FIXME: RBC 20060419 this should be done by the revision
241
    # serialiser not by commit. Then we can also add an unescaper
242
    # in the deserializer and start roundtripping revision messages
243
    # precisely. See repository_implementations/test_repository.py
244
    
245
    # Python strings can include characters that can't be
246
    # represented in well-formed XML; escape characters that
247
    # aren't listed in the XML specification
248
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
249
    message, _ = re.subn(
250
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
251
        lambda match: match.group(0).encode('unicode_escape'),
252
        message)
253
    return message
254
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
255
256
class ForeignRevision(Revision):
257
    """A Revision from a Foreign repository. Remembers 
258
    information about foreign revision id and mapping.
259
260
    """
261
262
    def __init__(self, foreign_revid, mapping, *args, **kwargs):
263
        super(ForeignRevision, self).__init__(*args, **kwargs)
264
        self.foreign_revid = foreign_revid
265
        self.mapping = mapping
266
267
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
268
def show_foreign_properties(rev):
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
269
    """Custom log displayer for foreign revision identifiers.
270
271
    :param rev: Revision object.
272
    """
273
    # Revision comes directly from a foreign repository
274
    if isinstance(rev, ForeignRevision):
275
        return rev.mapping.show_foreign_revid(rev.foreign_revid)
276
277
    # Revision was once imported from a foreign repository
278
    try:
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
279
        foreign_revid, mapping = foreign_vcs_registry.parse_revision_id(rev.revision_id)
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
280
    except InvalidRevisionId:
281
        return {}
282
283
    return mapping.show_foreign_revid(foreign_revid)
284
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
285
log.properties_handler_registry.register("foreign",
286
                                         show_foreign_properties,
287
                                         "Show foreign VCS properties")
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
288
0.205.20 by Jelmer Vernooij
Merge bzr-svn improvements.
289
foreign_vcs_registry = ForeignVcsRegistry()