mercurial/fileset.py
author Emanuele Giaquinta <emanuele.giaquinta@gmail.com>
Wed, 07 Oct 2015 11:33:52 +0300
changeset 26593 c60dfcc0abf2
parent 26587 56b2bcea2529
child 26995 d5a6be56970b
permissions -rw-r--r--
cvsps: fix computation of parent revisions when log caching is on cvsps computes the parent revisions of log entries by walking the cvs log sorted by (rcs, revision) and by iteratively maintaining a 'versions' dictionary which maps a (rcs, branch) pair onto the last revision seen for that pair. When log caching is on and a log cache exists, cvsps fails to set the parent revisions of new log entries because it does not iterate over the log cache in the parents computation. A complication is that a file rcs can change (move to/from the attic), with respect to its value in the log cache, if the file is removed/added back. This patch adds an iteration over the log cache to update the rcs of cached log entries, if changed, and to properly populate the 'versions' dictionary.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14511
30506b894359 filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
     1
# fileset.py - file set queries for mercurial
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2010 Matt Mackall <mpm@selenic.com>
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
     8
from __future__ import absolute_import
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
     9
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 19470
diff changeset
    10
import re
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    11
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    12
from .i18n import _
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    13
from . import (
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    14
    error,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    15
    merge,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    16
    parser,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    17
    util,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    18
)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    21
    # token-type: binding-strength, primary, prefix, infix, suffix
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    22
    "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    23
    "-": (5, None, ("negate", 19), ("minus", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    24
    "not": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    25
    "!": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    26
    "and": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    27
    "&": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    28
    "or": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    29
    "|": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    30
    "+": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    31
    ",": (2, None, None, ("list", 2), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    32
    ")": (0, None, None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    33
    "symbol": (0, "symbol", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    34
    "string": (0, "string", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    35
    "end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
19470
19ac0d8ee9a2 fileset: handle underbar in symbols
Matt Mackall <mpm@selenic.com>
parents: 19194
diff changeset
    40
globchars = ".*{}[]?/\\_"
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    41
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
            pass
14511
30506b894359 filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
    48
        elif c in "(),-|&+!": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    49
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    50
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    51
              program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    52
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    53
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    54
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    55
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    56
            else:
26233
d3dbb65c8dc6 fileset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26195
diff changeset
    57
                decode = parser.unescapestr
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    66
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    70
                raise error.ParseError(_("unterminated string"), s)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    71
        elif c.isalnum() or c in globchars or ord(c) > 127:
14513
85fe676c27e9 fileset: fix long line
Matt Mackall <mpm@selenic.com>
parents: 14511
diff changeset
    72
            # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
                d = program[pos]
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    77
                if not (d.isalnum() or d in globchars or ord(d) > 127):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    82
                yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    84
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    87
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    89
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
20208
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
    91
def parse(expr):
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25633
diff changeset
    92
    p = parser.parser(elements)
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25633
diff changeset
    93
    tree, pos = p.parse(tokenize(expr))
25252
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
    94
    if pos != len(expr):
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
    95
        raise error.ParseError(_("invalid token"), pos)
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
    96
    return tree
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    98
def getstring(x, err):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    99
    if x and (x[0] == 'string' or x[0] == 'symbol'):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   100
        return x[1]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   101
    raise error.ParseError(err)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   102
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   103
def getset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   104
    if not x:
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   105
        raise error.ParseError(_("missing argument"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   106
    return methods[x[0]](mctx, *x[1:])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   107
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   108
def stringset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   109
    m = mctx.matcher([x])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   110
    return [f for f in mctx.subset if m(f)]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   111
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   112
def andset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   113
    return getset(mctx.narrow(getset(mctx, x)), y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   114
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   115
def orset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   116
    # needs optimizing
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   117
    xl = getset(mctx, x)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   118
    yl = getset(mctx, y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   119
    return xl + [f for f in yl if f not in xl]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   120
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   121
def notset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   122
    s = set(getset(mctx, x))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   123
    return [r for r in mctx.subset if r not in s]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   124
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   125
def minusset(mctx, x, y):
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   126
    xl = getset(mctx, x)
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   127
    yl = set(getset(mctx, y))
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   128
    return [f for f in xl if f not in yl]
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   129
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   130
def listset(mctx, a, b):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   131
    raise error.ParseError(_("can't use a list in this context"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   132
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   133
def modified(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   134
    """``modified()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   135
    File that is modified according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   136
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   137
    # i18n: "modified" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   138
    getargs(x, 0, 0, _("modified takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   139
    s = mctx.status().modified
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   140
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   141
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   142
def added(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   143
    """``added()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   144
    File that is added according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   145
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   146
    # i18n: "added" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   147
    getargs(x, 0, 0, _("added takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   148
    s = mctx.status().added
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   149
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   150
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   151
def removed(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   152
    """``removed()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   153
    File that is removed according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   154
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   155
    # i18n: "removed" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   156
    getargs(x, 0, 0, _("removed takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   157
    s = mctx.status().removed
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   158
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   159
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   160
def deleted(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   161
    """``deleted()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   162
    File that is deleted according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   163
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   164
    # i18n: "deleted" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   165
    getargs(x, 0, 0, _("deleted takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   166
    s = mctx.status().deleted
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   167
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   168
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   169
def unknown(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   170
    """``unknown()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   171
    File that is unknown according to :hg:`status`. These files will only be
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   172
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   173
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   174
    # i18n: "unknown" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   175
    getargs(x, 0, 0, _("unknown takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   176
    s = mctx.status().unknown
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   177
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   178
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   179
def ignored(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   180
    """``ignored()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   181
    File that is ignored according to :hg:`status`. These files will only be
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   182
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   183
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   184
    # i18n: "ignored" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   185
    getargs(x, 0, 0, _("ignored takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   186
    s = mctx.status().ignored
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   187
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   188
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   189
def clean(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   190
    """``clean()``
26194
fc65d63ef3b9 help: filesets show hg status command
timeless@mozdev.org
parents: 25998
diff changeset
   191
    File that is clean according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   192
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   193
    # i18n: "clean" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   194
    getargs(x, 0, 0, _("clean takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   195
    s = mctx.status().clean
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   196
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   197
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   198
def func(mctx, a, b):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   199
    if a[0] == 'symbol' and a[1] in symbols:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   200
        return symbols[a[1]](mctx, b)
25633
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   201
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   202
    keep = lambda fn: getattr(fn, '__doc__', None) is not None
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   203
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   204
    syms = [s for (s, fn) in symbols.items() if keep(fn)]
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   205
    raise error.UnknownIdentifier(a[1], syms)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   206
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   207
def getlist(x):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   208
    if not x:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   209
        return []
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   210
    if x[0] == 'list':
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   211
        return getlist(x[1]) + [x[2]]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   212
    return [x]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   213
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   214
def getargs(x, min, max, err):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   215
    l = getlist(x)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   216
    if len(l) < min or len(l) > max:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   217
        raise error.ParseError(err)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   218
    return l
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   219
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   220
def binary(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   221
    """``binary()``
14830
35f5cfdd0427 fileset: fix typo in binary() doc
Idan Kamara <idankk86@gmail.com>
parents: 14785
diff changeset
   222
    File that appears to be binary (contains NUL bytes).
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   223
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   224
    # i18n: "binary" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   225
    getargs(x, 0, 0, _("binary takes no arguments"))
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   226
    return [f for f in mctx.existing() if util.binary(mctx.ctx[f].data())]
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   227
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   228
def exec_(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   229
    """``exec()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   230
    File that is marked as executable.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   231
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   232
    # i18n: "exec" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   233
    getargs(x, 0, 0, _("exec takes no arguments"))
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   234
    return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'x']
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   235
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   236
def symlink(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   237
    """``symlink()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   238
    File that is marked as a symlink.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   239
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   240
    # i18n: "symlink" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   241
    getargs(x, 0, 0, _("symlink takes no arguments"))
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   242
    return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'l']
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   243
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   244
def resolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   245
    """``resolved()``
26195
5a3338e0faf7 help: filesets show hg resolve command
timeless@mozdev.org
parents: 26194
diff changeset
   246
    File that is marked resolved according to :hg:`resolve -l`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   247
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   248
    # i18n: "resolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   249
    getargs(x, 0, 0, _("resolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   250
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   251
        return []
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   252
    ms = merge.mergestate(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   253
    return [f for f in mctx.subset if f in ms and ms[f] == 'r']
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   254
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   255
def unresolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   256
    """``unresolved()``
26195
5a3338e0faf7 help: filesets show hg resolve command
timeless@mozdev.org
parents: 26194
diff changeset
   257
    File that is marked unresolved according to :hg:`resolve -l`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   258
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   259
    # i18n: "unresolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   260
    getargs(x, 0, 0, _("unresolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   261
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   262
        return []
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   263
    ms = merge.mergestate(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   264
    return [f for f in mctx.subset if f in ms and ms[f] == 'u']
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   265
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   266
def hgignore(mctx, x):
14700
848a6658069e fileset: use correct function name for hgignore in docstring
Ollie Rutherfurd <orutherfurd@gmail.com>
parents: 14690
diff changeset
   267
    """``hgignore()``
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   268
    File that matches the active .hgignore pattern.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   269
    """
23113
c2dd79ad99cb i18n: add i18n comment to error messages of filesets predicates
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22924
diff changeset
   270
    # i18n: "hgignore" is a keyword
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   271
    getargs(x, 0, 0, _("hgignore takes no arguments"))
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   272
    ignore = mctx.ctx.repo().dirstate._ignore
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   273
    return [f for f in mctx.subset if ignore(f)]
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   274
24408
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   275
def portable(mctx, x):
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   276
    """``portable()``
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   277
    File that has a portable name. (This doesn't include filenames with case
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   278
    collisions.)
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   279
    """
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   280
    # i18n: "portable" is a keyword
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   281
    getargs(x, 0, 0, _("portable takes no arguments"))
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   282
    checkwinfilename = util.checkwinfilename
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   283
    return [f for f in mctx.subset if checkwinfilename(f) is None]
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   284
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   285
def grep(mctx, x):
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   286
    """``grep(regex)``
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   287
    File contains the given regular expression.
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   288
    """
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   289
    try:
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   290
        # i18n: "grep" is a keyword
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   291
        r = re.compile(getstring(x, _("grep requires a pattern")))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
   292
    except re.error as e:
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   293
        raise error.ParseError(_('invalid match pattern: %s') % e)
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   294
    return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())]
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   295
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   296
def _sizetomax(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   297
    try:
25925
23c4589fc678 filesets: ignore unit case in size() predicate for single value
Anton Shestakov <av6@dwimlabs.net>
parents: 25815
diff changeset
   298
        s = s.strip().lower()
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   299
        for k, v in util._sizeunits:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   300
            if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   301
                # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   302
                n = s[:-len(k)]
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   303
                inc = 1.0
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   304
                if "." in n:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   305
                    inc /= 10 ** len(n.split(".")[1])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   306
                return int((float(n) + inc) * v) - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   307
        # no extension, this is a precise value
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   308
        return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   309
    except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   310
        raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   311
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   312
def size(mctx, x):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   313
    """``size(expression)``
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   314
    File size matches the given expression. Examples:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   315
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   316
    - 1k (files from 1024 to 2047 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   317
    - < 20k (files less than 20480 bytes)
14689
25e4d2f35965 fileset: drop backwards SI size units
Matt Mackall <mpm@selenic.com>
parents: 14685
diff changeset
   318
    - >= .5MB (files at least 524288 bytes)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   319
    - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   320
    """
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   321
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   322
    # i18n: "size" is a keyword
14717
c8ee2729e89f revset and fileset: fix typos in parser error messages
Mads Kiilerich <mads@kiilerich.com>
parents: 14716
diff changeset
   323
    expr = getstring(x, _("size requires an expression")).strip()
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   324
    if '-' in expr: # do we have a range?
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   325
        a, b = expr.split('-', 1)
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   326
        a = util.sizetoint(a)
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   327
        b = util.sizetoint(b)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   328
        m = lambda x: x >= a and x <= b
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   329
    elif expr.startswith("<="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   330
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   331
        m = lambda x: x <= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   332
    elif expr.startswith("<"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   333
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   334
        m = lambda x: x < a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   335
    elif expr.startswith(">="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   336
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   337
        m = lambda x: x >= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   338
    elif expr.startswith(">"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   339
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   340
        m = lambda x: x > a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   341
    elif expr[0].isdigit or expr[0] == '.':
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   342
        a = util.sizetoint(expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   343
        b = _sizetomax(expr)
14690
15faf0e66909 fileset: add missing whitespace around operator
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14689
diff changeset
   344
        m = lambda x: x >= a and x <= b
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   345
    else:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   346
        raise error.ParseError(_("couldn't parse size: %s") % expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   347
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   348
    return [f for f in mctx.existing() if m(mctx.ctx[f].size())]
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   349
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   350
def encoding(mctx, x):
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   351
    """``encoding(name)``
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   352
    File can be successfully decoded with the given character
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   353
    encoding. May not be useful for encodings other than ASCII and
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   354
    UTF-8.
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   355
    """
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   356
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   357
    # i18n: "encoding" is a keyword
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   358
    enc = getstring(x, _("encoding requires an encoding name"))
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   359
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   360
    s = []
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   361
    for f in mctx.existing():
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   362
        d = mctx.ctx[f].data()
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   363
        try:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   364
            d.decode(enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   365
        except LookupError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26233
diff changeset
   366
            raise error.Abort(_("unknown encoding '%s'") % enc)
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   367
        except UnicodeDecodeError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   368
            continue
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   369
        s.append(f)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   370
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   371
    return s
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   372
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   373
def eol(mctx, x):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   374
    """``eol(style)``
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   375
    File contains newlines of the given style (dos, unix, mac). Binary
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   376
    files are excluded, files with mixed line endings match multiple
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   377
    styles.
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   378
    """
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   379
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   380
    # i18n: "encoding" is a keyword
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   381
    enc = getstring(x, _("encoding requires an encoding name"))
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   382
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   383
    s = []
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   384
    for f in mctx.existing():
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   385
        d = mctx.ctx[f].data()
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   386
        if util.binary(d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   387
            continue
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   388
        if (enc == 'dos' or enc == 'win') and '\r\n' in d:
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   389
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   390
        elif enc == 'unix' and re.search('(?<!\r)\n', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   391
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   392
        elif enc == 'mac' and re.search('\r(?!\n)', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   393
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   394
    return s
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   395
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   396
def copied(mctx, x):
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   397
    """``copied()``
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   398
    File that is recorded as being copied.
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   399
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   400
    # i18n: "copied" is a keyword
14718
0c81948636f3 fileset: copied takes no arguments
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
   401
    getargs(x, 0, 0, _("copied takes no arguments"))
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   402
    s = []
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   403
    for f in mctx.subset:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   404
        p = mctx.ctx[f].parents()
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   405
        if p and p[0].path() != f:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   406
            s.append(f)
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   407
    return s
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   408
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   409
def subrepo(mctx, x):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   410
    """``subrepo([pattern])``
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   411
    Subrepositories whose paths match the given pattern.
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   412
    """
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   413
    # i18n: "subrepo" is a keyword
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   414
    getargs(x, 0, 1, _("subrepo takes at most one argument"))
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   415
    ctx = mctx.ctx
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 17371
diff changeset
   416
    sstate = sorted(ctx.substate)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   417
    if x:
23113
c2dd79ad99cb i18n: add i18n comment to error messages of filesets predicates
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22924
diff changeset
   418
        # i18n: "subrepo" is a keyword
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   419
        pat = getstring(x, _("subrepo requires a pattern or no arguments"))
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   420
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
   421
        from . import match as matchmod # avoid circular import issues
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   422
        fast = not matchmod.patkind(pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   423
        if fast:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   424
            def m(s):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   425
                return (s == pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   426
        else:
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   427
            m = matchmod.match(ctx.repo().root, '', [pat], ctx=ctx)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   428
        return [sub for sub in sstate if m(sub)]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   429
    else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   430
        return [sub for sub in sstate]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   431
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   432
symbols = {
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   433
    'added': added,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   434
    'binary': binary,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   435
    'clean': clean,
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   436
    'copied': copied,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   437
    'deleted': deleted,
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   438
    'encoding': encoding,
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   439
    'eol': eol,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   440
    'exec': exec_,
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   441
    'grep': grep,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   442
    'ignored': ignored,
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   443
    'hgignore': hgignore,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   444
    'modified': modified,
24408
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   445
    'portable': portable,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   446
    'removed': removed,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   447
    'resolved': resolved,
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   448
    'size': size,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   449
    'symlink': symlink,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   450
    'unknown': unknown,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   451
    'unresolved': unresolved,
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   452
    'subrepo': subrepo,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   453
}
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   454
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   455
methods = {
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   456
    'string': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   457
    'symbol': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   458
    'and': andset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   459
    'or': orset,
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   460
    'minus': minusset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   461
    'list': listset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   462
    'group': getset,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   463
    'not': notset,
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   464
    'func': func,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   465
}
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   466
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   467
class matchctx(object):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   468
    def __init__(self, ctx, subset=None, status=None):
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   469
        self.ctx = ctx
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   470
        self.subset = subset
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   471
        self._status = status
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   472
    def status(self):
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   473
        return self._status
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   474
    def matcher(self, patterns):
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   475
        return self.ctx.match(patterns)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   476
    def filter(self, files):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   477
        return [f for f in files if f in self.subset]
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   478
    def existing(self):
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   479
        if self._status is not None:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   480
            removed = set(self._status[3])
17367
ce625185cfd9 fileset: matchctx.existing() must consider ignored files
Patrick Mezard <patrick@mezard.eu>
parents: 17366
diff changeset
   481
            unknown = set(self._status[4] + self._status[5])
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   482
        else:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   483
            removed = set()
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   484
            unknown = set()
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   485
        return (f for f in self.subset
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   486
                if (f in self.ctx and f not in removed) or f in unknown)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   487
    def narrow(self, files):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   488
        return matchctx(self.ctx, self.filter(files), self._status)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   489
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   490
def _intree(funcs, tree):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   491
    if isinstance(tree, tuple):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   492
        if tree[0] == 'func' and tree[1][0] == 'symbol':
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   493
            if tree[1][1] in funcs:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   494
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   495
        for s in tree[1:]:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   496
            if _intree(funcs, s):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   497
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   498
    return False
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   499
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   500
# filesets using matchctx.existing()
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   501
_existingcallers = [
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   502
    'binary',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   503
    'exec',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   504
    'grep',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   505
    'size',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   506
    'symlink',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   507
]
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   508
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   509
def getfileset(ctx, expr):
25252
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
   510
    tree = parse(expr)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   511
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   512
    # do we need status info?
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   513
    if (_intree(['modified', 'added', 'removed', 'deleted',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   514
                 'unknown', 'ignored', 'clean'], tree) or
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   515
        # Using matchctx.existing() on a workingctx requires us to check
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   516
        # for deleted files.
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   517
        (ctx.rev() is None and _intree(_existingcallers, tree))):
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   518
        unknown = _intree(['unknown'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   519
        ignored = _intree(['ignored'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   520
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   521
        r = ctx.repo()
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   522
        status = r.status(ctx.p1(), ctx,
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   523
                          unknown=unknown, ignored=ignored, clean=True)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   524
        subset = []
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   525
        for c in status:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   526
            subset.extend(c)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   527
    else:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   528
        status = None
17371
1310489eb5d6 fileset: fix generator vs list bug in fast path
Patrick Mezard <patrick@mezard.eu>
parents: 17368
diff changeset
   529
        subset = list(ctx.walk(ctx.match([])))
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   530
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   531
    return getset(matchctx(ctx, subset, status), tree)
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   532
25255
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   533
def prettyformat(tree):
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   534
    return parser.prettyformat(tree, ('string', 'symbol'))
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   535
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   536
# tell hggettext to extract docstrings from these functions:
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   537
i18nfunctions = symbols.values()