mercurial/fileset.py
author Patrick Mezard <patrick@mezard.eu>
Wed, 15 Aug 2012 22:29:09 +0200
branchstable
changeset 17366 04c65cb59467
parent 17365 8a0513bf030a
child 17367 ce625185cfd9
permissions -rw-r--r--
fileset: matchctx.existing() must consider unknown files By default, unknown files are ignored. If the 'unknown()' predicate appears in the syntax tree, then they are taken in account. Unfortunately, matchctx.existing() was filtering against non-deleted context files, which does not include unknown files. So: $ hg debugfileset 'binary() and unknown()' would not return existing binary unknown files.
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
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
     8
import parser, error, util, merge, re
13593
cc4721ed7a2a help: extract items doc generation function
Patrick Mezard <pmezard@gmail.com>
parents: 13506
diff changeset
     9
from i18n import _
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
elements = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
    "(": (20, ("group", 1, ")"), ("func", 1, ")")),
12616
e797fdf91df4 revset: lower precedence of minus infix (issue2361)
Matt Mackall <mpm@selenic.com>
parents: 12615
diff changeset
    13
    "-": (5, ("negate", 19), ("minus", 5)),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
    "not": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    "!": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    "and": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    "&": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    "or": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    "|": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    "+": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    ",": (2, None, ("list", 2)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    ")": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    "symbol": (0, ("symbol",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    "string": (0, ("string",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    "end": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    30
globchars = ".*{}[]?/\\"
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    31
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
            pass
14511
30506b894359 filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
    38
        elif c in "(),-|&+!": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    39
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    40
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    41
              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
    42
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    43
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    44
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    45
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    46
            else:
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    47
                decode = lambda x: x.decode('string-escape')
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    56
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
                    break
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
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    60
                raise error.ParseError(_("unterminated string"), s)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    61
        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
    62
            # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
                d = program[pos]
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    67
                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
    68
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    72
                yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    74
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    77
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    79
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
parse = parser.parser(tokenize, elements).parse
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    83
def getstring(x, err):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    84
    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
    85
        return x[1]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    86
    raise error.ParseError(err)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    87
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    88
def getset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    89
    if not x:
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    90
        raise error.ParseError(_("missing argument"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    91
    return methods[x[0]](mctx, *x[1:])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    92
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    93
def stringset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    94
    m = mctx.matcher([x])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    95
    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
    96
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    97
def andset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    98
    return getset(mctx.narrow(getset(mctx, x)), y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    99
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   100
def orset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   101
    # needs optimizing
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   102
    xl = getset(mctx, x)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   103
    yl = getset(mctx, y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   104
    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
   105
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   106
def notset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   107
    s = set(getset(mctx, x))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   108
    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
   109
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   110
def minusset(mctx, x, y):
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   111
    xl = getset(mctx, x)
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   112
    yl = set(getset(mctx, y))
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   113
    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
   114
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   115
def listset(mctx, a, b):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   116
    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
   117
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   118
def modified(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   119
    """``modified()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   120
    File that is modified according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   121
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   122
    # i18n: "modified" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   123
    getargs(x, 0, 0, _("modified takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   124
    s = mctx.status()[0]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   125
    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
   126
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   127
def added(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   128
    """``added()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   129
    File that is added according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   130
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   131
    # i18n: "added" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   132
    getargs(x, 0, 0, _("added takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   133
    s = mctx.status()[1]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   134
    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
   135
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   136
def removed(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   137
    """``removed()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   138
    File that is removed according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   139
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   140
    # i18n: "removed" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   141
    getargs(x, 0, 0, _("removed takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   142
    s = mctx.status()[2]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   143
    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
   144
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   145
def deleted(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   146
    """``deleted()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   147
    File that is deleted according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   148
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   149
    # i18n: "deleted" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   150
    getargs(x, 0, 0, _("deleted takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   151
    s = mctx.status()[3]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   152
    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
   153
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   154
def unknown(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   155
    """``unknown()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   156
    File that is unknown according to status. These files will only be
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   157
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   158
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   159
    # i18n: "unknown" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   160
    getargs(x, 0, 0, _("unknown takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   161
    s = mctx.status()[4]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   162
    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
   163
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   164
def ignored(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   165
    """``ignored()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   166
    File that is ignored according to status. These files will only be
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   167
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   168
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   169
    # i18n: "ignored" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   170
    getargs(x, 0, 0, _("ignored takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   171
    s = mctx.status()[5]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   172
    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
   173
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   174
def clean(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   175
    """``clean()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   176
    File that is clean according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   177
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   178
    # i18n: "clean" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   179
    getargs(x, 0, 0, _("clean takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   180
    s = mctx.status()[6]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   181
    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
   182
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   183
def func(mctx, a, b):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   184
    if a[0] == 'symbol' and a[1] in symbols:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   185
        return symbols[a[1]](mctx, b)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   186
    raise error.ParseError(_("not a function: %s") % a[1])
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   187
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   188
def getlist(x):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   189
    if not x:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   190
        return []
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   191
    if x[0] == 'list':
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   192
        return getlist(x[1]) + [x[2]]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   193
    return [x]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   194
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   195
def getargs(x, min, max, err):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   196
    l = getlist(x)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   197
    if len(l) < min or len(l) > max:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   198
        raise error.ParseError(err)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   199
    return l
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   200
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   201
def binary(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   202
    """``binary()``
14830
35f5cfdd0427 fileset: fix typo in binary() doc
Idan Kamara <idankk86@gmail.com>
parents: 14785
diff changeset
   203
    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
   204
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   205
    # i18n: "binary" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   206
    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
   207
    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
   208
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   209
def exec_(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   210
    """``exec()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   211
    File that is marked as executable.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   212
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   213
    # i18n: "exec" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   214
    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
   215
    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
   216
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   217
def symlink(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   218
    """``symlink()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   219
    File that is marked as a symlink.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   220
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   221
    # i18n: "symlink" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   222
    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
   223
    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
   224
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   225
def resolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   226
    """``resolved()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   227
    File that is marked resolved according to the resolve state.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   228
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   229
    # i18n: "resolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   230
    getargs(x, 0, 0, _("resolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   231
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   232
        return []
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   233
    ms = merge.mergestate(mctx.ctx._repo)
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   234
    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
   235
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   236
def unresolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   237
    """``unresolved()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   238
    File that is marked unresolved according to the resolve state.
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: "unresolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   241
    getargs(x, 0, 0, _("unresolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   242
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   243
        return []
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   244
    ms = merge.mergestate(mctx.ctx._repo)
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   245
    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
   246
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   247
def hgignore(mctx, x):
14700
848a6658069e fileset: use correct function name for hgignore in docstring
Ollie Rutherfurd <orutherfurd@gmail.com>
parents: 14690
diff changeset
   248
    """``hgignore()``
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   249
    File that matches the active .hgignore pattern.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   250
    """
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   251
    getargs(x, 0, 0, _("hgignore takes no arguments"))
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   252
    ignore = mctx.ctx._repo.dirstate._ignore
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   253
    return [f for f in mctx.subset if ignore(f)]
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   254
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   255
def grep(mctx, x):
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   256
    """``grep(regex)``
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   257
    File contains the given regular expression.
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   258
    """
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   259
    pat = getstring(x, _("grep requires a pattern"))
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   260
    r = re.compile(pat)
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   261
    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
   262
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   263
_units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10,
14689
25e4d2f35965 fileset: drop backwards SI size units
Matt Mackall <mpm@selenic.com>
parents: 14685
diff changeset
   264
              M=2**20, MB=2**20, G=2**30, GB=2**30)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   265
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   266
def _sizetoint(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   267
    try:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   268
        s = s.strip()
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   269
        for k, v in _units.items():
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   270
            if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   271
                return int(float(s[:-len(k)]) * v)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   272
        return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   273
    except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   274
        raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   275
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   276
def _sizetomax(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   277
    try:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   278
        s = s.strip()
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   279
        for k, v in _units.items():
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   280
            if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   281
                # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   282
                n = s[:-len(k)]
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   283
                inc = 1.0
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   284
                if "." in n:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   285
                    inc /= 10 ** len(n.split(".")[1])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   286
                return int((float(n) + inc) * v) - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   287
        # no extension, this is a precise value
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   288
        return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   289
    except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   290
        raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   291
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   292
def size(mctx, x):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   293
    """``size(expression)``
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   294
    File size matches the given expression. Examples:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   295
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   296
    - 1k (files from 1024 to 2047 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   297
    - < 20k (files less than 20480 bytes)
14689
25e4d2f35965 fileset: drop backwards SI size units
Matt Mackall <mpm@selenic.com>
parents: 14685
diff changeset
   298
    - >= .5MB (files at least 524288 bytes)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   299
    - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   300
    """
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   301
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   302
    # 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
   303
    expr = getstring(x, _("size requires an expression")).strip()
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   304
    if '-' in expr: # do we have a range?
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   305
        a, b = expr.split('-', 1)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   306
        a = _sizetoint(a)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   307
        b = _sizetoint(b)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   308
        m = lambda x: x >= a and x <= b
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   309
    elif expr.startswith("<="):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   310
        a = _sizetoint(expr[2:])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   311
        m = lambda x: x <= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   312
    elif expr.startswith("<"):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   313
        a = _sizetoint(expr[1:])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   314
        m = lambda x: x < a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   315
    elif expr.startswith(">="):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   316
        a = _sizetoint(expr[2:])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   317
        m = lambda x: x >= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   318
    elif expr.startswith(">"):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   319
        a = _sizetoint(expr[1:])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   320
        m = lambda x: x > a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   321
    elif expr[0].isdigit or expr[0] == '.':
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   322
        a = _sizetoint(expr)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   323
        b = _sizetomax(expr)
14690
15faf0e66909 fileset: add missing whitespace around operator
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14689
diff changeset
   324
        m = lambda x: x >= a and x <= b
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   325
    else:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   326
        raise error.ParseError(_("couldn't parse size: %s") % expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   327
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   328
    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
   329
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   330
def encoding(mctx, x):
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   331
    """``encoding(name)``
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   332
    File can be successfully decoded with the given character
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   333
    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
   334
    UTF-8.
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   335
    """
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   336
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   337
    # i18n: "encoding" is a keyword
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   338
    enc = getstring(x, _("encoding requires an encoding name"))
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   339
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   340
    s = []
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   341
    for f in mctx.existing():
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   342
        d = mctx.ctx[f].data()
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   343
        try:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   344
            d.decode(enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   345
        except LookupError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   346
            raise util.Abort(_("unknown encoding '%s'") % enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   347
        except UnicodeDecodeError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   348
            continue
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   349
        s.append(f)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   350
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   351
    return s
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   352
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   353
def copied(mctx, x):
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   354
    """``copied()``
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   355
    File that is recorded as being copied.
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   356
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   357
    # i18n: "copied" is a keyword
14718
0c81948636f3 fileset: copied takes no arguments
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
   358
    getargs(x, 0, 0, _("copied takes no arguments"))
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   359
    s = []
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   360
    for f in mctx.subset:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   361
        p = mctx.ctx[f].parents()
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   362
        if p and p[0].path() != f:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   363
            s.append(f)
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   364
    return s
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   365
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   366
def subrepo(mctx, x):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   367
    """``subrepo([pattern])``
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   368
    Subrepositories whose paths match the given pattern.
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   369
    """
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   370
    # i18n: "subrepo" is a keyword
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   371
    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
   372
    ctx = mctx.ctx
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   373
    sstate = ctx.substate
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   374
    if x:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   375
        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
   376
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   377
        import match as matchmod # avoid circular import issues
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   378
        fast = not matchmod.patkind(pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   379
        if fast:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   380
            def m(s):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   381
                return (s == pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   382
        else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   383
            m = matchmod.match(ctx._repo.root, '', [pat], ctx=ctx)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   384
        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
   385
    else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   386
        return [sub for sub in sstate]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   387
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   388
symbols = {
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   389
    'added': added,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   390
    'binary': binary,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   391
    'clean': clean,
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   392
    'copied': copied,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   393
    'deleted': deleted,
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   394
    'encoding': encoding,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   395
    'exec': exec_,
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   396
    'grep': grep,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   397
    'ignored': ignored,
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   398
    'hgignore': hgignore,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   399
    'modified': modified,
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   400
    'removed': removed,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   401
    'resolved': resolved,
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   402
    'size': size,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   403
    'symlink': symlink,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   404
    'unknown': unknown,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   405
    'unresolved': unresolved,
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   406
    'subrepo': subrepo,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   407
}
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   408
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   409
methods = {
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   410
    'string': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   411
    'symbol': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   412
    'and': andset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   413
    'or': orset,
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   414
    'minus': minusset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   415
    'list': listset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   416
    'group': getset,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   417
    'not': notset,
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   418
    'func': func,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   419
}
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   420
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   421
class matchctx(object):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   422
    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
   423
        self.ctx = ctx
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   424
        self.subset = subset
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   425
        self._status = status
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   426
    def status(self):
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   427
        return self._status
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   428
    def matcher(self, patterns):
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   429
        return self.ctx.match(patterns)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   430
    def filter(self, files):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   431
        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
   432
    def existing(self):
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   433
        if self._status is not None:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   434
            removed = set(self._status[3])
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   435
            unknown = set(self._status[4])
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   436
        else:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   437
            removed = set()
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   438
            unknown = set()
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   439
        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
   440
                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
   441
    def narrow(self, files):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   442
        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
   443
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   444
def _intree(funcs, tree):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   445
    if isinstance(tree, tuple):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   446
        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
   447
            if tree[1][1] in funcs:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   448
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   449
        for s in tree[1:]:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   450
            if _intree(funcs, s):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   451
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   452
    return False
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   453
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   454
# filesets using matchctx.existing()
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   455
_existingcallers = [
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   456
    'binary',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   457
    'exec',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   458
    'grep',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   459
    'size',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   460
    'symlink',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   461
]
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   462
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   463
def getfileset(ctx, expr):
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   464
    tree, pos = parse(expr)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   465
    if (pos != len(expr)):
14701
4b93bd041772 parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents: 14700
diff changeset
   466
        raise error.ParseError(_("invalid token"), pos)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   467
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   468
    # do we need status info?
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   469
    if (_intree(['modified', 'added', 'removed', 'deleted',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   470
                 'unknown', 'ignored', 'clean'], tree) or
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   471
        # 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
   472
        # for deleted files.
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   473
        (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
   474
        unknown = _intree(['unknown'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   475
        ignored = _intree(['ignored'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   476
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   477
        r = ctx._repo
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   478
        status = r.status(ctx.p1(), ctx,
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   479
                          unknown=unknown, ignored=ignored, clean=True)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   480
        subset = []
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   481
        for c in status:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   482
            subset.extend(c)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   483
    else:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   484
        status = None
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   485
        subset = ctx.walk(ctx.match([]))
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   486
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   487
    return getset(matchctx(ctx, subset, status), tree)
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   488
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   489
# tell hggettext to extract docstrings from these functions:
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   490
i18nfunctions = symbols.values()