1264
1265
if self._lock_mode == 'r':
1265
1266
self._real_branch.lock_read()
1268
def _clear_cached_state(self):
1269
super(RemoteBranch, self)._clear_cached_state()
1270
if self._real_branch is not None:
1271
self._real_branch._clear_cached_state()
1273
def _clear_cached_state_of_remote_branch_only(self):
1274
"""Like _clear_cached_state, but doesn't clear the cache of
1277
This is useful when falling back to calling a method of
1278
self._real_branch that changes state. In that case the underlying
1279
branch changes, so we need to invalidate this RemoteBranch's cache of
1280
it. However, there's no need to invalidate the _real_branch's cache
1281
too, in fact doing so might harm performance.
1283
super(RemoteBranch, self)._clear_cached_state()
1268
1286
def control_files(self):
1269
1287
# Defer actually creating RemoteBranchLockableFiles until its needed,
1431
1448
response_tuple, response_handler = self._client.call_expecting_body(
1432
1449
'Branch.revision_history', path)
1433
1450
if response_tuple[0] != 'ok':
1434
raise UnexpectedSmartServerResponse(response_tuple)
1451
raise errors.UnexpectedSmartServerResponse(response_tuple)
1435
1452
result = response_handler.read_body_bytes().split('\x00')
1436
1453
if result == ['']:
1457
def _set_last_revision_descendant(self, revision_id, other_branch,
1458
allow_diverged=False, allow_overwrite_descendant=False):
1459
path = self.bzrdir._path_for_remote_call(self._client)
1461
response = self._client.call('Branch.set_last_revision_ex',
1462
path, self._lock_token, self._repo_lock_token, revision_id,
1463
int(allow_diverged), int(allow_overwrite_descendant))
1464
except errors.ErrorFromSmartServer, err:
1465
if err.error_verb == 'NoSuchRevision':
1466
raise NoSuchRevision(self, revision_id)
1467
elif err.error_verb == 'Diverged':
1468
raise errors.DivergedBranches(self, other_branch)
1470
self._clear_cached_state()
1471
if len(response) != 3 and response[0] != 'ok':
1472
raise errors.UnexpectedSmartServerResponse(response)
1473
new_revno, new_revision_id = response[1:]
1474
self._last_revision_info_cache = new_revno, new_revision_id
1475
self._real_branch._last_revision_info_cache = new_revno, new_revision_id
1477
def _set_last_revision(self, revision_id):
1478
path = self.bzrdir._path_for_remote_call(self._client)
1479
self._clear_cached_state()
1481
response = self._client.call('Branch.set_last_revision',
1482
path, self._lock_token, self._repo_lock_token, revision_id)
1483
except errors.ErrorFromSmartServer, err:
1484
if err.error_verb == 'NoSuchRevision':
1485
raise NoSuchRevision(self, revision_id)
1487
if response != ('ok',):
1488
raise errors.UnexpectedSmartServerResponse(response)
1440
1490
@needs_write_lock
1441
1491
def set_revision_history(self, rev_history):
1442
1492
# Send just the tip revision of the history; the server will generate
1443
1493
# the full history from that. If the revision doesn't exist in this
1444
1494
# branch, NoSuchRevision will be raised.
1445
path = self.bzrdir._path_for_remote_call(self._client)
1446
1495
if rev_history == []:
1447
1496
rev_id = 'null:'
1449
1498
rev_id = rev_history[-1]
1450
self._clear_cached_state()
1452
response = self._client.call('Branch.set_last_revision',
1453
path, self._lock_token, self._repo_lock_token, rev_id)
1454
except errors.ErrorFromSmartServer, err:
1455
if err.error_verb == 'NoSuchRevision':
1456
raise NoSuchRevision(self, rev_id)
1458
if response != ('ok',):
1459
raise errors.UnexpectedSmartServerResponse(response)
1499
self._set_last_revision(rev_id)
1460
1500
self._cache_revision_history(rev_history)
1462
1502
def get_parent(self):
1505
1546
path, self._lock_token, self._repo_lock_token, str(revno), revision_id)
1506
1547
except errors.UnknownSmartMethod:
1507
1548
self._ensure_real()
1508
self._clear_cached_state()
1509
return self._real_branch.set_last_revision_info(revno, revision_id)
1549
self._clear_cached_state_of_remote_branch_only()
1550
self._real_branch.set_last_revision_info(revno, revision_id)
1551
self._last_revision_info_cache = revno, revision_id
1510
1553
except errors.ErrorFromSmartServer, err:
1511
1554
if err.error_verb == 'NoSuchRevision':
1512
1555
raise NoSuchRevision(self, err.error_args[0])
1514
1557
if response == ('ok',):
1515
1558
self._clear_cached_state()
1559
self._last_revision_info_cache = revno, revision_id
1560
# Update the _real_branch's cache too.
1561
if self._real_branch is not None:
1562
cache = self._last_revision_info_cache
1563
self._real_branch._last_revision_info_cache = cache
1517
1565
raise errors.UnexpectedSmartServerResponse(response)
1519
1568
def generate_revision_history(self, revision_id, last_rev=None,
1520
1569
other_branch=None):
1570
medium = self._client._medium
1571
if not medium._is_remote_before((1, 6)):
1573
self._set_last_revision_descendant(revision_id, other_branch,
1574
allow_diverged=True, allow_overwrite_descendant=True)
1576
except errors.UnknownSmartMethod:
1577
medium._remember_remote_is_before((1, 6))
1578
self._clear_cached_state_of_remote_branch_only()
1521
1579
self._ensure_real()
1522
return self._real_branch.generate_revision_history(
1580
self._real_branch.generate_revision_history(
1523
1581
revision_id, last_rev=last_rev, other_branch=other_branch)
1531
1589
self._ensure_real()
1532
1590
return self._real_branch.set_push_location(location)
1534
1593
def update_revisions(self, other, stop_revision=None, overwrite=False,
1537
return self._real_branch.update_revisions(
1538
other, stop_revision=stop_revision, overwrite=overwrite,
1595
"""See Branch.update_revisions."""
1598
if stop_revision is None:
1599
stop_revision = other.last_revision()
1600
if revision.is_null(stop_revision):
1601
# if there are no commits, we're done.
1603
self.fetch(other, stop_revision)
1606
# Just unconditionally set the new revision. We don't care if
1607
# the branches have diverged.
1608
self._set_last_revision(stop_revision)
1610
medium = self._client._medium
1611
if not medium._is_remote_before((1, 6)):
1613
self._set_last_revision_descendant(stop_revision, other)
1615
except errors.UnknownSmartMethod:
1616
medium._remember_remote_is_before((1, 6))
1617
# Fallback for pre-1.6 servers: check for divergence
1618
# client-side, then do _set_last_revision.
1619
last_rev = revision.ensure_null(self.last_revision())
1621
graph = self.repository.get_graph()
1622
if self._check_if_descendant_or_diverged(
1623
stop_revision, last_rev, graph, other):
1624
# stop_revision is a descendant of last_rev, but we aren't
1625
# overwriting, so we're done.
1627
self._set_last_revision(stop_revision)
1542
1632
def _extract_tar(tar, to_dir):