245
246
self.get_revision(revision_id))
249
class ForeignBranch(Branch):
250
"""Branch that exists in a foreign version control system."""
252
def __init__(self, mapping):
253
self.mapping = mapping
254
super(ForeignBranch, self).__init__()
256
def dpull(self, source, stop_revision=None):
257
"""Pull deltas from another branch.
259
:note: This does not, like pull, retain the revision ids from
260
the source branch and will, rather than adding bzr-specific
261
metadata, push only those semantics of the revision that can be
262
natively represented by this branch' VCS.
264
:param source: Source branch
265
:param stop_revision: Revision to pull, defaults to last revision.
266
:return: Dictionary mapping revision ids from the source branch
267
to new revision ids in the target branch, for each
268
revision that was pull.
270
raise NotImplementedError(self.dpull)
273
def update_workingtree_fileids(wt, target_tree):
274
"""Update the file ids in a working tree based on another tree.
276
:param wt: Working tree in which to update file ids
277
:param target_tree: Tree to retrieve new file ids from, based on path
279
tt = transform.TreeTransform(wt)
281
for f, p, c, v, d, n, k, e in target_tree.iter_changes(wt):
282
if v == (True, False):
283
trans_id = tt.trans_id_tree_path(p[0])
284
tt.unversion_file(trans_id)
285
elif v == (False, True):
286
trans_id = tt.trans_id_tree_path(p[1])
287
tt.version_file(f, trans_id)
291
if len(wt.get_parent_ids()) == 1:
292
wt.set_parent_trees([(target_tree.get_revision_id(), target_tree)])
294
wt.set_last_revision(target_tree.get_revision_id())
297
class cmd_dpush(Command):
298
"""Push diffs into a foreign version control system without any
299
Bazaar-specific metadata.
301
This will afterwards rebase the local Bazaar branch on the remote
302
branch unless the --no-rebase option is used, in which case
303
the two branches will be out of sync.
306
takes_args = ['location?']
307
takes_options = ['remember', Option('directory',
308
help='Branch to push from, '
309
'rather than the one containing the working directory.',
313
Option('no-rebase', help="Do not rebase after push.")]
315
def run(self, location=None, remember=False, directory=None,
317
from bzrlib import urlutils
318
from bzrlib.bzrdir import BzrDir
319
from bzrlib.errors import BzrCommandError, NoWorkingTree
320
from bzrlib.trace import info
321
from bzrlib.workingtree import WorkingTree
323
if directory is None:
326
source_wt = WorkingTree.open_containing(directory)[0]
327
source_branch = source_wt.branch
328
except NoWorkingTree:
329
source_branch = Branch.open(directory)
331
stored_loc = source_branch.get_push_location()
333
if stored_loc is None:
334
raise BzrCommandError("No push location known or specified.")
336
display_url = urlutils.unescape_for_display(stored_loc,
338
self.outf.write("Using saved location: %s\n" % display_url)
339
location = stored_loc
341
bzrdir = BzrDir.open(location)
342
target_branch = bzrdir.open_branch()
343
dpull = getattr(target_branch, "dpull", None)
345
raise BzrCommandError("%r is not a foreign branch, use "
346
"regular push." % target_branch)
347
target_branch.lock_write()
349
revid_map = dpull(source_branch)
350
# We successfully created the target, remember it
351
if source_branch.get_push_location() is None or remember:
352
source_branch.set_push_location(target_branch.base)
354
old_last_revid = source_branch.last_revision()
355
source_branch.pull(target_branch, overwrite=True)
356
new_last_revid = source_branch.last_revision()
357
if source_wt is not None and old_last_revid != new_last_revid:
358
source_wt.lock_write()
360
target = source_wt.branch.repository.revision_tree(
362
update_workingtree_fileids(source_wt, target)
366
target_branch.unlock()