# HG changeset patch # User Pierre-Yves David # Date 2017-03-03 13:08:20 # Node ID 6b098ac4542ebb97197688e91c64309678d72cb4 # Parent 016c63d6658c7dd25feed04c8c190f234c9d8937 fileset: add a 'status(...)' predicate to control evaluation context Same as 'revs', this predicate does not select files but switches the evaluation context. This allow to match file according arbitrary status call. We can now express the same query as 'hg status'. The API (two 'revsingle' class) have been picked instead of a single 'revs' revset for multiple reasons: * it is less confusing to express * it allow to express more query (eg: backward status, cross branch status) diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -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): diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -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]