diff mercurial/cmdutil.py @ 28253:c407583cf5f6 stable

log: fix order of revisions filtered by multiple OR options (issue5100) This is the simplest workaround for the issue of the ordering of revset, which is that the expression "x or y" takes over the ordering specified by the input set (or the left-hand-side expression.) For example, the following expression A & (x | y) will be evaluated as if (A & x) | (A & y) That's wrong because revset has ordering. I'm going to fix this problem in the revset module, but that wouldn't fit to stable. So, this patch just works around the common log cases. Since this change might have some impact on performance, it is enabled only if the expression built from log options has ' or ' operation.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 15 Feb 2016 22:46:07 +0900
parents cb6a952efbf4
children c7f89ad87bae 97175d9bf7cf
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Thu Feb 25 22:35:11 2016 -0800
+++ b/mercurial/cmdutil.py	Mon Feb 15 22:46:07 2016 +0900
@@ -2139,9 +2139,15 @@
         # Revset matches can reorder revisions. "A or B" typically returns
         # returns the revision matching A then the revision matching B. Sort
         # again to fix that.
+        fixopts = ['branch', 'only_branch', 'keyword', 'user']
+        oldrevs = revs
         revs = matcher(repo, revs)
         if not opts.get('rev'):
             revs.sort(reverse=True)
+        elif len(pats) > 1 or any(len(opts.get(op, [])) > 1 for op in fixopts):
+            # XXX "A or B" is known to change the order; fix it by filtering
+            # matched set again (issue5100)
+            revs = oldrevs & revs
     if limit is not None:
         limitedrevs = []
         for idx, r in enumerate(revs):