diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -1029,6 +1029,27 @@ static int index_issnapshotrev(indexObje return rev == -1; } +static PyObject *index_issnapshot(indexObject *self, PyObject *value) +{ + long rev; + int issnap; + Py_ssize_t length = index_length(self); + + if (!pylong_to_long(value, &rev)) { + return NULL; + } + if (rev < -1 || rev >= length) { + PyErr_Format(PyExc_ValueError, "revlog index out of range: %ld", + rev); + return NULL; + }; + issnap = index_issnapshotrev(self, (Py_ssize_t)rev); + if (issnap < 0) { + return NULL; + }; + return PyBool_FromLong((long)issnap); +} + static PyObject *index_deltachain(indexObject *self, PyObject *args) { int rev, generaldelta; @@ -2641,6 +2662,8 @@ static PyMethodDef index_methods[] = { "get head revisions"}, /* Can do filtering since 3.2 */ {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS, "get filtered head revisions"}, /* Can always do filtering */ + {"issnapshot", (PyCFunction)index_issnapshot, METH_O, + "True if the object is a snapshot"}, {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"}, {"slicechunktodensity", (PyCFunction)index_slicechunktodensity, diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1533,14 +1533,18 @@ class revlog(object): def issnapshot(self, rev): """tells whether rev is a snapshot """ + if not self._sparserevlog: + return self.deltaparent(rev) == nullrev + elif util.safehasattr(self.index, 'issnapshot'): + # directly assign the method to cache the testing and access + self.issnapshot = self.index.issnapshot + return self.issnapshot(rev) if rev == nullrev: return True entry = self.index[rev] base = entry[3] if base == rev: return True - elif not self._sparserevlog: - return False if base == nullrev: return True p1 = entry[5]