258
258
:param stop_revision: Revision to pull, defaults to last revision.
260
260
raise NotImplementedError(self.dpull)
263
def determine_fileid_renames(old_tree, new_tree):
264
for old_file_id in old_tree:
265
new_file_id = new_tree.path2id(old_tree.id2path(old_file_id))
266
if old_file_id == new_file_id:
268
if new_file_id is not None:
269
yield new_tree.id2path(new_file_id), old_file_id, new_file_id
272
def update_workingtree_fileids(wt, old_tree, new_tree):
273
"""Update all file ids in wt according to old_tree/new_tree.
275
old_tree and new_tree should be two RevisionTree's that differ only
278
fileid_renames = dict([(path, (old_fileid, new_fileid)) for (path, old_fileid, new_fileid) in determine_fileid_renames(old_tree, new_tree)])
282
# Adjust file ids in working tree
283
for path in sorted(fileid_renames.keys(), reverse=True):
285
old_fileids.append(fileid_renames[path][0])
286
new_fileids.append((path, fileid_renames[path][1]))
288
new_root_id = fileid_renames[path][1]
289
new_fileids.reverse()
290
wt.unversion(old_fileids)
291
if new_root_id is not None:
292
wt.set_root_id(new_root_id)
293
wt.add([x[0] for x in new_fileids], [x[1] for x in new_fileids])
294
wt.set_last_revision(new_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.
305
takes_args = ['location?']
306
takes_options = ['remember', Option('directory',
307
help='Branch to push from, '
308
'rather than the one containing the working directory.',
312
Option('no-rebase', help="Don't rebase after push")]
314
def run(self, location=None, remember=False, directory=None,
316
from bzrlib import urlutils
317
from bzrlib.bzrdir import BzrDir
318
from bzrlib.errors import BzrCommandError, NoWorkingTree
319
from bzrlib.trace import info
320
from bzrlib.workingtree import WorkingTree
322
if directory is None:
325
source_wt = WorkingTree.open_containing(directory)[0]
326
source_branch = source_wt.branch
327
except NoWorkingTree:
328
source_branch = Branch.open_containing(directory)[0]
330
stored_loc = source_branch.get_push_location()
332
if stored_loc is None:
333
raise BzrCommandError("No push location known or specified.")
335
display_url = urlutils.unescape_for_display(stored_loc,
337
self.outf.write("Using saved location: %s\n" % display_url)
338
location = stored_loc
340
bzrdir = BzrDir.open(location)
341
target_branch = bzrdir.open_branch()
342
target_branch.lock_write()
344
if not isinstance(target_branch, ForeignBranch):
345
info("target branch is not a foreign branch, using regular push.")
346
target_branch.pull(source_branch)
349
revid_map = target_branch.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_info()
355
new_last_revid = revid_map[old_last_revid]
356
if source_wt is not None:
357
source_wt.pull(target_branch, overwrite=True,
358
stop_revision=new_last_revid)
359
source_wt.lock_write()
361
update_workingtree_fileids(source_wt,
362
source_wt.branch.repository.revision_tree(old_last_revid),
363
source_wt.branch.repository.revision_tree(new_last_revid))
367
source_branch.pull(target_branch, overwrite=True,
368
stop_revision=new_last_revid)
370
target_branch.unlock()