~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

Merge bzr.dev to resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
from bzrlib import (
25
25
        bzrdir,
26
26
        cache_utf8,
 
27
        cleanup,
27
28
        config as _mod_config,
28
29
        debug,
29
30
        errors,
931
932
 
932
933
        :seealso: Branch._get_tags_bytes.
933
934
        """
934
 
        return _run_with_write_locked_target(self, self._set_tags_bytes_locked,
935
 
                bytes)
 
935
        op = cleanup.OperationWithCleanups(self._set_tags_bytes_locked)
 
936
        op.add_cleanup(self.lock_write().unlock)
 
937
        return op.run_simple(bytes)
936
938
 
937
939
    def _set_tags_bytes_locked(self, bytes):
938
940
        self._tags_bytes = bytes
3168
3170
        branch._transport.put_bytes('format', format.get_format_string())
3169
3171
 
3170
3172
 
3171
 
def _run_with_write_locked_target(target, callable, *args, **kwargs):
3172
 
    """Run ``callable(*args, **kwargs)``, write-locking target for the
3173
 
    duration.
3174
 
 
3175
 
    _run_with_write_locked_target will attempt to release the lock it acquires.
3176
 
 
3177
 
    If an exception is raised by callable, then that exception *will* be
3178
 
    propagated, even if the unlock attempt raises its own error.  Thus
3179
 
    _run_with_write_locked_target should be preferred to simply doing::
3180
 
 
3181
 
        target.lock_write()
3182
 
        try:
3183
 
            return callable(*args, **kwargs)
3184
 
        finally:
3185
 
            target.unlock()
3186
 
 
3187
 
    """
3188
 
    # This is very similar to bzrlib.decorators.needs_write_lock.  Perhaps they
3189
 
    # should share code?
3190
 
    target.lock_write()
3191
 
    try:
3192
 
        result = callable(*args, **kwargs)
3193
 
    except:
3194
 
        exc_info = sys.exc_info()
3195
 
        try:
3196
 
            target.unlock()
3197
 
        finally:
3198
 
            try:
3199
 
                raise exc_info[0], exc_info[1], exc_info[2]
3200
 
            finally:
3201
 
                del exc_info
3202
 
    else:
3203
 
        target.unlock()
3204
 
        return result
3205
 
 
3206
 
 
3207
3173
class InterBranch(InterObject):
3208
3174
    """This class represents operations taking place between two branches.
3209
3175
 
3408
3374
            raise errors.LossyPushToSameVCS(self.source, self.target)
3409
3375
        # TODO: Public option to disable running hooks - should be trivial but
3410
3376
        # needs tests.
3411
 
        self.source.lock_read()
3412
 
        try:
3413
 
            return _run_with_write_locked_target(
3414
 
                self.target, self._push_with_bound_branches, overwrite,
3415
 
                stop_revision, 
3416
 
                _override_hook_source_branch=_override_hook_source_branch)
3417
 
        finally:
3418
 
            self.source.unlock()
 
3377
 
 
3378
        op = cleanup.OperationWithCleanups(self._push_with_bound_branches)
 
3379
        op.add_cleanup(self.source.lock_read().unlock)
 
3380
        op.add_cleanup(self.target.lock_write().unlock)
 
3381
        return op.run(overwrite, stop_revision,
 
3382
            _override_hook_source_branch=_override_hook_source_branch)
3419
3383
 
3420
3384
    def _basic_push(self, overwrite, stop_revision):
3421
3385
        """Basic implementation of push without bound branches or hooks.
3439
3403
        result.new_revno, result.new_revid = self.target.last_revision_info()
3440
3404
        return result
3441
3405
 
3442
 
    def _push_with_bound_branches(self, overwrite, stop_revision,
 
3406
    def _push_with_bound_branches(self, operation, overwrite, stop_revision,
3443
3407
            _override_hook_source_branch=None):
3444
3408
        """Push from source into target, and into target's master if any.
3445
3409
        """
3457
3421
            # be bound to itself? -- mbp 20070507
3458
3422
            master_branch = self.target.get_master_branch()
3459
3423
            master_branch.lock_write()
3460
 
            try:
3461
 
                # push into the master from the source branch.
3462
 
                master_inter = InterBranch.get(self.source, master_branch)
3463
 
                master_inter._basic_push(overwrite, stop_revision)
3464
 
                # and push into the target branch from the source. Note that
3465
 
                # we push from the source branch again, because it's considered
3466
 
                # the highest bandwidth repository.
3467
 
                result = self._basic_push(overwrite, stop_revision)
3468
 
                result.master_branch = master_branch
3469
 
                result.local_branch = self.target
3470
 
                _run_hooks()
3471
 
                return result
3472
 
            finally:
3473
 
                master_branch.unlock()
 
3424
            operation.add_cleanup(master_branch.unlock)
 
3425
            # push into the master from the source branch.
 
3426
            master_inter = InterBranch.get(self.source, master_branch)
 
3427
            master_inter._basic_push(overwrite, stop_revision)
 
3428
            # and push into the target branch from the source. Note that
 
3429
            # we push from the source branch again, because it's considered
 
3430
            # the highest bandwidth repository.
 
3431
            result = self._basic_push(overwrite, stop_revision)
 
3432
            result.master_branch = master_branch
 
3433
            result.local_branch = self.target
3474
3434
        else:
 
3435
            master_branch = None
3475
3436
            # no master branch
3476
3437
            result = self._basic_push(overwrite, stop_revision)
3477
3438
            # TODO: Why set master_branch and local_branch if there's no
3479
3440
            # 20070504
3480
3441
            result.master_branch = self.target
3481
3442
            result.local_branch = None
3482
 
            _run_hooks()
3483
 
            return result
 
3443
        _run_hooks()
 
3444
        return result
3484
3445
 
3485
3446
    def _pull(self, overwrite=False, stop_revision=None,
3486
3447
             possible_transports=None, _hook_master=None, run_hooks=True,