diff -r 5ade47284dda -r 476754edac1f mercurial/repoview.py --- a/mercurial/repoview.py Tue Nov 05 14:14:45 2019 -0800 +++ b/mercurial/repoview.py Tue Nov 05 14:16:46 2019 -0800 @@ -18,6 +18,7 @@ setattr, ) from . import ( + error, obsolete, phases, pycompat, @@ -253,6 +254,40 @@ if i not in self.filteredrevs: yield i + 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: + return self.index.headrevsfiltered(self.filteredrevs) + # AttributeError covers non-c-extension environments and + # old c extensions without filter handling. + except AttributeError: + return self._headrevs() + + if self.filteredrevs: + revs = self._checknofilteredinrevs(revs) + return super(filteredchangelog, self).headrevs(revs) + cl.__class__ = filteredchangelog return cl