38
38
class VcsMapping(object):
39
"""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.
42
42
# Whether this is an experimental mapping that is still open to changes.
45
45
# Whether this mapping supports exporting and importing all bzr semantics.
46
46
roundtripping = False
48
# Prefix used when importing revisions native to the foreign VCS (as
49
# opposed to roundtripping bzr-native revisions) using this mapping.
48
# Prefix used when importing native foreign revisions (not roundtripped)
50
50
revid_prefix = None
52
52
def __init__(self, vcs):
119
119
self.mapping = mapping
122
def show_foreign_properties(rev):
123
"""Custom log displayer for foreign revision identifiers.
125
:param rev: Revision object.
127
# Revision comes directly from a foreign repository
128
if isinstance(rev, ForeignRevision):
129
return rev.mapping.vcs.show_foreign_revid(rev.foreign_revid)
131
# Revision was once imported from a foreign repository
133
foreign_revid, mapping = \
134
foreign_vcs_registry.parse_revision_id(rev.revision_id)
135
except errors.InvalidRevisionId:
138
return mapping.vcs.show_foreign_revid(foreign_revid)
122
141
class ForeignVcs(object):
123
142
"""A foreign version control system."""
127
repository_format = None
129
def __init__(self, mapping_registry, abbreviation=None):
130
"""Create a new foreign vcs instance.
132
:param mapping_registry: Registry with mappings for this VCS.
133
:param abbreviation: Optional abbreviation ('bzr', 'svn', 'git', etc)
135
self.abbreviation = abbreviation
144
def __init__(self, mapping_registry):
136
145
self.mapping_registry = mapping_registry
138
147
def show_foreign_revid(self, foreign_revid):
146
def serialize_foreign_revid(self, foreign_revid):
147
"""Serialize a foreign revision id for this VCS.
149
:param foreign_revid: Foreign revision id
150
:return: Bytestring with serialized revid, will not contain any
153
raise NotImplementedError(self.serialize_foreign_revid)
156
156
class ForeignVcsRegistry(registry.Registry):
157
157
"""Registry for Foreign VCSes.
179
179
:param revid: The bzr revision id
180
180
:return: tuple with foreign revid and vcs mapping
182
if not ":" in revid or not "-" in revid:
183
183
raise errors.InvalidRevisionId(revid, None)
185
185
foreign_vcs = self.get(revid.split("-")[0])
225
225
"""Get the default mapping for this repository."""
226
226
raise NotImplementedError(self.get_default_mapping)
228
def _get_inventory_xml(self, revision_id):
229
"""See Repository._get_inventory_xml()."""
230
return self._serialise_inventory(self.get_inventory(revision_id))
228
def get_inventory_xml(self, revision_id):
229
"""See Repository.get_inventory_xml()."""
230
return self.serialise_inventory(self.get_inventory(revision_id))
232
def get_inventory_sha1(self, revision_id):
233
"""Get the sha1 for the XML representation of an inventory.
235
:param revision_id: Revision id of the inventory for which to return
240
return osutils.sha_string(self.get_inventory_xml(revision_id))
232
242
def get_revision_xml(self, revision_id):
233
243
"""Return the XML representation of a revision.
282
292
takes_args = ['location?']
286
help='Branch to push from, '
287
'rather than the one containing the working directory.',
291
Option('no-rebase', help="Do not rebase after push."),
293
help='Refuse to push if there are uncommitted changes in'
294
' the working tree, --no-strict disables the check.'),
293
takes_options = ['remember', Option('directory',
294
help='Branch to push from, '
295
'rather than the one containing the working directory.',
299
Option('no-rebase', help="Do not rebase after push.")]
297
def run(self, location=None, remember=False, directory=None,
298
no_rebase=False, strict=None):
301
def run(self, location=None, remember=False, directory=None,
299
303
from bzrlib import urlutils
300
304
from bzrlib.bzrdir import BzrDir
301
305
from bzrlib.errors import BzrCommandError, NoWorkingTree
306
from bzrlib.trace import info
302
307
from bzrlib.workingtree import WorkingTree
304
309
if directory is None:
309
314
except NoWorkingTree:
310
315
source_branch = Branch.open(directory)
313
strict = source_branch.get_config(
314
).get_user_option_as_bool('dpush_strict')
315
if strict is None: strict = True # default value
316
if strict and source_wt is not None:
317
if (source_wt.has_changes()):
318
raise errors.UncommittedChanges(
319
source_wt, more='Use --no-strict to force the push.')
320
if source_wt.last_revision() != source_wt.branch.last_revision():
321
# The tree has lost sync with its branch, there is little
322
# chance that the user is aware of it but he can still force
323
# the push with --no-strict
324
raise errors.OutOfDateTree(
325
source_wt, more='Use --no-strict to force the push.')
326
317
stored_loc = source_branch.get_push_location()
327
318
if location is None:
328
319
if stored_loc is None: