changeset 30044:69b61d0bb008

revset: do not rewrite ':y' to '0:y' (issue5385) That's no longer valid since the revision 0 may be hidden. Bypass validating the existence of '0' and filter it by spanset.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 01 Oct 2016 20:20:11 +0900
parents 49d5434d68fb
children 12cac1e4d6d9
files mercurial/revset.py tests/test-log.t tests/test-revset.t
diffstat 3 files changed, 97 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Sat Oct 01 20:11:48 2016 +0900
+++ b/mercurial/revset.py	Sat Oct 01 20:20:11 2016 +0900
@@ -368,6 +368,13 @@
         return baseset()
     return _makerangeset(repo, subset, m.first(), n.last(), order)
 
+def rangepre(repo, subset, y, order):
+    # ':y' can't be rewritten to '0:y' since '0' may be hidden
+    n = getset(repo, fullreposet(repo), y)
+    if not n:
+        return baseset()
+    return _makerangeset(repo, subset, 0, n.last(), order)
+
 def _makerangeset(repo, subset, m, n, order):
     if m == n:
         r = baseset([m])
@@ -2329,6 +2336,7 @@
 
 methods = {
     "range": rangeset,
+    "rangepre": rangepre,
     "dagrange": dagrange,
     "string": stringset,
     "symbol": stringset,
@@ -2444,9 +2452,7 @@
     elif op == 'dagrangepost':
         return _analyze(('func', ('symbol', 'descendants'), x[1]), order)
     elif op == 'rangeall':
-        return _analyze(('range', ('string', '0'), ('string', 'tip')), order)
-    elif op == 'rangepre':
-        return _analyze(('range', ('string', '0'), x[1]), order)
+        return _analyze(('rangepre', ('string', 'tip')), order)
     elif op == 'rangepost':
         return _analyze(('range', x[1], ('string', 'tip')), order)
     elif op == 'negate':
@@ -2462,7 +2468,7 @@
         return (op, _analyze(x[1], order), order)
     elif op == 'not':
         return (op, _analyze(x[1], anyorder), order)
-    elif op == 'parentpost':
+    elif op in ('rangepre', 'parentpost'):
         return (op, _analyze(x[1], defineorder), order)
     elif op == 'group':
         return _analyze(x[1], order)
@@ -2567,7 +2573,7 @@
             o = _optimize(x[1], not small)
             order = x[2]
             return o[0], (op, o[1], order)
-    elif op == 'parentpost':
+    elif op in ('rangepre', 'parentpost'):
         o = _optimize(x[1], small)
         order = x[2]
         return o[0], (op, o[1], order)
--- a/tests/test-log.t	Sat Oct 01 20:11:48 2016 +0900
+++ b/tests/test-log.t	Sat Oct 01 20:20:11 2016 +0900
@@ -1747,6 +1747,34 @@
   1:a765632148dc55d38c35c4f247c618701886cb2f
   0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
 
+test hidden revision 0 (issue5385)
+
+  $ hg bookmark -d X@foo
+  $ hg up null -q
+  $ hg debugobsolete 9f758d63dcde62d547ebfb08e1e7ee96535f2b05
+  $ echo f > b
+  $ hg ci -Am'b' -d '2 0'
+  adding b
+  $ echo f >> b
+  $ hg ci -m'b bis' -d '3 0'
+  $ hg log -T'{rev}:{node}\n'
+  3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
+  2:94375ec45bddd2a824535fc04855bd058c926ec0
+
+  $ hg log -T'{rev}:{node}\n' -r:
+  2:94375ec45bddd2a824535fc04855bd058c926ec0
+  3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
+  $ hg log -T'{rev}:{node}\n' -r:tip
+  2:94375ec45bddd2a824535fc04855bd058c926ec0
+  3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
+  $ hg log -T'{rev}:{node}\n' -r:0
+  abort: hidden revision '0'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg log -T'{rev}:{node}\n' -f
+  3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
+  2:94375ec45bddd2a824535fc04855bd058c926ec0
+
 clear extensions configuration
   $ echo '[extensions]' >> $HGRCPATH
   $ echo "obs=!" >> $HGRCPATH
--- a/tests/test-revset.t	Sat Oct 01 20:11:48 2016 +0900
+++ b/tests/test-revset.t	Sat Oct 01 20:20:11 2016 +0900
@@ -161,8 +161,7 @@
   (rangeall
     None)
   * optimized:
-  (range
-    ('string', '0')
+  (rangepre
     ('string', 'tip')
     define)
   * set:
@@ -612,6 +611,63 @@
   8
   9
 
+':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
+may be hidden (issue5385)
+
+  $ try -p parsed -p analyzed ':'
+  * parsed:
+  (rangeall
+    None)
+  * analyzed:
+  (rangepre
+    ('string', 'tip')
+    define)
+  * set:
+  <spanset+ 0:9>
+  0
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+  $ try -p analyzed ':1'
+  * analyzed:
+  (rangepre
+    ('symbol', '1')
+    define)
+  * set:
+  <spanset+ 0:1>
+  0
+  1
+  $ try -p analyzed ':(1|2)'
+  * analyzed:
+  (rangepre
+    (or
+      (list
+        ('symbol', '1')
+        ('symbol', '2'))
+      define)
+    define)
+  * set:
+  <spanset+ 0:2>
+  0
+  1
+  2
+  $ try -p analyzed ':(1&2)'
+  * analyzed:
+  (rangepre
+    (and
+      ('symbol', '1')
+      ('symbol', '2')
+      define)
+    define)
+  * set:
+  <baseset []>
+
 infix/suffix resolution of ^ operator (issue2884):
 
  x^:y means (x^):y