@@ -463,6 +463,32 @@ def revs(mctx, x):
result.append(f)
return result
+@predicate('status(base, rev, pattern)')
+def status(mctx, x):
+ """``status(base, rev, revspec)``
+
+ Evaluate predicate using status change between ``base`` and
+ ``rev``. Examples:
+
+ - ``status(3, 7, added())`` - matches files added from "3" to "7"
+ """
+ repo = mctx.ctx.repo()
+ # i18n: "status" is a keyword
+ b, r, x = getargs(x, 3, 3, _("status takes three arguments"))
+ # i18n: "status" is a keyword
+ baseerr = _("first argument to status must be a revision")
+ baserevspec = getstring(b, baseerr)
+ if not baserevspec:
+ raise error.ParseError(baseerr)
+ reverr = _("second argument to status must be a revision")
+ revspec = getstring(r, reverr)
+ if not revspec:
+ raise error.ParseError(reverr)
+ basenode, node = scmutil.revpair(repo, [baserevspec, revspec])
+ basectx = repo[basenode]
+ ctx = repo[node]
+ return getset(mctx.switch(ctx, _buildstatus(ctx, x, basectx=basectx)), x)
+
@predicate('subrepo([pattern])')
def subrepo(mctx, x):
"""Subrepositories whose paths match the given pattern.
@@ -538,6 +564,7 @@ class fullmatchctx(matchctx):
# filesets using matchctx.switch()
_switchcallers = [
'revs',
+ 'status',
]
def _intree(funcs, tree):
@@ -521,3 +521,101 @@ overlapping set
$ fileset "revs('1+2', modified())"
b2
+
+test 'status(...)'
+=================
+
+Simple case
+-----------
+
+ $ fileset "status(3, 4, added())"
+ .hgsub
+ .hgsubstate
+
+use rev to restrict matched file
+-----------------------------------------
+
+ $ hg status --removed --rev 0 --rev 1
+ R a2
+ $ fileset "status(0, 1, removed())"
+ a2
+ $ fileset "* and status(0, 1, removed())"
+ $ fileset -r 4 "status(0, 1, removed())"
+ a2
+ $ fileset -r 4 "* and status(0, 1, removed())"
+ $ fileset "revs('4', * and status(0, 1, removed()))"
+ $ fileset "revs('0', * and status(0, 1, removed()))"
+ a2
+
+check wdir()
+------------
+
+ $ hg status --removed --rev 4
+ R con.xml
+ $ fileset "status(4, 'wdir()', removed())"
+ con.xml
+
+ $ hg status --removed --rev 2
+ R a2
+ $ fileset "status('2', 'wdir()', removed())"
+ a2
+
+test backward status
+--------------------
+
+ $ hg status --removed --rev 0 --rev 4
+ R a2
+ $ hg status --added --rev 4 --rev 0
+ A a2
+ $ fileset "status(4, 0, added())"
+ a2
+
+test cross branch status
+------------------------
+
+ $ hg status --added --rev 1 --rev 2
+ A a2
+ $ fileset "status(1, 2, added())"
+ a2
+
+test with multi revs revset
+---------------------------
+ $ hg status --added --rev 0:1 --rev 3:4
+ A .hgsub
+ A .hgsubstate
+ A 1k
+ A 2k
+ A b2link
+ A bin
+ A c1
+ A con.xml
+ $ fileset "status('0:1', '3:4', added())"
+ .hgsub
+ .hgsubstate
+ 1k
+ 2k
+ b2link
+ bin
+ c1
+ con.xml
+
+tests with empty value
+----------------------
+
+Fully empty revset
+
+ $ fileset "status('', '4', added())"
+ hg: parse error: first argument to status must be a revision
+ [255]
+ $ fileset "status('2', '', added())"
+ hg: parse error: second argument to status must be a revision
+ [255]
+
+Empty revset will error at the revset layer
+
+ $ fileset "status(' ', '4', added())"
+ hg: parse error at 1: not a prefix: end
+ [255]
+ $ fileset "status('2', ' ', added())"
+ hg: parse error at 1: not a prefix: end
+ [255]