~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/foreign.py

  • Committer: John Arbash Meinel
  • Date: 2009-03-27 22:29:55 UTC
  • mto: (3735.39.2 clean)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090327222955-utifmfm888zerixt
Implement apply_delta_to_source which doesn't have to malloc another string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
    errors,
29
29
    osutils,
30
30
    registry,
31
 
    transform,
32
31
    )
33
32
""")
34
33
 
246
245
            self.get_revision(revision_id))
247
246
 
248
247
 
249
 
class ForeignBranch(Branch):
250
 
    """Branch that exists in a foreign version control system."""
251
 
 
252
 
    def __init__(self, mapping):
253
 
        self.mapping = mapping
254
 
        super(ForeignBranch, self).__init__()
255
 
 
256
 
    def dpull(self, source, stop_revision=None):
257
 
        """Pull deltas from another branch.
258
 
 
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.
263
 
 
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.
269
 
        """
270
 
        raise NotImplementedError(self.dpull)
271
 
 
272
 
 
273
 
def update_workingtree_fileids(wt, target_tree):
274
 
    """Update the file ids in a working tree based on another tree.
275
 
 
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
278
 
    """
279
 
    tt = transform.TreeTransform(wt)
280
 
    try:
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)
288
 
        tt.apply()
289
 
    finally:
290
 
        tt.finalize()
291
 
    if len(wt.get_parent_ids()) == 1:
292
 
        wt.set_parent_trees([(target_tree.get_revision_id(), target_tree)])
293
 
    else:
294
 
        wt.set_last_revision(target_tree.get_revision_id())
295
 
 
296
 
 
297
 
class cmd_dpush(Command):
298
 
    """Push diffs into a foreign version control system without any 
299
 
    Bazaar-specific metadata.
300
 
 
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. 
304
 
    """
305
 
    hidden = True
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.',
310
 
            short_name='d',
311
 
            type=unicode,
312
 
            ),
313
 
            Option('no-rebase', help="Do not rebase after push.")]
314
 
 
315
 
    def run(self, location=None, remember=False, directory=None, 
316
 
            no_rebase=False):
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
322
 
 
323
 
        if directory is None:
324
 
            directory = "."
325
 
        try:
326
 
            source_wt = WorkingTree.open_containing(directory)[0]
327
 
            source_branch = source_wt.branch
328
 
        except NoWorkingTree:
329
 
            source_branch = Branch.open(directory)
330
 
            source_wt = None
331
 
        stored_loc = source_branch.get_push_location()
332
 
        if location is None:
333
 
            if stored_loc is None:
334
 
                raise BzrCommandError("No push location known or specified.")
335
 
            else:
336
 
                display_url = urlutils.unescape_for_display(stored_loc,
337
 
                        self.outf.encoding)
338
 
                self.outf.write("Using saved location: %s\n" % display_url)
339
 
                location = stored_loc
340
 
 
341
 
        bzrdir = BzrDir.open(location)
342
 
        target_branch = bzrdir.open_branch()
343
 
        dpull = getattr(target_branch, "dpull", None)
344
 
        if dpull is None:
345
 
            raise BzrCommandError("%r is not a foreign branch, use "
346
 
                                  "regular push." % target_branch)
347
 
        target_branch.lock_write()
348
 
        try:
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)
353
 
            if not no_rebase:
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()
359
 
                    try:
360
 
                        target = source_wt.branch.repository.revision_tree(
361
 
                            new_last_revid)
362
 
                        update_workingtree_fileids(source_wt, target)
363
 
                    finally:
364
 
                        source_wt.unlock()
365
 
        finally:
366
 
            target_branch.unlock()