~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/foreign.py

(jam) Handle bug #382709 by encoding paths as 'mbcs' when spawning
        external diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008-2011 Canonical Ltd
 
1
# Copyright (C) 2008 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
20
20
 
21
21
from bzrlib.branch import (
22
22
    Branch,
 
23
    InterBranch,
23
24
    )
24
25
from bzrlib.commands import Command, Option
25
26
from bzrlib.repository import Repository
28
29
lazy_import(globals(), """
29
30
from bzrlib import (
30
31
    errors,
 
32
    osutils,
31
33
    registry,
32
34
    transform,
33
35
    )
34
 
from bzrlib.i18n import gettext
35
36
""")
36
37
 
37
38
class VcsMapping(object):
38
 
    """Describes the mapping between the semantics of Bazaar and a foreign VCS.
 
39
    """Describes the mapping between the semantics of Bazaar and a foreign vcs.
39
40
 
40
41
    """
41
42
    # Whether this is an experimental mapping that is still open to changes.
121
122
class ForeignVcs(object):
122
123
    """A foreign version control system."""
123
124
 
124
 
    branch_format = None
125
 
 
126
 
    repository_format = None
127
 
 
128
 
    def __init__(self, mapping_registry, abbreviation=None):
129
 
        """Create a new foreign vcs instance.
130
 
 
131
 
        :param mapping_registry: Registry with mappings for this VCS.
132
 
        :param abbreviation: Optional abbreviation ('bzr', 'svn', 'git', etc)
133
 
        """
134
 
        self.abbreviation = abbreviation
 
125
    def __init__(self, mapping_registry):
135
126
        self.mapping_registry = mapping_registry
136
127
 
137
128
    def show_foreign_revid(self, foreign_revid):
142
133
        """
143
134
        return { }
144
135
 
145
 
    def serialize_foreign_revid(self, foreign_revid):
146
 
        """Serialize a foreign revision id for this VCS.
147
 
 
148
 
        :param foreign_revid: Foreign revision id
149
 
        :return: Bytestring with serialized revid, will not contain any 
150
 
            newlines.
151
 
        """
152
 
        raise NotImplementedError(self.serialize_foreign_revid)
153
 
 
154
136
 
155
137
class ForeignVcsRegistry(registry.Registry):
156
138
    """Registry for Foreign VCSes.
224
206
        """Get the default mapping for this repository."""
225
207
        raise NotImplementedError(self.get_default_mapping)
226
208
 
 
209
    def get_inventory_xml(self, revision_id):
 
210
        """See Repository.get_inventory_xml()."""
 
211
        return self.serialise_inventory(self.get_inventory(revision_id))
 
212
 
 
213
    def get_inventory_sha1(self, revision_id):
 
214
        """Get the sha1 for the XML representation of an inventory.
 
215
 
 
216
        :param revision_id: Revision id of the inventory for which to return
 
217
         the SHA1.
 
218
        :return: XML string
 
219
        """
 
220
 
 
221
        return osutils.sha_string(self.get_inventory_xml(revision_id))
 
222
 
 
223
    def get_revision_xml(self, revision_id):
 
224
        """Return the XML representation of a revision.
 
225
 
 
226
        :param revision_id: Revision for which to return the XML.
 
227
        :return: XML string
 
228
        """
 
229
        return self._serializer.write_revision_to_string(
 
230
            self.get_revision(revision_id))
 
231
 
227
232
 
228
233
class ForeignBranch(Branch):
229
234
    """Branch that exists in a foreign version control system."""
258
263
 
259
264
 
260
265
class cmd_dpush(Command):
261
 
    __doc__ = """Push into a different VCS without any custom bzr metadata.
 
266
    """Push into a different VCS without any custom bzr metadata.
262
267
 
263
268
    This will afterwards rebase the local branch on the remote
264
269
    branch unless the --no-rebase option is used, in which case 
266
271
    """
267
272
    hidden = True
268
273
    takes_args = ['location?']
