[PATCH 1 of 3 V2] revsets: record sort order keys

Martijn Pieters mj at zopatista.com
Wed May 18 12:16:12 UTC 2016


# HG changeset patch
# User Martijn Pieters <mjpieters at fb.com>
# Date 1463566278 -3600
#      Wed May 18 11:11:18 2016 +0100
# Node ID 9080a1803e83e848942ece74c430dbbb450c92cd
# Parent  8c8442523eefac2d53e3f10ff1ebf37f4d3c63c3
revsets: record sort order keys

With sort order recorded, the graphmod module (or other users) can avoid
re-sorting already-sorted revsets.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1888,7 +1888,7 @@
             ctxs.sort(key=lambda c: c.date()[0], reverse=True)
         else:
             raise error.ParseError(_("unknown sort key %r") % k)
-    return baseset([c.rev() for c in ctxs])
+    return baseset([c.rev() for c in ctxs], sortorder=keys)
 
 @predicate('subrepo([pattern])')
 def subrepo(repo, subset, x):
@@ -2503,6 +2503,10 @@
     fastasc = None
     fastdesc = None
 
+    # recorded sort if available. The default is an empty sequence (no sorting
+    # applied)
+    sortorder = ()
+
     def isascending(self):
         """True if the set will iterate in ascending order"""
         raise NotImplementedError()
@@ -2596,17 +2600,25 @@
 
     Every method in this class should be implemented by any smartset class.
     """
-    def __init__(self, data=(), datarepr=None):
+    def __init__(self, data=(), datarepr=None, sortorder=()):
         """
         datarepr: a tuple of (format, obj, ...), a function or an object that
                   provides a printable representation of the given data.
+
+        sortorder: a tuple of sort keys (empty for no sort); each key a string.
+                   if a sort key starts with a "-" the sort direction is
+                   reversed. Informative only.
+
         """
         self._ascending = None
+        self.sortorder = tuple(sortorder)
+
         if not isinstance(data, list):
             if isinstance(data, set):
                 self._set = data
                 # set has no order we pick one for stability purpose
                 self._ascending = True
+                self.sortorder = ('rev',)
             data = list(data)
         self._list = data
         self._datarepr = datarepr
@@ -2644,12 +2656,16 @@
 
     def sort(self, reverse=False):
         self._ascending = not bool(reverse)
+        self.sortorder = ('rev' if self._ascending else '-rev'),
 
     def reverse(self):
         if self._ascending is None:
             self._list.reverse()
+            self.sortorder = tuple(d[1:] if d[0] == '-' else '-' + d
+                                   for d in self.sortorder)
         else:
             self._ascending = not self._ascending
+            self.sortorder = ('rev' if self._ascending else '-rev'),
 
     def __len__(self):
         return len(self._list)
@@ -2778,6 +2794,10 @@
     def isdescending(self):
         return self._subset.isdescending()
 
+    @property
+    def sortorder(self):
+        return self._subset.sortorder
+
     def first(self):
         for x in self:
             return x
@@ -3247,6 +3267,10 @@
         self._end = end
         self._hiddenrevs = repo.changelog.filteredrevs
 
+    @property
+    def sortorder(self):
+        return ('rev' if self._ascending else '-rev'),
+
     def sort(self, reverse=False):
         self._ascending = not reverse
 
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1100,6 +1100,39 @@
   0 b12  m111 u112 111 10800
   2 b111 m11  u12  111 3600
 
+verify that revsets retain sort order keys
+
+  $ cat <<EOF > $TESTTMP/echosortorder.py
+  > from mercurial import cmdutil, revset
+  > cmdtable = {}
+  > command = cmdutil.command(cmdtable)
+  > @command('echosortorder')
+  > def echosortorder(ui, repo, expr, **opts):
+  >     """write out the sort-order list to the ui"""
+  >     func = revset.match(ui, expr, repo)
+  >     revs = func(repo)
+  >     ui.status('Sort order: {0!r}\n'.format(revs.sortorder))
+  > EOF
+  $ cat <<EOF >> .hg/hgrc
+  > [extensions]
+  > echosortorder = $TESTTMP/echosortorder.py
+  > EOF
+
+  $ hg echosortorder 'sort(all(), rev)'
+  Sort order: ('rev',)
+
+  $ hg echosortorder 'sort(all(), -rev)'
+  Sort order: ('-rev',)
+
+  $ hg echosortorder 'reverse(sort(0 + 2, date))'
+  Sort order: ('-date',)
+
+  $ hg echosortorder 'sort(all(), "user -branch date rev")'
+  Sort order: ('user', '-branch', 'date', 'rev')
+
+  $ hg echosortorder 'reverse(sort(all(), "user -branch date rev"))'
+  Sort order: ('-user', 'branch', '-date', '-rev')
+
   $ cd ..
   $ cd repo
 


More information about the Mercurial-devel mailing list