comparison mercurial/cmdutil.py @ 24391:6c3a93e690c7

walkchangerevs: make followfilter a top-level class The class only depends on the 'repo' variable in the closure, so let's move the class out of the function and make it explicit that that (the repo) is all it needs.
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 19 Mar 2015 09:12:21 -0700
parents 5cb459dc32d2
children a8595176dd64
comparison
equal deleted inserted replaced
24390:72d7d390ef5d 24391:6c3a93e690c7
1667 if copied: 1667 if copied:
1668 copies.append(copied) 1668 copies.append(copied)
1669 1669
1670 return wanted 1670 return wanted
1671 1671
1672 class _followfilter(object):
1673 def __init__(self, repo, onlyfirst=False):
1674 self.repo = repo
1675 self.startrev = nullrev
1676 self.roots = set()
1677 self.onlyfirst = onlyfirst
1678
1679 def match(self, rev):
1680 def realparents(rev):
1681 if self.onlyfirst:
1682 return self.repo.changelog.parentrevs(rev)[0:1]
1683 else:
1684 return filter(lambda x: x != nullrev,
1685 self.repo.changelog.parentrevs(rev))
1686
1687 if self.startrev == nullrev:
1688 self.startrev = rev
1689 return True
1690
1691 if rev > self.startrev:
1692 # forward: all descendants
1693 if not self.roots:
1694 self.roots.add(self.startrev)
1695 for parent in realparents(rev):
1696 if parent in self.roots:
1697 self.roots.add(rev)
1698 return True
1699 else:
1700 # backwards: all parents
1701 if not self.roots:
1702 self.roots.update(realparents(self.startrev))
1703 if rev in self.roots:
1704 self.roots.remove(rev)
1705 self.roots.update(realparents(rev))
1706 return True
1707
1708 return False
1709
1672 def walkchangerevs(repo, match, opts, prepare): 1710 def walkchangerevs(repo, match, opts, prepare):
1673 '''Iterate over files and the revs in which they changed. 1711 '''Iterate over files and the revs in which they changed.
1674 1712
1675 Callers most commonly need to iterate backwards over the history 1713 Callers most commonly need to iterate backwards over the history
1676 in which they are interested. Doing so has awful (quadratic-looking) 1714 in which they are interested. Doing so has awful (quadratic-looking)
1755 self.revs.discard(value) 1793 self.revs.discard(value)
1756 self.set.discard(value) 1794 self.set.discard(value)
1757 1795
1758 wanted = lazywantedset() 1796 wanted = lazywantedset()
1759 1797
1760 class followfilter(object):
1761 def __init__(self, onlyfirst=False):
1762 self.startrev = nullrev
1763 self.roots = set()
1764 self.onlyfirst = onlyfirst
1765
1766 def match(self, rev):
1767 def realparents(rev):
1768 if self.onlyfirst:
1769 return repo.changelog.parentrevs(rev)[0:1]
1770 else:
1771 return filter(lambda x: x != nullrev,
1772 repo.changelog.parentrevs(rev))
1773
1774 if self.startrev == nullrev:
1775 self.startrev = rev
1776 return True
1777
1778 if rev > self.startrev:
1779 # forward: all descendants
1780 if not self.roots:
1781 self.roots.add(self.startrev)
1782 for parent in realparents(rev):
1783 if parent in self.roots:
1784 self.roots.add(rev)
1785 return True
1786 else:
1787 # backwards: all parents
1788 if not self.roots:
1789 self.roots.update(realparents(self.startrev))
1790 if rev in self.roots:
1791 self.roots.remove(rev)
1792 self.roots.update(realparents(rev))
1793 return True
1794
1795 return False
1796
1797 # it might be worthwhile to do this in the iterator if the rev range 1798 # it might be worthwhile to do this in the iterator if the rev range
1798 # is descending and the prune args are all within that range 1799 # is descending and the prune args are all within that range
1799 for rev in opts.get('prune', ()): 1800 for rev in opts.get('prune', ()):
1800 rev = repo[rev].rev() 1801 rev = repo[rev].rev()
1801 ff = followfilter() 1802 ff = _followfilter(repo)
1802 stop = min(revs[0], revs[-1]) 1803 stop = min(revs[0], revs[-1])
1803 for x in xrange(rev, stop - 1, -1): 1804 for x in xrange(rev, stop - 1, -1):
1804 if ff.match(x): 1805 if ff.match(x):
1805 wanted = wanted - [x] 1806 wanted = wanted - [x]
1806 1807
1807 # Now that wanted is correctly initialized, we can iterate over the 1808 # Now that wanted is correctly initialized, we can iterate over the
1808 # revision range, yielding only revisions in wanted. 1809 # revision range, yielding only revisions in wanted.
1809 def iterate(): 1810 def iterate():
1810 if follow and not match.files(): 1811 if follow and not match.files():
1811 ff = followfilter(onlyfirst=opts.get('follow_first')) 1812 ff = _followfilter(repo, onlyfirst=opts.get('follow_first'))
1812 def want(rev): 1813 def want(rev):
1813 return ff.match(rev) and rev in wanted 1814 return ff.match(rev) and rev in wanted
1814 else: 1815 else:
1815 def want(rev): 1816 def want(rev):
1816 return rev in wanted 1817 return rev in wanted