mercurial/revset.py
author Bryan O'Sullivan <bryano@fb.com>
Tue, 08 May 2012 15:29:09 -0700
changeset 16647 14913fcb30c6
parent 16640 592e0beee8b0
child 16657 b6081c2c4647
permissions -rw-r--r--
bisect: track the current changeset (issue3382) Introduce a new revset feature, bisect(current), that identifies the changeset currently being bisected.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# revset.py - revision set queries for mercurial
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
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
import re
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
     9
import parser, util, error, discovery, hbisect, phases
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
    10
import node
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    11
import bookmarks as bookmarksmod
12085
6f833fc3ccab Consistently import foo as foomod when foo to avoid shadowing
Martin Geisler <mg@aragost.com>
parents: 11944
diff changeset
    12
import match as matchmod
13593
cc4721ed7a2a help: extract items doc generation function
Patrick Mezard <pmezard@gmail.com>
parents: 13506
diff changeset
    13
from i18n import _
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
    14
import encoding
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    16
def _revancestors(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    17
    """Like revlog.ancestors(), but supports followfirst."""
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    18
    cut = followfirst and 1 or None
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    19
    cl = repo.changelog
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    20
    visit = list(revs)
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
    21
    seen = set([node.nullrev])
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    22
    while visit:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    23
        for parent in cl.parentrevs(visit.pop(0))[:cut]:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    24
            if parent not in seen:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    25
                visit.append(parent)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    26
                seen.add(parent)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    27
                yield parent
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    28
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    29
def _revdescendants(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    30
    """Like revlog.descendants() but supports followfirst."""
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    31
    cut = followfirst and 1 or None
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    32
    cl = repo.changelog
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    33
    first = min(revs)
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
    34
    nullrev = node.nullrev
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
    35
    if first == nullrev:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    36
        # Are there nodes with a null first parent and a non-null
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    37
        # second one? Maybe. Do we care? Probably not.
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    38
        for i in cl:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    39
            yield i
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    40
        return
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    41
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    42
    seen = set(revs)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    43
    for i in xrange(first + 1, len(cl)):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    44
        for x in cl.parentrevs(i)[:cut]:
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
    45
            if x != nullrev and x in seen:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    46
                seen.add(i)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    47
                yield i
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    48
                break
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    49
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
elements = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
    "(": (20, ("group", 1, ")"), ("func", 1, ")")),
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
    52
    "~": (18, None, ("ancestor", 18)),
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
    53
    "^": (18, None, ("parent", 18), ("parentpost", 18)),
12616
e797fdf91df4 revset: lower precedence of minus infix (issue2361)
Matt Mackall <mpm@selenic.com>
parents: 12615
diff changeset
    54
    "-": (5, ("negate", 19), ("minus", 5)),
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    55
    "::": (17, ("dagrangepre", 17), ("dagrange", 17),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    56
           ("dagrangepost", 17)),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    57
    "..": (17, ("dagrangepre", 17), ("dagrange", 17),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    58
           ("dagrangepost", 17)),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    59
    ":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
    "not": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
    "!": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
    "and": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    "&": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
    "or": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    "|": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
    "+": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    ",": (2, None, ("list", 2)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
    ")": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
    "symbol": (0, ("symbol",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
    "string": (0, ("string",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
    "end": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
            pass
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    82
        elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    83
            yield ('::', None, pos)
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
    84
            pos += 1 # skip ahead
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
        elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    86
            yield ('..', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
            pos += 1 # skip ahead
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
    88
        elif c in "():,-|&+!~^": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    89
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    90
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    91
              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
    92
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    93
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    94
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    95
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    96
            else:
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    97
                decode = lambda x: x.decode('string-escape')
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   106
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   107
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   110
                raise error.ParseError(_("unterminated string"), s)
11404
37cbedbeae96 revset: allow extended characters in symbols
Matt Mackall <mpm@selenic.com>
parents: 11385
diff changeset
   111
        elif c.isalnum() or c in '._' or ord(c) > 127: # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   112
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
                d = program[pos]
15949
d5edbbf55a75 revset: allow slashes in symbols
Matt Mackall <mpm@selenic.com>
parents: 15938
diff changeset
   116
                if not (d.isalnum() or d in "._/" or ord(d) > 127):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
                if d == '.' and program[pos - 1] == '.': # special case for ..
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
                    pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   124
                yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   126
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   129
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   130
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   131
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   132
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   133
# helpers
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   135
def getstring(x, err):
11406
42408cd43f55 revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents: 11404
diff changeset
   136
    if x and (x[0] == 'string' or x[0] == 'symbol'):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   137
        return x[1]
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   138
    raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   139
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
def getlist(x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
    if not x:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   142
        return []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
    if x[0] == 'list':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
        return getlist(x[1]) + [x[2]]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
    return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
11339
744d5b73f776 revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents: 11304
diff changeset
   147
def getargs(x, min, max, err):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
    l = getlist(x)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   149
    if len(l) < min or (max >= 0 and len(l) > max):
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   150
        raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   151
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   153
def getset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
    if not x:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   155
        raise error.ParseError(_("missing argument"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   156
    return methods[x[0]](repo, subset, *x[1:])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
# operator methods
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   160
def stringset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   161
    x = repo[x].rev()
11282
e581f3acc338 revset: fix up tests
Matt Mackall <mpm@selenic.com>
parents: 11280
diff changeset
   162
    if x == -1 and len(subset) == len(repo):
e581f3acc338 revset: fix up tests
Matt Mackall <mpm@selenic.com>
parents: 11280
diff changeset
   163
        return [-1]
13938
e44ebd2a142a revset: optimize stringset when subset == entire repo
Idan Kamara <idankk86@gmail.com>
parents: 13932
diff changeset
   164
    if len(subset) == len(repo) or x in subset:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
        return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
    return []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   167
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
def symbolset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   169
    if x in symbols:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   170
        raise error.ParseError(_("can't use %s here") % x)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
    return stringset(repo, subset, x)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   172
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
def rangeset(repo, subset, x, y):
11456
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   174
    m = getset(repo, subset, x)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   175
    if not m:
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   176
        m = getset(repo, range(len(repo)), x)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   177
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   178
    n = getset(repo, subset, y)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   179
    if not n:
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   180
        n = getset(repo, range(len(repo)), y)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   181
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   182
    if not m or not n:
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   183
        return []
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   184
    m, n = m[0], n[-1]
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   185
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
    if m < n:
11456
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   187
        r = range(m, n + 1)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   188
    else:
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   189
        r = range(m, n - 1, -1)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   190
    s = set(subset)
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   191
    return [x for x in r if x in s]
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
def andset(repo, subset, x, y):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
    return getset(repo, getset(repo, subset, x), y)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   196
def orset(repo, subset, x, y):
13932
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   197
    xl = getset(repo, subset, x)
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   198
    s = set(xl)
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   199
    yl = getset(repo, [r for r in subset if r not in s], y)
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   200
    return xl + yl
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   201
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   202
def notset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   203
    s = set(getset(repo, subset, x))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
    return [r for r in subset if r not in s]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   205
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   206
def listset(repo, subset, a, b):
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   207
    raise error.ParseError(_("can't use a list in this context"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   208
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   209
def func(repo, subset, a, b):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
    if a[0] == 'symbol' and a[1] in symbols:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   211
        return symbols[a[1]](repo, subset, b)
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   212
    raise error.ParseError(_("not a function: %s") % a[1])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   213
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   214
# functions
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   215
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   216
def adds(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   217
    """``adds(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   218
    Changesets that add a file matching pattern.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   219
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   220
    # i18n: "adds" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   221
    pat = getstring(x, _("adds requires a pattern"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   222
    return checkstatus(repo, subset, pat, 1)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   223
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   224
def ancestor(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   225
    """``ancestor(single, single)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   226
    Greatest common ancestor of the two changesets.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   227
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   228
    # i18n: "ancestor" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   229
    l = getargs(x, 2, 2, _("ancestor requires two arguments"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   230
    r = range(len(repo))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   231
    a = getset(repo, r, l[0])
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   232
    b = getset(repo, r, l[1])
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   233
    if len(a) != 1 or len(b) != 1:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   234
        # i18n: "ancestor" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   235
        raise error.ParseError(_("ancestor arguments must be single revisions"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   236
    an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   237
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   238
    return [r for r in an if r in subset]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   239
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   240
def _ancestors(repo, subset, x, followfirst=False):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   241
    args = getset(repo, range(len(repo)), x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   242
    if not args:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   243
        return []
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   244
    s = set(_revancestors(repo, args, followfirst)) | set(args)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   245
    return [r for r in subset if r in s]
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   246
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   247
def ancestors(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   248
    """``ancestors(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   249
    Changesets that are ancestors of a changeset in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   250
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   251
    return _ancestors(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   252
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   253
def _firstancestors(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   254
    # ``_firstancestors(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   255
    # Like ``ancestors(set)`` but follows only the first parents.
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   256
    return _ancestors(repo, subset, x, followfirst=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   257
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   258
def ancestorspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   259
    """``set~n``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   260
    Changesets that are the Nth ancestor (first parents only) of a changeset in set.
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   261
    """
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   262
    try:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   263
        n = int(n[1])
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
   264
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   265
        raise error.ParseError(_("~ expects a number"))
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   266
    ps = set()
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   267
    cl = repo.changelog
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   268
    for r in getset(repo, subset, x):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   269
        for i in range(n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   270
            r = cl.parentrevs(r)[0]
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   271
        ps.add(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   272
    return [r for r in subset if r in ps]
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   273
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   274
def author(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   275
    """``author(string)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   276
    Alias for ``user(string)``.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   277
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   278
    # i18n: "author" is a keyword
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   279
    n = encoding.lower(getstring(x, _("author requires a string")))
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   280
    return [r for r in subset if n in encoding.lower(repo[r].user())]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   281
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   282
def bisect(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   283
    """``bisect(string)``
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   284
    Changesets marked in the specified bisect status:
15136
18219c0789ae revset.bisect: add new 'range' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15135
diff changeset
   285
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   286
    - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   287
    - ``goods``, ``bads``      : csets topologicaly good/bad
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   288
    - ``range``              : csets taking part in the bisection
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   289
    - ``pruned``             : csets that are goods, bads or skipped
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   290
    - ``untested``           : csets whose fate is yet unknown
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   291
    - ``ignored``            : csets ignored due to DAG topology
16647
14913fcb30c6 bisect: track the current changeset (issue3382)
Bryan O'Sullivan <bryano@fb.com>
parents: 16640
diff changeset
   292
    - ``current``            : the cset currently being bisected
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   293
    """
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15134
diff changeset
   294
    status = getstring(x, _("bisect requires a string")).lower()
16467
7f59900e3f8b revset: fix O(n**2) behaviour of bisect() (issue3381)
Bryan O'Sullivan <bryano@fb.com>
parents: 16453
diff changeset
   295
    state = set(hbisect.get(repo, status))
7f59900e3f8b revset: fix O(n**2) behaviour of bisect() (issue3381)
Bryan O'Sullivan <bryano@fb.com>
parents: 16453
diff changeset
   296
    return [r for r in subset if r in state]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   297
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   298
# Backward-compatibility
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   299
# - no help entry so that we do not advertise it any more
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   300
def bisected(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   301
    return bisect(repo, subset, x)
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   302
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   303
def bookmark(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   304
    """``bookmark([name])``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   305
    The named bookmark or all bookmarks.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   306
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   307
    # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   308
    args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   309
    if args:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   310
        bm = getstring(args[0],
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   311
                       # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   312
                       _('the argument to bookmark must be a string'))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   313
        bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   314
        if not bmrev:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   315
            raise util.Abort(_("bookmark '%s' does not exist") % bm)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   316
        bmrev = repo[bmrev].rev()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   317
        return [r for r in subset if r == bmrev]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   318
    bms = set([repo[r].rev()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   319
               for r in bookmarksmod.listbookmarks(repo).values()])
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   320
    return [r for r in subset if r in bms]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   321
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   322
def branch(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   323
    """``branch(string or set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   324
    All changesets belonging to the given branch or the branches of the given
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   325
    changesets.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   326
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   327
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   328
        b = getstring(x, '')
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   329
        if b in repo.branchmap():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   330
            return [r for r in subset if repo[r].branch() == b]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   331
    except error.ParseError:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   332
        # not a string, but another revspec, e.g. tip()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   333
        pass
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   334
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   335
    s = getset(repo, range(len(repo)), x)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   336
    b = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   337
    for r in s:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   338
        b.add(repo[r].branch())
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   339
    s = set(s)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   340
    return [r for r in subset if r in s or repo[r].branch() in b]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   341
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   342
def checkstatus(repo, subset, pat, field):
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   343
    m = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   344
    s = []
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   345
    hasset = matchmod.patkind(pat) == 'set'
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   346
    fname = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   347
    for r in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   348
        c = repo[r]
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   349
        if not m or hasset:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   350
            m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   351
            if not m.anypats() and len(m.files()) == 1:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   352
                fname = m.files()[0]
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   353
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   354
            if fname not in c.files():
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   355
                continue
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   356
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   357
            for f in c.files():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   358
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   359
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   360
            else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   361
                continue
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   362
        files = repo.status(c.p1().node(), c.node())[field]
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   363
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   364
            if fname in files:
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   365
                s.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   366
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   367
            for f in files:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   368
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   369
                    s.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   370
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   371
    return s
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   372
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   373
def _children(repo, narrow, parentset):
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   374
    cs = set()
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   375
    pr = repo.changelog.parentrevs
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
   376
    for r in narrow:
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   377
        for p in pr(r):
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   378
            if p in parentset:
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   379
                cs.add(r)
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   380
    return cs
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   381
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   382
def children(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   383
    """``children(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   384
    Child changesets of changesets in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   385
    """
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   386
    s = set(getset(repo, range(len(repo)), x))
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   387
    cs = _children(repo, subset, s)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   388
    return [r for r in subset if r in cs]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   389
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   390
def closed(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   391
    """``closed()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   392
    Changeset is closed.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   393
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   394
    # i18n: "closed" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   395
    getargs(x, 0, 0, _("closed takes no arguments"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   396
    return [r for r in subset if repo[r].extra().get('close')]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   397
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   398
def contains(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   399
    """``contains(pattern)``
14357
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   400
    Revision contains a file matching pattern. See :hg:`help patterns`
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   401
    for information about file patterns.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   402
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   403
    # i18n: "contains" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   404
    pat = getstring(x, _("contains requires a pattern"))
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   405
    m = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   406
    s = []
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   407
    if not matchmod.patkind(pat):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   408
        for r in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   409
            if pat in repo[r]:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   410
                s.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   411
    else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   412
        for r in subset:
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   413
            c = repo[r]
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   414
            if not m or matchmod.patkind(pat) == 'set':
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   415
                m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   416
            for f in c.manifest():
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   417
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   418
                    s.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   419
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   420
    return s
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   421
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   422
def date(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   423
    """``date(interval)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   424
    Changesets within the interval, see :hg:`help dates`.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   425
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   426
    # i18n: "date" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   427
    ds = getstring(x, _("date requires a string"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   428
    dm = util.matchdate(ds)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   429
    return [r for r in subset if dm(repo[r].date()[0])]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   430
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   431
def desc(repo, subset, x):
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   432
    """``desc(string)``
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   433
    Search commit message for string. The match is case-insensitive.
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   434
    """
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   435
    # i18n: "desc" is a keyword
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   436
    ds = encoding.lower(getstring(x, _("desc requires a string")))
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   437
    l = []
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   438
    for r in subset:
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   439
        c = repo[r]
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   440
        if ds in encoding.lower(c.description()):
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   441
            l.append(r)
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   442
    return l
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   443
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   444
def _descendants(repo, subset, x, followfirst=False):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   445
    args = getset(repo, range(len(repo)), x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   446
    if not args:
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   447
        return []
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   448
    s = set(_revdescendants(repo, args, followfirst)) | set(args)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   449
    return [r for r in subset if r in s]
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   450
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   451
def descendants(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   452
    """``descendants(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   453
    Changesets which are descendants of changesets in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   454
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   455
    return _descendants(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   456
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   457
def _firstdescendants(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   458
    # ``_firstdescendants(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   459
    # Like ``descendants(set)`` but follows only the first parents.
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   460
    return _descendants(repo, subset, x, followfirst=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   461
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   462
def draft(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   463
    """``draft()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   464
    Changeset in draft phase."""
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   465
    getargs(x, 0, 0, _("draft takes no arguments"))
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   466
    return [r for r in subset if repo._phaserev[r] == phases.draft]
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   467
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   468
def filelog(repo, subset, x):
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   469
    """``filelog(pattern)``
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   470
    Changesets connected to the specified filelog.
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   471
    """
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   472
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   473
    pat = getstring(x, _("filelog requires a pattern"))
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   474
    m = matchmod.match(repo.root, repo.getcwd(), [pat], default='relpath',
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   475
                       ctx=repo[None])
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   476
    s = set()
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   477
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   478
    if not matchmod.patkind(pat):
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   479
        for f in m.files():
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   480
            fl = repo.file(f)
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   481
            for fr in fl:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   482
                s.add(fl.linkrev(fr))
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   483
    else:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   484
        for f in repo[None]:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   485
            if m(f):
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   486
                fl = repo.file(f)
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   487
                for fr in fl:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   488
                    s.add(fl.linkrev(fr))
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   489
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   490
    return [r for r in subset if r in s]
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   491
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   492
def first(repo, subset, x):
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   493
    """``first(set, [n])``
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   494
    An alias for limit().
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   495
    """
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   496
    return limit(repo, subset, x)
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   497
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   498
def _follow(repo, subset, x, name, followfirst=False):
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   499
    l = getargs(x, 0, 1, _("%s takes no arguments or a filename") % name)
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   500
    c = repo['.']
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   501
    if l:
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   502
        x = getstring(l[0], _("%s expected a filename") % name)
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   503
        if x in c:
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   504
            cx = c[x]
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   505
            s = set(ctx.rev() for ctx in cx.ancestors(followfirst=followfirst))
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   506
            # include the revision responsible for the most recent version
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   507
            s.add(cx.linkrev())
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   508
        else:
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   509
            return []
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   510
    else:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   511
        s = set(_revancestors(repo, [c.rev()], followfirst)) | set([c.rev()])
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   512
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   513
    return [r for r in subset if r in s]
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   514
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   515
def follow(repo, subset, x):
14343
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   516
    """``follow([file])``
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   517
    An alias for ``::.`` (ancestors of the working copy's first parent).
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   518
    If a filename is specified, the history of the given file is followed,
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   519
    including copies.
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   520
    """
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   521
    return _follow(repo, subset, x, 'follow')
14343
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   522
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   523
def _followfirst(repo, subset, x):
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   524
    # ``followfirst([file])``
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   525
    # Like ``follow([file])`` but follows only the first parent of
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   526
    # every revision or file revision.
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   527
    return _follow(repo, subset, x, '_followfirst', followfirst=True)
14343
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   528
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   529
def getall(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   530
    """``all()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   531
    All changesets, the same as ``0:tip``.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   532
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   533
    # i18n: "all" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   534
    getargs(x, 0, 0, _("all takes no arguments"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   535
    return subset
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   536
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   537
def grep(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   538
    """``grep(regex)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   539
    Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
14357
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   540
    to ensure special escape characters are handled correctly. Unlike
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   541
    ``keyword(string)``, the match is case-sensitive.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   542
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   543
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   544
        # i18n: "grep" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   545
        gr = re.compile(getstring(x, _("grep requires a string")))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   546
    except re.error, e:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   547
        raise error.ParseError(_('invalid match pattern: %s') % e)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   548
    l = []
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   549
    for r in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   550
        c = repo[r]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   551
        for e in c.files() + [c.user(), c.description()]:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   552
            if gr.search(e):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   553
                l.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   554
                break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   555
    return l
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   556
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   557
def _matchfiles(repo, subset, x):
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   558
    # _matchfiles takes a revset list of prefixed arguments:
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   559
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   560
    #   [p:foo, i:bar, x:baz]
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   561
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   562
    # builds a match object from them and filters subset. Allowed
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   563
    # prefixes are 'p:' for regular patterns, 'i:' for include
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   564
    # patterns and 'x:' for exclude patterns. Use 'r:' prefix to pass
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   565
    # a revision identifier, or the empty string to reference the
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   566
    # working directory, from which the match object is
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   567
    # initialized. Use 'd:' to set the default matching mode, default
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   568
    # to 'glob'. At most one 'r:' and 'd:' argument can be passed.
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   569
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   570
    # i18n: "_matchfiles" is a keyword
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   571
    l = getargs(x, 1, -1, _("_matchfiles requires at least one argument"))
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   572
    pats, inc, exc = [], [], []
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   573
    hasset = False
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   574
    rev, default = None, None
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   575
    for arg in l:
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   576
        s = getstring(arg, _("_matchfiles requires string arguments"))
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   577
        prefix, value = s[:2], s[2:]
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   578
        if prefix == 'p:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   579
            pats.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   580
        elif prefix == 'i:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   581
            inc.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   582
        elif prefix == 'x:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   583
            exc.append(value)
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   584
        elif prefix == 'r:':
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   585
            if rev is not None:
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   586
                raise error.ParseError(_('_matchfiles expected at most one '
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   587
                                         'revision'))
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   588
            rev = value
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   589
        elif prefix == 'd:':
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   590
            if default is not None:
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   591
                raise error.ParseError(_('_matchfiles expected at most one '
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   592
                                         'default mode'))
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   593
            default = value
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   594
        else:
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   595
            raise error.ParseError(_('invalid _matchfiles prefix: %s') % prefix)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   596
        if not hasset and matchmod.patkind(value) == 'set':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   597
            hasset = True
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   598
    if not default:
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   599
        default = 'glob'
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   600
    m = None
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   601
    s = []
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   602
    for r in subset:
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   603
        c = repo[r]
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   604
        if not m or (hasset and rev is None):
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   605
            ctx = c
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   606
            if rev is not None:
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   607
                ctx = repo[rev or None]
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   608
            m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   609
                               exclude=exc, ctx=ctx, default=default)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   610
        for f in c.files():
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   611
            if m(f):
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   612
                s.append(r)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   613
                break
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   614
    return s
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   615
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   616
def hasfile(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   617
    """``file(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   618
    Changesets affecting files matched by pattern.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   619
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   620
    # i18n: "file" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   621
    pat = getstring(x, _("file requires a pattern"))
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   622
    return _matchfiles(repo, subset, ('string', 'p:' + pat))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   623
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   624
def head(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   625
    """``head()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   626
    Changeset is a named branch head.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   627
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   628
    # i18n: "head" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   629
    getargs(x, 0, 0, _("head takes no arguments"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   630
    hs = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   631
    for b, ls in repo.branchmap().iteritems():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   632
        hs.update(repo[h].rev() for h in ls)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   633
    return [r for r in subset if r in hs]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   634
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   635
def heads(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   636
    """``heads(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   637
    Members of set with no children in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   638
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   639
    s = getset(repo, subset, x)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   640
    ps = set(parents(repo, subset, x))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   641
    return [r for r in s if r not in ps]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   642
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   643
def keyword(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   644
    """``keyword(string)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   645
    Search commit message, user name, and names of changed files for
14357
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   646
    string. The match is case-insensitive.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   647
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   648
    # i18n: "keyword" is a keyword
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   649
    kw = encoding.lower(getstring(x, _("keyword requires a string")))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   650
    l = []
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   651
    for r in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   652
        c = repo[r]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   653
        t = " ".join(c.files() + [c.user(), c.description()])
15726
9b822edecb4c i18n: use "encoding.lower()" to normalize specified string for revset
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15596
diff changeset
   654
        if kw in encoding.lower(t):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   655
            l.append(r)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   656
    return l
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   657
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   658
def limit(repo, subset, x):
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   659
    """``limit(set, [n])``
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   660
    First n members of set, defaulting to 1.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   661
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   662
    # i18n: "limit" is a keyword
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   663
    l = getargs(x, 1, 2, _("limit requires one or two arguments"))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   664
    try:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   665
        lim = 1
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   666
        if len(l) == 2:
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   667
            # i18n: "limit" is a keyword
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   668
            lim = int(getstring(l[1], _("limit requires a number")))
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
   669
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   670
        # i18n: "limit" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   671
        raise error.ParseError(_("limit expects a number"))
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   672
    ss = set(subset)
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   673
    os = getset(repo, range(len(repo)), l[0])[:lim]
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   674
    return [r for r in os if r in ss]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   675
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   676
def last(repo, subset, x):
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   677
    """``last(set, [n])``
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   678
    Last n members of set, defaulting to 1.
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   679
    """
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   680
    # i18n: "last" is a keyword
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   681
    l = getargs(x, 1, 2, _("last requires one or two arguments"))
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   682
    try:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   683
        lim = 1
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   684
        if len(l) == 2:
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   685
            # i18n: "last" is a keyword
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   686
            lim = int(getstring(l[1], _("last requires a number")))
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
   687
    except (TypeError, ValueError):
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   688
        # i18n: "last" is a keyword
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   689
        raise error.ParseError(_("last expects a number"))
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   690
    ss = set(subset)
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   691
    os = getset(repo, range(len(repo)), l[0])[-lim:]
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   692
    return [r for r in os if r in ss]
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
   693
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   694
def maxrev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   695
    """``max(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   696
    Changeset with highest revision number in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   697
    """
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   698
    os = getset(repo, range(len(repo)), x)
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   699
    if os:
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   700
        m = max(os)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   701
        if m in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   702
            return [m]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   703
    return []
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   704
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   705
def merge(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   706
    """``merge()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   707
    Changeset is a merge changeset.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   708
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   709
    # i18n: "merge" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   710
    getargs(x, 0, 0, _("merge takes no arguments"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   711
    cl = repo.changelog
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   712
    return [r for r in subset if cl.parentrevs(r)[1] != -1]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   713
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   714
def minrev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   715
    """``min(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   716
    Changeset with lowest revision number in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   717
    """
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   718
    os = getset(repo, range(len(repo)), x)
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   719
    if os:
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
   720
        m = min(os)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   721
        if m in subset:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   722
            return [m]
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   723
    return []
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   724
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   725
def modifies(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   726
    """``modifies(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   727
    Changesets modifying files matched by pattern.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   728
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   729
    # i18n: "modifies" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   730
    pat = getstring(x, _("modifies requires a pattern"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   731
    return checkstatus(repo, subset, pat, 0)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   732
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
   733
def node_(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   734
    """``id(string)``
12859
76066903ae08 revset: fix missing dot in docstring
Wagner Bruna <wbruna@yahoo.com>
parents: 12855
diff changeset
   735
    Revision non-ambiguously specified by the given hex string prefix.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   736
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
   737
    # i18n: "id" is a keyword
12736
7e14e67e6622 revset: use 'requires' instead of 'wants' in error message
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12733
diff changeset
   738
    l = getargs(x, 1, 1, _("id requires one argument"))
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
   739
    # i18n: "id" is a keyword
12736
7e14e67e6622 revset: use 'requires' instead of 'wants' in error message
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12733
diff changeset
   740
    n = getstring(l[0], _("id requires a string"))
12716
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   741
    if len(n) == 40:
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   742
        rn = repo[n].rev()
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   743
    else:
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   744
        rn = repo.changelog.rev(repo.changelog._partialmatch(n))
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   745
    return [r for r in subset if r == rn]
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   746
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   747
def outgoing(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   748
    """``outgoing([path])``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   749
    Changesets not found in the specified destination repository, or the
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   750
    default push location.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   751
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   752
    import hg # avoid start-up nasties
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   753
    # i18n: "outgoing" is a keyword
14717
c8ee2729e89f revset and fileset: fix typos in parser error messages
Mads Kiilerich <mads@kiilerich.com>
parents: 14715
diff changeset
   754
    l = getargs(x, 0, 1, _("outgoing takes one or no arguments"))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   755
    # i18n: "outgoing" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   756
    dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   757
    dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   758
    dest, branches = hg.parseurl(dest)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   759
    revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   760
    if revs:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   761
        revs = [repo.lookup(rev) for rev in revs]
14556
517e1d88bf7e hg: change various repository() users to use peer() where appropriate
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
   762
    other = hg.peer(repo, {}, dest)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   763
    repo.ui.pushbuffer()
15837
cd956049fc14 discovery: introduce outgoing object for result of findcommonoutgoing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15819
diff changeset
   764
    outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   765
    repo.ui.popbuffer()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   766
    cl = repo.changelog
15837
cd956049fc14 discovery: introduce outgoing object for result of findcommonoutgoing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15819
diff changeset
   767
    o = set([cl.rev(r) for r in outgoing.missing])
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   768
    return [r for r in subset if r in o]
12716
c7e619e30ba3 revset: add id() and rev() to allow explicitly referring to changes by hash or rev
Augie Fackler <durin42@gmail.com>
parents: 12715
diff changeset
   769
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   770
def p1(repo, subset, x):
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   771
    """``p1([set])``
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   772
    First parent of changesets in set, or the working directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   773
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   774
    if x is None:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13873
diff changeset
   775
        p = repo[x].p1().rev()
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
   776
        return [r for r in subset if r == p]
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   777
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   778
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   779
    cl = repo.changelog
12786
9aae04f4fcf6 revset: disable subset optimization for parents() and children() (issue2437)
Wagner Bruna <wbruna@yahoo.com>
parents: 12736
diff changeset
   780
    for r in getset(repo, range(len(repo)), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   781
        ps.add(cl.parentrevs(r)[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   782
    return [r for r in subset if r in ps]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   783
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   784
def p2(repo, subset, x):
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   785
    """``p2([set])``
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   786
    Second parent of changesets in set, or the working directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   787
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   788
    if x is None:
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   789
        ps = repo[x].parents()
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   790
        try:
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
   791
            p = ps[1].rev()
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
   792
            return [r for r in subset if r == p]
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   793
        except IndexError:
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   794
            return []
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
   795
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   796
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   797
    cl = repo.changelog
12786
9aae04f4fcf6 revset: disable subset optimization for parents() and children() (issue2437)
Wagner Bruna <wbruna@yahoo.com>
parents: 12736
diff changeset
   798
    for r in getset(repo, range(len(repo)), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   799
        ps.add(cl.parentrevs(r)[1])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   800
    return [r for r in subset if r in ps]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   801
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   802
def parents(repo, subset, x):
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
   803
    """``parents([set])``
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
   804
    The set of all parents for all changesets in set, or the working directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   805
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
   806
    if x is None:
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
   807
        ps = tuple(p.rev() for p in repo[x].parents())
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
   808
        return [r for r in subset if r in ps]
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
   809
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   810
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   811
    cl = repo.changelog
12786
9aae04f4fcf6 revset: disable subset optimization for parents() and children() (issue2437)
Wagner Bruna <wbruna@yahoo.com>
parents: 12736
diff changeset
   812
    for r in getset(repo, range(len(repo)), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   813
        ps.update(cl.parentrevs(r))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   814
    return [r for r in subset if r in ps]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   815
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   816
def parentspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   817
    """``set^0``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   818
    The set.
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   819
    ``set^1`` (or ``set^``), ``set^2``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   820
    First or second parent, respectively, of all changesets in set.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   821
    """
12320
40c40c6f20b8 revset: handle re.compile() errors in grep()
Brodie Rao <brodie@bitheap.org>
parents: 11882
diff changeset
   822
    try:
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   823
        n = int(n[1])
14072
2e4d79dcc0a0 revset: add missing whitespace
Kevin Gessner <kevin@kevingessner.com>
parents: 14070
diff changeset
   824
        if n not in (0, 1, 2):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   825
            raise ValueError
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
   826
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   827
        raise error.ParseError(_("^ expects a number 0, 1, or 2"))
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   828
    ps = set()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   829
    cl = repo.changelog
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   830
    for r in getset(repo, subset, x):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   831
        if n == 0:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   832
            ps.add(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   833
        elif n == 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   834
            ps.add(cl.parentrevs(r)[0])
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   835
        elif n == 2:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   836
            parents = cl.parentrevs(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   837
            if len(parents) > 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   838
                ps.add(parents[1])
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   839
    return [r for r in subset if r in ps]
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   840
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   841
def present(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   842
    """``present(set)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   843
    An empty set, if any revision in set isn't found; otherwise,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   844
    all revisions in set.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   845
    """
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   846
    try:
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   847
        return getset(repo, subset, x)
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   848
    except error.RepoLookupError:
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   849
        return []
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
   850
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   851
def public(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   852
    """``public()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   853
    Changeset in public phase."""
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   854
    getargs(x, 0, 0, _("public takes no arguments"))
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   855
    return [r for r in subset if repo._phaserev[r] == phases.public]
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   856
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   857
def remote(repo, subset, x):
16007
f06c53ca59a9 revset: fix documentation for 'remote()' predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16006
diff changeset
   858
    """``remote([id [,path]])``
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   859
    Local revision that corresponds to the given identifier in a
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   860
    remote repository, if present. Here, the '.' identifier is a
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   861
    synonym for the current local branch.
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   862
    """
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   863
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   864
    import hg # avoid start-up nasties
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   865
    # i18n: "remote" is a keyword
16007
f06c53ca59a9 revset: fix documentation for 'remote()' predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16006
diff changeset
   866
    l = getargs(x, 0, 2, _("remote takes one, two or no arguments"))
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   867
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   868
    q = '.'
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   869
    if len(l) > 0:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   870
    # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   871
        q = getstring(l[0], _("remote requires a string id"))
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   872
    if q == '.':
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   873
        q = repo['.'].branch()
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   874
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   875
    dest = ''
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   876
    if len(l) > 1:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   877
        # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   878
        dest = getstring(l[1], _("remote requires a repository path"))
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   879
    dest = repo.ui.expandpath(dest or 'default')
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   880
    dest, branches = hg.parseurl(dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   881
    revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   882
    if revs:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   883
        revs = [repo.lookup(rev) for rev in revs]
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   884
    other = hg.peer(repo, {}, dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   885
    n = other.lookup(q)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   886
    if n in repo:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   887
        r = repo[n].rev()
16006
39e60576ac98 revset: fix 'remote()' failure when remote repo has more revs than local
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15966
diff changeset
   888
        if r in subset:
39e60576ac98 revset: fix 'remote()' failure when remote repo has more revs than local
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15966
diff changeset
   889
            return [r]
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   890
    return []
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
   891
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   892
def removes(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   893
    """``removes(pattern)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   894
    Changesets which remove files matching pattern.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   895
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
   896
    # i18n: "removes" is a keyword
12736
7e14e67e6622 revset: use 'requires' instead of 'wants' in error message
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12733
diff changeset
   897
    pat = getstring(x, _("removes requires a pattern"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   898
    return checkstatus(repo, subset, pat, 2)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   899
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   900
def rev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   901
    """``rev(number)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   902
    Revision with the given numeric identifier.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
   903
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   904
    # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   905
    l = getargs(x, 1, 1, _("rev requires one argument"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   906
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   907
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   908
        l = int(getstring(l[0], _("rev requires a number")))
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
   909
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   910
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   911
        raise error.ParseError(_("rev expects a number"))
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   912
    return [r for r in subset if r == l]
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   913
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   914
def matching(repo, subset, x):
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   915
    """``matching(revision [, field])``
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   916
    Changesets in which a given set of fields match the set of fields in the
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   917
    selected revision or set.
16528
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   918
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   919
    To match more than one field pass the list of fields to match separated
16528
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   920
    by spaces (e.g. ``author description``).
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   921
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   922
    Valid fields are most regular revision fields and some special fields.
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   923
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   924
    Regular revision fields are ``description``, ``author``, ``branch``,
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   925
    ``date``, ``files``, ``phase``, ``parents``, ``substate`` and ``user``.
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   926
    Note that ``author`` and ``user`` are synonyms.
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   927
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   928
    Special fields are ``summary`` and ``metadata``:
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   929
    ``summary`` matches the first line of the description.
16639
00290bd359fe revset: documentation typo "metatadata"
Jesse Glick <jesse.glick@oracle.com>
parents: 16528
diff changeset
   930
    ``metadata`` is equivalent to matching ``description user date``
16528
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   931
    (i.e. it matches the main metadata fields).
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   932
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   933
    ``metadata`` is the default field which is used when no fields are
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
   934
    specified. You can match more than one field at a time.
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   935
    """
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   936
    l = getargs(x, 1, 2, _("matching takes 1 or 2 arguments"))
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   937
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   938
    revs = getset(repo, xrange(len(repo)), l[0])
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   939
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   940
    fieldlist = ['metadata']
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   941
    if len(l) > 1:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   942
            fieldlist = getstring(l[1],
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   943
                _("matching requires a string "
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   944
                "as its second argument")).split()
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   945
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   946
    # Make sure that there are no repeated fields, and expand the
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   947
    # 'special' 'metadata' field type
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   948
    fields = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   949
    for field in fieldlist:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   950
        if field == 'metadata':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   951
            fields += ['user', 'description', 'date']
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   952
        else:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   953
            if field == 'author':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   954
                field = 'user'
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   955
            fields.append(field)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   956
    fields = set(fields)
16444
432f198600c6 revset: make matching keyword not match summary when matching for description
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16417
diff changeset
   957
    if 'summary' in fields and 'description' in fields:
432f198600c6 revset: make matching keyword not match summary when matching for description
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16417
diff changeset
   958
        # If a revision matches its description it also matches its summary
432f198600c6 revset: make matching keyword not match summary when matching for description
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16417
diff changeset
   959
        fields.discard('summary')
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   960
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   961
    # We may want to match more than one field
16446
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   962
    # Not all fields take the same amount of time to be matched
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   963
    # Sort the selected fields in order of increasing matching cost
16453
d2a865d4b963 revset: make matching() work on python 2.4
Patrick Mezard <patrick@mezard.eu>
parents: 16452
diff changeset
   964
    fieldorder = ['phase', 'parents', 'user', 'date', 'branch', 'summary',
d2a865d4b963 revset: make matching() work on python 2.4
Patrick Mezard <patrick@mezard.eu>
parents: 16452
diff changeset
   965
        'files', 'description', 'substate']
16446
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   966
    def fieldkeyfunc(f):
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   967
        try:
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   968
            return fieldorder.index(f)
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   969
        except ValueError:
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   970
            # assume an unknown field is very costly
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   971
            return len(fieldorder)
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   972
    fields = list(fields)
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   973
    fields.sort(key=fieldkeyfunc)
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
   974
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   975
    # Each field will be matched with its own "getfield" function
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   976
    # which will be added to the getfieldfuncs array of functions
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   977
    getfieldfuncs = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   978
    _funcs = {
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   979
        'user': lambda r: repo[r].user(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   980
        'branch': lambda r: repo[r].branch(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   981
        'date': lambda r: repo[r].date(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   982
        'description': lambda r: repo[r].description(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   983
        'files': lambda r: repo[r].files(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   984
        'parents': lambda r: repo[r].parents(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   985
        'phase': lambda r: repo[r].phase(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   986
        'substate': lambda r: repo[r].substate,
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   987
        'summary': lambda r: repo[r].description().splitlines()[0],
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   988
    }
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   989
    for info in fields:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   990
        getfield = _funcs.get(info, None)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   991
        if getfield is None:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   992
            raise error.ParseError(
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   993
                _("unexpected field name passed to matching: %s") % info)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   994
        getfieldfuncs.append(getfield)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   995
    # convert the getfield array of functions into a "getinfo" function
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   996
    # which returns an array of field values (or a single value if there
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   997
    # is only one field to match)
16445
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
   998
    getinfo = lambda r: [f(r) for f in getfieldfuncs]
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
   999
16640
592e0beee8b0 revset: make matching() preserve input revision order
Patrick Mezard <patrick@mezard.eu>
parents: 16639
diff changeset
  1000
    matches = set()
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1001
    for rev in revs:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1002
        target = getinfo(rev)
16445
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1003
        for r in subset:
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1004
            match = True
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1005
            for n, f in enumerate(getfieldfuncs):
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1006
                if target[n] != f(r):
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1007
                    match = False
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1008
                    break
453c8670566c revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16444
diff changeset
  1009
            if match:
16640
592e0beee8b0 revset: make matching() preserve input revision order
Patrick Mezard <patrick@mezard.eu>
parents: 16639
diff changeset
  1010
                matches.add(r)
592e0beee8b0 revset: make matching() preserve input revision order
Patrick Mezard <patrick@mezard.eu>
parents: 16639
diff changeset
  1011
    return [r for r in subset if r in matches]
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1012
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1013
def reverse(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1014
    """``reverse(set)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1015
    Reverse order of set.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1016
    """
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1017
    l = getset(repo, subset, x)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1018
    l.reverse()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1019
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1020
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1021
def roots(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1022
    """``roots(set)``
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1023
    Changesets in set with no parent changeset in set.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1024
    """
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1025
    s = set(getset(repo, xrange(len(repo)), x))
16395
c3fd35f88fbb revset: retrieve a bit less parents in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16394
diff changeset
  1026
    subset = [r for r in subset if r in s]
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1027
    cs = _children(repo, subset, s)
16395
c3fd35f88fbb revset: retrieve a bit less parents in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16394
diff changeset
  1028
    return [r for r in subset if r not in cs]
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1029
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1030
def secret(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1031
    """``secret()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1032
    Changeset in secret phase."""
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1033
    getargs(x, 0, 0, _("secret takes no arguments"))
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1034
    return [r for r in subset if repo._phaserev[r] == phases.secret]
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1035
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1036
def sort(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1037
    """``sort(set[, [-]key...])``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1038
    Sort set by keys. The default sort order is ascending, specify a key
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1039
    as ``-key`` to sort in descending order.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1040
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1041
    The keys can be:
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1042
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1043
    - ``rev`` for the revision number,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1044
    - ``branch`` for the branch name,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1045
    - ``desc`` for the commit message (description),
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1046
    - ``user`` for user name (``author`` can be used as an alias),
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1047
    - ``date`` for the commit date
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1048
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1049
    # i18n: "sort" is a keyword
12736
7e14e67e6622 revset: use 'requires' instead of 'wants' in error message
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12733
diff changeset
  1050
    l = getargs(x, 1, 2, _("sort requires one or two arguments"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1051
    keys = "rev"
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1052
    if len(l) == 2:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1053
        keys = getstring(l[1], _("sort spec must be a string"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1054
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1055
    s = l[0]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1056
    keys = keys.split()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1057
    l = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1058
    def invert(s):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1059
        return "".join(chr(255 - ord(c)) for c in s)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1060
    for r in getset(repo, subset, s):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1061
        c = repo[r]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1062
        e = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1063
        for k in keys:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1064
            if k == 'rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1065
                e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1066
            elif k == '-rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1067
                e.append(-r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1068
            elif k == 'branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1069
                e.append(c.branch())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1070
            elif k == '-branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1071
                e.append(invert(c.branch()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1072
            elif k == 'desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1073
                e.append(c.description())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1074
            elif k == '-desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1075
                e.append(invert(c.description()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1076
            elif k in 'user author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1077
                e.append(c.user())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1078
            elif k in '-user -author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1079
                e.append(invert(c.user()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1080
            elif k == 'date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1081
                e.append(c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1082
            elif k == '-date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1083
                e.append(-c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1084
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1085
                raise error.ParseError(_("unknown sort key %r") % k)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1086
        e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1087
        l.append(e)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1088
    l.sort()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1089
    return [e[-1] for e in l]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1090
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1091
def tag(repo, subset, x):
14356
02a5bebd0dc4 revset: the name is optional for the tag predicate
Martin Geisler <mg@aragost.com>
parents: 14355
diff changeset
  1092
    """``tag([name])``
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1093
    The specified tag by name, or all tagged revisions if no name is given.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1094
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1095
    # i18n: "tag" is a keyword
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1096
    args = getargs(x, 0, 1, _("tag takes one or no arguments"))
11280
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  1097
    cl = repo.changelog
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1098
    if args:
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1099
        tn = getstring(args[0],
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1100
                       # i18n: "tag" is a keyword
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1101
                       _('the argument to tag must be a string'))
13914
27573f2ddfb9 revset: abort when tag or bookmark doesn't exist
Idan Kamara <idankk86@gmail.com>
parents: 13908
diff changeset
  1102
        if not repo.tags().get(tn, None):
27573f2ddfb9 revset: abort when tag or bookmark doesn't exist
Idan Kamara <idankk86@gmail.com>
parents: 13908
diff changeset
  1103
            raise util.Abort(_("tag '%s' does not exist") % tn)
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1104
        s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1105
    else:
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1106
        s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
11280
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  1107
    return [r for r in subset if r in s]
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  1108
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1109
def tagged(repo, subset, x):
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1110
    return tag(repo, subset, x)
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1111
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1112
def user(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1113
    """``user(string)``
14357
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
  1114
    User name contains string. The match is case-insensitive.
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1115
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1116
    return author(repo, subset, x)
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1117
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1118
# for internal use
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1119
def _list(repo, subset, x):
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1120
    s = getstring(x, "internal error")
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1121
    if not s:
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1122
        return []
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1123
    if not isinstance(subset, set):
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1124
        subset = set(subset)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1125
    ls = [repo[r].rev() for r in s.split('\0')]
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1126
    return [r for r in ls if r in subset]
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1127
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1128
symbols = {
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1129
    "adds": adds,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1130
    "all": getall,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1131
    "ancestor": ancestor,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1132
    "ancestors": ancestors,
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
  1133
    "_firstancestors": _firstancestors,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1134
    "author": author,
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
  1135
    "bisect": bisect,
13602
54b198fe9768 revset: add a revset command to get bisect state.
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13593
diff changeset
  1136
    "bisected": bisected,
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1137
    "bookmark": bookmark,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1138
    "branch": branch,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1139
    "children": children,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1140
    "closed": closed,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1141
    "contains": contains,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1142
    "date": date,
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
  1143
    "desc": desc,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1144
    "descendants": descendants,
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
  1145
    "_firstdescendants": _firstdescendants,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1146
    "draft": draft,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1147
    "file": hasfile,
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1148
    "filelog": filelog,
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1149
    "first": first,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1150
    "follow": follow,
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
  1151
    "_followfirst": _followfirst,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1152
    "grep": grep,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1153
    "head": head,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1154
    "heads": heads,
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1155
    "id": node_,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1156
    "keyword": keyword,
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1157
    "last": last,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1158
    "limit": limit,
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1159
    "_matchfiles": _matchfiles,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1160
    "max": maxrev,
14649
a6a8809c6e33 revset: update sorting of symbols
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14556
diff changeset
  1161
    "merge": merge,
11708
ba65d61f3158 revset: add min function
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11650
diff changeset
  1162
    "min": minrev,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1163
    "modifies": modifies,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1164
    "outgoing": outgoing,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1165
    "p1": p1,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1166
    "p2": p2,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1167
    "parents": parents,
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1168
    "present": present,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1169
    "public": public,
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1170
    "remote": remote,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1171
    "removes": removes,
14649
a6a8809c6e33 revset: update sorting of symbols
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14556
diff changeset
  1172
    "rev": rev,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1173
    "reverse": reverse,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1174
    "roots": roots,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1175
    "sort": sort,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1176
    "secret": secret,
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1177
    "matching": matching,
12715
33820dccbea4 revset: rename tagged() to tag() and allow it to take an optional tag name
Augie Fackler <durin42@gmail.com>
parents: 12616
diff changeset
  1178
    "tag": tag,
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1179
    "tagged": tagged,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1180
    "user": user,
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1181
    "_list": _list,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1182
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1183
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1184
methods = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1185
    "range": rangeset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1186
    "string": stringset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1187
    "symbol": symbolset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1188
    "and": andset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1189
    "or": orset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1190
    "not": notset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1191
    "list": listset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1192
    "func": func,
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1193
    "ancestor": ancestorspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1194
    "parent": parentspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1195
    "parentpost": p1,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1196
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1197
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1198
def optimize(x, small):
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12936
diff changeset
  1199
    if x is None:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1200
        return 0, x
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1201
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1202
    smallbonus = 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1203
    if small:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1204
        smallbonus = .5
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1205
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1206
    op = x[0]
11283
a6356b2695a3 revset: fix - handling in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 11282
diff changeset
  1207
    if op == 'minus':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1208
        return optimize(('and', x[1], ('not', x[2])), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1209
    elif op == 'dagrange':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1210
        return optimize(('and', ('func', ('symbol', 'descendants'), x[1]),
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1211
                         ('func', ('symbol', 'ancestors'), x[2])), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1212
    elif op == 'dagrangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1213
        return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1214
    elif op == 'dagrangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1215
        return optimize(('func', ('symbol', 'descendants'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1216
    elif op == 'rangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1217
        return optimize(('range', ('string', '0'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1218
    elif op == 'rangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1219
        return optimize(('range', x[1], ('string', 'tip')), small)
11467
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  1220
    elif op == 'negate':
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  1221
        return optimize(('string',
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  1222
                         '-' + getstring(x[1], _("can't negate that"))), small)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1223
    elif op in 'string symbol negate':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1224
        return smallbonus, x # single revisions are small
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1225
    elif op == 'and' or op == 'dagrange':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1226
        wa, ta = optimize(x[1], True)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1227
        wb, tb = optimize(x[2], True)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1228
        w = min(wa, wb)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1229
        if wa > wb:
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1230
            return w, (op, tb, ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1231
        return w, (op, ta, tb)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1232
    elif op == 'or':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1233
        wa, ta = optimize(x[1], False)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1234
        wb, tb = optimize(x[2], False)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1235
        if wb < wa:
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1236
            wb, wa = wa, wb
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1237
        return max(wa, wb), (op, ta, tb)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1238
    elif op == 'not':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1239
        o = optimize(x[1], not small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1240
        return o[0], (op, o[1])
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1241
    elif op == 'parentpost':
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1242
        o = optimize(x[1], small)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1243
        return o[0], (op, o[1])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1244
    elif op == 'group':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1245
        return optimize(x[1], small)
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1246
    elif op in 'range list parent ancestorspec':
14842
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1247
        if op == 'parent':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1248
            # x^:y means (x^) : y, not x ^ (:y)
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1249
            post = ('parentpost', x[1])
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1250
            if x[2][0] == 'dagrangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1251
                return optimize(('dagrange', post, x[2][1]), small)
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1252
            elif x[2][0] == 'rangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1253
                return optimize(('range', post, x[2][1]), small)
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1254
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1255
        wa, ta = optimize(x[1], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1256
        wb, tb = optimize(x[2], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1257
        return wa + wb, (op, ta, tb)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1258
    elif op == 'func':
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1259
        f = getstring(x[1], _("not a symbol"))
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1260
        wa, ta = optimize(x[2], small)
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
  1261
        if f in ("author branch closed date desc file grep keyword "
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
  1262
                 "outgoing user"):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1263
            w = 10 # slow
12351
b913232d13c1 revsets: reduce cost of outgoing in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 12321
diff changeset
  1264
        elif f in "modifies adds removes":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1265
            w = 30 # slower
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1266
        elif f == "contains":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1267
            w = 100 # very slow
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1268
        elif f == "ancestor":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1269
            w = 1 * smallbonus
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1270
        elif f in "reverse limit first":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1271
            w = 0
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1272
        elif f in "sort":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1273
            w = 10 # assume most sorts look at changelog
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1274
        else:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1275
            w = 1
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1276
        return w + wa, (op, x[1], ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1277
    return 1, x
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1278
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1279
class revsetalias(object):
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1280
    funcre = re.compile('^([^(]+)\(([^)]+)\)$')
14723
b9faf94ee196 revset: fix aliases with 0 or more than 2 parameters
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
  1281
    args = None
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1282
14723
b9faf94ee196 revset: fix aliases with 0 or more than 2 parameters
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
  1283
    def __init__(self, name, value):
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1284
        '''Aliases like:
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1285
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1286
        h = heads(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1287
        b($1) = ancestors($1) - ancestors(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1288
        '''
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1289
        m = self.funcre.search(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1290
        if m:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1291
            self.name = m.group(1)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1292
            self.tree = ('func', ('symbol', m.group(1)))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1293
            self.args = [x.strip() for x in m.group(2).split(',')]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1294
            for arg in self.args:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1295
                value = value.replace(arg, repr(arg))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1296
        else:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1297
            self.name = name
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1298
            self.tree = ('symbol', name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1299
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1300
        self.replacement, pos = parse(value)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1301
        if pos != len(value):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1302
            raise error.ParseError(_('invalid token'), pos)
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1303
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1304
def _getalias(aliases, tree):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1305
    """If tree looks like an unexpanded alias, return it. Return None
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1306
    otherwise.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1307
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1308
    if isinstance(tree, tuple) and tree:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1309
        if tree[0] == 'symbol' and len(tree) == 2:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1310
            name = tree[1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1311
            alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1312
            if alias and alias.args is None and alias.tree == tree:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1313
                return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1314
        if tree[0] == 'func' and len(tree) > 1:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1315
            if tree[1][0] == 'symbol' and len(tree[1]) == 2:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1316
                name = tree[1][1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1317
                alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1318
                if alias and alias.args is not None and alias.tree == tree[:2]:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1319
                    return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1320
    return None
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1321
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1322
def _expandargs(tree, args):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1323
    """Replace all occurences of ('string', name) with the
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1324
    substitution value of the same name in args, recursively.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1325
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1326
    if not isinstance(tree, tuple):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1327
        return tree
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1328
    if len(tree) == 2 and tree[0] == 'string':
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1329
        return args.get(tree[1], tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1330
    return tuple(_expandargs(t, args) for t in tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1331
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1332
def _expandaliases(aliases, tree, expanding):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1333
    """Expand aliases in tree, recursively.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1334
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1335
    'aliases' is a dictionary mapping user defined aliases to
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1336
    revsetalias objects.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1337
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1338
    if not isinstance(tree, tuple):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1339
        # Do not expand raw strings
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1340
        return tree
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1341
    alias = _getalias(aliases, tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1342
    if alias is not None:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1343
        if alias in expanding:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1344
            raise error.ParseError(_('infinite expansion of revset alias "%s" '
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1345
                                     'detected') % alias.name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1346
        expanding.append(alias)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1347
        result = alias.replacement
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1348
        if alias.args is not None:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1349
            l = getlist(tree[2])
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1350
            if len(l) != len(alias.args):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1351
                raise error.ParseError(
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1352
                    _('invalid number of arguments: %s') % len(l))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1353
            result = _expandargs(result, dict(zip(alias.args, l)))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1354
        # Recurse in place, the base expression may have been rewritten
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1355
        result = _expandaliases(aliases, result, expanding)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1356
        expanding.pop()
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1357
    else:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1358
        result = tuple(_expandaliases(aliases, t, expanding)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1359
                       for t in tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1360
    return result
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1361
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1362
def findaliases(ui, tree):
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1363
    aliases = {}
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1364
    for k, v in ui.configitems('revsetalias'):
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1365
        alias = revsetalias(k, v)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1366
        aliases[alias.name] = alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1367
    return _expandaliases(aliases, tree, [])
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1368
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1369
parse = parser.parser(tokenize, elements).parse
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1370
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1371
def match(ui, spec):
11385
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  1372
    if not spec:
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  1373
        raise error.ParseError(_("empty query"))
14496
ffcb7e4d719f revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents: 14356
diff changeset
  1374
    tree, pos = parse(spec)
ffcb7e4d719f revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents: 14356
diff changeset
  1375
    if (pos != len(spec)):
14701
4b93bd041772 parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents: 14650
diff changeset
  1376
        raise error.ParseError(_("invalid token"), pos)
14900
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  1377
    if ui:
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  1378
        tree = findaliases(ui, tree)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1379
    weight, tree = optimize(tree, True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1380
    def mfunc(repo, subset):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1381
        return getset(repo, subset, tree)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1382
    return mfunc
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1383
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1384
def formatspec(expr, *args):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1385
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1386
    This is a convenience function for using revsets internally, and
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1387
    escapes arguments appropriately. Aliases are intentionally ignored
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1388
    so that intended expression behavior isn't accidentally subverted.
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1389
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1390
    Supported arguments:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1391
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  1392
    %r = revset expression, parenthesized
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1393
    %d = int(arg), no quoting
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1394
    %s = string(arg), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1395
    %b = arg.branch(), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1396
    %n = hex(arg), single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1397
    %% = a literal '%'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1398
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  1399
    Prefixing the type with 'l' specifies a parenthesized list of that type.
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1400
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  1401
    >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  1402
    '(10 or 11):: and ((this()) or (that()))'
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1403
    >>> formatspec('%d:: and not %d::', 10, 20)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1404
    '10:: and not 20::'
15325
cdf1daa3b83f revset: deal with empty lists in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15268
diff changeset
  1405
    >>> formatspec('%ld or %ld', [], [1])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1406
    "_list('') or 1"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1407
    >>> formatspec('keyword(%s)', 'foo\\xe9')
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1408
    "keyword('foo\\\\xe9')"
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1409
    >>> b = lambda: 'default'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1410
    >>> b.branch = b
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1411
    >>> formatspec('branch(%b)', b)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1412
    "branch('default')"
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1413
    >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1414
    "root(_list('a\\x00b\\x00c\\x00d'))"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1415
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1416
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1417
    def quote(s):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1418
        return repr(str(s))
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1419
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1420
    def argtype(c, arg):
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1421
        if c == 'd':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1422
            return str(int(arg))
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1423
        elif c == 's':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1424
            return quote(arg)
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  1425
        elif c == 'r':
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  1426
            parse(arg) # make sure syntax errors are confined
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  1427
            return '(%s)' % arg
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1428
        elif c == 'n':
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1429
            return quote(node.hex(arg))
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1430
        elif c == 'b':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1431
            return quote(arg.branch())
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1432
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1433
    def listexp(s, t):
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1434
        l = len(s)
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1435
        if l == 0:
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1436
            return "_list('')"
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1437
        elif l == 1:
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1438
            return argtype(t, s[0])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1439
        elif t == 'd':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1440
            return "_list('%s')" % "\0".join(str(int(a)) for a in s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1441
        elif t == 's':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1442
            return "_list('%s')" % "\0".join(s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1443
        elif t == 'n':
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1444
            return "_list('%s')" % "\0".join(node.hex(a) for a in s)
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1445
        elif t == 'b':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1446
            return "_list('%s')" % "\0".join(a.branch() for a in s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1447
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15726
diff changeset
  1448
        m = l // 2
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1449
        return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  1450
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1451
    ret = ''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1452
    pos = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1453
    arg = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1454
    while pos < len(expr):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1455
        c = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1456
        if c == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1457
            pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1458
            d = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1459
            if d == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1460
                ret += d
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  1461
            elif d in 'dsnbr':
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1462
                ret += argtype(d, args[arg])
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1463
                arg += 1
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1464
            elif d == 'l':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1465
                # a list of some type
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1466
                pos += 1
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  1467
                d = expr[pos]
15596
2555f441a32f merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15595
diff changeset
  1468
                ret += listexp(list(args[arg]), d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1469
                arg += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1470
            else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1471
                raise util.Abort('unexpected revspec format character %s' % d)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1472
        else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1473
            ret += c
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1474
        pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1475
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1476
    return ret
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  1477
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1478
def prettyformat(tree):
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1479
    def _prettyformat(tree, level, lines):
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1480
        if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1481
            lines.append((level, str(tree)))
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1482
        else:
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1483
            lines.append((level, '(%s' % tree[0]))
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1484
            for s in tree[1:]:
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1485
                _prettyformat(s, level + 1, lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1486
            lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')]
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1487
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1488
    lines = []
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1489
    _prettyformat(tree, 0, lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1490
    output = '\n'.join(('  '*l + s) for l, s in lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1491
    return output
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  1492
12823
80deae3bc5ea hggettext: handle i18nfunctions declaration for docstrings translations
Patrick Mezard <pmezard@gmail.com>
parents: 12821
diff changeset
  1493
# tell hggettext to extract docstrings from these functions:
80deae3bc5ea hggettext: handle i18nfunctions declaration for docstrings translations
Patrick Mezard <pmezard@gmail.com>
parents: 12821
diff changeset
  1494
i18nfunctions = symbols.values()