mercurial/revset.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Mon, 29 Dec 2014 23:40:24 -0800
changeset 23704 c624fb2c4239
parent 23467 c237499a7fba
child 23719 34364a4b25eb
permissions -rw-r--r--
linkrev: also adjust linkrev when bootstrapping 'follow' revset The follow revset (used by `hg log --follow`) now uses the new 'introrev' method to bootstrap its traversal. This catches issues from linkrev-shadowing of the changesets introducing the version of a file in source changeset. A new test has been added to display pathological cases. Another test is affected because it was meant to test this behavior but actually failed to do so for half of the output. The output are now similar.
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
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16825
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
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    11
import heapq
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
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
    15
import obsolete as obsmod
20286
760151697a4f revset: make default kind of pattern for "contains()" rooted at cwd
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20285
diff changeset
    16
import pathutil
18251
a6483f827512 revset: retrieve hidden from filteredrevs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18071
diff changeset
    17
import repoview
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    19
def _revancestors(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    20
    """Like revlog.ancestors(), but supports followfirst."""
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    21
    cut = followfirst and 1 or None
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    22
    cl = repo.changelog
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    23
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    24
    def iterate():
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    25
        revqueue, revsnode = None, None
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    26
        h = []
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    27
22832
2f1d2a42f040 revancestors: replace `descending` with `sort(reverse=False)`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22831
diff changeset
    28
        revs.sort(reverse=True)
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    29
        revqueue = util.deque(revs)
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    30
        if revqueue:
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    31
            revsnode = revqueue.popleft()
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    32
            heapq.heappush(h, -revsnode)
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    33
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    34
        seen = set([node.nullrev])
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    35
        while h:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    36
            current = -heapq.heappop(h)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    37
            if current not in seen:
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    38
                if revsnode and current == revsnode:
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    39
                    if revqueue:
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    40
                        revsnode = revqueue.popleft()
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    41
                        heapq.heappush(h, -revsnode)
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    42
                seen.add(current)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    43
                yield current
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    44
                for parent in cl.parentrevs(current)[:cut]:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    45
                    if parent != node.nullrev:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    46
                        heapq.heappush(h, -parent)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    47
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    48
    return generatorset(iterate(), iterasc=False)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    49
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    50
def _revdescendants(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    51
    """Like revlog.descendants() but supports followfirst."""
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    52
    cut = followfirst and 1 or None
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    53
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    54
    def iterate():
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    55
        cl = repo.changelog
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    56
        first = min(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    57
        nullrev = node.nullrev
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    58
        if first == nullrev:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    59
            # Are there nodes with a null first parent and a non-null
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    60
            # second one? Maybe. Do we care? Probably not.
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    61
            for i in cl:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    62
                yield i
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    63
        else:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    64
            seen = set(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    65
            for i in cl.revs(first + 1):
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    66
                for x in cl.parentrevs(i)[:cut]:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    67
                    if x != nullrev and x in seen:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    68
                        seen.add(i)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    69
                        yield i
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    70
                        break
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    71
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    72
    return generatorset(iterate(), iterasc=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    73
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    74
def _revsbetween(repo, roots, heads):
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    75
    """Return all paths between roots and heads, inclusive of both endpoint
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    76
    sets."""
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    77
    if not roots:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
    78
        return baseset()
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    79
    parentrevs = repo.changelog.parentrevs
22487
e40bb83d0989 revset: stop using a baseset instead of a plain list in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22483
diff changeset
    80
    visit = list(heads)
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    81
    reachable = set()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    82
    seen = {}
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    83
    minroot = min(roots)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    84
    roots = set(roots)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    85
    # open-code the post-order traversal due to the tiny size of
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    86
    # sys.getrecursionlimit()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    87
    while visit:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    88
        rev = visit.pop()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    89
        if rev in roots:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    90
            reachable.add(rev)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    91
        parents = parentrevs(rev)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    92
        seen[rev] = parents
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    93
        for parent in parents:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    94
            if parent >= minroot and parent not in seen:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    95
                visit.append(parent)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    96
    if not reachable:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
    97
        return baseset()
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    98
    for rev in sorted(seen):
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    99
        for parent in seen[rev]:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   100
            if parent in reachable:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   101
                reachable.add(rev)
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
   102
    return baseset(sorted(reachable))
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   103
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
elements = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
    "(": (20, ("group", 1, ")"), ("func", 1, ")")),
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   106
    "~": (18, None, ("ancestor", 18)),
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   107
    "^": (18, None, ("parent", 18), ("parentpost", 18)),
12616
e797fdf91df4 revset: lower precedence of minus infix (issue2361)
Matt Mackall <mpm@selenic.com>
parents: 12615
diff changeset
   108
    "-": (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
   109
    "::": (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
   110
           ("dagrangepost", 17)),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   111
    "..": (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
   112
           ("dagrangepost", 17)),
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   113
    ":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
    "not": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
    "!": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
    "and": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
    "&": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
    "or": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
    "|": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
    "+": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
    ",": (2, None, ("list", 2)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
    ")": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
    "symbol": (0, ("symbol",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   124
    "string": (0, ("string",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
    "end": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   129
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
   130
def tokenize(program, lookup=None):
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   131
    '''
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   132
    Parse a revset statement into a stream of tokens
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   133
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   134
    Check that @ is a valid unquoted token character (issue3686):
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   135
    >>> list(tokenize("@::"))
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   136
    [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   137
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   138
    '''
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   139
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   142
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
            pass
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   145
        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
   146
            yield ('::', None, pos)
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   147
            pos += 1 # skip ahead
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
        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
   149
            yield ('..', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   150
            pos += 1 # skip ahead
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   151
        elif c in "():,-|&+!~^": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   152
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   153
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   154
              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
   155
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   156
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   157
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   158
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   159
            else:
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   160
                decode = lambda x: x.decode('string-escape')
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   161
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   163
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   164
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   167
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   169
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   170
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   172
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   173
                raise error.ParseError(_("unterminated string"), s)
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   174
        # gather up a symbol/keyword
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   175
        elif c.isalnum() or c in '._@' or ord(c) > 127:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   177
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   178
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
                d = program[pos]
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   180
                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
   181
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
                if d == '.' and program[pos - 1] == '.': # special case for ..
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   183
                    pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   184
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   185
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   187
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   188
                yield (sym, None, s)
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   189
            elif '-' in sym:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   190
                # some jerk gave us foo-bar-baz, try to check if it's a symbol
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   191
                if lookup and lookup(sym):
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   192
                    # looks like a real symbol
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   193
                    yield ('symbol', sym, s)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   194
                else:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   195
                    # looks like an expression
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   196
                    parts = sym.split('-')
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   197
                    for p in parts[:-1]:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   198
                        if p: # possible consecutive -
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   199
                            yield ('symbol', p, s)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   200
                        s += len(p)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   201
                        yield ('-', None, pos)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   202
                        s += 1
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   203
                    if parts[-1]: # possible trailing -
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   204
                        yield ('symbol', parts[-1], s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   205
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   206
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   207
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   208
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   209
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   211
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   213
# helpers
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   214
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   215
def getstring(x, err):
11406
42408cd43f55 revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents: 11404
diff changeset
   216
    if x and (x[0] == 'string' or x[0] == 'symbol'):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
        return x[1]
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   218
    raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   219
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
def getlist(x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   221
    if not x:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   222
        return []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   223
    if x[0] == 'list':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   224
        return getlist(x[1]) + [x[2]]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   225
    return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   226
11339
744d5b73f776 revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents: 11304
diff changeset
   227
def getargs(x, min, max, err):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   228
    l = getlist(x)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   229
    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
   230
        raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   231
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   232
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   233
def getset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   234
    if not x:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   235
        raise error.ParseError(_("missing argument"))
20527
bde426f18e0a revset: changed mfunc and getset to work with old style revset methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20526
diff changeset
   236
    s = methods[x[0]](repo, subset, *x[1:])
22884
4584eec9aead getset: check if an object is a baseset using `isascending` instead of `set`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22883
diff changeset
   237
    if util.safehasattr(s, 'isascending'):
20527
bde426f18e0a revset: changed mfunc and getset to work with old style revset methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20526
diff changeset
   238
        return s
bde426f18e0a revset: changed mfunc and getset to work with old style revset methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20526
diff changeset
   239
    return baseset(s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   240
17003
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   241
def _getrevsource(repo, r):
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   242
    extra = repo[r].extra()
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   243
    for label in ('source', 'transplant_source', 'rebase_source'):
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   244
        if label in extra:
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   245
            try:
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   246
                return repo[extra[label]].rev()
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   247
            except error.RepoLookupError:
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   248
                pass
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   249
    return None
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   250
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   251
# operator methods
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   252
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   253
def stringset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   254
    x = repo[x].rev()
11282
e581f3acc338 revset: fix up tests
Matt Mackall <mpm@selenic.com>
parents: 11280
diff changeset
   255
    if x == -1 and len(subset) == len(repo):
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
   256
        return baseset([-1])
13938
e44ebd2a142a revset: optimize stringset when subset == entire repo
Idan Kamara <idankk86@gmail.com>
parents: 13932
diff changeset
   257
    if len(subset) == len(repo) or x in subset:
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
   258
        return baseset([x])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   259
    return baseset()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   260
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   261
def symbolset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   262
    if x in symbols:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   263
        raise error.ParseError(_("can't use %s here") % x)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   264
    return stringset(repo, subset, x)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   265
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   266
def rangeset(repo, subset, x, y):
23162
69524a05a7fa revset-rangeset: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   267
    m = getset(repo, fullreposet(repo), x)
69524a05a7fa revset-rangeset: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   268
    n = getset(repo, fullreposet(repo), y)
11456
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   269
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   270
    if not m or not n:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   271
        return baseset()
22817
e4eb4bfc3616 rangeset: use `first` and `last` instead of direct indexing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22813
diff changeset
   272
    m, n = m.first(), n.last()
11456
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   273
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   274
    if m < n:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   275
        r = spanset(repo, m, n + 1)
11456
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   276
    else:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   277
        r = spanset(repo, m, n - 1)
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   278
    return r & subset
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   279
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
   280
def dagrange(repo, subset, x, y):
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   281
    r = spanset(repo)
18991
c1af1fb314bc log: fix behavior with empty repositories (issue3497)
Alexander Plavin <me@aplavin.ru>
parents: 18779
diff changeset
   282
    xs = _revsbetween(repo, getset(repo, r, x), getset(repo, r, y))
22866
6e739356f9bf revset-rangeset: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22865
diff changeset
   283
    return xs & subset
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
   284
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   285
def andset(repo, subset, x, y):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   286
    return getset(repo, getset(repo, subset, x), y)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   287
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   288
def orset(repo, subset, x, y):
13932
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   289
    xl = getset(repo, subset, x)
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   290
    yl = getset(repo, subset - xl, y)
13932
34f577007ffe revsets: preserve ordering with the or operator
Augie Fackler <durin42@gmail.com>
parents: 13915
diff changeset
   291
    return xl + yl
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   292
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   293
def notset(repo, subset, x):
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   294
    return subset - getset(repo, subset, x)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   295
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   296
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
   297
    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
   298
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   299
def func(repo, subset, a, b):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   300
    if a[0] == 'symbol' and a[1] in symbols:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   301
        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
   302
    raise error.ParseError(_("not a function: %s") % a[1])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   303
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   304
# functions
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   305
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   306
def adds(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   307
    """``adds(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   308
    Changesets that add a file matching pattern.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   309
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   310
    The pattern without explicit kind like ``glob:`` is expected to be
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   311
    relative to the current directory and match against a file or a
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   312
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   313
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   314
    # i18n: "adds" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   315
    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
   316
    return checkstatus(repo, subset, pat, 1)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   317
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   318
def ancestor(repo, subset, x):
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   319
    """``ancestor(*changeset)``
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   320
    A greatest common ancestor of the changesets.
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   321
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   322
    Accepts 0 or more changesets.
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   323
    Will return empty list when passed no args.
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   324
    Greatest common ancestor of a single changeset is that changeset.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   325
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   326
    # i18n: "ancestor" is a keyword
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   327
    l = getlist(x)
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   328
    rl = spanset(repo)
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   329
    anc = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   330
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   331
    # (getset(repo, rl, i) for i in l) generates a list of lists
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   332
    for revs in (getset(repo, rl, i) for i in l):
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   333
        for r in revs:
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   334
            if anc is None:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   335
                anc = repo[r]
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   336
            else:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   337
                anc = anc.ancestor(repo[r])
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   338
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   339
    if anc is not None and anc.rev() in subset:
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   340
        return baseset([anc.rev()])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   341
    return baseset()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   342
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   343
def _ancestors(repo, subset, x, followfirst=False):
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   344
    heads = getset(repo, spanset(repo), x)
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   345
    if not heads:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   346
        return baseset()
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   347
    s = _revancestors(repo, heads, followfirst)
23003
62d19ce9d7b6 revset-_ancestor: use & instead of filter
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22999
diff changeset
   348
    return subset & s
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   349
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   350
def ancestors(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   351
    """``ancestors(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   352
    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
   353
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   354
    return _ancestors(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   355
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   356
def _firstancestors(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   357
    # ``_firstancestors(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   358
    # 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
   359
    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
   360
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   361
def ancestorspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   362
    """``set~n``
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   363
    Changesets that are the Nth ancestor (first parents only) of a changeset
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   364
    in set.
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   365
    """
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   366
    try:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   367
        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
   368
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   369
        raise error.ParseError(_("~ expects a number"))
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   370
    ps = set()
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   371
    cl = repo.changelog
23163
6f1b8b3f12fd revset-ancestorspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23162
diff changeset
   372
    for r in getset(repo, fullreposet(repo), x):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   373
        for i in range(n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   374
            r = cl.parentrevs(r)[0]
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   375
        ps.add(r)
22531
22ba2c0825da revset: use `subset &` in `ancestorspec`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22530
diff changeset
   376
    return subset & ps
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   377
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   378
def author(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   379
    """``author(string)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   380
    Alias for ``user(string)``.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   381
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   382
    # 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
   383
    n = encoding.lower(getstring(x, _("author requires a string")))
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
   384
    kind, pattern, matcher = _substringmatcher(n)
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   385
    return subset.filter(lambda x: matcher(encoding.lower(repo[x].user())))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   386
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   387
def bisect(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   388
    """``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
   389
    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
   390
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   391
    - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17390
diff changeset
   392
    - ``goods``, ``bads``      : csets topologically good/bad
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   393
    - ``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
   394
    - ``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
   395
    - ``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
   396
    - ``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
   397
    - ``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
   398
    """
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   399
    # i18n: "bisect" is a keyword
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15134
diff changeset
   400
    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
   401
    state = set(hbisect.get(repo, status))
22532
0cf46b8298fe revset: use `subset &` in `bisect`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22531
diff changeset
   402
    return subset & state
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   403
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   404
# Backward-compatibility
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   405
# - 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
   406
def bisected(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   407
    return bisect(repo, subset, x)
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   408
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   409
def bookmark(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   410
    """``bookmark([name])``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   411
    The named bookmark or all bookmarks.
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   412
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   413
    If `name` starts with `re:`, the remainder of the name is treated as
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   414
    a regular expression. To match a bookmark that actually starts with `re:`,
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   415
    use the prefix `literal:`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   416
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   417
    # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   418
    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
   419
    if args:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   420
        bm = getstring(args[0],
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   421
                       # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   422
                       _('the argument to bookmark must be a string'))
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   423
        kind, pattern, matcher = _stringmatcher(bm)
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   424
        bms = set()
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   425
        if kind == 'literal':
22105
3efe3c2609e0 revset: bookmark revset interprets 'literal:' prefix correctly (issue4329)
Michael O'Connor <mkoconnor@gmail.com>
parents: 21939
diff changeset
   426
            bmrev = repo._bookmarks.get(pattern, None)
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   427
            if not bmrev:
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   428
                raise util.Abort(_("bookmark '%s' does not exist") % bm)
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   429
            bms.add(repo[bmrev].rev())
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   430
        else:
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   431
            matchrevs = set()
18495
8260fa9f30b9 bookmarks: don't use bookmarks.listbookmarks in local computations
Kevin Bullock <kbullock@ringworld.org>
parents: 18473
diff changeset
   432
            for name, bmrev in repo._bookmarks.iteritems():
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   433
                if matcher(name):
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   434
                    matchrevs.add(bmrev)
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   435
            if not matchrevs:
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   436
                raise util.Abort(_("no bookmarks exist that match '%s'")
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   437
                                 % pattern)
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   438
            for bmrev in matchrevs:
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   439
                bms.add(repo[bmrev].rev())
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   440
    else:
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   441
        bms = set([repo[r].rev()
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   442
                   for r in repo._bookmarks.values()])
22500
171015d3b30c revset: remove nullrev from the bookmark computation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22499
diff changeset
   443
    bms -= set([node.nullrev])
22530
faf4f63533ff revset: use `subset &` in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22529
diff changeset
   444
    return subset & bms
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   445
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   446
def branch(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   447
    """``branch(string or set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   448
    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
   449
    changesets.
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   450
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   451
    If `string` starts with `re:`, the remainder of the name is treated as
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   452
    a regular expression. To match a branch that actually starts with `re:`,
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   453
    use the prefix `literal:`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   454
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   455
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   456
        b = getstring(x, '')
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   457
    except error.ParseError:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   458
        # 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
   459
        pass
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   460
    else:
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   461
        kind, pattern, matcher = _stringmatcher(b)
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   462
        if kind == 'literal':
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   463
            # note: falls through to the revspec case if no branch with
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   464
            # this name exists
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   465
            if pattern in repo.branchmap():
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   466
                return subset.filter(lambda r: matcher(repo[r].branch()))
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   467
        else:
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   468
            return subset.filter(lambda r: matcher(repo[r].branch()))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   469
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   470
    s = getset(repo, spanset(repo), x)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   471
    b = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   472
    for r in s:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   473
        b.add(repo[r].branch())
22867
5ee9b78ce805 revset-branch: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22866
diff changeset
   474
    c = s.__contains__
5ee9b78ce805 revset-branch: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22866
diff changeset
   475
    return subset.filter(lambda r: c(r) or repo[r].branch() in b)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   476
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   477
def bumped(repo, subset, x):
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   478
    """``bumped()``
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   479
    Mutable changesets marked as successors of public changesets.
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   480
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   481
    Only non-public and non-obsolete changesets can be `bumped`.
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   482
    """
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   483
    # i18n: "bumped" is a keyword
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   484
    getargs(x, 0, 0, _("bumped takes no arguments"))
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   485
    bumped = obsmod.getrevs(repo, 'bumped')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   486
    return subset & bumped
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   487
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   488
def bundle(repo, subset, x):
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   489
    """``bundle()``
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   490
    Changesets in the bundle.
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   491
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   492
    Bundle must be specified by the -R option."""
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   493
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   494
    try:
18411
8b0f0dd56cec bundlerepo: improve performance for bundle() revset expression
Mads Kiilerich <madski@unity3d.com>
parents: 18382
diff changeset
   495
        bundlerevs = repo.changelog.bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   496
    except AttributeError:
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   497
        raise util.Abort(_("no bundle provided - specify with -R"))
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   498
    return subset & bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   499
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   500
def checkstatus(repo, subset, pat, field):
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   501
    hasset = matchmod.patkind(pat) == 'set'
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   502
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   503
    mcache = [None]
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   504
    def matches(x):
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   505
        c = repo[x]
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   506
        if not mcache[0] or hasset:
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   507
            mcache[0] = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   508
        m = mcache[0]
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   509
        fname = None
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   510
        if not m.anypats() and len(m.files()) == 1:
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   511
            fname = m.files()[0]
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   512
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   513
            if fname not in c.files():
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   514
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   515
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   516
            for f in c.files():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   517
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   518
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   519
            else:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   520
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   521
        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
   522
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   523
            if fname in files:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   524
                return True
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   525
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   526
            for f in files:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   527
                if m(f):
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   528
                    return True
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   529
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   530
    return subset.filter(matches)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   531
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   532
def _children(repo, narrow, parentset):
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   533
    cs = set()
18063
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   534
    if not parentset:
20709
71df845d86cf revsets: backout d04aac468bf4 due to performance regressions
Matt Mackall <mpm@selenic.com>
parents: 20708
diff changeset
   535
        return baseset(cs)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   536
    pr = repo.changelog.parentrevs
18063
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   537
    minrev = min(parentset)
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
   538
    for r in narrow:
18063
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   539
        if r <= minrev:
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   540
            continue
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   541
        for p in pr(r):
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   542
            if p in parentset:
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   543
                cs.add(r)
20709
71df845d86cf revsets: backout d04aac468bf4 due to performance regressions
Matt Mackall <mpm@selenic.com>
parents: 20708
diff changeset
   544
    return baseset(cs)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   545
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   546
def children(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   547
    """``children(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   548
    Child changesets of changesets in set.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   549
    """
23164
7a42e5d4c418 revset-children: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23163
diff changeset
   550
    s = getset(repo, fullreposet(repo), x)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   551
    cs = _children(repo, subset, s)
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   552
    return subset & cs
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   553
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   554
def closed(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   555
    """``closed()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   556
    Changeset is closed.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   557
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   558
    # i18n: "closed" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   559
    getargs(x, 0, 0, _("closed takes no arguments"))
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   560
    return subset.filter(lambda r: repo[r].closesbranch())
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   561
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   562
def contains(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   563
    """``contains(pattern)``
21199
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   564
    The revision's manifest contains a file matching pattern (but might not
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   565
    modify it). See :hg:`help patterns` for information about file patterns.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   566
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   567
    The pattern without explicit kind like ``glob:`` is expected to be
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   568
    relative to the current directory and match against a file exactly
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   569
    for efficiency.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   570
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   571
    # i18n: "contains" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   572
    pat = getstring(x, _("contains requires a pattern"))
20461
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   573
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   574
    def matches(x):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   575
        if not matchmod.patkind(pat):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   576
            pats = pathutil.canonpath(repo.root, repo.getcwd(), pat)
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   577
            if pats in repo[x]:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   578
                return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   579
        else:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   580
            c = repo[x]
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   581
            m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   582
            for f in c.manifest():
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   583
                if m(f):
20461
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   584
                    return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   585
        return False
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   586
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   587
    return subset.filter(matches)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   588
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   589
def converted(repo, subset, x):
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   590
    """``converted([id])``
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   591
    Changesets converted from the given identifier in the old repository if
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   592
    present, or all converted changesets if no identifier is specified.
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   593
    """
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   594
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   595
    # There is exactly no chance of resolving the revision, so do a simple
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   596
    # string compare and hope for the best
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   597
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   598
    rev = None
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   599
    # i18n: "converted" is a keyword
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   600
    l = getargs(x, 0, 1, _('converted takes one or no arguments'))
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   601
    if l:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   602
        # i18n: "converted" is a keyword
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   603
        rev = getstring(l[0], _('converted requires a revision'))
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   604
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   605
    def _matchvalue(r):
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   606
        source = repo[r].extra().get('convert_revision', None)
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   607
        return source is not None and (rev is None or source.startswith(rev))
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   608
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   609
    return subset.filter(lambda r: _matchvalue(r))
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   610
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   611
def date(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   612
    """``date(interval)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   613
    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
   614
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   615
    # i18n: "date" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   616
    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
   617
    dm = util.matchdate(ds)
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   618
    return subset.filter(lambda x: dm(repo[x].date()[0]))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   619
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   620
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
   621
    """``desc(string)``
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   622
    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
   623
    """
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   624
    # 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
   625
    ds = encoding.lower(getstring(x, _("desc requires a string")))
20452
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   626
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   627
    def matches(x):
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   628
        c = repo[x]
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   629
        return ds in encoding.lower(c.description())
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   630
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   631
    return subset.filter(matches)
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   632
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   633
def _descendants(repo, subset, x, followfirst=False):
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   634
    roots = getset(repo, spanset(repo), x)
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   635
    if not roots:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   636
        return baseset()
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   637
    s = _revdescendants(repo, roots, followfirst)
20894
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   638
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   639
    # Both sets need to be ascending in order to lazily return the union
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   640
    # in the correct order.
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   641
    base = subset & roots
22860
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   642
    desc = subset & s
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   643
    result = base + desc
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   644
    if subset.isascending():
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   645
        result.sort()
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   646
    elif subset.isdescending():
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   647
        result.sort(reverse=True)
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   648
    else:
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   649
        result = subset & result
22830
1d1da8abe130 _descendants: directly use smartset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22829
diff changeset
   650
    return result
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   651
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   652
def descendants(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   653
    """``descendants(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   654
    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
   655
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   656
    return _descendants(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   657
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   658
def _firstdescendants(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   659
    # ``_firstdescendants(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   660
    # 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
   661
    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
   662
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   663
def destination(repo, subset, x):
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   664
    """``destination([set])``
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   665
    Changesets that were created by a graft, transplant or rebase operation,
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   666
    with the given revisions specified as the source.  Omitting the optional set
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   667
    is the same as passing all().
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   668
    """
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   669
    if x is not None:
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   670
        sources = getset(repo, spanset(repo), x)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   671
    else:
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   672
        sources = getall(repo, spanset(repo), x)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   673
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   674
    dests = set()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   675
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   676
    # subset contains all of the possible destinations that can be returned, so
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   677
    # iterate over them and see if their source(s) were provided in the arg set.
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   678
    # Even if the immediate src of r is not in the arg set, src's source (or
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   679
    # further back) may be.  Scanning back further than the immediate src allows
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   680
    # transitive transplants and rebases to yield the same results as transitive
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   681
    # grafts.
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   682
    for r in subset:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   683
        src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   684
        lineage = None
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   685
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   686
        while src is not None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   687
            if lineage is None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   688
                lineage = list()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   689
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   690
            lineage.append(r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   691
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   692
            # The visited lineage is a match if the current source is in the arg
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   693
            # set.  Since every candidate dest is visited by way of iterating
17494
74801685aaa2 spelling: further
timeless@mozdev.org
parents: 17291
diff changeset
   694
            # subset, any dests further back in the lineage will be tested by a
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   695
            # different iteration over subset.  Likewise, if the src was already
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   696
            # selected, the current lineage can be selected without going back
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   697
            # further.
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   698
            if src in sources or src in dests:
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   699
                dests.update(lineage)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   700
                break
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   701
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   702
            r = src
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   703
            src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   704
21217
2195ac506c6a revset: directly use __contains__ instead of a lambda
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21215
diff changeset
   705
    return subset.filter(dests.__contains__)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   706
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   707
def divergent(repo, subset, x):
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   708
    """``divergent()``
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   709
    Final successors of changesets with an alternative set of final successors.
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   710
    """
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   711
    # i18n: "divergent" is a keyword
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   712
    getargs(x, 0, 0, _("divergent takes no arguments"))
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   713
    divergent = obsmod.getrevs(repo, 'divergent')
22533
5b65429721d5 revset: use `subset &` in `divergent`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22532
diff changeset
   714
    return subset & divergent
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   715
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   716
def draft(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   717
    """``draft()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   718
    Changeset in draft phase."""
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   719
    # i18n: "draft" is a keyword
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   720
    getargs(x, 0, 0, _("draft takes no arguments"))
23019
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
   721
    phase = repo._phasecache.phase
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
   722
    target = phases.draft
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
   723
    condition = lambda r: phase(repo, r) == target
23018
73d9d5548dfe revset-phases: do not cache phase-related filters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23005
diff changeset
   724
    return subset.filter(condition, cache=False)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   725
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   726
def extinct(repo, subset, x):
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   727
    """``extinct()``
17291
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
   728
    Obsolete changesets with obsolete descendants only.
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
   729
    """
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   730
    # i18n: "extinct" is a keyword
17258
5822345e9e46 revset: use appropriate predicate name in error messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17244
diff changeset
   731
    getargs(x, 0, 0, _("extinct takes no arguments"))
17825
3cc06457f15e obsolete: rename `getobscache` into `getrevs`
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17804
diff changeset
   732
    extincts = obsmod.getrevs(repo, 'extinct')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   733
    return subset & extincts
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   734
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   735
def extra(repo, subset, x):
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   736
    """``extra(label, [value])``
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   737
    Changesets with the given label in the extra metadata, with the given
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   738
    optional value.
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   739
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   740
    If `value` starts with `re:`, the remainder of the value is treated as
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   741
    a regular expression. To match a value that actually starts with `re:`,
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   742
    use the prefix `literal:`.
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   743
    """
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   744
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   745
    # i18n: "extra" is a keyword
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   746
    l = getargs(x, 1, 2, _('extra takes at least 1 and at most 2 arguments'))
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   747
    # i18n: "extra" is a keyword
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   748
    label = getstring(l[0], _('first argument to extra must be a string'))
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   749
    value = None
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   750
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   751
    if len(l) > 1:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   752
        # i18n: "extra" is a keyword
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   753
        value = getstring(l[1], _('second argument to extra must be a string'))
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   754
        kind, value, matcher = _stringmatcher(value)
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   755
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   756
    def _matchvalue(r):
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   757
        extra = repo[r].extra()
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   758
        return label in extra and (value is None or matcher(extra[label]))
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   759
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   760
    return subset.filter(lambda r: _matchvalue(r))
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   761
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   762
def filelog(repo, subset, x):
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   763
    """``filelog(pattern)``
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   764
    Changesets connected to the specified filelog.
17244
483aa765f6c4 revset: add explanation about difference between 'filelog()' and 'file()'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17186
diff changeset
   765
21199
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   766
    For performance reasons, visits only revisions mentioned in the file-level
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   767
    filelog, rather than filtering through all changesets (much faster, but
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   768
    doesn't include deletes or duplicate changes). For a slower, more accurate
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   769
    result, use ``file()``.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   770
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   771
    The pattern without explicit kind like ``glob:`` is expected to be
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   772
    relative to the current directory and match against a file exactly
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   773
    for efficiency.
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   774
    """
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   775
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   776
    # i18n: "filelog" is a keyword
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   777
    pat = getstring(x, _("filelog requires a pattern"))
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   778
    s = set()
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   779
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   780
    if not matchmod.patkind(pat):
20288
b61ad01c4e73 revset: use "canonpath()" for "filelog()" pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20287
diff changeset
   781
        f = pathutil.canonpath(repo.root, repo.getcwd(), pat)
20287
f3cef19befb1 revset: avoid loop for "match.files()" having always one element for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20286
diff changeset
   782
        fl = repo.file(f)
f3cef19befb1 revset: avoid loop for "match.files()" having always one element for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20286
diff changeset
   783
        for fr in fl:
f3cef19befb1 revset: avoid loop for "match.files()" having always one element for efficiency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20286
diff changeset
   784
            s.add(fl.linkrev(fr))
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   785
    else:
20288
b61ad01c4e73 revset: use "canonpath()" for "filelog()" pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20287
diff changeset
   786
        m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None])
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   787
        for f in repo[None]:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   788
            if m(f):
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   789
                fl = repo.file(f)
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   790
                for fr in fl:
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   791
                    s.add(fl.linkrev(fr))
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   792
22534
6261b9c549a2 revset: use `subset &` in `filelog`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22533
diff changeset
   793
    return subset & s
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   794
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   795
def first(repo, subset, x):
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   796
    """``first(set, [n])``
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   797
    An alias for limit().
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   798
    """
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   799
    return limit(repo, subset, x)
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
   800
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   801
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
   802
    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
   803
    c = repo['.']
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   804
    if l:
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   805
        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
   806
        if x in c:
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   807
            cx = c[x]
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   808
            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
   809
            # include the revision responsible for the most recent version
23704
c624fb2c4239 linkrev: also adjust linkrev when bootstrapping 'follow' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23467
diff changeset
   810
            s.add(cx.introrev())
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   811
        else:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
   812
            return baseset()
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   813
    else:
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
   814
        s = _revancestors(repo, baseset([c.rev()]), followfirst)
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   815
22535
44f471102f3a revset: use `subset &` in `follow`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22534
diff changeset
   816
    return subset & s
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   817
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   818
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
   819
    """``follow([file])``
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   820
    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
   821
    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
   822
    including copies.
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
   823
    """
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   824
    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
   825
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   826
def _followfirst(repo, subset, x):
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   827
    # ``followfirst([file])``
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   828
    # Like ``follow([file])`` but follows only the first parent of
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
   829
    # every revision or file revision.
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
   830
    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
   831
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   832
def getall(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   833
    """``all()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   834
    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
   835
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   836
    # i18n: "all" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   837
    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
   838
    return subset
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   839
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   840
def grep(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   841
    """``grep(regex)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   842
    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
   843
    to ensure special escape characters are handled correctly. Unlike
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
   844
    ``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
   845
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   846
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   847
        # i18n: "grep" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   848
        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
   849
    except re.error, e:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   850
        raise error.ParseError(_('invalid match pattern: %s') % e)
20453
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   851
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   852
    def matches(x):
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   853
        c = repo[x]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   854
        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
   855
            if gr.search(e):
20453
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   856
                return True
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   857
        return False
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
   858
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   859
    return subset.filter(matches)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   860
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   861
def _matchfiles(repo, subset, x):
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   862
    # _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
   863
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   864
    #   [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
   865
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   866
    # 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
   867
    # 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
   868
    # 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
   869
    # 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
   870
    # 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
   871
    # 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
   872
    # 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
   873
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   874
    # i18n: "_matchfiles" is a keyword
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   875
    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
   876
    pats, inc, exc = [], [], []
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   877
    rev, default = None, None
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   878
    for arg in l:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   879
        # i18n: "_matchfiles" is a keyword
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   880
        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
   881
        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
   882
        if prefix == 'p:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   883
            pats.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   884
        elif prefix == 'i:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   885
            inc.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   886
        elif prefix == 'x:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   887
            exc.append(value)
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   888
        elif prefix == 'r:':
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   889
            if rev is not None:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   890
                # i18n: "_matchfiles" is a keyword
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   891
                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
   892
                                         'revision'))
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
   893
            rev = value
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   894
        elif prefix == 'd:':
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   895
            if default is not None:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   896
                # i18n: "_matchfiles" is a keyword
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   897
                raise error.ParseError(_('_matchfiles expected at most one '
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   898
                                         'default mode'))
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   899
            default = value
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   900
        else:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
   901
            # i18n: "_matchfiles" is a keyword
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   902
            raise error.ParseError(_('invalid _matchfiles prefix: %s') % prefix)
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   903
    if not default:
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
   904
        default = 'glob'
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
   905
23061
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
   906
    m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
   907
                       exclude=exc, ctx=repo[rev], default=default)
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
   908
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
   909
    def matches(x):
23061
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
   910
        for f in repo[x].files():
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   911
            if m(f):
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
   912
                return True
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
   913
        return False
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
   914
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   915
    return subset.filter(matches)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   916
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   917
def hasfile(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   918
    """``file(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   919
    Changesets affecting files matched by pattern.
17244
483aa765f6c4 revset: add explanation about difference between 'filelog()' and 'file()'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17186
diff changeset
   920
17265
c30307eeec4b revset: polish explanation of the difference between file() and filelog()
Greg Ward <greg@gerg.ca>
parents: 17259
diff changeset
   921
    For a faster but less accurate result, consider using ``filelog()``
c30307eeec4b revset: polish explanation of the difference between file() and filelog()
Greg Ward <greg@gerg.ca>
parents: 17259
diff changeset
   922
    instead.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   923
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   924
    This predicate uses ``glob:`` as the default kind of pattern.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   925
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   926
    # i18n: "file" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   927
    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
   928
    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
   929
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   930
def head(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   931
    """``head()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   932
    Changeset is a named branch head.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   933
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   934
    # i18n: "head" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   935
    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
   936
    hs = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   937
    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
   938
        hs.update(repo[h].rev() for h in ls)
20713
6a1a4c212d50 revset: improve head revset performance
Durham Goode <durham@fb.com>
parents: 20712
diff changeset
   939
    return baseset(hs).filter(subset.__contains__)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   940
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   941
def heads(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   942
    """``heads(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   943
    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
   944
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   945
    s = getset(repo, subset, x)
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   946
    ps = parents(repo, subset, x)
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   947
    return s - ps
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   948
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   949
def hidden(repo, subset, x):
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   950
    """``hidden()``
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   951
    Hidden changesets.
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   952
    """
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   953
    # i18n: "hidden" is a keyword
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   954
    getargs(x, 0, 0, _("hidden takes no arguments"))
18382
f3b21beb9802 filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents: 18251
diff changeset
   955
    hiddenrevs = repoview.filterrevs(repo, 'visible')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   956
    return subset & hiddenrevs
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
   957
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   958
def keyword(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   959
    """``keyword(string)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   960
    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
   961
    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
   962
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   963
    # 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
   964
    kw = encoding.lower(getstring(x, _("keyword requires a string")))
20447
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
   965
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
   966
    def matches(r):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   967
        c = repo[r]
20447
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
   968
        return util.any(kw in encoding.lower(t) for t in c.files() + [c.user(),
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
   969
            c.description()])
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
   970
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
   971
    return subset.filter(matches)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   972
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   973
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
   974
    """``limit(set, [n])``
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   975
    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
   976
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   977
    # 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
   978
    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
   979
    try:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   980
        lim = 1
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   981
        if len(l) == 2:
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
   982
            # 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
   983
            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
   984
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   985
        # i18n: "limit" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   986
        raise error.ParseError(_("limit expects a number"))
22870
970d78f3f47c revset-limit: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22869
diff changeset
   987
    ss = subset
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   988
    os = getset(repo, spanset(repo), l[0])
22804
5385314e0b14 revset-limit: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22802
diff changeset
   989
    result = []
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   990
    it = iter(os)
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   991
    for x in xrange(lim):
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   992
        try:
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   993
            y = it.next()
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   994
            if y in ss:
22804
5385314e0b14 revset-limit: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22802
diff changeset
   995
                result.append(y)
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   996
        except (StopIteration):
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
   997
            break
22804
5385314e0b14 revset-limit: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22802
diff changeset
   998
    return baseset(result)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   999
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1000
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
  1001
    """``last(set, [n])``
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1002
    Last n members of set, defaulting to 1.
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1003
    """
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1004
    # 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
  1005
    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
  1006
    try:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1007
        lim = 1
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1008
        if len(l) == 2:
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1009
            # 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
  1010
            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
  1011
    except (TypeError, ValueError):
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1012
        # i18n: "last" is a keyword
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1013
        raise error.ParseError(_("last expects a number"))
22871
9b73ab9bcbfb revset-last: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22870
diff changeset
  1014
    ss = subset
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1015
    os = getset(repo, spanset(repo), l[0])
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1016
    os.reverse()
22805
e74245b79901 revset-last: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22804
diff changeset
  1017
    result = []
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1018
    it = iter(os)
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1019
    for x in xrange(lim):
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1020
        try:
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1021
            y = it.next()
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1022
            if y in ss:
22805
e74245b79901 revset-last: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22804
diff changeset
  1023
                result.append(y)
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1024
        except (StopIteration):
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1025
            break
22805
e74245b79901 revset-last: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22804
diff changeset
  1026
    return baseset(result)
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1027
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1028
def maxrev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1029
    """``max(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1030
    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
  1031
    """
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
  1032
    os = getset(repo, spanset(repo), x)
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
  1033
    if os:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1034
        m = os.max()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1035
        if m in subset:
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
  1036
            return baseset([m])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1037
    return baseset()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1038
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1039
def merge(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1040
    """``merge()``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1041
    Changeset is a merge changeset.
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1042
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1043
    # i18n: "merge" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1044
    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
  1045
    cl = repo.changelog
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
  1046
    return subset.filter(lambda r: cl.parentrevs(r)[1] != -1)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1047
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1048
def branchpoint(repo, subset, x):
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1049
    """``branchpoint()``
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1050
    Changesets with more than one child.
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1051
    """
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1052
    # i18n: "branchpoint" is a keyword
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1053
    getargs(x, 0, 0, _("branchpoint takes no arguments"))
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1054
    cl = repo.changelog
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1055
    if not subset:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1056
        return baseset()
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1057
    baserev = min(subset)
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1058
    parentscount = [0]*(len(repo) - baserev)
17785
ac5c9c8046f7 clfilter: use changelog to iterate over the repo in branchpoint
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17753
diff changeset
  1059
    for r in cl.revs(start=baserev + 1):
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1060
        for p in cl.parentrevs(r):
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1061
            if p >= baserev:
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1062
                parentscount[p - baserev] += 1
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
  1063
    return subset.filter(lambda r: parentscount[r - baserev] > 1)
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1064
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1065
def minrev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1066
    """``min(set)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1067
    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
  1068
    """
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
  1069
    os = getset(repo, spanset(repo), x)
14153
f8047a059ca0 revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
Mads Kiilerich <mads@kiilerich.com>
parents: 14098
diff changeset
  1070
    if os:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1071
        m = os.min()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1072
        if m in subset:
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
  1073
            return baseset([m])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1074
    return baseset()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1075
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1076
def modifies(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1077
    """``modifies(pattern)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1078
    Changesets modifying files matched by pattern.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1079
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1080
    The pattern without explicit kind like ``glob:`` is expected to be
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1081
    relative to the current directory and match against a file or a
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1082
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1083
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1084
    # i18n: "modifies" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1085
    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
  1086
    return checkstatus(repo, subset, pat, 0)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1087
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1088
def node_(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1089
    """``id(string)``
12859
76066903ae08 revset: fix missing dot in docstring
Wagner Bruna <wbruna@yahoo.com>
parents: 12855
diff changeset
  1090
    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
  1091
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1092
    # 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
  1093
    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
  1094
    # 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
  1095
    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
  1096
    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
  1097
        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
  1098
    else:
16735
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1099
        rn = None
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1100
        pm = repo.changelog._partialmatch(n)
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1101
        if pm is not None:
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1102
            rn = repo.changelog.rev(pm)
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1103
23005
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1104
    if rn is None:
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1105
        return baseset()
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1106
    result = baseset([rn])
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1107
    return result & subset
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
  1108
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1109
def obsolete(repo, subset, x):
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1110
    """``obsolete()``
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1111
    Mutable changeset with a newer version."""
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1112
    # i18n: "obsolete" is a keyword
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1113
    getargs(x, 0, 0, _("obsolete takes no arguments"))
17825
3cc06457f15e obsolete: rename `getobscache` into `getrevs`
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17804
diff changeset
  1114
    obsoletes = obsmod.getrevs(repo, 'obsolete')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1115
    return subset & obsoletes
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1116
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1117
def only(repo, subset, x):
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1118
    """``only(set, [set])``
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1119
    Changesets that are ancestors of the first set that are not ancestors
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1120
    of any other head in the repo. If a second set is specified, the result
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1121
    is ancestors of the first set that are not ancestors of the second set
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1122
    (i.e. ::<set1> - ::<set2>).
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1123
    """
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1124
    cl = repo.changelog
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1125
    # i18n: "only" is a keyword
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1126
    args = getargs(x, 1, 2, _('only takes one or two arguments'))
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1127
    include = getset(repo, spanset(repo), args[0])
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1128
    if len(args) == 1:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1129
        if not include:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1130
            return baseset()
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1131
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1132
        descendants = set(_revdescendants(repo, include, False))
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1133
        exclude = [rev for rev in cl.headrevs()
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1134
            if not rev in descendants and not rev in include]
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1135
    else:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1136
        exclude = getset(repo, spanset(repo), args[1])
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1137
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1138
    results = set(cl.findmissingrevs(common=exclude, heads=include))
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1139
    return subset & results
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1140
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1141
def origin(repo, subset, x):
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1142
    """``origin([set])``
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1143
    Changesets that were specified as a source for the grafts, transplants or
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1144
    rebases that created the given revisions.  Omitting the optional set is the
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1145
    same as passing all().  If a changeset created by these operations is itself
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1146
    specified as a source for one of these operations, only the source changeset
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1147
    for the first operation is selected.
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1148
    """
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1149
    if x is not None:
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
  1150
        dests = getset(repo, spanset(repo), x)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1151
    else:
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
  1152
        dests = getall(repo, spanset(repo), x)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1153
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1154
    def _firstsrc(rev):
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1155
        src = _getrevsource(repo, rev)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1156
        if src is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1157
            return None
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1158
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1159
        while True:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1160
            prev = _getrevsource(repo, src)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1161
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1162
            if prev is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1163
                return src
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1164
            src = prev
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1165
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
  1166
    o = set([_firstsrc(r) for r in dests])
22498
64673dc48931 revset: remove invalid value in the origin set
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22497
diff changeset
  1167
    o -= set([None])
22536
8040a44aab1c revset: use `subset &` in `origin`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22535
diff changeset
  1168
    return subset & o
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1169
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1170
def outgoing(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1171
    """``outgoing([path])``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1172
    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
  1173
    default push location.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1174
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1175
    import hg # avoid start-up nasties
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1176
    # 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
  1177
    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
  1178
    # i18n: "outgoing" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1179
    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
  1180
    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
  1181
    dest, branches = hg.parseurl(dest)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1182
    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
  1183
    if revs:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1184
        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
  1185
    other = hg.peer(repo, {}, dest)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1186
    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
  1187
    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
  1188
    repo.ui.popbuffer()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1189
    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
  1190
    o = set([cl.rev(r) for r in outgoing.missing])
22529
5c53d7888aef revset: use `subset &` in `outgoing`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22528
diff changeset
  1191
    return subset & 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
  1192
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1193
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
  1194
    """``p1([set])``
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1195
    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
  1196
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1197
    if x is None:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13873
diff changeset
  1198
        p = repo[x].p1().rev()
22538
a428db9ab61d revset: use `subset &` in bare `p1()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22537
diff changeset
  1199
        if p >= 0:
a428db9ab61d revset: use `subset &` in bare `p1()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22537
diff changeset
  1200
            return subset & baseset([p])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1201
        return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1202
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1203
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1204
    cl = repo.changelog
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
  1205
    for r in getset(repo, spanset(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1206
        ps.add(cl.parentrevs(r)[0])
22495
668b26d32bf6 revset: remove nullrev from set computed in p1() and p2()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22494
diff changeset
  1207
    ps -= set([node.nullrev])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1208
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1209
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1210
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
  1211
    """``p2([set])``
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1212
    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
  1213
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1214
    if x is None:
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1215
        ps = repo[x].parents()
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1216
        try:
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
  1217
            p = ps[1].rev()
22539
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1218
            if p >= 0:
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1219
                return subset & baseset([p])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1220
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1221
        except IndexError:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1222
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1223
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1224
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1225
    cl = repo.changelog
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
  1226
    for r in getset(repo, spanset(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1227
        ps.add(cl.parentrevs(r)[1])
22495
668b26d32bf6 revset: remove nullrev from set computed in p1() and p2()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22494
diff changeset
  1228
    ps -= set([node.nullrev])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1229
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1230
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1231
def parents(repo, subset, x):
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1232
    """``parents([set])``
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1233
    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
  1234
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1235
    if x is None:
22496
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1236
        ps = set(p.rev() for p in repo[x].parents())
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1237
    else:
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1238
        ps = set()
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1239
        cl = repo.changelog
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1240
        for r in getset(repo, spanset(repo), x):
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1241
            ps.update(cl.parentrevs(r))
22497
8ea3f47bcaff revset: remove nullrev from set computed in parents()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22496
diff changeset
  1242
    ps -= set([node.nullrev])
22712
093df3b77f27 revert: bring back usage of `subset & ps` in `parents`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22692
diff changeset
  1243
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1244
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1245
def parentspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1246
    """``set^0``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1247
    The set.
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1248
    ``set^1`` (or ``set^``), ``set^2``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1249
    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
  1250
    """
12320
40c40c6f20b8 revset: handle re.compile() errors in grep()
Brodie Rao <brodie@bitheap.org>
parents: 11882
diff changeset
  1251
    try:
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1252
        n = int(n[1])
14072
2e4d79dcc0a0 revset: add missing whitespace
Kevin Gessner <kevin@kevingessner.com>
parents: 14070
diff changeset
  1253
        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
  1254
            raise ValueError
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
  1255
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1256
        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
  1257
    ps = set()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1258
    cl = repo.changelog
23165
7e8737e6ab08 revset-parentspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23164
diff changeset
  1259
    for r in getset(repo, fullreposet(repo), x):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1260
        if n == 0:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1261
            ps.add(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1262
        elif n == 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1263
            ps.add(cl.parentrevs(r)[0])
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1264
        elif n == 2:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1265
            parents = cl.parentrevs(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1266
            if len(parents) > 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1267
                ps.add(parents[1])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1268
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1269
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1270
def present(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1271
    """``present(set)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1272
    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
  1273
    all revisions in set.
16748
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1274
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1275
    If any of specified revisions is not present in the local repository,
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1276
    the query is normally aborted. But this predicate allows the query
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1277
    to continue even in such cases.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1278
    """
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1279
    try:
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1280
        return getset(repo, subset, x)
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1281
    except error.RepoLookupError:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1282
        return baseset()
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1283
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1284
def public(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1285
    """``public()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1286
    Changeset in public phase."""
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1287
    # i18n: "public" is a keyword
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1288
    getargs(x, 0, 0, _("public takes no arguments"))
23019
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1289
    phase = repo._phasecache.phase
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1290
    target = phases.public
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1291
    condition = lambda r: phase(repo, r) == target
23018
73d9d5548dfe revset-phases: do not cache phase-related filters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23005
diff changeset
  1292
    return subset.filter(condition, cache=False)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1293
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1294
def remote(repo, subset, x):
16007
f06c53ca59a9 revset: fix documentation for 'remote()' predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16006
diff changeset
  1295
    """``remote([id [,path]])``
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1296
    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
  1297
    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
  1298
    synonym for the current local branch.
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1299
    """
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1300
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1301
    import hg # avoid start-up nasties
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1302
    # i18n: "remote" is a keyword
16007
f06c53ca59a9 revset: fix documentation for 'remote()' predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16006
diff changeset
  1303
    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
  1304
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1305
    q = '.'
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1306
    if len(l) > 0:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1307
    # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1308
        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
  1309
    if q == '.':
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1310
        q = repo['.'].branch()
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1311
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1312
    dest = ''
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1313
    if len(l) > 1:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1314
        # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1315
        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
  1316
    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
  1317
    dest, branches = hg.parseurl(dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1318
    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
  1319
    if revs:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1320
        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
  1321
    other = hg.peer(repo, {}, dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1322
    n = other.lookup(q)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1323
    if n in repo:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1324
        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
  1325
        if r in subset:
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
  1326
            return baseset([r])
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1327
    return baseset()
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1328
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1329
def removes(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1330
    """``removes(pattern)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1331
    Changesets which remove files matching pattern.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1332
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1333
    The pattern without explicit kind like ``glob:`` is expected to be
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1334
    relative to the current directory and match against a file or a
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1335
    directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1336
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1337
    # 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
  1338
    pat = getstring(x, _("removes requires a pattern"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1339
    return checkstatus(repo, subset, pat, 2)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1340
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1341
def rev(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1342
    """``rev(number)``
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1343
    Revision with the given numeric identifier.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1344
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1345
    # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1346
    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
  1347
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1348
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1349
        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
  1350
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1351
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1352
        raise error.ParseError(_("rev expects a number"))
23078
eb763217152a revset: avoid O(n) lookup of invalid revision in rev()
Yuya Nishihara <yuya@tcha.org>
parents: 23062
diff changeset
  1353
    if l not in fullreposet(repo):
23062
ba89f7b542c9 revset: have rev() drop out-of-range or filtered rev explicitly (issue4396)
Yuya Nishihara <yuya@tcha.org>
parents: 23061
diff changeset
  1354
        return baseset()
22537
bbf4f3dfd700 revset: use `subset &` in `rev`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22536
diff changeset
  1355
    return subset & baseset([l])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1356
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1357
def matching(repo, subset, x):
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1358
    """``matching(revision [, field])``
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1359
    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
  1360
    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
  1361
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1362
    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
  1363
    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
  1364
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1365
    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
  1366
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1367
    Regular revision fields are ``description``, ``author``, ``branch``,
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1368
    ``date``, ``files``, ``phase``, ``parents``, ``substate``, ``user``
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1369
    and ``diff``.
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1370
    Note that ``author`` and ``user`` are synonyms. ``diff`` refers to the
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1371
    contents of the revision. Two revisions matching their ``diff`` will
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1372
    also match their ``files``.
16528
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1373
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1374
    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
  1375
    ``summary`` matches the first line of the description.
16639
00290bd359fe revset: documentation typo "metatadata"
Jesse Glick <jesse.glick@oracle.com>
parents: 16528
diff changeset
  1376
    ``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
  1377
    (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
  1378
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1379
    ``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
  1380
    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
  1381
    """
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1382
    # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1383
    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
  1384
23166
30e0dcd7c5ff revset-matching: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23165
diff changeset
  1385
    revs = getset(repo, fullreposet(repo), l[0])
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1386
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1387
    fieldlist = ['metadata']
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1388
    if len(l) > 1:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1389
            fieldlist = getstring(l[1],
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1390
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1391
                _("matching requires a string "
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1392
                "as its second argument")).split()
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1393
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1394
    # Make sure that there are no repeated fields,
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1395
    # expand the 'special' 'metadata' field type
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1396
    # and check the 'files' whenever we check the 'diff'
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1397
    fields = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1398
    for field in fieldlist:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1399
        if field == 'metadata':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1400
            fields += ['user', 'description', 'date']
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1401
        elif field == 'diff':
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1402
            # a revision matching the diff must also match the files
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1403
            # since matching the diff is very costly, make sure to
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1404
            # also match the files first
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1405
            fields += ['files', 'diff']
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1406
        else:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1407
            if field == 'author':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1408
                field = 'user'
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1409
            fields.append(field)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1410
    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
  1411
    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
  1412
        # 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
  1413
        fields.discard('summary')
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1414
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1415
    # 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
  1416
    # 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
  1417
    # 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
  1418
    fieldorder = ['phase', 'parents', 'user', 'date', 'branch', 'summary',
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1419
        'files', 'description', 'substate', 'diff']
16446
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
  1420
    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
  1421
        try:
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
  1422
            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
  1423
        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
  1424
            # 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
  1425
            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
  1426
    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
  1427
    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
  1428
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1429
    # 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
  1430
    # 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
  1431
    getfieldfuncs = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1432
    _funcs = {
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1433
        'user': lambda r: repo[r].user(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1434
        'branch': lambda r: repo[r].branch(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1435
        'date': lambda r: repo[r].date(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1436
        'description': lambda r: repo[r].description(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1437
        'files': lambda r: repo[r].files(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1438
        'parents': lambda r: repo[r].parents(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1439
        'phase': lambda r: repo[r].phase(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1440
        'substate': lambda r: repo[r].substate,
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1441
        'summary': lambda r: repo[r].description().splitlines()[0],
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1442
        'diff': lambda r: list(repo[r].diff(git=True),)
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1443
    }
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1444
    for info in fields:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1445
        getfield = _funcs.get(info, None)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1446
        if getfield is None:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1447
            raise error.ParseError(
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1448
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1449
                _("unexpected field name passed to matching: %s") % info)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1450
        getfieldfuncs.append(getfield)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1451
    # 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
  1452
    # 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
  1453
    # 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
  1454
    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
  1455
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1456
    def matches(x):
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1457
        for rev in revs:
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1458
            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
  1459
            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
  1460
            for n, f in enumerate(getfieldfuncs):
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1461
                if target[n] != f(x):
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
  1462
                    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
  1463
            if match:
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1464
                return True
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1465
        return False
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1466
20611
6490f8385391 revset: changed revset code to use filter method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20610
diff changeset
  1467
    return subset.filter(matches)
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1468
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1469
def reverse(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1470
    """``reverse(set)``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1471
    Reverse order of set.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1472
    """
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1473
    l = getset(repo, subset, x)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1474
    l.reverse()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1475
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1476
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1477
def roots(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1478
    """``roots(set)``
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1479
    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
  1480
    """
22874
e15027cc4cd8 revset-roots: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22872
diff changeset
  1481
    s = getset(repo, spanset(repo), x)
e15027cc4cd8 revset-roots: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22872
diff changeset
  1482
    subset = baseset([r for r in s if r in subset])
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1483
    cs = _children(repo, subset, s)
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
  1484
    return subset - cs
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1485
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1486
def secret(repo, subset, x):
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1487
    """``secret()``
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1488
    Changeset in secret phase."""
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1489
    # i18n: "secret" is a keyword
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1490
    getargs(x, 0, 0, _("secret takes no arguments"))
23019
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1491
    phase = repo._phasecache.phase
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1492
    target = phases.secret
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1493
    condition = lambda r: phase(repo, r) == target
23018
73d9d5548dfe revset-phases: do not cache phase-related filters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23005
diff changeset
  1494
    return subset.filter(condition, cache=False)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1495
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1496
def sort(repo, subset, x):
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1497
    """``sort(set[, [-]key...])``
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1498
    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
  1499
    as ``-key`` to sort in descending order.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1500
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1501
    The keys can be:
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1502
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1503
    - ``rev`` for the revision number,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1504
    - ``branch`` for the branch name,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1505
    - ``desc`` for the commit message (description),
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1506
    - ``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
  1507
    - ``date`` for the commit date
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1508
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1509
    # 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
  1510
    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
  1511
    keys = "rev"
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1512
    if len(l) == 2:
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1513
        # i18n: "sort" is a keyword
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1514
        keys = getstring(l[1], _("sort spec must be a string"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1515
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1516
    s = l[0]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1517
    keys = keys.split()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1518
    l = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1519
    def invert(s):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1520
        return "".join(chr(255 - ord(c)) for c in s)
20719
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1521
    revs = getset(repo, subset, s)
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1522
    if keys == ["rev"]:
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1523
        revs.sort()
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1524
        return revs
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1525
    elif keys == ["-rev"]:
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1526
        revs.sort(reverse=True)
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1527
        return revs
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1528
    for r in revs:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1529
        c = repo[r]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1530
        e = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1531
        for k in keys:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1532
            if k == 'rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1533
                e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1534
            elif k == '-rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1535
                e.append(-r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1536
            elif k == 'branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1537
                e.append(c.branch())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1538
            elif k == '-branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1539
                e.append(invert(c.branch()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1540
            elif k == 'desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1541
                e.append(c.description())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1542
            elif k == '-desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1543
                e.append(invert(c.description()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1544
            elif k in 'user author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1545
                e.append(c.user())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1546
            elif k in '-user -author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1547
                e.append(invert(c.user()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1548
            elif k == 'date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1549
                e.append(c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1550
            elif k == '-date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1551
                e.append(-c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1552
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1553
                raise error.ParseError(_("unknown sort key %r") % k)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1554
        e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1555
        l.append(e)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1556
    l.sort()
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
  1557
    return baseset([e[-1] for e in l])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1558
16819
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1559
def _stringmatcher(pattern):
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1560
    """
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1561
    accepts a string, possibly starting with 're:' or 'literal:' prefix.
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1562
    returns the matcher name, pattern, and matcher function.
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1563
    missing or unknown prefixes are treated as literal matches.
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1564
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1565
    helper for tests:
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1566
    >>> def test(pattern, *tests):
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1567
    ...     kind, pattern, matcher = _stringmatcher(pattern)
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1568
    ...     return (kind, pattern, [bool(matcher(t)) for t in tests])
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1569
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1570
    exact matching (no prefix):
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1571
    >>> test('abcdefg', 'abc', 'def', 'abcdefg')
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1572
    ('literal', 'abcdefg', [False, False, True])
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1573
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1574
    regex matching ('re:' prefix)
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1575
    >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1576
    ('re', 'a.+b', [False, False, True])
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1577
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1578
    force exact matches ('literal:' prefix)
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1579
    >>> test('literal:re:foobar', 'foobar', 're:foobar')
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1580
    ('literal', 're:foobar', [False, True])
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1581
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1582
    unknown prefixes are ignored and treated as literals
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1583
    >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1584
    ('literal', 'foo:bar', [False, False, True])
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1585
    """
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1586
    if pattern.startswith('re:'):
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1587
        pattern = pattern[3:]
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1588
        try:
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1589
            regex = re.compile(pattern)
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1590
        except re.error, e:
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1591
            raise error.ParseError(_('invalid regular expression: %s')
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1592
                                   % e)
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1593
        return 're', pattern, regex.search
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1594
    elif pattern.startswith('literal:'):
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1595
        pattern = pattern[8:]
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1596
    return 'literal', pattern, pattern.__eq__
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1597
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1598
def _substringmatcher(pattern):
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1599
    kind, pattern, matcher = _stringmatcher(pattern)
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1600
    if kind == 'literal':
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1601
        matcher = lambda s: pattern in s
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1602
    return kind, pattern, matcher
16819
5260a9e93113 revset: add helper function for matching strings to patterns
Simon King <simon@simonking.org.uk>
parents: 16803
diff changeset
  1603
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
  1604
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
  1605
    """``tag([name])``
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1606
    The specified tag by name, or all tagged revisions if no name is given.
20824
c57c9cece645 revset: document the regular expression support for tag(name)
Matt Harbison <matt_harbison@yahoo.com>
parents: 20289
diff changeset
  1607
c57c9cece645 revset: document the regular expression support for tag(name)
Matt Harbison <matt_harbison@yahoo.com>
parents: 20289
diff changeset
  1608
    If `name` starts with `re:`, the remainder of the name is treated as
c57c9cece645 revset: document the regular expression support for tag(name)
Matt Harbison <matt_harbison@yahoo.com>
parents: 20289
diff changeset
  1609
    a regular expression. To match a tag that actually starts with `re:`,
c57c9cece645 revset: document the regular expression support for tag(name)
Matt Harbison <matt_harbison@yahoo.com>
parents: 20289
diff changeset
  1610
    use the prefix `literal:`.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1611
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1612
    # 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
  1613
    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
  1614
    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
  1615
    if args:
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1616
        pattern = getstring(args[0],
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1617
                            # i18n: "tag" is a keyword
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1618
                            _('the argument to tag must be a string'))
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1619
        kind, pattern, matcher = _stringmatcher(pattern)
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1620
        if kind == 'literal':
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  1621
            # avoid resolving all tags
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  1622
            tn = repo._tagscache.tags.get(pattern, None)
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  1623
            if tn is None:
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1624
                raise util.Abort(_("tag '%s' does not exist") % pattern)
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  1625
            s = set([repo[tn].rev()])
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1626
        else:
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  1627
            s = set([cl.rev(n) for t, n in repo.tagslist() if matcher(t)])
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
  1628
    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
  1629
        s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1630
    return subset & s
11280
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  1631
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1632
def tagged(repo, subset, x):
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1633
    return tag(repo, subset, x)
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1634
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  1635
def unstable(repo, subset, x):
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  1636
    """``unstable()``
17291
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
  1637
    Non-obsolete changesets with obsolete ancestors.
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
  1638
    """
17259
e96ad092fb18 i18n: add/relocate "i18n keyword" comments for i18n messages in revset.py
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17258
diff changeset
  1639
    # i18n: "unstable" is a keyword
17258
5822345e9e46 revset: use appropriate predicate name in error messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17244
diff changeset
  1640
    getargs(x, 0, 0, _("unstable takes no arguments"))
17825
3cc06457f15e obsolete: rename `getobscache` into `getrevs`
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17804
diff changeset
  1641
    unstables = obsmod.getrevs(repo, 'unstable')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1642
    return subset & unstables
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  1643
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  1644
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1645
def user(repo, subset, x):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1646
    """``user(string)``
14357
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
  1647
    User name contains string. The match is case-insensitive.
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1648
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1649
    If `string` starts with `re:`, the remainder of the string is treated as
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1650
    a regular expression. To match a user that actually contains `re:`, use
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1651
    the prefix `literal:`.
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1652
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1653
    return author(repo, subset, x)
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1654
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1655
# for internal use
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1656
def _list(repo, subset, x):
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1657
    s = getstring(x, "internal error")
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1658
    if not s:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1659
        return baseset()
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1660
    ls = [repo[r].rev() for r in s.split('\0')]
22875
eed95fe914c5 revset-_list: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22874
diff changeset
  1661
    s = subset
20365
bc770ee6a351 revset: implemented set caching for revset evaluation
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20364
diff changeset
  1662
    return baseset([r for r in ls if r in s])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1663
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1664
# for internal use
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1665
def _intlist(repo, subset, x):
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1666
    s = getstring(x, "internal error")
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1667
    if not s:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1668
        return baseset()
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1669
    ls = [int(r) for r in s.split('\0')]
22876
d52ca940c665 revset-_intlist: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22875
diff changeset
  1670
    s = subset
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1671
    return baseset([r for r in ls if r in s])
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1672
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1673
# for internal use
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1674
def _hexlist(repo, subset, x):
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1675
    s = getstring(x, "internal error")
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1676
    if not s:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1677
        return baseset()
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1678
    cl = repo.changelog
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1679
    ls = [cl.rev(node.bin(r)) for r in s.split('\0')]
22877
489d2f3688c9 revset-_hexlist: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22876
diff changeset
  1680
    s = subset
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1681
    return baseset([r for r in ls if r in s])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1682
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1683
symbols = {
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1684
    "adds": adds,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1685
    "all": getall,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1686
    "ancestor": ancestor,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1687
    "ancestors": ancestors,
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
  1688
    "_firstancestors": _firstancestors,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1689
    "author": author,
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
  1690
    "bisect": bisect,
13602
54b198fe9768 revset: add a revset command to get bisect state.
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13593
diff changeset
  1691
    "bisected": bisected,
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1692
    "bookmark": bookmark,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1693
    "branch": branch,
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1694
    "branchpoint": branchpoint,
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
  1695
    "bumped": bumped,
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
  1696
    "bundle": bundle,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1697
    "children": children,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1698
    "closed": closed,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1699
    "contains": contains,
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
  1700
    "converted": converted,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1701
    "date": date,
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
  1702
    "desc": desc,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1703
    "descendants": descendants,
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
  1704
    "_firstdescendants": _firstdescendants,
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
  1705
    "destination": destination,
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
  1706
    "divergent": divergent,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1707
    "draft": draft,
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
  1708
    "extinct": extinct,
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
  1709
    "extra": extra,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1710
    "file": hasfile,
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1711
    "filelog": filelog,
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1712
    "first": first,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1713
    "follow": follow,
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
  1714
    "_followfirst": _followfirst,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1715
    "grep": grep,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1716
    "head": head,
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1717
    "heads": heads,
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1718
    "hidden": hidden,
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1719
    "id": node_,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1720
    "keyword": keyword,
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1721
    "last": last,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1722
    "limit": limit,
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1723
    "_matchfiles": _matchfiles,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1724
    "max": maxrev,
14649
a6a8809c6e33 revset: update sorting of symbols
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14556
diff changeset
  1725
    "merge": merge,
11708
ba65d61f3158 revset: add min function
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11650
diff changeset
  1726
    "min": minrev,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1727
    "modifies": modifies,
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1728
    "obsolete": obsolete,
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1729
    "only": only,
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1730
    "origin": origin,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1731
    "outgoing": outgoing,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1732
    "p1": p1,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1733
    "p2": p2,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1734
    "parents": parents,
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1735
    "present": present,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1736
    "public": public,
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1737
    "remote": remote,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1738
    "removes": removes,
14649
a6a8809c6e33 revset: update sorting of symbols
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14556
diff changeset
  1739
    "rev": rev,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1740
    "reverse": reverse,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1741
    "roots": roots,
11284
0b5c2e82aeb5 revset: sort the predicate list
Matt Mackall <mpm@selenic.com>
parents: 11283
diff changeset
  1742
    "sort": sort,
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1743
    "secret": secret,
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1744
    "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
  1745
    "tag": tag,
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1746
    "tagged": tagged,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1747
    "user": user,
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  1748
    "unstable": unstable,
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  1749
    "_list": _list,
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1750
    "_intlist": _intlist,
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1751
    "_hexlist": _hexlist,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1752
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1753
19721
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1754
# symbols which can't be used for a DoS attack for any given input
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1755
# (e.g. those which accept regexes as plain strings shouldn't be included)
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1756
# functions that just return a lot of changesets (like all) don't count here
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1757
safesymbols = set([
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1758
    "adds",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1759
    "all",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1760
    "ancestor",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1761
    "ancestors",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1762
    "_firstancestors",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1763
    "author",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1764
    "bisect",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1765
    "bisected",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1766
    "bookmark",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1767
    "branch",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1768
    "branchpoint",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1769
    "bumped",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1770
    "bundle",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1771
    "children",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1772
    "closed",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1773
    "converted",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1774
    "date",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1775
    "desc",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1776
    "descendants",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1777
    "_firstdescendants",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1778
    "destination",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1779
    "divergent",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1780
    "draft",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1781
    "extinct",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1782
    "extra",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1783
    "file",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1784
    "filelog",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1785
    "first",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1786
    "follow",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1787
    "_followfirst",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1788
    "head",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1789
    "heads",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1790
    "hidden",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1791
    "id",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1792
    "keyword",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1793
    "last",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1794
    "limit",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1795
    "_matchfiles",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1796
    "max",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1797
    "merge",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1798
    "min",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1799
    "modifies",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1800
    "obsolete",
23467
c237499a7fba revset: add 'only' to DoS-safe symbols
Yuya Nishihara <yuya@tcha.org>
parents: 23466
diff changeset
  1801
    "only",
19721
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1802
    "origin",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1803
    "outgoing",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1804
    "p1",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1805
    "p2",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1806
    "parents",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1807
    "present",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1808
    "public",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1809
    "remote",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1810
    "removes",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1811
    "rev",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1812
    "reverse",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1813
    "roots",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1814
    "sort",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1815
    "secret",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1816
    "matching",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1817
    "tag",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1818
    "tagged",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1819
    "user",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1820
    "unstable",
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1821
    "_list",
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  1822
    "_intlist",
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  1823
    "_hexlist",
19721
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1824
])
d8ca6d965230 revset: add a whitelist of DoS-safe symbols
Alexander Plavin <alexander@plav.in>
parents: 19720
diff changeset
  1825
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1826
methods = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1827
    "range": rangeset,
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
  1828
    "dagrange": dagrange,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1829
    "string": stringset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1830
    "symbol": symbolset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1831
    "and": andset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1832
    "or": orset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1833
    "not": notset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1834
    "list": listset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1835
    "func": func,
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1836
    "ancestor": ancestorspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1837
    "parent": parentspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1838
    "parentpost": p1,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1839
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1840
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1841
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
  1842
    if x is None:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1843
        return 0, x
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1844
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1845
    smallbonus = 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1846
    if small:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1847
        smallbonus = .5
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1848
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1849
    op = x[0]
11283
a6356b2695a3 revset: fix - handling in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 11282
diff changeset
  1850
    if op == 'minus':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1851
        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
  1852
    elif op == 'dagrangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1853
        return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1854
    elif op == 'dagrangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1855
        return optimize(('func', ('symbol', 'descendants'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1856
    elif op == 'rangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1857
        return optimize(('range', ('string', '0'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1858
    elif op == 'rangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1859
        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
  1860
    elif op == 'negate':
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  1861
        return optimize(('string',
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  1862
                         '-' + 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
  1863
    elif op in 'string symbol negate':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1864
        return smallbonus, x # single revisions are small
16859
eeb464ed7275 revset: drop unreachable code
Bryan O'Sullivan <bryano@fb.com>
parents: 16838
diff changeset
  1865
    elif op == 'and':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1866
        wa, ta = optimize(x[1], True)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1867
        wb, tb = optimize(x[2], True)
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1868
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1869
        # (::x and not ::y)/(not ::y and ::x) have a fast path
21893
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  1870
        def isonly(revs, bases):
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1871
            return (
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1872
                revs[0] == 'func'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1873
                and getstring(revs[1], _('not a symbol')) == 'ancestors'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1874
                and bases[0] == 'not'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1875
                and bases[1][0] == 'func'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1876
                and getstring(bases[1][1], _('not a symbol')) == 'ancestors')
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1877
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1878
        w = min(wa, wb)
21893
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  1879
        if isonly(ta, tb):
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  1880
            return w, ('func', ('symbol', 'only'), ('list', ta[2], tb[1][2]))
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  1881
        if isonly(tb, ta):
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  1882
            return w, ('func', ('symbol', 'only'), ('list', tb[2], ta[1][2]))
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  1883
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1884
        if wa > wb:
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1885
            return w, (op, tb, ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1886
        return w, (op, ta, tb)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1887
    elif op == 'or':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1888
        wa, ta = optimize(x[1], False)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1889
        wb, tb = optimize(x[2], False)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1890
        if wb < wa:
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1891
            wb, wa = wa, wb
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1892
        return max(wa, wb), (op, ta, tb)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1893
    elif op == 'not':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1894
        o = optimize(x[1], not small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1895
        return o[0], (op, o[1])
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1896
    elif op == 'parentpost':
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1897
        o = optimize(x[1], small)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1898
        return o[0], (op, o[1])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1899
    elif op == 'group':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1900
        return optimize(x[1], small)
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
  1901
    elif op in 'dagrange range list parent ancestorspec':
14842
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1902
        if op == 'parent':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1903
            # 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
  1904
            post = ('parentpost', x[1])
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1905
            if x[2][0] == 'dagrangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1906
                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
  1907
            elif x[2][0] == 'rangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  1908
                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
  1909
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1910
        wa, ta = optimize(x[1], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1911
        wb, tb = optimize(x[2], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1912
        return wa + wb, (op, ta, tb)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1913
    elif op == 'func':
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1914
        f = getstring(x[1], _("not a symbol"))
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1915
        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
  1916
        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
  1917
                 "outgoing user"):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1918
            w = 10 # slow
12351
b913232d13c1 revsets: reduce cost of outgoing in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 12321
diff changeset
  1919
        elif f in "modifies adds removes":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1920
            w = 30 # slower
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1921
        elif f == "contains":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1922
            w = 100 # very slow
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1923
        elif f == "ancestor":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1924
            w = 1 * smallbonus
22451
186fd06283b4 revset: lower weight for _intlist function
Durham Goode <durham@fb.com>
parents: 22450
diff changeset
  1925
        elif f in "reverse limit first _intlist":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1926
            w = 0
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1927
        elif f in "sort":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1928
            w = 10 # assume most sorts look at changelog
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1929
        else:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1930
            w = 1
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1931
        return w + wa, (op, x[1], ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  1932
    return 1, x
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1933
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1934
_aliasarg = ('func', ('symbol', '_aliasarg'))
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1935
def _getaliasarg(tree):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1936
    """If tree matches ('func', ('symbol', '_aliasarg'), ('string', X))
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1937
    return X, None otherwise.
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1938
    """
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1939
    if (len(tree) == 3 and tree[:2] == _aliasarg
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1940
        and tree[2][0] == 'string'):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1941
        return tree[2][1]
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1942
    return None
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1943
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1944
def _checkaliasarg(tree, known=None):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1945
    """Check tree contains no _aliasarg construct or only ones which
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1946
    value is in known. Used to avoid alias placeholders injection.
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1947
    """
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1948
    if isinstance(tree, tuple):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1949
        arg = _getaliasarg(tree)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1950
        if arg is not None and (not known or arg not in known):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1951
            raise error.ParseError(_("not a function: %s") % '_aliasarg')
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1952
        for t in tree:
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1953
            _checkaliasarg(t, known)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1954
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1955
class revsetalias(object):
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1956
    funcre = re.compile('^([^(]+)\(([^)]+)\)$')
14723
b9faf94ee196 revset: fix aliases with 0 or more than 2 parameters
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
  1957
    args = None
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1958
14723
b9faf94ee196 revset: fix aliases with 0 or more than 2 parameters
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
  1959
    def __init__(self, name, value):
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1960
        '''Aliases like:
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1961
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1962
        h = heads(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1963
        b($1) = ancestors($1) - ancestors(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1964
        '''
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1965
        m = self.funcre.search(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1966
        if m:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1967
            self.name = m.group(1)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1968
            self.tree = ('func', ('symbol', m.group(1)))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1969
            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
  1970
            for arg in self.args:
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1971
                # _aliasarg() is an unknown symbol only used separate
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1972
                # alias argument placeholders from regular strings.
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1973
                value = value.replace(arg, '_aliasarg(%r)' % (arg,))
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1974
        else:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1975
            self.name = name
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1976
            self.tree = ('symbol', name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1977
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1978
        self.replacement, pos = parse(value)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1979
        if pos != len(value):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1980
            raise error.ParseError(_('invalid token'), pos)
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1981
        # Check for placeholder injection
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  1982
        _checkaliasarg(self.replacement, self.args)
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  1983
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1984
def _getalias(aliases, tree):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1985
    """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
  1986
    otherwise.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1987
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1988
    if isinstance(tree, tuple) and tree:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1989
        if tree[0] == 'symbol' and len(tree) == 2:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1990
            name = tree[1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1991
            alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1992
            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
  1993
                return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1994
        if tree[0] == 'func' and len(tree) > 1:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1995
            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
  1996
                name = tree[1][1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1997
                alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  1998
                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
  1999
                    return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2000
    return None
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2001
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2002
def _expandargs(tree, args):
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2003
    """Replace _aliasarg instances with the substitution value of the
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2004
    same name in args, recursively.
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2005
    """
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2006
    if not tree or not isinstance(tree, tuple):
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2007
        return tree
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2008
    arg = _getaliasarg(tree)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2009
    if arg is not None:
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2010
        return args[arg]
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2011
    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
  2012
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2013
def _expandaliases(aliases, tree, expanding, cache):
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2014
    """Expand aliases in tree, recursively.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2015
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2016
    '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
  2017
    revsetalias objects.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2018
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2019
    if not isinstance(tree, tuple):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2020
        # Do not expand raw strings
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2021
        return tree
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2022
    alias = _getalias(aliases, tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2023
    if alias is not None:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2024
        if alias in expanding:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2025
            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
  2026
                                     'detected') % alias.name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2027
        expanding.append(alias)
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2028
        if alias.name not in cache:
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2029
            cache[alias.name] = _expandaliases(aliases, alias.replacement,
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2030
                                               expanding, cache)
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2031
        result = cache[alias.name]
16772
30e46d7138de revset: fix infinite alias expansion detection
Patrick Mezard <patrick@mezard.eu>
parents: 16771
diff changeset
  2032
        expanding.pop()
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2033
        if alias.args is not None:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2034
            l = getlist(tree[2])
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2035
            if len(l) != len(alias.args):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2036
                raise error.ParseError(
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2037
                    _('invalid number of arguments: %s') % len(l))
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2038
            l = [_expandaliases(aliases, a, [], cache) for a in l]
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2039
            result = _expandargs(result, dict(zip(alias.args, l)))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2040
    else:
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2041
        result = tuple(_expandaliases(aliases, t, expanding, cache)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2042
                       for t in tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2043
    return result
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2044
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2045
def findaliases(ui, tree):
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2046
    _checkaliasarg(tree)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2047
    aliases = {}
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2048
    for k, v in ui.configitems('revsetalias'):
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2049
        alias = revsetalias(k, v)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2050
        aliases[alias.name] = alias
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2051
    return _expandaliases(aliases, tree, [], {})
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2052
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2053
def parse(spec, lookup=None):
20208
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19721
diff changeset
  2054
    p = parser.parser(tokenize, elements)
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2055
    return p.parse(spec, lookup=lookup)
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2056
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2057
def match(ui, spec, repo=None):
11385
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  2058
    if not spec:
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  2059
        raise error.ParseError(_("empty query"))
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2060
    lookup = None
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2061
    if repo:
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2062
        lookup = repo.__contains__
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2063
    tree, pos = parse(spec, lookup)
14496
ffcb7e4d719f revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents: 14356
diff changeset
  2064
    if (pos != len(spec)):
14701
4b93bd041772 parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents: 14650
diff changeset
  2065
        raise error.ParseError(_("invalid token"), pos)
14900
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  2066
    if ui:
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  2067
        tree = findaliases(ui, tree)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2068
    weight, tree = optimize(tree, True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2069
    def mfunc(repo, subset):
22885
e02b16f496f2 match: check if an object is a baseset using `isascending` instead of `set`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22884
diff changeset
  2070
        if util.safehasattr(subset, 'isascending'):
22686
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2071
            result = getset(repo, subset, tree)
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2072
        else:
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2073
            result = getset(repo, baseset(subset), tree)
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2074
        return result
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2075
    return mfunc
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2076
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2077
def formatspec(expr, *args):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2078
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2079
    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
  2080
    escapes arguments appropriately. Aliases are intentionally ignored
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2081
    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
  2082
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2083
    Supported arguments:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2084
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2085
    %r = revset expression, parenthesized
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2086
    %d = int(arg), no quoting
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2087
    %s = string(arg), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2088
    %b = arg.branch(), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2089
    %n = hex(arg), single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2090
    %% = a literal '%'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2091
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2092
    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
  2093
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2094
    >>> 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
  2095
    '(10 or 11):: and ((this()) or (that()))'
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2096
    >>> formatspec('%d:: and not %d::', 10, 20)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2097
    '10:: and not 20::'
15325
cdf1daa3b83f revset: deal with empty lists in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15268
diff changeset
  2098
    >>> formatspec('%ld or %ld', [], [1])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2099
    "_list('') or 1"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2100
    >>> formatspec('keyword(%s)', 'foo\\xe9')
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2101
    "keyword('foo\\\\xe9')"
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2102
    >>> b = lambda: 'default'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2103
    >>> b.branch = b
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2104
    >>> formatspec('branch(%b)', b)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2105
    "branch('default')"
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2106
    >>> 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
  2107
    "root(_list('a\\x00b\\x00c\\x00d'))"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2108
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2109
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2110
    def quote(s):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2111
        return repr(str(s))
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2112
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2113
    def argtype(c, arg):
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2114
        if c == 'd':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2115
            return str(int(arg))
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2116
        elif c == 's':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2117
            return quote(arg)
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2118
        elif c == 'r':
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2119
            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
  2120
            return '(%s)' % arg
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2121
        elif c == 'n':
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  2122
            return quote(node.hex(arg))
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2123
        elif c == 'b':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2124
            return quote(arg.branch())
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2125
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2126
    def listexp(s, t):
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2127
        l = len(s)
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2128
        if l == 0:
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2129
            return "_list('')"
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2130
        elif l == 1:
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2131
            return argtype(t, s[0])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2132
        elif t == 'd':
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2133
            return "_intlist('%s')" % "\0".join(str(int(a)) for a in s)
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2134
        elif t == 's':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2135
            return "_list('%s')" % "\0".join(s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2136
        elif t == 'n':
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2137
            return "_hexlist('%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
  2138
        elif t == 'b':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2139
            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
  2140
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15726
diff changeset
  2141
        m = l // 2
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2142
        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
  2143
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2144
    ret = ''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2145
    pos = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2146
    arg = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2147
    while pos < len(expr):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2148
        c = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2149
        if c == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2150
            pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2151
            d = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2152
            if d == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2153
                ret += d
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2154
            elif d in 'dsnbr':
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2155
                ret += argtype(d, args[arg])
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2156
                arg += 1
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2157
            elif d == 'l':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2158
                # a list of some type
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2159
                pos += 1
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2160
                d = expr[pos]
15596
2555f441a32f merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15595
diff changeset
  2161
                ret += listexp(list(args[arg]), d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2162
                arg += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2163
            else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2164
                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
  2165
        else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2166
            ret += c
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2167
        pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2168
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2169
    return ret
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2170
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2171
def prettyformat(tree):
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2172
    def _prettyformat(tree, level, lines):
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2173
        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
  2174
            lines.append((level, str(tree)))
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2175
        else:
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2176
            lines.append((level, '(%s' % tree[0]))
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2177
            for s in tree[1:]:
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2178
                _prettyformat(s, level + 1, lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2179
            lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')]
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2180
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2181
    lines = []
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2182
    _prettyformat(tree, 0, lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2183
    output = '\n'.join(('  '*l + s) for l, s in lines)
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2184
    return output
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2185
19719
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2186
def depth(tree):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2187
    if isinstance(tree, tuple):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2188
        return max(map(depth, tree)) + 1
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2189
    else:
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2190
        return 0
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2191
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2192
def funcsused(tree):
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2193
    if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2194
        return set()
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2195
    else:
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2196
        funcs = set()
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2197
        for s in tree[1:]:
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2198
            funcs |= funcsused(s)
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2199
        if tree[0] == 'func':
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2200
            funcs.add(tree[1][1])
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2201
        return funcs
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2202
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2203
class abstractsmartset(object):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2204
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2205
    def __nonzero__(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2206
        """True if the smartset is not empty"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2207
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2208
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2209
    def __contains__(self, rev):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2210
        """provide fast membership testing"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2211
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2212
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2213
    def __iter__(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2214
        """iterate the set in the order it is supposed to be iterated"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2215
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2216
22716
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2217
    # Attributes containing a function to perform a fast iteration in a given
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2218
    # direction. A smartset can have none, one, or both defined.
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2219
    #
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2220
    # Default value is None instead of a function returning None to avoid
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2221
    # initializing an iterator just for testing if a fast method exists.
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2222
    fastasc = None
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2223
    fastdesc = None
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2224
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2225
    def isascending(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2226
        """True if the set will iterate in ascending order"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2227
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2228
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2229
    def isdescending(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2230
        """True if the set will iterate in descending order"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2231
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2232
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2233
    def min(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2234
        """return the minimum element in the set"""
22722
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2235
        if self.fastasc is not None:
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2236
            for r in self.fastasc():
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2237
                return r
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2238
            raise ValueError('arg is an empty sequence')
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2239
        return min(self)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2240
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2241
    def max(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2242
        """return the maximum element in the set"""
22722
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2243
        if self.fastdesc is not None:
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2244
            for r in self.fastdesc():
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2245
                return r
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2246
            raise ValueError('arg is an empty sequence')
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2247
        return max(self)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2248
22808
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2249
    def first(self):
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2250
        """return the first element in the set (user iteration perspective)
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2251
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2252
        Return None if the set is empty"""
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2253
        raise NotImplementedError()
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2254
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2255
    def last(self):
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2256
        """return the last element in the set (user iteration perspective)
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2257
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2258
        Return None if the set is empty"""
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2259
        raise NotImplementedError()
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2260
22995
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2261
    def __len__(self):
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2262
        """return the length of the smartsets
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2263
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2264
        This can be expensive on smartset that could be lazy otherwise."""
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2265
        raise NotImplementedError()
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2266
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2267
    def reverse(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2268
        """reverse the expected iteration order"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2269
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2270
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2271
    def sort(self, reverse=True):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2272
        """get the set to iterate in an ascending or descending order"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2273
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2274
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2275
    def __and__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2276
        """Returns a new object with the intersection of the two collections.
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2277
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2278
        This is part of the mandatory API for smartset."""
22864
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2279
        return self.filter(other.__contains__, cache=False)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2280
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2281
    def __add__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2282
        """Returns a new object with the union of the two collections.
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2283
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2284
        This is part of the mandatory API for smartset."""
22861
546fa6576815 revset: restore order of `or` operation as in Mercurial 2.9
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22860
diff changeset
  2285
        return addset(self, other)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2286
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2287
    def __sub__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2288
        """Returns a new object with the substraction of the two collections.
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2289
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2290
        This is part of the mandatory API for smartset."""
22730
aeacc2055f0d abstractsmartset: add default implementation for __sub__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22729
diff changeset
  2291
        c = other.__contains__
22864
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2292
        return self.filter(lambda r: not c(r), cache=False)
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2293
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2294
    def filter(self, condition, cache=True):
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2295
        """Returns this smartset filtered by condition as a new smartset.
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2296
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2297
        `condition` is a callable which takes a revision number and returns a
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2298
        boolean.
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2299
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2300
        This is part of the mandatory API for smartset."""
22864
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2301
        # builtin cannot be cached. but do not needs to
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2302
        if cache and util.safehasattr(condition, 'func_code'):
96b6b3d78697 revset: cache most conditions used in `filter`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22863
diff changeset
  2303
            condition = util.cachefunc(condition)
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2304
        return filteredset(self, condition)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2305
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2306
class baseset(abstractsmartset):
20416
e72bcc245ecb revset: added docstring to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20393
diff changeset
  2307
    """Basic data structure that represents a revset and contains the basic
e72bcc245ecb revset: added docstring to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20393
diff changeset
  2308
    operation that it should be able to perform.
20727
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2309
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2310
    Every method in this class should be implemented by any smartset class.
20416
e72bcc245ecb revset: added docstring to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20393
diff changeset
  2311
    """
20752
6744f4621434 revset: add a default argument for baseset.__init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20751
diff changeset
  2312
    def __init__(self, data=()):
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2313
        if not isinstance(data, list):
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2314
            data = list(data)
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2315
        self._list = data
22827
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2316
        self._ascending = None
20365
bc770ee6a351 revset: implemented set caching for revset evaluation
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20364
diff changeset
  2317
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2318
    @util.propertycache
22879
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2319
    def _set(self):
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2320
        return set(self._list)
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2321
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2322
    @util.propertycache
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2323
    def _asclist(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2324
        asclist = self._list[:]
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2325
        asclist.sort()
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2326
        return asclist
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2327
22827
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2328
    def __iter__(self):
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2329
        if self._ascending is None:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2330
            return iter(self._list)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2331
        elif self._ascending:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2332
            return iter(self._asclist)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2333
        else:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2334
            return reversed(self._asclist)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2335
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2336
    def fastasc(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2337
        return iter(self._asclist)
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2338
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2339
    def fastdesc(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2340
        return reversed(self._asclist)
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2341
22503
300e07582e9b revset: add an optimised baseset.__contains__ (issue4371)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22105
diff changeset
  2342
    @util.propertycache
300e07582e9b revset: add an optimised baseset.__contains__ (issue4371)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22105
diff changeset
  2343
    def __contains__(self):
22880
5b635b44af14 baseset: access `_set` directly for containment check
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22879
diff changeset
  2344
        return self._set.__contains__
22503
300e07582e9b revset: add an optimised baseset.__contains__ (issue4371)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22105
diff changeset
  2345
22691
d8a08b68f754 revset: add a `__nonzero__` to baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22690
diff changeset
  2346
    def __nonzero__(self):
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2347
        return bool(self._list)
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2348
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2349
    def sort(self, reverse=False):
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2350
        self._ascending = not bool(reverse)
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2351
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2352
    def reverse(self):
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2353
        if self._ascending is None:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2354
            self._list.reverse()
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2355
        else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2356
            self._ascending = not self._ascending
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2357
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2358
    def __len__(self):
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2359
        return len(self._list)
22691
d8a08b68f754 revset: add a `__nonzero__` to baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22690
diff changeset
  2360
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2361
    def isascending(self):
20727
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2362
        """Returns True if the collection is ascending order, False if not.
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2363
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2364
        This is part of the mandatory API for smartset."""
22863
a1a02b516cca baseset: empty or one-element sets are ascending and descending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22862
diff changeset
  2365
        if len(self) <= 1:
a1a02b516cca baseset: empty or one-element sets are ascending and descending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22862
diff changeset
  2366
            return True
22828
966860f7a1a8 baseset: fix isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22827
diff changeset
  2367
        return self._ascending is not None and self._ascending
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2368
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2369
    def isdescending(self):
20727
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2370
        """Returns True if the collection is descending order, False if not.
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2371
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2372
        This is part of the mandatory API for smartset."""
22863
a1a02b516cca baseset: empty or one-element sets are ascending and descending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22862
diff changeset
  2373
        if len(self) <= 1:
a1a02b516cca baseset: empty or one-element sets are ascending and descending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22862
diff changeset
  2374
            return True
22828
966860f7a1a8 baseset: fix isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22827
diff changeset
  2375
        return self._ascending is not None and not self._ascending
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2376
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2377
    def first(self):
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2378
        if self:
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2379
            if self._ascending is None:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2380
                return self._list[0]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2381
            elif self._ascending:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2382
                return self._asclist[0]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2383
            else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2384
                return self._asclist[-1]
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2385
        return None
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2386
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2387
    def last(self):
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2388
        if self:
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2389
            if self._ascending is None:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2390
                return self._list[-1]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2391
            elif self._ascending:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2392
                return self._asclist[-1]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2393
            else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2394
                return self._asclist[0]
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2395
        return None
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2396
22726
169aa5e74b52 lazyset: rename the class to filteredset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22725
diff changeset
  2397
class filteredset(abstractsmartset):
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2398
    """Duck type for baseset class which iterates lazily over the revisions in
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2399
    the subset and contains a function which tests for membership in the
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2400
    revset
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2401
    """
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2402
    def __init__(self, subset, condition=lambda x: True):
20738
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2403
        """
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2404
        condition: a function that decide whether a revision in the subset
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2405
                   belongs to the revset or not.
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2406
        """
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2407
        self._subset = subset
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2408
        self._condition = condition
20512
659b8d8ddf19 revset: added cache to lazysets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20499
diff changeset
  2409
        self._cache = {}
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2410
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2411
    def __contains__(self, x):
20512
659b8d8ddf19 revset: added cache to lazysets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20499
diff changeset
  2412
        c = self._cache
659b8d8ddf19 revset: added cache to lazysets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20499
diff changeset
  2413
        if x not in c:
22527
6e38b5d49977 revset: reduce dict lookup in lazyset.__contains__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22526
diff changeset
  2414
            v = c[x] = x in self._subset and self._condition(x)
6e38b5d49977 revset: reduce dict lookup in lazyset.__contains__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22526
diff changeset
  2415
            return v
20512
659b8d8ddf19 revset: added cache to lazysets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20499
diff changeset
  2416
        return c[x]
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2417
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2418
    def __iter__(self):
22719
21fda9dcd4e8 lazyset: split the iteration logic from the condition filtering logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22718
diff changeset
  2419
        return self._iterfilter(self._subset)
21fda9dcd4e8 lazyset: split the iteration logic from the condition filtering logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22718
diff changeset
  2420
21fda9dcd4e8 lazyset: split the iteration logic from the condition filtering logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22718
diff changeset
  2421
    def _iterfilter(self, it):
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2422
        cond = self._condition
22719
21fda9dcd4e8 lazyset: split the iteration logic from the condition filtering logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22718
diff changeset
  2423
        for x in it:
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2424
            if cond(x):
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2425
                yield x
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2426
22720
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2427
    @property
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2428
    def fastasc(self):
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2429
        it = self._subset.fastasc
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2430
        if it is None:
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2431
            return None
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2432
        return lambda: self._iterfilter(it())
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2433
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2434
    @property
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2435
    def fastdesc(self):
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2436
        it = self._subset.fastdesc
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2437
        if it is None:
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2438
            return None
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2439
        return lambda: self._iterfilter(it())
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2440
20552
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  2441
    def __nonzero__(self):
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  2442
        for r in self:
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  2443
            return True
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  2444
        return False
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  2445
20429
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2446
    def __len__(self):
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2447
        # Basic implementation to be changed in future patches.
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2448
        l = baseset([r for r in self])
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2449
        return len(l)
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2450
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2451
    def sort(self, reverse=False):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2452
        self._subset.sort(reverse=reverse)
20429
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2453
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2454
    def reverse(self):
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2455
        self._subset.reverse()
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  2456
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2457
    def isascending(self):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2458
        return self._subset.isascending()
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2459
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2460
    def isdescending(self):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2461
        return self._subset.isdescending()
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2462
22813
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2463
    def first(self):
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2464
        for x in self:
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2465
            return x
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2466
        return None
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2467
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2468
    def last(self):
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2469
        it = None
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2470
        if self._subset.isascending:
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2471
            it = self.fastdesc
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2472
        elif self._subset.isdescending:
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  2473
            it = self.fastdesc
22813
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2474
        if it is None:
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2475
            # slowly consume everything. This needs improvement
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2476
            it = lambda: reversed(list(self))
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2477
        for x in it():
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2478
            return x
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2479
        return None
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  2480
22793
ff6689b47e48 addset: drop the leading underscore from the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22792
diff changeset
  2481
class addset(abstractsmartset):
20708
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  2482
    """Represent the addition of two sets
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  2483
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  2484
    Wrapper structure for lazily adding two structures without losing much
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2485
    performance on the __contains__ method
20708
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  2486
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  2487
    If the ascending attribute is set, that means the two structures are
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  2488
    ordered in either an ascending or descending way. Therefore, we can add
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20991
diff changeset
  2489
    them maintaining the order by iterating over both at the same time
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2490
    """
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  2491
    def __init__(self, revs1, revs2, ascending=None):
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2492
        self._r1 = revs1
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2493
        self._r2 = revs2
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2494
        self._iter = None
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  2495
        self._ascending = ascending
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2496
        self._genlist = None
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2497
        self._asclist = None
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2498
20845
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  2499
    def __len__(self):
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  2500
        return len(self._list)
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  2501
22743
eccf9907b844 addset: add a __nonzero__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22742
diff changeset
  2502
    def __nonzero__(self):
23100
ac494b087feb revset: fix O(2^n) perf regression in addset
Durham Goode <durham@fb.com>
parents: 23078
diff changeset
  2503
        return bool(self._r1) or bool(self._r2)
22743
eccf9907b844 addset: add a __nonzero__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22742
diff changeset
  2504
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2505
    @util.propertycache
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2506
    def _list(self):
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2507
        if not self._genlist:
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2508
            self._genlist = baseset(self._iterator())
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  2509
        return self._genlist
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2510
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2511
    def _iterator(self):
20722
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2512
        """Iterate over both collections without repeating elements
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2513
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2514
        If the ascending attribute is not set, iterate over the first one and
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2515
        then over the second one checking for membership on the first one so we
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2516
        dont yield any duplicates.
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2517
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2518
        If the ascending attribute is set, iterate over both collections at the
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2519
        same time, yielding only one value at a time in the given order.
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  2520
        """
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2521
        if self._ascending is None:
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2522
            def gen():
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2523
                for r in self._r1:
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2524
                    yield r
22881
057ebf7714e1 addset: drop `.set()` usage during iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22880
diff changeset
  2525
                inr1 = self._r1.__contains__
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2526
                for r in self._r2:
22881
057ebf7714e1 addset: drop `.set()` usage during iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22880
diff changeset
  2527
                    if not inr1(r):
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2528
                        yield r
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2529
            gen = gen()
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2530
        else:
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2531
            iter1 = iter(self._r1)
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2532
            iter2 = iter(self._r2)
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2533
            gen = self._iterordered(self._ascending, iter1, iter2)
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  2534
        return gen
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2535
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2536
    def __iter__(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2537
        if self._ascending is None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2538
            if self._genlist:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2539
                return iter(self._genlist)
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2540
            return iter(self._iterator())
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2541
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2542
        if self._ascending:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2543
            it = self.fastasc
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2544
        else:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2545
            it = self.fastdesc
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2546
        if it is None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2547
            # consume the gen and try again
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2548
            self._list
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2549
            return iter(self)
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2550
        return it()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2551
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2552
    def _trysetasclist(self):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  2553
        """populate the _asclist attribute if possible and necessary"""
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2554
        if self._genlist is not None and self._asclist is None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2555
            self._asclist = sorted(self._genlist)
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2556
22742
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2557
    @property
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2558
    def fastasc(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2559
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2560
        if self._asclist is not None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2561
            return self._asclist.__iter__
22742
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2562
        iter1 = self._r1.fastasc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2563
        iter2 = self._r2.fastasc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2564
        if None in (iter1, iter2):
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2565
            return None
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2566
        return lambda: self._iterordered(True, iter1(), iter2())
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2567
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2568
    @property
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2569
    def fastdesc(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2570
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2571
        if self._asclist is not None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2572
            return self._asclist.__reversed__
22742
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2573
        iter1 = self._r1.fastdesc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2574
        iter2 = self._r2.fastdesc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2575
        if None in (iter1, iter2):
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2576
            return None
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2577
        return lambda: self._iterordered(False, iter1(), iter2())
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  2578
22741
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2579
    def _iterordered(self, ascending, iter1, iter2):
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2580
        """produce an ordered iteration from two iterators with the same order
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2581
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2582
        The ascending is used to indicated the iteration direction.
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2583
        """
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2584
        choice = max
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2585
        if ascending:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2586
            choice = min
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2587
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2588
        val1 = None
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2589
        val2 = None
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2590
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2591
        choice = max
22791
a074421fa4e1 addset: use the ascending argument in _iterordered
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22761
diff changeset
  2592
        if ascending:
22741
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2593
            choice = min
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2594
        try:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2595
            # Consume both iterators in an ordered way until one is
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2596
            # empty
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2597
            while True:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2598
                if val1 is None:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2599
                    val1 = iter1.next()
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2600
                if val2 is None:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2601
                    val2 = iter2.next()
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2602
                next = choice(val1, val2)
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2603
                yield next
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2604
                if val1 == next:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2605
                    val1 = None
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2606
                if val2 == next:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2607
                    val2 = None
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2608
        except StopIteration:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2609
            # Flush any remaining values and consume the other one
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2610
            it = iter2
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2611
            if val1 is not None:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2612
                yield val1
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2613
                it = iter1
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2614
            elif val2 is not None:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2615
                # might have been equality and both are empty
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2616
                yield val2
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2617
            for val in it:
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2618
                yield val
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  2619
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2620
    def __contains__(self, x):
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2621
        return x in self._r1 or x in self._r2
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  2622
20724
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2623
    def sort(self, reverse=False):
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2624
        """Sort the added set
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2625
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2626
        For this we use the cached list with all the generated values and if we
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2627
        know they are ascending or descending we can sort them in a smart way.
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2628
        """
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2629
        self._ascending = not reverse
20724
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  2630
20733
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2631
    def isascending(self):
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2632
        return self._ascending is not None and self._ascending
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2633
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2634
    def isdescending(self):
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2635
        return self._ascending is not None and not self._ascending
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  2636
20723
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  2637
    def reverse(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2638
        if self._ascending is None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2639
            self._list.reverse()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  2640
        else:
20723
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  2641
            self._ascending = not self._ascending
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  2642
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  2643
    def first(self):
23127
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2644
        for x in self:
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2645
            return x
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  2646
        return None
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  2647
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  2648
    def last(self):
23127
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2649
        self.reverse()
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2650
        val = self.first()
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2651
        self.reverse()
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  2652
        return val
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  2653
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
  2654
class generatorset(abstractsmartset):
20705
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  2655
    """Wrap a generator for lazy iteration
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  2656
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  2657
    Wrapper structure for generators that provides lazy membership and can
20540
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  2658
    be iterated more than once.
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  2659
    When asked for membership it generates values until either it finds the
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  2660
    requested one or has gone through all the elements in the generator
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  2661
    """
22755
f9a825b593be generatorset: make it possible to use gen as fastasc or fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22754
diff changeset
  2662
    def __init__(self, gen, iterasc=None):
20739
1b4f2399f3c4 revset: add documentation and comment for _generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20738
diff changeset
  2663
        """
1b4f2399f3c4 revset: add documentation and comment for _generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20738
diff changeset
  2664
        gen: a generator producing the values for the generatorset.
1b4f2399f3c4 revset: add documentation and comment for _generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20738
diff changeset
  2665
        """
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2666
        self._gen = gen
22798
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2667
        self._asclist = None
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2668
        self._cache = {}
22796
43f664bf2e1e generatorset: stop using a base as the _genlist
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22795
diff changeset
  2669
        self._genlist = []
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  2670
        self._finished = False
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2671
        self._ascending = True
22755
f9a825b593be generatorset: make it possible to use gen as fastasc or fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22754
diff changeset
  2672
        if iterasc is not None:
f9a825b593be generatorset: make it possible to use gen as fastasc or fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22754
diff changeset
  2673
            if iterasc:
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  2674
                self.fastasc = self._iterator
22757
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2675
                self.__contains__ = self._asccontains
22755
f9a825b593be generatorset: make it possible to use gen as fastasc or fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22754
diff changeset
  2676
            else:
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  2677
                self.fastdesc = self._iterator
22757
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2678
                self.__contains__ = self._desccontains
20540
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  2679
22739
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  2680
    def __nonzero__(self):
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  2681
        for r in self:
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  2682
            return True
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  2683
        return False
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  2684
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2685
    def __contains__(self, x):
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2686
        if x in self._cache:
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2687
            return self._cache[x]
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2688
20828
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  2689
        # Use new values only, as existing values would be cached.
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  2690
        for l in self._consumegen():
20634
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  2691
            if l == x:
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  2692
                return True
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2693
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2694
        self._cache[x] = False
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2695
        return False
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2696
22757
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2697
    def _asccontains(self, x):
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2698
        """version of contains optimised for ascending generator"""
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2699
        if x in self._cache:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2700
            return self._cache[x]
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2701
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2702
        # Use new values only, as existing values would be cached.
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2703
        for l in self._consumegen():
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2704
            if l == x:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2705
                return True
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2706
            if l > x:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2707
                break
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2708
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2709
        self._cache[x] = False
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2710
        return False
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2711
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2712
    def _desccontains(self, x):
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2713
        """version of contains optimised for descending generator"""
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2714
        if x in self._cache:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2715
            return self._cache[x]
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2716
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2717
        # Use new values only, as existing values would be cached.
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2718
        for l in self._consumegen():
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2719
            if l == x:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2720
                return True
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2721
            if l < x:
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2722
                break
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2723
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2724
        self._cache[x] = False
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2725
        return False
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  2726
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  2727
    def __iter__(self):
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2728
        if self._ascending:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2729
            it = self.fastasc
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2730
        else:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2731
            it = self.fastdesc
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2732
        if it is not None:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2733
            return it()
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2734
        # we need to consume the iterator
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2735
        for x in self._consumegen():
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2736
            pass
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2737
        # recall the same code
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2738
        return iter(self)
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  2739
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  2740
    def _iterator(self):
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  2741
        if self._finished:
22670
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2742
            return iter(self._genlist)
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  2743
22494
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  2744
        # We have to use this complex iteration strategy to allow multiple
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  2745
        # iterations at the same time. We need to be able to catch revision
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  2746
        # removed from _consumegen and added to genlist in another instance.
22494
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  2747
        #
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  2748
        # Getting rid of it would provide an about 15% speed up on this
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  2749
        # iteration.
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  2750
        genlist = self._genlist
22669
00c8abe64cf3 revset: prefetch an attribute in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22539
diff changeset
  2751
        nextrev = self._consumegen().next
00c8abe64cf3 revset: prefetch an attribute in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22539
diff changeset
  2752
        _len = len # cache global lookup
22670
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2753
        def gen():
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2754
            i = 0
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2755
            while True:
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2756
                if i < _len(genlist):
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2757
                    yield genlist[i]
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2758
                else:
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2759
                    yield nextrev()
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2760
                i += 1
44dce874de97 revset: rely on built in iterator when possible in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22669
diff changeset
  2761
        return gen()
20828
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  2762
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  2763
    def _consumegen(self):
22528
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  2764
        cache = self._cache
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  2765
        genlist = self._genlist.append
20634
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  2766
        for item in self._gen:
22528
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  2767
            cache[item] = True
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  2768
            genlist(item)
20634
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  2769
            yield item
22798
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2770
        if not self._finished:
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2771
            self._finished = True
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2772
            asc = self._genlist[:]
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2773
            asc.sort()
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2774
            self._asclist = asc
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2775
            self.fastasc = asc.__iter__
586d7058ea48 generatorset: get list-based fast iterations after the generator is consumed
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22797
diff changeset
  2776
            self.fastdesc = asc.__reversed__
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  2777
22996
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  2778
    def __len__(self):
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  2779
        for x in self._consumegen():
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  2780
            pass
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  2781
        return len(self._genlist)
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  2782
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  2783
    def sort(self, reverse=False):
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2784
        self._ascending = not reverse
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2785
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2786
    def reverse(self):
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  2787
        self._ascending = not self._ascending
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  2788
22801
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2789
    def isascending(self):
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2790
        return self._ascending
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2791
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2792
    def isdescending(self):
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2793
        return not self._ascending
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  2794
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2795
    def first(self):
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2796
        if self._ascending:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2797
            it = self.fastasc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2798
        else:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2799
            it = self.fastdesc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2800
        if it is None:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2801
            # we need to consume all and try again
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2802
            for x in self._consumegen():
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2803
                pass
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2804
            return self.first()
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2805
        if self:
23413
0c432696dae3 revset: fix first and last for generatorset (issue4465)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23127
diff changeset
  2806
            return it().next()
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2807
        return None
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2808
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2809
    def last(self):
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2810
        if self._ascending:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2811
            it = self.fastdesc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2812
        else:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2813
            it = self.fastasc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2814
        if it is None:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2815
            # we need to consume all and try again
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2816
            for x in self._consumegen():
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2817
                pass
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2818
            return self.first()
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2819
        if self:
23413
0c432696dae3 revset: fix first and last for generatorset (issue4465)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23127
diff changeset
  2820
            return it().next()
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2821
        return None
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  2822
22509
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2823
def spanset(repo, start=None, end=None):
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2824
    """factory function to dispatch between fullreposet and actual spanset
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2825
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2826
    Feel free to update all spanset call sites and kill this function at some
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2827
    point.
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2828
    """
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2829
    if start is None and end is None:
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2830
        return fullreposet(repo)
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2831
    return _spanset(repo, start, end)
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2832
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2833
22752
7bbc35c43bff spanset: drop _orderedsetmixin inheritance
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22751
diff changeset
  2834
class _spanset(abstractsmartset):
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2835
    """Duck type for baseset class which represents a range of revisions and
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2836
    can work lazily and without having all the range in memory
20737
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2837
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2838
    Note that spanset(x, y) behave almost like xrange(x, y) except for two
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2839
    notable points:
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2840
    - when x < y it will be automatically descending,
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2841
    - revision filtered with this repoview will be skipped.
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2842
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2843
    """
20525
aa73a6327df4 revset: changed spanset to take a repo argument
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20521
diff changeset
  2844
    def __init__(self, repo, start=0, end=None):
20737
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2845
        """
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2846
        start: first revision included the set
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2847
               (default to 0)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2848
        end:   first revision excluded (last+1)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2849
               (default to len(repo)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2850
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2851
        Spanset will be descending if `end` < `start`.
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  2852
        """
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2853
        if end is None:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2854
            end = len(repo)
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2855
        self._ascending = start <= end
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2856
        if not self._ascending:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2857
            start, end = end + 1, start +1
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2858
        self._start = start
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2859
        self._end = end
20525
aa73a6327df4 revset: changed spanset to take a repo argument
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20521
diff changeset
  2860
        self._hiddenrevs = repo.changelog.filteredrevs
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2861
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2862
    def sort(self, reverse=False):
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2863
        self._ascending = not reverse
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2864
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2865
    def reverse(self):
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2866
        self._ascending = not self._ascending
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2867
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2868
    def _iterfilter(self, iterrange):
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2869
        s = self._hiddenrevs
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2870
        for r in iterrange:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2871
            if r not in s:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2872
                yield r
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2873
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2874
    def __iter__(self):
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2875
        if self._ascending:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2876
            return self.fastasc()
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2877
        else:
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2878
            return self.fastdesc()
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2879
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2880
    def fastasc(self):
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2881
        iterrange = xrange(self._start, self._end)
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2882
        if self._hiddenrevs:
22717
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2883
            return self._iterfilter(iterrange)
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2884
        return iter(iterrange)
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2885
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2886
    def fastdesc(self):
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2887
        iterrange = xrange(self._end - 1, self._start - 1, -1)
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2888
        if self._hiddenrevs:
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2889
            return self._iterfilter(iterrange)
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  2890
        return iter(iterrange)
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2891
21201
c8b9c6147108 revset: fix revision filtering in spanset.contains (regression)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21199
diff changeset
  2892
    def __contains__(self, rev):
22526
1e6d2b6b37ea revset: do less lookup during spanset.__contains__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22510
diff changeset
  2893
        hidden = self._hiddenrevs
22718
7b123e5639f4 spanset: do a single range check in __contains__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22717
diff changeset
  2894
        return ((self._start <= rev < self._end)
22526
1e6d2b6b37ea revset: do less lookup during spanset.__contains__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22510
diff changeset
  2895
                and not (hidden and rev in hidden))
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  2896
20716
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  2897
    def __nonzero__(self):
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  2898
        for r in self:
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  2899
            return True
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  2900
        return False
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  2901
20484
0f1ef9e9e904 revset: added operations to spanset to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20483
diff changeset
  2902
    def __len__(self):
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2903
        if not self._hiddenrevs:
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2904
            return abs(self._end - self._start)
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2905
        else:
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2906
            count = 0
21205
e2031c8ca4f8 revset: also inline spanset._contained in __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21204
diff changeset
  2907
            start = self._start
e2031c8ca4f8 revset: also inline spanset._contained in __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21204
diff changeset
  2908
            end = self._end
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2909
            for rev in self._hiddenrevs:
21284
3e53a64345c1 revset: cosmetic changes in spanset range comparison
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21283
diff changeset
  2910
                if (end < rev <= start) or (start <= rev < end):
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2911
                    count += 1
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  2912
            return abs(self._end - self._start) - count
20484
0f1ef9e9e904 revset: added operations to spanset to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20483
diff changeset
  2913
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2914
    def isascending(self):
22481
8488955127b0 revset: wider definition of ascending and descending for spanset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22451
diff changeset
  2915
        return self._start <= self._end
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2916
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2917
    def isdescending(self):
22481
8488955127b0 revset: wider definition of ascending and descending for spanset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22451
diff changeset
  2918
        return self._start >= self._end
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2919
22809
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2920
    def first(self):
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2921
        if self._ascending:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2922
            it = self.fastasc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2923
        else:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2924
            it = self.fastdesc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2925
        for x in it():
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2926
            return x
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2927
        return None
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2928
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2929
    def last(self):
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2930
        if self._ascending:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2931
            it = self.fastdesc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2932
        else:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2933
            it = self.fastasc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2934
        for x in it():
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2935
            return x
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2936
        return None
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  2937
22509
fbae659543cf revset: turn spanset into a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22508
diff changeset
  2938
class fullreposet(_spanset):
22508
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2939
    """a set containing all revisions in the repo
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2940
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  2941
    This class exists to host special optimization.
22508
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2942
    """
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2943
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2944
    def __init__(self, repo):
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2945
        super(fullreposet, self).__init__(repo)
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  2946
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2947
    def __and__(self, other):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  2948
        """As self contains the whole repo, all of the other set should also be
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  2949
        in self. Therefore `self & other = other`.
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2950
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2951
        This boldly assumes the other contains valid revs only.
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2952
        """
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2953
        # other not a smartset, make is so
22883
e7b8cf352614 fullreposet: detect smartset using "isascending" instead of "set"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22882
diff changeset
  2954
        if not util.safehasattr(other, 'isascending'):
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2955
            # filter out hidden revision
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2956
            # (this boldly assumes all smartset are pure)
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2957
            #
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2958
            # `other` was used with "&", let's assume this is a set like
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2959
            # object.
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2960
            other = baseset(other - self._hiddenrevs)
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2961
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2962
        if self.isascending():
22833
6f4109aa6877 fullreposet: use `sort` to enforce the order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22832
diff changeset
  2963
            other.sort()
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2964
        else:
22833
6f4109aa6877 fullreposet: use `sort` to enforce the order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22832
diff changeset
  2965
            other.sort(reverse)
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2966
        return other
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  2967
12823
80deae3bc5ea hggettext: handle i18nfunctions declaration for docstrings translations
Patrick Mezard <pmezard@gmail.com>
parents: 12821
diff changeset
  2968
# 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
  2969
i18nfunctions = symbols.values()