117
115
self.mapping = mapping
118
def show_foreign_properties(rev):
119
"""Custom log displayer for foreign revision identifiers.
121
:param rev: Revision object.
123
# Revision comes directly from a foreign repository
124
if isinstance(rev, ForeignRevision):
125
return rev.mapping.vcs.show_foreign_revid(rev.foreign_revid)
127
# Revision was once imported from a foreign repository
129
foreign_revid, mapping = \
130
foreign_vcs_registry.parse_revision_id(rev.revision_id)
131
except errors.InvalidRevisionId:
134
return mapping.vcs.show_foreign_revid(foreign_revid)
120
137
class ForeignVcs(object):
121
138
"""A foreign version control system."""
125
repository_format = None
127
def __init__(self, mapping_registry, abbreviation=None):
128
"""Create a new foreign vcs instance.
130
:param mapping_registry: Registry with mappings for this VCS.
131
:param abbreviation: Optional abbreviation ('bzr', 'svn', 'git', etc)
133
self.abbreviation = abbreviation
140
def __init__(self, mapping_registry):
134
141
self.mapping_registry = mapping_registry
136
143
def show_foreign_revid(self, foreign_revid):
223
221
"""Get the default mapping for this repository."""
224
222
raise NotImplementedError(self.get_default_mapping)
227
class ForeignBranch(Branch):
228
"""Branch that exists in a foreign version control system."""
230
def __init__(self, mapping):
231
self.mapping = mapping
232
super(ForeignBranch, self).__init__()
235
def update_workingtree_fileids(wt, target_tree):
236
"""Update the file ids in a working tree based on another tree.
238
:param wt: Working tree in which to update file ids
239
:param target_tree: Tree to retrieve new file ids from, based on path
241
tt = transform.TreeTransform(wt)
243
for f, p, c, v, d, n, k, e in target_tree.iter_changes(wt):
244
if v == (True, False):
245
trans_id = tt.trans_id_tree_path(p[0])
246
tt.unversion_file(trans_id)
247
elif v == (False, True):
248
trans_id = tt.trans_id_tree_path(p[1])
249
tt.version_file(f, trans_id)
253
if len(wt.get_parent_ids()) == 1:
254
wt.set_parent_trees([(target_tree.get_revision_id(), target_tree)])
256
wt.set_last_revision(target_tree.get_revision_id())
259
class cmd_dpush(Command):
260
__doc__ = """Push into a different VCS without any custom bzr metadata.
262
This will afterwards rebase the local branch on the remote
263
branch unless the --no-rebase option is used, in which case
264
the two branches will be out of sync after the push.
267
takes_args = ['location?']
271
help='Branch to push from, '
272
'rather than the one containing the working directory.',
276
Option('no-rebase', help="Do not rebase after push."),
278
help='Refuse to push if there are uncommitted changes in'
279
' the working tree, --no-strict disables the check.'),
282
def run(self, location=None, remember=False, directory=None,
283
no_rebase=False, strict=None):
284
from bzrlib import urlutils
285
from bzrlib.bzrdir import BzrDir
286
from bzrlib.errors import BzrCommandError, NoWorkingTree
287
from bzrlib.workingtree import WorkingTree
289
if directory is None:
292
source_wt = WorkingTree.open_containing(directory)[0]
293
source_branch = source_wt.branch
294
except NoWorkingTree:
295
source_branch = Branch.open(directory)
297
if source_wt is not None:
298
source_wt.check_changed_or_out_of_date(
299
strict, 'dpush_strict',
300
more_error='Use --no-strict to force the push.',
301
more_warning='Uncommitted changes will not be pushed.')
302
stored_loc = source_branch.get_push_location()
304
if stored_loc is None:
305
raise BzrCommandError("No push location known or specified.")
307
display_url = urlutils.unescape_for_display(stored_loc,
309
self.outf.write("Using saved location: %s\n" % display_url)
310
location = stored_loc
312
bzrdir = BzrDir.open(location)
313
target_branch = bzrdir.open_branch()
314
target_branch.lock_write()
317
push_result = source_branch.push(target_branch, lossy=True)
318
except errors.LossyPushToSameVCS:
319
raise BzrCommandError("%r and %r are in the same VCS, lossy "
320
"push not necessary. Please use regular push." %
321
(source_branch, target_branch))
322
# We successfully created the target, remember it
323
if source_branch.get_push_location() is None or remember:
324
source_branch.set_push_location(target_branch.base)
326
old_last_revid = source_branch.last_revision()
327
source_branch.pull(target_branch, overwrite=True)
328
new_last_revid = source_branch.last_revision()
329
if source_wt is not None and old_last_revid != new_last_revid:
330
source_wt.lock_write()
332
target = source_wt.branch.repository.revision_tree(
334
update_workingtree_fileids(source_wt, target)
337
push_result.report(self.outf)
339
target_branch.unlock()
224
def get_inventory_xml(self, revision_id):
225
"""See Repository.get_inventory_xml()."""
226
return self.serialise_inventory(self.get_inventory(revision_id))
228
def get_inventory_sha1(self, revision_id):
229
"""Get the sha1 for the XML representation of an inventory.
231
:param revision_id: Revision id of the inventory for which to return
236
return osutils.sha_string(self.get_inventory_xml(revision_id))
238
def get_revision_xml(self, revision_id):
239
"""Return the XML representation of a revision.
241
:param revision_id: Revision for which to return the XML.
244
return self._serializer.write_revision_to_string(
245
self.get_revision(revision_id))