changeset 26638:7afaf2566e25

revset: add optional offset argument to limit() predicate It's common for GUI or web frontend to fetch chunk of revisions per batch size. Previously it was possible only if revisions were sorted by revision number. $ hg log -r 'limit({revspec} & :{last_known}, 101)' So this patch introduces a general way to retrieve chunk of revisions after skipping offset revisions. $ hg log -r 'limit({revspec}, 100, {last_count})' This is a dumb implementation. We can optimize it for baseset and spanset later.
author Yuya Nishihara <yuya@tcha.org>
date Tue, 24 Mar 2015 00:28:28 +0900
parents 179764469754
children 92d67e5729b9
files mercurial/revset.py tests/test-revset.t
diffstat 2 files changed, 24 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Mon Oct 12 17:19:22 2015 +0900
+++ b/mercurial/revset.py	Tue Mar 24 00:28:28 2015 +0900
@@ -1284,24 +1284,33 @@
     return subset.filter(matches)
 
 def limit(repo, subset, x):
-    """``limit(set, [n])``
-    First n members of set, defaulting to 1.
+    """``limit(set[, n[, offset]])``
+    First n members of set, defaulting to 1, starting from offset.
     """
-    args = getargsdict(x, 'limit', 'set n')
+    args = getargsdict(x, 'limit', 'set n offset')
     if 'set' not in args:
         # i18n: "limit" is a keyword
-        raise error.ParseError(_("limit requires one or two arguments"))
+        raise error.ParseError(_("limit requires one to three arguments"))
     try:
-        lim = 1
+        lim, ofs = 1, 0
         if 'n' in args:
             # i18n: "limit" is a keyword
             lim = int(getstring(args['n'], _("limit requires a number")))
+        if 'offset' in args:
+            # i18n: "limit" is a keyword
+            ofs = int(getstring(args['offset'], _("limit requires a number")))
+        if ofs < 0:
+            raise error.ParseError(_("negative offset"))
     except (TypeError, ValueError):
         # i18n: "limit" is a keyword
         raise error.ParseError(_("limit expects a number"))
     os = getset(repo, fullreposet(repo), args['set'])
     result = []
     it = iter(os)
+    for x in xrange(ofs):
+        y = next(it, None)
+        if y is None:
+            break
     for x in xrange(lim):
         y = next(it, None)
         if y is None:
--- a/tests/test-revset.t	Mon Oct 12 17:19:22 2015 +0900
+++ b/tests/test-revset.t	Tue Mar 24 00:28:28 2015 +0900
@@ -566,6 +566,16 @@
   $ log 'keyword("test a")'
   $ log 'limit(head(), 1)'
   0
+  $ log 'limit(author("re:bob|test"), 3, 5)'
+  5
+  6
+  7
+  $ log 'limit(author("re:bob|test"), offset=6)'
+  6
+  $ log 'limit(author("re:bob|test"), offset=10)'
+  $ log 'limit(all(), 1, -1)'
+  hg: parse error: negative offset
+  [255]
   $ log 'matching(6)'
   6
   $ log 'matching(6:7, "phase parents user date branch summary files description substate")'