455
455
filtered = self._filter_merge_sorted_revisions(
456
456
self._merge_sorted_revisions_cache, start_revision_id,
457
457
stop_revision_id, stop_rule)
458
# Make sure we don't return revisions that are not part of the
459
# start_revision_id ancestry.
460
filtered = self._filter_non_ancestors(filtered)
458
461
if direction == 'reverse':
460
463
if direction == 'forward':
526
529
raise ValueError('invalid stop_rule %r' % stop_rule)
531
def _filter_non_ancestors(self, rev_iter):
532
# If we started from a dotted revno, we want to consider it as a tip
533
# and don't want to yield revisions that are not part of its
534
# ancestry. Given the order guaranteed by the merge sort, we will see
535
# uninteresting descendants of the first parent of our tip before the
537
first = rev_iter.next()
538
(rev_id, merge_depth, revno, end_of_merge) = first
541
# We start at a mainline revision so by definition, all others
542
# revisions in rev_iter are ancestors
543
for node in rev_iter:
548
pmap = self.repository.get_parent_map([rev_id])
549
parents = pmap.get(rev_id, [])
551
whitelist.update(parents)
553
# If there is no parents, there is nothing of interest left
555
# FIXME: It's hard to test this scenario here as this code is never
556
# called in that case. -- vila 20100322
559
for (rev_id, merge_depth, revno, end_of_merge) in rev_iter:
561
if rev_id in whitelist:
562
pmap = self.repository.get_parent_map([rev_id])
563
parents = pmap.get(rev_id, [])
564
whitelist.remove(rev_id)
565
whitelist.update(parents)
567
# We've reached the mainline, there is nothing left to
571
# A revision that is not part of the ancestry of our
574
yield (rev_id, merge_depth, revno, end_of_merge)
528
576
def leave_lock_in_place(self):
529
577
"""Tell this branch object not to release the physical lock when this
530
578
object is unlocked.
1366
1414
def supports_tags(self):
1367
1415
return self._format.supports_tags()
1417
def automatic_tag_name(self, revision_id):
1418
"""Try to automatically find the tag name for a revision.
1420
:param revision_id: Revision id of the revision.
1421
:return: A tag name or None if no tag name could be determined.
1423
for hook in Branch.hooks['automatic_tag_name']:
1424
ret = hook(self, revision_id)
1369
1429
def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
1371
1431
"""Ensure that revision_b is a descendant of revision_a.
1685
1745
"multiple hooks installed for transform_fallback_location, "
1686
1746
"all are called with the url returned from the previous hook."
1687
1747
"The order is however undefined.", (1, 9), None))
1748
self.create_hook(HookPoint('automatic_tag_name',
1749
"Called to determine an automatic tag name for a revision."
1750
"automatic_tag_name is called with (branch, revision_id) and "
1751
"should return a tag name or None if no tag name could be "
1752
"determined. The first non-None tag name returned will be used.",
1690
1757
# install the default hooks into the Branch class.
1760
1827
def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
1761
1828
"""See BranchFormat.open()."""
1762
if name is not None:
1763
raise errors.NoColocatedBranchSupport(a_bzrdir)
1765
1830
# we are being called directly and must probe.
1766
1831
raise NotImplementedError
1767
1832
return BzrBranch(_format=self,
1768
1833
_control_files=a_bzrdir._control_files,
1769
1834
a_bzrdir=a_bzrdir,
1770
1836
_repository=a_bzrdir.open_repository())
1772
1838
def __str__(self):
1800
1866
lockdir.LockDir)
1801
1867
return self._branch_class()(_format=self,
1802
1868
_control_files=control_files,
1803
1870
a_bzrdir=a_bzrdir,
1804
1871
_repository=a_bzrdir.find_repository(),
1805
1872
ignore_fallbacks=ignore_fallbacks)
2100
2167
:ivar repository: Repository for this branch.
2101
2168
:ivar base: The url of the base directory for this branch; the one
2102
2169
containing the .bzr directory.
2170
:ivar name: Optional colocated branch name as it exists in the control
2105
2174
def __init__(self, _format=None,
2106
_control_files=None, a_bzrdir=None, _repository=None,
2107
ignore_fallbacks=False):
2175
_control_files=None, a_bzrdir=None, name=None,
2176
_repository=None, ignore_fallbacks=False):
2108
2177
"""Create new branch object at a particular location."""
2109
2178
if a_bzrdir is None:
2110
2179
raise ValueError('a_bzrdir must be supplied')
2112
2181
self.bzrdir = a_bzrdir
2113
2182
self._base = self.bzrdir.transport.clone('..').base
2114
2184
# XXX: We should be able to just do
2115
2185
# self.base = self.bzrdir.root_transport.base
2116
2186
# but this does not quite work yet -- mbp 20080522
2123
2193
Branch.__init__(self)
2125
2195
def __str__(self):
2126
return '%s(%r)' % (self.__class__.__name__, self.base)
2196
if self.name is None:
2197
return '%s(%r)' % (self.__class__.__name__, self.base)
2199
return '%s(%r,%r)' % (self.__class__.__name__, self.base, self.name)
2128
2201
__repr__ = __str__