1518
def _set_last_revision_descendant(self, revision_id, other_branch):
1519
path = self.bzrdir._path_for_remote_call(self._client)
1521
response = self._client.call('Branch.set_last_revision_descendant',
1522
path, self._lock_token, self._repo_lock_token, revision_id)
1523
except errors.ErrorFromSmartServer, err:
1524
if err.error_verb == 'NoSuchRevision':
1525
raise NoSuchRevision(self, revision_id)
1526
elif err.error_verb == 'NotDescendant':
1527
raise errors.DivergedBranches(self, other_branch)
1529
self._clear_cached_state()
1530
if len(response) != 2 and response[0] != 'ok':
1531
raise errors.UnexpectedSmartServerResponse(response)
1532
new_revno = response[1]
1533
self._last_revision_info_cache = new_revno, revision_id
1518
1535
def _set_last_revision(self, revision_id):
1519
1536
path = self.bzrdir._path_for_remote_call(self._client)
1520
1537
self._clear_cached_state()
1609
1626
def generate_revision_history(self, revision_id, last_rev=None,
1610
1627
other_branch=None):
1628
medium = self._client._medium
1629
if medium._remote_is_at_least_1_6:
1631
self._set_last_revision_descendant(revision_id, other_branch)
1633
except UnknownSmartMethod:
1634
medium._remote_is_at_least_1_6 = False
1611
1635
self._clear_cached_state()
1612
1636
self._ensure_real()
1613
return self._real_branch.generate_revision_history(
1637
self._real_branch.generate_revision_history(
1614
1638
revision_id, last_rev=last_rev, other_branch=other_branch)
1622
1646
self._ensure_real()
1623
1647
return self._real_branch.set_push_location(location)
1625
1650
def update_revisions(self, other, stop_revision=None, overwrite=False):
1627
self._clear_cached_state()
1629
return self._real_branch.update_revisions(
1630
other, stop_revision=stop_revision, overwrite=True)
1631
# XXX: this code is substantially copy-and-pasted from
1632
# Branch.update_revisions. This is however much faster than calling
1633
# the same code on _real_branch, because it will use RPCs and cache
1635
1651
other.lock_read()
1637
other_last_revno, other_last_revision = other.last_revision_info()
1638
1653
if stop_revision is None:
1639
stop_revision = other_last_revision
1654
stop_revision = other.last_revision()
1640
1655
if revision.is_null(stop_revision):
1641
1656
# if there are no commits, we're done.
1643
1658
# whats the current last revision, before we fetch [and change it
1645
last_rev = revision.ensure_null(self.last_revision())
1646
# we fetch here so that we don't process data twice in the common
1647
# case of having something to pull, and so that the check for
1648
# already merged can operate on the just fetched graph, which will
1649
# be cached in memory.
1650
1660
self.fetch(other, stop_revision)
1651
# Check to see if one is an ancestor of the other
1652
heads = self.repository.get_graph().heads([stop_revision,
1654
if heads == set([last_rev]):
1655
# The current revision is a decendent of the target,
1658
elif heads == set([stop_revision, last_rev]):
1659
# These branches have diverged
1660
raise errors.DivergedBranches(self, other)
1661
elif heads != set([stop_revision]):
1662
raise AssertionError("invalid heads: %r" % heads)
1663
if other_last_revision == stop_revision:
1664
self.set_last_revision_info(other_last_revno,
1665
other_last_revision)
1667
# XXX: In Branch.update_revisions this code is more
1668
# complicated. Here we just allow the remote side to generate
1669
# the new history for us.
1670
1663
self._set_last_revision(stop_revision)
1665
medium = self._client._medium
1666
if medium._remote_is_at_least_1_6:
1668
self._set_last_revision_descendant(stop_revision, other)
1670
except UnknownSmartMethod:
1671
medium._remote_is_at_least_1_6 = False
1672
last_rev = revision.ensure_null(self.last_revision())
1673
self.generate_revision_history(
1674
stop_revision, last_rev=last_rev, other_branch=other)