34
class VcsMapping(object):
35
"""Describes the mapping between the semantics of Bazaar and a foreign vcs.
38
# Whether this is an experimental mapping that is still open to changes.
41
# Whether this mapping supports exporting and importing all bzr semantics.
44
# Prefix used when importing native foreign revisions (not roundtripped)
48
def revision_id_bzr_to_foreign(self, bzr_revid):
49
"""Parse a bzr revision id and convert it to a foreign revid.
51
:param bzr_revid: The bzr revision id (a string).
52
:return: A foreign revision id, can be any sort of object.
54
raise NotImplementedError(self.revision_id_bzr_to_foreign)
56
def revision_id_foreign_to_bzr(self, foreign_revid):
57
"""Parse a foreign revision id and convert it to a bzr revid.
59
:param foreign_revid: Foreign revision id, can be any sort of object.
60
:return: A bzr revision id.
62
raise NotImplementedError(self.revision_id_foreign_to_bzr)
64
def show_foreign_revid(self, foreign_revid):
65
"""Prepare a foreign revision id for formatting using bzr log.
67
:param foreign_revid: Foreign revision id.
68
:return: Dictionary mapping string keys to string values.
70
# TODO: This could be on ForeignVcs instead
74
class VcsMappingRegistry(registry.Registry):
75
"""Registry for Bazaar<->foreign VCS mappings.
77
There should be one instance of this registry for every foreign VCS.
80
def register(self, key, factory, help):
81
"""Register a mapping between Bazaar and foreign VCS semantics.
83
The factory must be a callable that takes one parameter: the key.
84
It must produce an instance of VcsMapping when called.
87
raise ValueError("mapping name can not contain colon (:)")
88
registry.Registry.register(self, key, factory, help)
90
def set_default(self, key):
91
"""Set the 'default' key to be a clone of the supplied key.
93
This method must be called once and only once.
95
self._set_default_key(key)
97
def get_default(self):
98
"""Convenience function for obtaining the default mapping to use."""
99
return self.get(self._get_default_key())
101
def revision_id_bzr_to_foreign(self, revid):
102
"""Convert a bzr revision id to a foreign revid."""
103
raise NotImplementedError(self.revision_id_bzr_to_foreign)
106
34
class ForeignBranch(Branch):
107
35
"""Branch that exists in a foreign version control system."""
273
class ForeignRevision(Revision):
274
"""A Revision from a Foreign repository. Remembers
275
information about foreign revision id and mapping.
279
def __init__(self, foreign_revid, mapping, *args, **kwargs):
280
if not "inventory_sha1" in kwargs:
281
kwargs["inventory_sha1"] = ""
282
super(ForeignRevision, self).__init__(*args, **kwargs)
283
self.foreign_revid = foreign_revid
284
self.mapping = mapping
287
def show_foreign_properties(rev):
288
"""Custom log displayer for foreign revision identifiers.
290
:param rev: Revision object.
292
# Revision comes directly from a foreign repository
293
if isinstance(rev, ForeignRevision):
294
return rev.mapping.show_foreign_revid(rev.foreign_revid)
296
# Revision was once imported from a foreign repository
298
foreign_revid, mapping = \
299
foreign_vcs_registry.parse_revision_id(rev.revision_id)
300
except errors.InvalidRevisionId:
303
return mapping.show_foreign_revid(foreign_revid)
306
class ForeignVcs(object):
307
"""A foreign version control system."""
309
def __init__(self, mapping_registry):
310
self.mapping_registry = mapping_registry
313
class ForeignVcsRegistry(registry.Registry):
314
"""Registry for Foreign VCSes.
316
There should be one entry per foreign VCS. Example entries would be
317
"git", "svn", "hg", "darcs", etc.
321
def register(self, key, foreign_vcs, help):
322
"""Register a foreign VCS.
324
:param key: Prefix of the foreign VCS in revision ids
325
:param foreign_vcs: ForeignVCS instance
326
:param help: Description of the foreign VCS
328
if ":" in key or "-" in key:
329
raise ValueError("vcs name can not contain : or -")
330
registry.Registry.register(self, key, foreign_vcs, help)
332
def parse_revision_id(self, revid):
333
"""Parse a bzr revision and return the matching mapping and foreign
336
:param revid: The bzr revision id
337
:return: tuple with foreign revid and vcs mapping
340
raise errors.InvalidRevisionId(revid, None)
342
foreign_vcs = self.get(revid.split("-")[0])
344
raise errors.InvalidRevisionId(revid, None)
345
return foreign_vcs.mapping_registry.revision_id_bzr_to_foreign(revid)
348
if not "foreign" in log.properties_handler_registry:
349
log.properties_handler_registry.register("foreign",
350
show_foreign_properties,
351
"Show foreign VCS properties")
353
foreign_vcs_registry = ForeignVcsRegistry()