85
85
self.tags = self._make_tags()
86
86
self._revision_history_cache = None
87
87
self._revision_id_to_revno_cache = None
88
self._last_revision_info_cache = None
89
90
def break_lock(self):
90
91
"""Break a lock if one is present from another instance.
362
363
self._revision_history_cache = None
363
364
self._revision_id_to_revno_cache = None
365
self._last_revision_info_cache = None
365
367
def _gen_revision_history(self):
366
368
"""Return sequence of revision hashes on to this branch.
413
415
"""Return last revision id, or NULL_REVISION."""
414
416
return self.last_revision_info()[1]
416
419
def last_revision_info(self):
417
420
"""Return information about the last revision.
419
:return: A tuple (revno, last_revision_id).
422
:return: A tuple (revno, revision_id).
424
if self._last_revision_info_cache is None:
425
self._last_revision_info_cache = self._last_revision_info()
426
return self._last_revision_info_cache
428
def _last_revision_info(self):
421
429
rh = self.revision_history()
484
492
if not overwrite:
485
493
if graph is None:
486
494
graph = self.repository.get_graph()
487
heads = graph.heads([stop_revision, last_rev])
488
if heads == set([last_rev]):
489
# The current revision is a decendent of the target,
495
if self._check_if_descendant_or_diverged(
496
stop_revision, last_rev, graph, other):
497
# stop_revision is a descendant of last_rev, but we aren't
498
# overwriting, so we're done.
492
elif heads == set([stop_revision, last_rev]):
493
# These branches have diverged
494
raise errors.DivergedBranches(self, other)
495
elif heads != set([stop_revision]):
496
raise AssertionError("invalid heads: %r" % heads)
497
500
if stop_revno is None:
498
501
if graph is None:
499
502
graph = self.repository.get_graph()
854
857
def supports_tags(self):
855
858
return self._format.supports_tags()
860
def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
862
"""Ensure that revision_b is a descendant of revision_a.
864
This is a helper function for update_revisions.
866
:raises: DivergedBranches if revision_b has diverged from revision_a.
867
:returns: True if revision_b is a descendant of revision_a.
869
relation = self._revision_relations(revision_a, revision_b, graph)
870
if relation == 'b_descends_from_a':
872
elif relation == 'diverged':
873
raise errors.DivergedBranches(self, other_branch)
874
elif relation == 'a_descends_from_b':
877
raise AssertionError("invalid heads: %r" % heads)
879
def _revision_relations(self, revision_a, revision_b, graph):
880
"""Determine the relationship between two revisions.
882
:returns: One of: 'a_descends_from_b', 'b_descends_from_a', 'diverged'
884
heads = graph.heads([revision_a, revision_b])
885
if heads == set([revision_b]):
886
return 'b_descends_from_a'
887
elif heads == set([revision_a, revision_b]):
888
# These branches have diverged
890
elif heads == set([revision_a]):
891
return 'a_descends_from_b'
893
raise AssertionError("invalid heads: %r" % heads)
858
896
class BranchFormat(object):
859
897
"""An encapsulation of the initialization and open routines for a format.
1465
1503
"""See Branch.set_revision_history."""
1466
1504
if 'evil' in debug.debug_flags:
1467
1505
mutter_callsite(3, "set_revision_history scales with history.")
1506
check_not_reserved_id = _mod_revision.check_not_reserved_id
1507
for rev_id in rev_history:
1508
check_not_reserved_id(rev_id)
1468
1509
self._write_revision_history(rev_history)
1469
1510
self._clear_cached_state()
1470
1511
self._cache_revision_history(rev_history)
1528
1569
raise errors.NoSuchRevision(self, revision_id)
1529
1570
current_rev_id = revision_id
1530
1571
new_history = []
1572
check_not_reserved_id = _mod_revision.check_not_reserved_id
1531
1573
# Do not include ghosts or graph origin in revision_history
1532
1574
while (current_rev_id in parents_map and
1533
1575
len(parents_map[current_rev_id]) > 0):
1576
check_not_reserved_id(current_rev_id)
1534
1577
new_history.append(current_rev_id)
1535
1578
current_rev_id = parents_map[current_rev_id][0]
1536
1579
parents_map = graph.get_parent_map([current_rev_id])
1883
1926
def __init__(self, *args, **kwargs):
1884
1927
super(BzrBranch6, self).__init__(*args, **kwargs)
1885
self._last_revision_info_cache = None
1886
1928
self._partial_revision_history_cache = []
1888
1930
def _clear_cached_state(self):
1889
1931
super(BzrBranch6, self)._clear_cached_state()
1890
self._last_revision_info_cache = None
1891
1932
self._partial_revision_history_cache = []
1894
def last_revision_info(self):
1895
"""Return information about the last revision.
1897
:return: A tuple (revno, revision_id).
1899
if self._last_revision_info_cache is None:
1900
self._last_revision_info_cache = self._last_revision_info()
1901
return self._last_revision_info_cache
1903
1934
def _last_revision_info(self):
1904
1935
revision_string = self._transport.get_bytes('last-revision')
1905
1936
revno, revision_id = revision_string.rstrip('\n').split(' ', 1)