filelog: add a hasnode() method (API)
Missing in the file storage interface is the ability to query whether
a specified value is a known node.
This commit defines that interface member and implements it on the
revlog and sqlite file stores.
Storage unit tests have been added.
The revlog implementation is a bit more complicated because index lookups
don't consistently raise the same exception. For SQLite, we can simply look
for a key in a dict.
Differential Revision: https://phab.mercurial-scm.org/D5163
--- a/hgext/sqlitestore.py Sun Oct 21 22:26:00 2018 -0400
+++ b/hgext/sqlitestore.py Wed Oct 03 14:57:29 2018 -0700
@@ -381,6 +381,12 @@
def __iter__(self):
return iter(pycompat.xrange(len(self._revisions)))
+ def hasnode(self, node):
+ if node == nullid:
+ return False
+
+ return node in self._nodetorev
+
def revs(self, start=0, stop=None):
return storageutil.iterrevs(len(self._revisions), start=start,
stop=stop)
--- a/mercurial/filelog.py Sun Oct 21 22:26:00 2018 -0400
+++ b/mercurial/filelog.py Wed Oct 03 14:57:29 2018 -0700
@@ -7,6 +7,10 @@
from __future__ import absolute_import
+from .node import (
+ nullid,
+ nullrev,
+)
from . import (
error,
repository,
@@ -33,6 +37,16 @@
def __iter__(self):
return self._revlog.__iter__()
+ def hasnode(self, node):
+ if node in (nullid, nullrev):
+ return False
+
+ try:
+ self._revlog.rev(node)
+ return True
+ except (TypeError, ValueError, IndexError, error.LookupError):
+ return False
+
def revs(self, start=0, stop=None):
return self._revlog.revs(start=start, stop=stop)
--- a/mercurial/repository.py Sun Oct 21 22:26:00 2018 -0400
+++ b/mercurial/repository.py Wed Oct 03 14:57:29 2018 -0700
@@ -484,6 +484,16 @@
def __iter__():
"""Iterate over revision numbers for this file."""
+ def hasnode(node):
+ """Returns a bool indicating if a node is known to this store.
+
+ Implementations must only return True for full, binary node values:
+ hex nodes, revision numbers, and partial node matches must be
+ rejected.
+
+ The null node is never present.
+ """
+
def revs(start=0, stop=None):
"""Iterate over revision numbers for this file, with control."""
--- a/mercurial/testing/storage.py Sun Oct 21 22:26:00 2018 -0400
+++ b/mercurial/testing/storage.py Wed Oct 03 14:57:29 2018 -0700
@@ -45,6 +45,13 @@
with self.assertRaises(StopIteration):
next(gen)
+ self.assertFalse(f.hasnode(None))
+ self.assertFalse(f.hasnode(0))
+ self.assertFalse(f.hasnode(nullrev))
+ self.assertFalse(f.hasnode(nullid))
+ self.assertFalse(f.hasnode(b'0'))
+ self.assertFalse(f.hasnode(b'a' * 20))
+
# revs() should evaluate to an empty list.
self.assertEqual(list(f.revs()), [])
@@ -161,6 +168,13 @@
with self.assertRaises(StopIteration):
next(gen)
+ self.assertTrue(f.hasnode(node))
+ self.assertFalse(f.hasnode(hex(node)))
+ self.assertFalse(f.hasnode(nullrev))
+ self.assertFalse(f.hasnode(nullid))
+ self.assertFalse(f.hasnode(node[0:12]))
+ self.assertFalse(f.hasnode(hex(node)[0:20]))
+
self.assertEqual(list(f.revs()), [0])
self.assertEqual(list(f.revs(start=1)), [])
self.assertEqual(list(f.revs(start=0)), [0])