[PATCH 1 of 2 V3] changelog: prefilter in headrevs()

Georges Racinet georges.racinet at octobus.net
Thu Feb 21 10:27:24 UTC 2019


# HG changeset patch
# User Georges Racinet <georges.racinet at octobus.net>
# Date 1550659746 -3600
#      Wed Feb 20 11:49:06 2019 +0100
# Node ID 1c1f122821291657b33b447e89dc4420b3f833b5
# Parent  0c7b353ce100e9125251f4ae37a8739242ce537c
# EXP-Topic revset.predicates
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 -r 0c7b353ce100 -r 1c1f12282129 mercurial/changelog.py
--- a/mercurial/changelog.py	Thu Jan 10 18:25:18 2019 +0100
+++ b/mercurial/changelog.py	Wed Feb 20 11:49:06 2019 +0100
@@ -22,6 +22,7 @@
     error,
     pycompat,
     revlog,
+    util,
 )
 from .utils import (
     dateutil,
@@ -350,6 +351,27 @@
     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 @@
             except AttributeError:
                 return self._headrevs()
 
+        if self.filteredrevs:
+            revs = self._checknofilteredinrevs(revs)
         return super(changelog, self).headrevs(revs)
 
     def strip(self, *args, **kwargs):
diff -r 0c7b353ce100 -r 1c1f12282129 mercurial/revlog.py
--- a/mercurial/revlog.py	Thu Jan 10 18:25:18 2019 +0100
+++ b/mercurial/revlog.py	Wed Feb 20 11:49:06 2019 +0100
@@ -1121,7 +1121,7 @@
                 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)


More information about the Mercurial-devel mailing list