269
 
    takes_options = [
270
 
        'remember',
271
 
        Option('directory',
272
 
               help='Branch to push from, '
273
 
               'rather than the one containing the working directory.',
274
 
               short_name='d',
275
 
               type=unicode,
276
 
               ),
277
 
        Option('no-rebase', help="Do not rebase after push."),
278
 
        Option('strict',
279
 
               help='Refuse to push if there are uncommitted changes in'
280
 
               ' the working tree, --no-strict disables the check.'),
281
 
        ]
 
274
    takes_options = ['remember', Option('directory',
 
275
            help='Branch to push from, '
 
276
                 'rather than the one containing the working directory.',
 
277
            short_name='d',
 
278
            type=unicode,
 
279
            ),
 
280
            Option('no-rebase', help="Do not rebase after push.")]
282
281
 
283
 
    def run(self, location=None, remember=False, directory=None,
284
 
            no_rebase=False, strict=None):
 
282
    def run(self, location=None, remember=False, directory=None, 
 
283
            no_rebase=False):
285
284
        from bzrlib import urlutils
286
 
        from bzrlib.controldir import ControlDir
 
285
        from bzrlib.bzrdir import BzrDir
287
286
        from bzrlib.errors import BzrCommandError, NoWorkingTree
 
287
        from bzrlib.trace import info
288
288
        from bzrlib.workingtree import WorkingTree
289
289
 
290
290
        if directory is None:
295
295
        except NoWorkingTree:
296
296
            source_branch = Branch.open(directory)
297
297
            source_wt = None
298
 
        if source_wt is not None:
299
 
            source_wt.check_changed_or_out_of_date(
300
 
                strict, 'dpush_strict',
301
 
                more_error='Use --no-strict to force the push.',
302
 
                more_warning='Uncommitted changes will not be pushed.')
303
298
        stored_loc = source_branch.get_push_location()
304
299
        if location is None:
305
300
            if stored_loc is None:
306
 
                raise BzrCommandError(gettext("No push location known or specified."))
 
301
                raise BzrCommandError("No push location known or specified.")
307
302
            else:
308
303
                display_url = urlutils.unescape_for_display(stored_loc,
309
304
                        self.outf.encoding)
310
 
                self.outf.write(
311
 
                       gettext("Using saved location: %s\n") % display_url)
 
305
                self.outf.write("Using saved location: %s\n" % display_url)
312
306
                location = stored_loc
313
307
 
314
 
        controldir = ControlDir.open(location)
315
 
        target_branch = controldir.open_branch()
 
308
        bzrdir = BzrDir.open(location)
 
309
        target_branch = bzrdir.open_branch()
316
310
        target_branch.lock_write()
317
311
        try:
318
312
            try:
319
 
                push_result = source_branch.push(target_branch, lossy=True)
 
313
                push_result = source_branch.lossy_push(target_branch)
320
314
            except errors.LossyPushToSameVCS:
321
 
                raise BzrCommandError(gettext("{0!r} and {1!r} are in the same VCS, lossy "
322
 
                    "push not necessary. Please use regular push.").format(
323
 
                    source_branch, target_branch))
 
315
                raise BzrCommandError("%r and %r are in the same VCS, lossy "
 
316
                    "push not necessary. Please use regular push." %
 
317
                    (source_branch, target_branch))
324
318
            # We successfully created the target, remember it
325
319
            if source_branch.get_push_location() is None or remember:
326
320
                source_branch.set_push_location(target_branch.base)
339
333
            push_result.report(self.outf)
340
334
        finally:
341
335
            target_branch.unlock()
 
336
 
 
337
 
 
338
class InterToForeignBranch(InterBranch):
 
339
 
 
340
    def lossy_push(self, stop_revision=None):
 
341
        """Push deltas into another branch.
 
342
 
 
343
        :note: This does not, like push, retain the revision ids from 
 
344
            the source branch and will, rather than adding bzr-specific 
 
345
            metadata, push only those semantics of the revision that can be 
 
346
            natively represented by this branch' VCS.
 
347
 
 
348
        :param target: Target branch
 
349
        :param stop_revision: Revision to push, defaults to last revision.
 
350
        :return: BranchPushResult with an extra member revidmap: 
 
351
            A dictionary mapping revision ids from the target branch 
 
352
            to new revision ids in the target branch, for each 
 
353
            revision that was pushed.
 
354
        """
 
355
        raise NotImplementedError(self.lossy_push)