# HG changeset patch # User Georges Racinet # Date 2019-02-20 10:49:06 # Node ID 6843379bf99ecb9313bf007223821b7535f0a2d3 # Parent cde37ed080c9dd57e25d9c7cb581dfe3b77b1976 changelog: prefilter in headrevs() In case where headrevs() is called on some revisions, we perform the check that aren't filtered in advance, and switch revlog to use its unchecked form. This allows to work with alternative implementations that don't have knowledge of the filtering system, such as the Rust one. diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -22,6 +22,7 @@ from . import ( error, pycompat, revlog, + util, ) from .utils import ( dateutil, @@ -350,6 +351,27 @@ class changelog(revlog.revlog): def reachableroots(self, minroot, heads, roots, includepath=False): return self.index.reachableroots2(minroot, heads, roots, includepath) + def _checknofilteredinrevs(self, revs): + """raise the appropriate error if 'revs' contains a filtered revision + + This returns a version of 'revs' to be used thereafter by the caller. + In particular, if revs is an iterator, it is converted into a set. + """ + safehasattr = util.safehasattr + if safehasattr(revs, '__next__'): + # Note that inspect.isgenerator() is not true for iterators, + revs = set(revs) + + filteredrevs = self.filteredrevs + if safehasattr(revs, 'first'): # smartset + offenders = revs & filteredrevs + else: + offenders = filteredrevs.intersection(revs) + + for rev in offenders: + raise error.FilteredIndexError(rev) + return revs + def headrevs(self, revs=None): if revs is None and self.filteredrevs: try: @@ -359,6 +381,8 @@ class changelog(revlog.revlog): except AttributeError: return self._headrevs() + if self.filteredrevs: + revs = self._checknofilteredinrevs(revs) return super(changelog, self).headrevs(revs) def strip(self, *args, **kwargs): diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1121,7 +1121,7 @@ class revlog(object): return self.index.headrevs() except AttributeError: return self._headrevs() - return dagop.headrevs(revs, self.parentrevs) + return dagop.headrevs(revs, self._uncheckedparentrevs) def computephases(self, roots): return self.index.computephasesmapsets(roots)