426
426
self.repository = remote_repository
427
427
if real_branch is not None:
428
428
self._real_branch = real_branch
429
# Give the remote repository the matching real repo.
430
self.repository._set_real_repository(self._real_branch.repository)
431
# Give the branch the remote repository to let fast-pathing happen.
432
self._real_branch.repository = self.repository
430
434
self._real_branch = None
431
435
# Fill out expected attributes of branch for bzrlib api users.
432
436
self._format = RemoteBranchFormat()
433
437
self.base = self.bzrdir.root_transport.base
434
438
self.control_files = RemoteBranchLockableFiles(self.bzrdir, self._client)
439
self._lock_mode = None
440
self._lock_token = None
442
self._leave_lock = False
436
444
def _ensure_real(self):
437
445
"""Ensure that there is a _real_branch set.
457
465
self._ensure_real()
458
466
return self._real_branch.lock_read()
460
def lock_write(self, token=None):
462
return self._real_branch.lock_write(token=token)
468
def _lock_write(self, tokens):
470
branch_token = repo_token = ''
472
branch_token, repo_token = tokens
473
path = self.bzrdir._path_for_remote_call(self._client)
474
response = self._client.call('Branch.lock_write', path, branch_token,
476
if response[0] == 'ok':
477
ok, branch_token, repo_token = response
478
return branch_token, repo_token
479
elif response[0] == 'LockContention':
480
raise errors.LockContention('(remote lock)')
481
elif response[0] == 'TokenMismatch':
482
raise errors.TokenMismatch(tokens, '(remote tokens)')
484
assert False, 'unexpected response code %s' % (response,)
486
def lock_write(self, tokens=None):
487
if not self._lock_mode:
488
remote_tokens = self._lock_write(tokens)
489
self._lock_token, self._repo_lock_token = remote_tokens
490
assert self._lock_token, 'Remote server did not return a token!'
491
if self._real_branch is not None:
492
self._real_branch.lock_write(tokens=remote_tokens)
493
if tokens is not None:
494
self._leave_lock = True
496
# XXX: this case seems to be unreachable; tokens cannot be None.
497
self._leave_lock = False
498
self._lock_mode = 'w'
500
elif self._lock_mode == 'r':
501
raise errors.ReadOnlyTransaction
503
if tokens is not None:
504
# Tokens were given to lock_write, and we're relocking, so check
505
# that the given tokens actually match the ones we already have.
506
held_tokens = (self._lock_token, self._repo_lock_token)
507
if tokens != held_tokens:
508
raise errors.TokenMismatch(str(tokens), str(held_tokens))
509
self._lock_count += 1
510
return self._lock_token, self._repo_lock_token
512
def _unlock(self, branch_token, repo_token):
513
path = self.bzrdir._path_for_remote_call(self._client)
514
response = self._client.call('Branch.unlock', path, branch_token,
516
if response == ('ok',):
518
elif response[0] == 'TokenMismatch':
519
raise errors.TokenMismatch(token, '(remote token)')
521
assert False, 'unexpected response code %s' % (response,)
464
523
def unlock(self):
466
return self._real_branch.unlock()
524
self._lock_count -= 1
525
if not self._lock_count:
526
mode = self._lock_mode
527
self._lock_mode = None
528
if self._real_branch is not None:
529
self._real_branch.unlock()
532
assert self._lock_token, 'Locked, but no token!'
533
branch_token = self._lock_token
534
repo_token = self._repo_lock_token
535
self._lock_token = None
536
self._repo_lock_token = None
537
if not self._leave_lock:
538
self._unlock(branch_token, repo_token)
468
540
def break_lock(self):
469
541
self._ensure_real()
470
542
return self._real_branch.break_lock()
544
def leave_lock_in_place(self):
545
self._leave_lock = True
547
def dont_leave_lock_in_place(self):
548
self._leave_lock = False
472
550
def last_revision_info(self):
473
551
"""See Branch.last_revision_info()."""
474
552
path = self.bzrdir._path_for_remote_call(self._client)