mercurial/revset.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Thu, 24 Mar 2016 00:09:58 -0700
changeset 28617 1a1e4350b560
parent 28445 d749b1832d2f
child 28689 a14732e08fec
permissions -rw-r--r--
graphmod: move the graphstyle options to experimental I let this slip in the [ui] section during the review, as far as I understand we don't plan to actually support customisation of the output on we are happy with our choice. The option are just here to help people tests various options so we can decide which one we'll actually use. I'm moving the config option in the experimental section to make this clearer and avoid making them part of the public API by mistake.
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
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
     8
from __future__ import absolute_import
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
     9
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    10
import heapq
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    11
import re
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    12
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    13
from .i18n import _
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    14
from . import (
26713
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
    15
    destutil,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    16
    encoding,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    17
    error,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    18
    hbisect,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    19
    match as matchmod,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    20
    node,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    21
    obsolete as obsmod,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    22
    parser,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    23
    pathutil,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    24
    phases,
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
    25
    registrar,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    26
    repoview,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    27
    util,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    28
)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    30
def _revancestors(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    31
    """Like revlog.ancestors(), but supports followfirst."""
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    32
    if followfirst:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    33
        cut = 1
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    34
    else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    35
        cut = None
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    36
    cl = repo.changelog
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    37
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    38
    def iterate():
22832
2f1d2a42f040 revancestors: replace `descending` with `sort(reverse=False)`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22831
diff changeset
    39
        revs.sort(reverse=True)
24939
85544a52ee84 revset: use an iterator instead of a dequeue in ancestors()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24938
diff changeset
    40
        irevs = iter(revs)
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    41
        h = []
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    42
25143
91c49621b2b8 _revancestors: use 'next' to remove the verbose try except clauses
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25131
diff changeset
    43
        inputrev = next(irevs, None)
91c49621b2b8 _revancestors: use 'next' to remove the verbose try except clauses
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25131
diff changeset
    44
        if inputrev is not None:
24939
85544a52ee84 revset: use an iterator instead of a dequeue in ancestors()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24938
diff changeset
    45
            heapq.heappush(h, -inputrev)
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    46
23956
b1e026c25552 revset: fix ancestors(null) to include null revision (issue4512)
Yuya Nishihara <yuya@tcha.org>
parents: 23954
diff changeset
    47
        seen = set()
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    48
        while h:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    49
            current = -heapq.heappop(h)
24940
6b54f749659b revset: avoid returning duplicates when returning ancestors
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24939
diff changeset
    50
            if current == inputrev:
25143
91c49621b2b8 _revancestors: use 'next' to remove the verbose try except clauses
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25131
diff changeset
    51
                inputrev = next(irevs, None)
91c49621b2b8 _revancestors: use 'next' to remove the verbose try except clauses
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25131
diff changeset
    52
                if inputrev is not None:
24940
6b54f749659b revset: avoid returning duplicates when returning ancestors
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24939
diff changeset
    53
                    heapq.heappush(h, -inputrev)
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    54
            if current not in seen:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    55
                seen.add(current)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    56
                yield current
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    57
                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
    58
                    if parent != node.nullrev:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    59
                        heapq.heappush(h, -parent)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    60
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    61
    return generatorset(iterate(), iterasc=False)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    62
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    63
def _revdescendants(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    64
    """Like revlog.descendants() but supports followfirst."""
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    65
    if followfirst:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    66
        cut = 1
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    67
    else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    68
        cut = None
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    69
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    70
    def iterate():
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    71
        cl = repo.changelog
25549
f93ff3ab8d14 revset: mark spots that should use 'smartset.min()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25548
diff changeset
    72
        # XXX this should be 'parentset.min()' assuming 'parentset' is a
f93ff3ab8d14 revset: mark spots that should use 'smartset.min()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25548
diff changeset
    73
        # smartset (and if it is not, it should.)
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    74
        first = min(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    75
        nullrev = node.nullrev
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    76
        if first == nullrev:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    77
            # 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
    78
            # 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
    79
            for i in cl:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    80
                yield i
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    81
        else:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    82
            seen = set(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    83
            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
    84
                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
    85
                    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
    86
                        seen.add(i)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    87
                        yield i
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    88
                        break
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    89
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    90
    return generatorset(iterate(), iterasc=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    91
26095
6eed95ca4c03 revset: mark reachablerootspure as private
Yuya Nishihara <yuya@tcha.org>
parents: 26094
diff changeset
    92
def _reachablerootspure(repo, minroot, roots, heads, includepath):
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
    93
    """return (heads(::<roots> and ::<heads>))
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
    94
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
    95
    If includepath is True, return (<roots>::<heads>)."""
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    96
    if not roots:
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
    97
        return []
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
    98
    parentrevs = repo.changelog.parentrevs
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26006
diff changeset
    99
    roots = set(roots)
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
   100
    visit = list(heads)
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   101
    reachable = set()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   102
    seen = {}
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   103
    # prefetch all the things! (because python is slow)
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   104
    reached = reachable.add
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   105
    dovisit = visit.append
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   106
    nextvisit = visit.pop
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   107
    # 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
   108
    # sys.getrecursionlimit()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   109
    while visit:
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   110
        rev = nextvisit()
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   111
        if rev in roots:
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   112
            reached(rev)
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   113
            if not includepath:
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   114
                continue
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   115
        parents = parentrevs(rev)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   116
        seen[rev] = parents
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   117
        for parent in parents:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   118
            if parent >= minroot and parent not in seen:
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   119
                dovisit(parent)
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   120
    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
   121
        return baseset()
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   122
    if not includepath:
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   123
        return reachable
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   124
    for rev in sorted(seen):
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   125
        for parent in seen[rev]:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   126
            if parent in reachable:
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   127
                reached(rev)
26091
60bbd4f9abd1 reachableroots: sort the smartset in the pure version too
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26060
diff changeset
   128
    return reachable
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   129
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   130
def reachableroots(repo, roots, heads, includepath=False):
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   131
    """return (heads(::<roots> and ::<heads>))
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   132
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   133
    If includepath is True, return (<roots>::<heads>)."""
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   134
    if not roots:
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   135
        return baseset()
26093
204131131766 reachableroots: use smartset min
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26091
diff changeset
   136
    minroot = roots.min()
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26006
diff changeset
   137
    roots = list(roots)
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   138
    heads = list(heads)
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   139
    try:
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   140
        revs = repo.changelog.reachableroots(minroot, heads, roots, includepath)
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   141
    except AttributeError:
26095
6eed95ca4c03 revset: mark reachablerootspure as private
Yuya Nishihara <yuya@tcha.org>
parents: 26094
diff changeset
   142
        revs = _reachablerootspure(repo, minroot, roots, heads, includepath)
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   143
    revs = baseset(revs)
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   144
    revs.sort()
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   145
    return revs
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   146
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   147
elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   148
    # token-type: binding-strength, primary, prefix, infix, suffix
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   149
    "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   150
    "##": (20, None, None, ("_concat", 20), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   151
    "~": (18, None, None, ("ancestor", 18), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   152
    "^": (18, None, None, ("parent", 18), ("parentpost", 18)),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   153
    "-": (5, None, ("negate", 19), ("minus", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   154
    "::": (17, None, ("dagrangepre", 17), ("dagrange", 17),
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   155
           ("dagrangepost", 17)),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   156
    "..": (17, None, ("dagrangepre", 17), ("dagrange", 17),
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   157
           ("dagrangepost", 17)),
25819
be29d26e2949 revset: parse nullary ":" operator as "0:tip"
Yuya Nishihara <yuya@tcha.org>
parents: 25815
diff changeset
   158
    ":": (15, "rangeall", ("rangepre", 15), ("range", 15), ("rangepost", 15)),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   159
    "not": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   160
    "!": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   161
    "and": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   162
    "&": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   163
    "%": (5, None, None, ("only", 5), ("onlypost", 5)),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   164
    "or": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   165
    "|": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   166
    "+": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   167
    "=": (3, None, None, ("keyvalue", 3), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   168
    ",": (2, None, None, ("list", 2), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   169
    ")": (0, None, None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   170
    "symbol": (0, "symbol", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   171
    "string": (0, "string", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   172
    "end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   174
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   177
# default set of valid characters for the initial letter of symbols
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   178
_syminitletters = set(c for c in [chr(i) for i in xrange(256)]
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   179
                      if c.isalnum() or c in '._@' or ord(c) > 127)
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   180
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   181
# default set of valid characters for non-initial letters of symbols
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   182
_symletters = set(c for c in  [chr(i) for i in xrange(256)]
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   183
                  if c.isalnum() or c in '-._/@' or ord(c) > 127)
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   184
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   185
def tokenize(program, lookup=None, syminitletters=None, symletters=None):
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   186
    '''
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   187
    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
   188
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   189
    ``syminitletters`` is the set of valid characters for the initial
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   190
    letter of symbols.
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   191
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   192
    By default, character ``c`` is recognized as valid for initial
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   193
    letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``.
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   194
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   195
    ``symletters`` is the set of valid characters for non-initial
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   196
    letters of symbols.
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   197
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   198
    By default, character ``c`` is recognized as valid for non-initial
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   199
    letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   200
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   201
    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
   202
    >>> list(tokenize("@::"))
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   203
    [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   204
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   205
    '''
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   206
    if syminitletters is None:
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   207
        syminitletters = _syminitletters
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   208
    if symletters is None:
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   209
        symletters = _symletters
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   210
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   211
    if program and lookup:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   212
        # attempt to parse old-style ranges first to deal with
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   213
        # things like old-tag which contain query metacharacters
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   214
        parts = program.split(':', 1)
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   215
        if all(lookup(sym) for sym in parts if sym):
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   216
            if parts[0]:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   217
                yield ('symbol', parts[0], 0)
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   218
            if len(parts) > 1:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   219
                s = len(parts[0])
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   220
                yield (':', None, s)
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   221
                if parts[1]:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   222
                    yield ('symbol', parts[1], s + 1)
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   223
            yield ('end', None, len(program))
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   224
            return
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   225
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   226
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   227
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   228
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   229
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   230
            pass
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   231
        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
   232
            yield ('::', None, pos)
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   233
            pos += 1 # skip ahead
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   234
        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
   235
            yield ('..', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   236
            pos += 1 # skip ahead
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
   237
        elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
   238
            yield ('##', None, pos)
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
   239
            pos += 1 # skip ahead
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   240
        elif c in "():=,-|&+!~^%": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   241
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   242
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   243
              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
   244
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   245
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   246
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   247
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   248
            else:
26232
43f9976346e9 revset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26212
diff changeset
   249
                decode = parser.unescapestr
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   250
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   251
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   252
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   253
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   254
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   255
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   256
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   257
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   258
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   259
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   260
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   261
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   262
                raise error.ParseError(_("unterminated string"), s)
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   263
        # gather up a symbol/keyword
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   264
        elif c in syminitletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   265
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   266
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   267
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   268
                d = program[pos]
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   269
                if d not in symletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   270
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   271
                if d == '.' and program[pos - 1] == '.': # special case for ..
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   272
                    pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   273
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   274
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   275
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   276
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   277
                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
   278
            elif '-' in sym:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   279
                # 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
   280
                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
   281
                    # 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
   282
                    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
   283
                else:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   284
                    # 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
   285
                    parts = sym.split('-')
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   286
                    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
   287
                        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
   288
                            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
   289
                        s += len(p)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   290
                        yield ('-', None, pos)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   291
                        s += 1
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   292
                    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
   293
                        yield ('symbol', parts[-1], s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   294
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   295
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   296
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   297
        else:
24708
fb47816e1a9c revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents: 24518
diff changeset
   298
            raise error.ParseError(_("syntax error in revset '%s'") %
fb47816e1a9c revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents: 24518
diff changeset
   299
                                   program, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   300
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   301
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   302
23843
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   303
def parseerrordetail(inst):
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   304
    """Compose error message from specified ParseError object
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   305
    """
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   306
    if len(inst.args) > 1:
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   307
        return _('at %s: %s') % (inst.args[1], inst.args[0])
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   308
    else:
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   309
        return inst.args[0]
c4d0c3d05721 revset: factor out composing error message for ParseError to reuse
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23842
diff changeset
   310
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   311
# helpers
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   312
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   313
def getstring(x, err):
11406
42408cd43f55 revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents: 11404
diff changeset
   314
    if x and (x[0] == 'string' or x[0] == 'symbol'):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   315
        return x[1]
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   316
    raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   317
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   318
def getlist(x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   319
    if not x:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   320
        return []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   321
    if x[0] == 'list':
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
   322
        return list(x[1:])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   323
    return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   324
11339
744d5b73f776 revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents: 11304
diff changeset
   325
def getargs(x, min, max, err):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   326
    l = getlist(x)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   327
    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
   328
        raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   329
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   330
25767
026105c442d7 revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 25766
diff changeset
   331
def getargsdict(x, funcname, keys):
25705
48919d246a47 revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25704
diff changeset
   332
    return parser.buildargsdict(getlist(x), funcname, keys.split(),
48919d246a47 revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25704
diff changeset
   333
                                keyvaluenode='keyvalue', keynode='symbol')
48919d246a47 revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25704
diff changeset
   334
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   335
def isvalidsymbol(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   336
    """Examine whether specified ``tree`` is valid ``symbol`` or not
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   337
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   338
    return tree[0] == 'symbol' and len(tree) > 1
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   339
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   340
def getsymbol(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   341
    """Get symbol name from valid ``symbol`` in ``tree``
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   342
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   343
    This assumes that ``tree`` is already examined by ``isvalidsymbol``.
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   344
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   345
    return tree[1]
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   346
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   347
def isvalidfunc(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   348
    """Examine whether specified ``tree`` is valid ``func`` or not
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   349
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   350
    return tree[0] == 'func' and len(tree) > 1 and isvalidsymbol(tree[1])
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   351
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   352
def getfuncname(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   353
    """Get function name from valid ``func`` in ``tree``
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   354
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   355
    This assumes that ``tree`` is already examined by ``isvalidfunc``.
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   356
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   357
    return getsymbol(tree[1])
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   358
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   359
def getfuncargs(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   360
    """Get list of function arguments from valid ``func`` in ``tree``
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   361
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   362
    This assumes that ``tree`` is already examined by ``isvalidfunc``.
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   363
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   364
    if len(tree) > 2:
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   365
        return getlist(tree[2])
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   366
    else:
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   367
        return []
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
   368
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   369
def getset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   370
    if not x:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   371
        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
   372
    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
   373
    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
   374
        return s
25630
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   375
    if (repo.ui.configbool('devel', 'all-warnings')
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   376
            or repo.ui.configbool('devel', 'old-revset')):
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   377
        # else case should not happen, because all non-func are internal,
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   378
        # ignoring for now.
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   379
        if x[0] == 'func' and x[1][0] == 'symbol' and x[1][1] in symbols:
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   380
            repo.ui.develwarn('revset "%s" use list instead of smartset, '
c88082baf693 devel-warn: issue a warning for old style revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25622
diff changeset
   381
                              '(upgrade your code)' % x[1][1])
20527
bde426f18e0a revset: changed mfunc and getset to work with old style revset methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20526
diff changeset
   382
    return baseset(s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   383
17003
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   384
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
   385
    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
   386
    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
   387
        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
   388
            try:
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   389
                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
   390
            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
   391
                pass
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   392
    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
   393
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   394
# operator methods
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   395
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   396
def stringset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   397
    x = repo[x].rev()
25265
e16456831516 revset: drop magic of fullreposet membership test (issue4682)
Yuya Nishihara <yuya@tcha.org>
parents: 25094
diff changeset
   398
    if (x in subset
e16456831516 revset: drop magic of fullreposet membership test (issue4682)
Yuya Nishihara <yuya@tcha.org>
parents: 25094
diff changeset
   399
        or x == node.nullrev and isinstance(subset, fullreposet)):
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
   400
        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
   401
    return baseset()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   402
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   403
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
   404
    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
   405
    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
   406
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   407
    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
   408
        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
   409
    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
   410
25766
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   411
    if m == n:
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   412
        r = baseset([m])
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   413
    elif n == node.wdirrev:
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   414
        r = spanset(repo, m, len(repo)) + baseset([n])
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   415
    elif m == node.wdirrev:
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   416
        r = baseset([m]) + spanset(repo, len(repo) - 1, n - 1)
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   417
    elif m < n:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   418
        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
   419
    else:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   420
        r = spanset(repo, m, n - 1)
25548
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   421
    # XXX We should combine with subset first: 'subset & baseset(...)'. This is
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   422
    # necessary to ensure we preserve the order in subset.
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   423
    #
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   424
    # This has performance implication, carrying the sorting over when possible
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   425
    # would be more efficient.
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   426
    return r & subset
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   427
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
   428
def dagrange(repo, subset, x, y):
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   429
    r = fullreposet(repo)
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   430
    xs = reachableroots(repo, getset(repo, r, x), getset(repo, r, y),
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   431
                         includepath=True)
25548
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   432
    # XXX We should combine with subset first: 'subset & baseset(...)'. This is
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
   433
    # necessary to ensure we preserve the order in subset.
22866
6e739356f9bf revset-rangeset: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22865
diff changeset
   434
    return xs & subset
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
   435
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   436
def andset(repo, subset, x, y):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   437
    return getset(repo, getset(repo, subset, x), y)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   438
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
   439
def differenceset(repo, subset, x, y):
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
   440
    return getset(repo, subset, x) - getset(repo, subset, y)
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
   441
25309
b333ca94403d revset: reduce nesting of chained 'or' operations (issue4624)
Yuya Nishihara <yuya@tcha.org>
parents: 25308
diff changeset
   442
def orset(repo, subset, *xs):
25929
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   443
    assert xs
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   444
    if len(xs) == 1:
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   445
        return getset(repo, subset, xs[0])
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   446
    p = len(xs) // 2
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   447
    a = orset(repo, subset, *xs[:p])
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   448
    b = orset(repo, subset, *xs[p:])
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   449
    return a + b
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   450
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   451
def notset(repo, subset, x):
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   452
    return subset - getset(repo, subset, x)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   453
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
   454
def listset(repo, subset, *xs):
27517
c60a9c16ae25 revset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27440
diff changeset
   455
    raise error.ParseError(_("can't use a list in this context"),
c60a9c16ae25 revset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27440
diff changeset
   456
                           hint=_('see hg help "revsets.x or y"'))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   457
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   458
def keyvaluepair(repo, subset, k, v):
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   459
    raise error.ParseError(_("can't use a key-value pair in this context"))
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   460
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   461
def func(repo, subset, a, b):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   462
    if a[0] == 'symbol' and a[1] in symbols:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   463
        return symbols[a[1]](repo, subset, b)
25632
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   464
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   465
    keep = lambda fn: getattr(fn, '__doc__', None) is not None
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   466
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   467
    syms = [s for (s, fn) in symbols.items() if keep(fn)]
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   468
    raise error.UnknownIdentifier(a[1], syms)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   469
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   470
# functions
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   471
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   472
# symbols are callables like:
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   473
#   fn(repo, subset, x)
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   474
# with:
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   475
#   repo - current repository instance
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   476
#   subset - of revisions to be examined
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   477
#   x - argument in tree form
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   478
symbols = {}
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   479
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   480
# symbols which can't be used for a DoS attack for any given input
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   481
# (e.g. those which accept regexes as plain strings shouldn't be included)
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   482
# functions that just return a lot of changesets (like all) don't count here
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   483
safesymbols = set()
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   484
28395
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
   485
predicate = registrar.revsetpredicate()
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   486
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   487
@predicate('_destupdate')
26713
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   488
def _destupdate(repo, subset, x):
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   489
    # experimental revset for update destination
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   490
    args = getargsdict(x, 'limit', 'clean check')
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   491
    return subset & baseset([destutil.destupdate(repo, **args)[0]])
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   492
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   493
@predicate('_destmerge')
26716
c027641f8a83 revset: rename and test '_destmerge'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26714
diff changeset
   494
def _destmerge(repo, subset, x):
c027641f8a83 revset: rename and test '_destmerge'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26714
diff changeset
   495
    # experimental revset for merge destination
28139
5476a7a039c0 destutil: allow to specify an explicit source for the merge
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28015
diff changeset
   496
    sourceset = None
5476a7a039c0 destutil: allow to specify an explicit source for the merge
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28015
diff changeset
   497
    if x is not None:
5476a7a039c0 destutil: allow to specify an explicit source for the merge
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28015
diff changeset
   498
        sourceset = getset(repo, fullreposet(repo), x)
5476a7a039c0 destutil: allow to specify an explicit source for the merge
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28015
diff changeset
   499
    return subset & baseset([destutil.destmerge(repo, sourceset=sourceset)])
26303
c99b4d6efdd8 merge: move default destination computation in a revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26232
diff changeset
   500
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   501
@predicate('adds(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   502
def adds(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   503
    """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
   504
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   505
    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
   506
    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
   507
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   508
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   509
    # i18n: "adds" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   510
    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
   511
    return checkstatus(repo, subset, pat, 1)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   512
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   513
@predicate('ancestor(*changeset)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   514
def ancestor(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   515
    """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
   516
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   517
    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
   518
    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
   519
    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
   520
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   521
    # 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
   522
    l = getlist(x)
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   523
    rl = fullreposet(repo)
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   524
    anc = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   525
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   526
    # (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
   527
    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
   528
        for r in revs:
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   529
            if anc is None:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   530
                anc = repo[r]
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   531
            else:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   532
                anc = anc.ancestor(repo[r])
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   533
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   534
    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
   535
        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
   536
    return baseset()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   537
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   538
def _ancestors(repo, subset, x, followfirst=False):
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   539
    heads = getset(repo, fullreposet(repo), x)
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   540
    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
   541
        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
   542
    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
   543
    return subset & s
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   544
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   545
@predicate('ancestors(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   546
def ancestors(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   547
    """Changesets that are ancestors of a changeset in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   548
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   549
    return _ancestors(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   550
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   551
@predicate('_firstancestors', safe=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   552
def _firstancestors(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   553
    # ``_firstancestors(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   554
    # 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
   555
    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
   556
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   557
def ancestorspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   558
    """``set~n``
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   559
    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
   560
    in set.
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   561
    """
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   562
    try:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   563
        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
   564
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   565
        raise error.ParseError(_("~ expects a number"))
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   566
    ps = set()
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   567
    cl = repo.changelog
23163
6f1b8b3f12fd revset-ancestorspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23162
diff changeset
   568
    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
   569
        for i in range(n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   570
            r = cl.parentrevs(r)[0]
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   571
        ps.add(r)
22531
22ba2c0825da revset: use `subset &` in `ancestorspec`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22530
diff changeset
   572
    return subset & ps
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   573
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   574
@predicate('author(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   575
def author(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   576
    """Alias for ``user(string)``.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   577
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   578
    # 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
   579
    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
   580
    kind, pattern, matcher = _substringmatcher(n)
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   581
    return subset.filter(lambda x: matcher(encoding.lower(repo[x].user())),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   582
                         condrepr=('<user %r>', n))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   583
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   584
@predicate('bisect(string)', safe=True)
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   585
def bisect(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   586
    """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
   587
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   588
    - ``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
   589
    - ``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
   590
    - ``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
   591
    - ``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
   592
    - ``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
   593
    - ``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
   594
    - ``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
   595
    """
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
   596
    # 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
   597
    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
   598
    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
   599
    return subset & state
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   600
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   601
# Backward-compatibility
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   602
# - no help entry so that we do not advertise it any more
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   603
@predicate('bisected', safe=True)
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   604
def bisected(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   605
    return bisect(repo, subset, x)
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   606
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   607
@predicate('bookmark([name])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   608
def bookmark(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   609
    """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
   610
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   611
    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
   612
    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
   613
    use the prefix `literal:`.
13915
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: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   616
    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
   617
    if args:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   618
        bm = getstring(args[0],
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   619
                       # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   620
                       _('the argument to bookmark must be a string'))
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
   621
        kind, pattern, matcher = util.stringmatcher(bm)
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   622
        bms = set()
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   623
        if kind == 'literal':
22105
3efe3c2609e0 revset: bookmark revset interprets 'literal:' prefix correctly (issue4329)
Michael O'Connor <mkoconnor@gmail.com>
parents: 21939
diff changeset
   624
            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
   625
            if not bmrev:
23978
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
   626
                raise error.RepoLookupError(_("bookmark '%s' does not exist")
26538
5c9ec1cc671a revset: strip off "literal:" prefix from bookmark not found error
Yuya Nishihara <yuya@tcha.org>
parents: 26537
diff changeset
   627
                                            % pattern)
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   628
            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
   629
        else:
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   630
            matchrevs = set()
18495
8260fa9f30b9 bookmarks: don't use bookmarks.listbookmarks in local computations
Kevin Bullock <kbullock@ringworld.org>
parents: 18473
diff changeset
   631
            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
   632
                if matcher(name):
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   633
                    matchrevs.add(bmrev)
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   634
            if not matchrevs:
23978
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
   635
                raise error.RepoLookupError(_("no bookmarks exist"
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
   636
                                              " that match '%s'") % pattern)
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   637
            for bmrev in matchrevs:
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   638
                bms.add(repo[bmrev].rev())
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   639
    else:
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   640
        bms = set([repo[r].rev()
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   641
                   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
   642
    bms -= set([node.nullrev])
22530
faf4f63533ff revset: use `subset &` in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22529
diff changeset
   643
    return subset & bms
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   644
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   645
@predicate('branch(string or set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   646
def branch(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   647
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   648
    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
   649
    changesets.
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   650
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   651
    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
   652
    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
   653
    use the prefix `literal:`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   654
    """
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24366
diff changeset
   655
    getbi = repo.revbranchcache().branchinfo
23787
678f53865c68 revset: use localrepo revbranchcache for branch name filtering
Mads Kiilerich <madski@unity3d.com>
parents: 23765
diff changeset
   656
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   657
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   658
        b = getstring(x, '')
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   659
    except error.ParseError:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   660
        # 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
   661
        pass
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   662
    else:
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
   663
        kind, pattern, matcher = util.stringmatcher(b)
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   664
        if kind == 'literal':
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   665
            # note: falls through to the revspec case if no branch with
26537
832feae7c986 revset: do not fall through to revspec for literal: branch (issue4838)
Yuya Nishihara <yuya@tcha.org>
parents: 26481
diff changeset
   666
            # this name exists and pattern kind is not specified explicitly
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   667
            if pattern in repo.branchmap():
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   668
                return subset.filter(lambda r: matcher(getbi(r)[0]),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   669
                                     condrepr=('<branch %r>', b))
26537
832feae7c986 revset: do not fall through to revspec for literal: branch (issue4838)
Yuya Nishihara <yuya@tcha.org>
parents: 26481
diff changeset
   670
            if b.startswith('literal:'):
832feae7c986 revset: do not fall through to revspec for literal: branch (issue4838)
Yuya Nishihara <yuya@tcha.org>
parents: 26481
diff changeset
   671
                raise error.RepoLookupError(_("branch '%s' does not exist")
832feae7c986 revset: do not fall through to revspec for literal: branch (issue4838)
Yuya Nishihara <yuya@tcha.org>
parents: 26481
diff changeset
   672
                                            % pattern)
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   673
        else:
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   674
            return subset.filter(lambda r: matcher(getbi(r)[0]),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   675
                                 condrepr=('<branch %r>', b))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   676
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   677
    s = getset(repo, fullreposet(repo), x)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   678
    b = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   679
    for r in s:
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24366
diff changeset
   680
        b.add(getbi(r)[0])
22867
5ee9b78ce805 revset-branch: remove usage of `set()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22866
diff changeset
   681
    c = s.__contains__
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   682
    return subset.filter(lambda r: c(r) or getbi(r)[0] in b,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   683
                         condrepr=lambda: '<branch %r>' % sorted(b))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   684
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   685
@predicate('bumped()', safe=True)
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   686
def bumped(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   687
    """Mutable changesets marked as successors of public changesets.
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   688
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   689
    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
   690
    """
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   691
    # i18n: "bumped" is a keyword
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   692
    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
   693
    bumped = obsmod.getrevs(repo, 'bumped')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   694
    return subset & bumped
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   695
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   696
@predicate('bundle()', safe=True)
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   697
def bundle(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   698
    """Changesets in the bundle.
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   699
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   700
    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
   701
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   702
    try:
18411
8b0f0dd56cec bundlerepo: improve performance for bundle() revset expression
Mads Kiilerich <madski@unity3d.com>
parents: 18382
diff changeset
   703
        bundlerevs = repo.changelog.bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   704
    except AttributeError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26571
diff changeset
   705
        raise error.Abort(_("no bundle provided - specify with -R"))
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   706
    return subset & bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   707
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   708
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
   709
    hasset = matchmod.patkind(pat) == 'set'
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   710
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   711
    mcache = [None]
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   712
    def matches(x):
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   713
        c = repo[x]
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   714
        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
   715
            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
   716
        m = mcache[0]
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   717
        fname = None
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   718
        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
   719
            fname = m.files()[0]
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   720
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   721
            if fname not in c.files():
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   722
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   723
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   724
            for f in c.files():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   725
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   726
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   727
            else:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   728
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   729
        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
   730
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   731
            if fname in files:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   732
                return True
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   733
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   734
            for f in files:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   735
                if m(f):
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   736
                    return True
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   737
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   738
    return subset.filter(matches, condrepr=('<status[%r] %r>', field, pat))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   739
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   740
def _children(repo, narrow, parentset):
25550
3e9049876ace revset: gratuitous code move in '_children'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25549
diff changeset
   741
    if not parentset:
3e9049876ace revset: gratuitous code move in '_children'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25549
diff changeset
   742
        return baseset()
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   743
    cs = set()
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   744
    pr = repo.changelog.parentrevs
25567
f140d6207cca revset: use parentsets.min in _children
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25566
diff changeset
   745
    minrev = parentset.min()
16394
f3df7d34791e revset: do not ignore input revisions in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
   746
    for r in narrow:
18063
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   747
        if r <= minrev:
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   748
            continue
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   749
        for p in pr(r):
16396
03e408a122c4 revset: avoid set duplication in roots()
Patrick Mezard <patrick@mezard.eu>
parents: 16395
diff changeset
   750
            if p in parentset:
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   751
                cs.add(r)
25553
fa2e91d00e4c revset: mark spot that feeds a set to a baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25552
diff changeset
   752
    # XXX using a set to feed the baseset is wrong. Sets are not ordered.
fa2e91d00e4c revset: mark spot that feeds a set to a baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25552
diff changeset
   753
    # This does not break because of other fullreposet misbehavior.
20709
71df845d86cf revsets: backout d04aac468bf4 due to performance regressions
Matt Mackall <mpm@selenic.com>
parents: 20708
diff changeset
   754
    return baseset(cs)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   755
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   756
@predicate('children(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   757
def children(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   758
    """Child changesets of changesets in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   759
    """
23164
7a42e5d4c418 revset-children: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23163
diff changeset
   760
    s = getset(repo, fullreposet(repo), x)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   761
    cs = _children(repo, subset, s)
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   762
    return subset & cs
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   763
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   764
@predicate('closed()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   765
def closed(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   766
    """Changeset is closed.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   767
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   768
    # i18n: "closed" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   769
    getargs(x, 0, 0, _("closed takes no arguments"))
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   770
    return subset.filter(lambda r: repo[r].closesbranch(),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   771
                         condrepr='<branch closed>')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   772
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   773
@predicate('contains(pattern)')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   774
def contains(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   775
    """The revision's manifest contains a file matching pattern (but might not
21199
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   776
    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
   777
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   778
    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
   779
    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
   780
    for efficiency.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   781
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   782
    # i18n: "contains" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   783
    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
   784
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   785
    def matches(x):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   786
        if not matchmod.patkind(pat):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   787
            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
   788
            if pats in repo[x]:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   789
                return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   790
        else:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   791
            c = repo[x]
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   792
            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
   793
            for f in c.manifest():
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   794
                if m(f):
20461
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   795
                    return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   796
        return False
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   797
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   798
    return subset.filter(matches, condrepr=('<contains %r>', pat))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   799
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   800
@predicate('converted([id])', safe=True)
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   801
def converted(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   802
    """Changesets converted from the given identifier in the old repository if
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   803
    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
   804
    """
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   805
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   806
    # 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
   807
    # 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
   808
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
   809
    rev = None
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   810
    # i18n: "converted" is a keyword
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   811
    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
   812
    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
   813
        # 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
   814
        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
   815
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   816
    def _matchvalue(r):
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   817
        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
   818
        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
   819
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   820
    return subset.filter(lambda r: _matchvalue(r),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   821
                         condrepr=('<converted %r>', rev))
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   822
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   823
@predicate('date(interval)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   824
def date(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   825
    """Changesets within the interval, see :hg:`help dates`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   826
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   827
    # i18n: "date" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   828
    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
   829
    dm = util.matchdate(ds)
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   830
    return subset.filter(lambda x: dm(repo[x].date()[0]),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   831
                         condrepr=('<date %r>', ds))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   832
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   833
@predicate('desc(string)', safe=True)
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   834
def desc(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   835
    """Search commit message for string. The match is case-insensitive.
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   836
    """
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   837
    # 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
   838
    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
   839
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   840
    def matches(x):
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   841
        c = repo[x]
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   842
        return ds in encoding.lower(c.description())
a685d9870eb5 revset: added lazyset implementation to desc revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20451
diff changeset
   843
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   844
    return subset.filter(matches, condrepr=('<desc %r>', ds))
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   845
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   846
def _descendants(repo, subset, x, followfirst=False):
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   847
    roots = getset(repo, fullreposet(repo), x)
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   848
    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
   849
        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
   850
    s = _revdescendants(repo, roots, followfirst)
20894
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   851
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   852
    # 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
   853
    # 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
   854
    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
   855
    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
   856
    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
   857
    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
   858
        result.sort()
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   859
    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
   860
        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
   861
    else:
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   862
        result = subset & result
22830
1d1da8abe130 _descendants: directly use smartset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22829
diff changeset
   863
    return result
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   864
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   865
@predicate('descendants(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   866
def descendants(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   867
    """Changesets which are descendants of changesets in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   868
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   869
    return _descendants(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   870
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   871
@predicate('_firstdescendants', safe=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   872
def _firstdescendants(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   873
    # ``_firstdescendants(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   874
    # 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
   875
    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
   876
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   877
@predicate('destination([set])', safe=True)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   878
def destination(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   879
    """Changesets that were created by a graft, transplant or rebase operation,
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   880
    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
   881
    is the same as passing all().
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   882
    """
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   883
    if x is not None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   884
        sources = getset(repo, fullreposet(repo), x)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   885
    else:
24201
77ef059b3317 revset: drop unnecessary calls of getall() with empty argument
Yuya Nishihara <yuya@tcha.org>
parents: 24163
diff changeset
   886
        sources = fullreposet(repo)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   887
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   888
    dests = set()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   889
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   890
    # 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
   891
    # 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
   892
    # 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
   893
    # 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
   894
    # 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
   895
    # grafts.
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   896
    for r in subset:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   897
        src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   898
        lineage = None
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   899
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   900
        while src is not None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   901
            if lineage is None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   902
                lineage = list()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   903
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   904
            lineage.append(r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   905
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   906
            # 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
   907
            # set.  Since every candidate dest is visited by way of iterating
17494
74801685aaa2 spelling: further
timeless@mozdev.org
parents: 17291
diff changeset
   908
            # 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
   909
            # 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
   910
            # 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
   911
            # further.
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   912
            if src in sources or src in dests:
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   913
                dests.update(lineage)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   914
                break
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   915
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   916
            r = src
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   917
            src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   918
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   919
    return subset.filter(dests.__contains__,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   920
                         condrepr=lambda: '<destination %r>' % sorted(dests))
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   921
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   922
@predicate('divergent()', safe=True)
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   923
def divergent(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   924
    """
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   925
    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
   926
    """
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   927
    # 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
   928
    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
   929
    divergent = obsmod.getrevs(repo, 'divergent')
22533
5b65429721d5 revset: use `subset &` in `divergent`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22532
diff changeset
   930
    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
   931
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   932
@predicate('extinct()', safe=True)
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   933
def extinct(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   934
    """Obsolete changesets with obsolete descendants only.
17291
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
   935
    """
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
   936
    # 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
   937
    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
   938
    extincts = obsmod.getrevs(repo, 'extinct')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   939
    return subset & extincts
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   940
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   941
@predicate('extra(label, [value])', safe=True)
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   942
def extra(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   943
    """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
   944
    optional value.
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   945
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   946
    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
   947
    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
   948
    use the prefix `literal:`.
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   949
    """
25767
026105c442d7 revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 25766
diff changeset
   950
    args = getargsdict(x, 'extra', 'label value')
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   951
    if 'label' not in args:
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   952
        # i18n: "extra" is a keyword
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   953
        raise error.ParseError(_('extra takes at least 1 argument'))
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
   954
    # i18n: "extra" is a keyword
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   955
    label = getstring(args['label'], _('first argument to extra must be '
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   956
                                       'a string'))
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   957
    value = None
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   958
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   959
    if 'value' in args:
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
   960
        # i18n: "extra" is a keyword
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   961
        value = getstring(args['value'], _('second argument to extra must be '
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   962
                                           'a string'))
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
   963
        kind, value, matcher = util.stringmatcher(value)
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   964
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   965
    def _matchvalue(r):
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   966
        extra = repo[r].extra()
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   967
        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
   968
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   969
    return subset.filter(lambda r: _matchvalue(r),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   970
                         condrepr=('<extra[%r] %r>', label, value))
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
   971
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   972
@predicate('filelog(pattern)', safe=True)
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   973
def filelog(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   974
    """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
   975
21199
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   976
    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
   977
    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
   978
    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
   979
    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
   980
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   981
    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
   982
    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
   983
    for efficiency.
23719
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   984
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   985
    If some linkrev points to revisions filtered by the current repoview, we'll
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   986
    work around it to return a non-filtered value.
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   987
    """
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   988
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
   989
    # 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
   990
    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
   991
    s = set()
23719
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   992
    cl = repo.changelog
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   993
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
   994
    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
   995
        f = pathutil.canonpath(repo.root, repo.getcwd(), pat)
23719
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   996
        files = [f]
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
   997
    else:
20288
b61ad01c4e73 revset: use "canonpath()" for "filelog()" pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20287
diff changeset
   998
        m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None])
23719
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
   999
        files = (f for f in repo[None] if m(f))
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
  1000
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
  1001
    for f in files:
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
  1002
        fl = repo.file(f)
27945
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1003
        known = {}
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1004
        scanpos = 0
23719
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
  1005
        for fr in list(fl):
27945
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1006
            fn = fl.node(fr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1007
            if fn in known:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1008
                s.add(known[fn])
23821
7a7f437ab63d filelog: remove trailing "form feed" character
Martin von Zweigbergk <martinvonz@google.com>
parents: 23820
diff changeset
  1009
                continue
27945
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1010
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1011
            lr = fl.linkrev(fr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1012
            if lr in cl:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1013
                s.add(lr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1014
            elif scanpos is not None:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1015
                # lowest matching changeset is filtered, scan further
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1016
                # ahead in changelog
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1017
                start = max(lr, scanpos) + 1
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1018
                scanpos = None
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1019
                for r in cl.revs(start):
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1020
                    # minimize parsing of non-matching entries
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1021
                    if f in cl.revision(r) and f in cl.readfiles(r):
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1022
                        try:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1023
                            # try to use manifest delta fastpath
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1024
                            n = repo[r].filenode(f)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1025
                            if n not in known:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1026
                                if n == fn:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1027
                                    s.add(r)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1028
                                    scanpos = r
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1029
                                    break
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1030
                                else:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1031
                                    known[n] = r
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1032
                        except error.ManifestLookupError:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1033
                            # deletion in changelog
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1034
                            continue
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1035
22534
6261b9c549a2 revset: use `subset &` in `filelog`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22533
diff changeset
  1036
    return subset & s
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1037
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1038
@predicate('first(set, [n])', safe=True)
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1039
def first(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1040
    """An alias for limit().
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1041
    """
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1042
    return limit(repo, subset, x)
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1043
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1044
def _follow(repo, subset, x, name, followfirst=False):
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1045
    l = getargs(x, 0, 1, _("%s takes no arguments or a pattern") % name)
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1046
    c = repo['.']
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1047
    if l:
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1048
        x = getstring(l[0], _("%s expected a pattern") % name)
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1049
        matcher = matchmod.match(repo.root, repo.getcwd(), [x],
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1050
                                 ctx=repo[None], default='path')
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1051
28008
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1052
        files = c.manifest().walk(matcher)
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1053
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1054
        s = set()
28008
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1055
        for fname in files:
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1056
            fctx = c[fname]
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1057
            s = s.union(set(c.rev() for c in fctx.ancestors(followfirst)))
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1058
            # include the revision responsible for the most recent version
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1059
            s.add(fctx.introrev())
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1060
    else:
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
  1061
        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
  1062
22535
44f471102f3a revset: use `subset &` in `follow`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22534
diff changeset
  1063
    return subset & s
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1064
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1065
@predicate('follow([pattern])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1066
def follow(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1067
    """
24366
e8ea31131705 revset: replace "working copy" with "working directory" in function help
Yuya Nishihara <yuya@tcha.org>
parents: 24306
diff changeset
  1068
    An alias for ``::.`` (ancestors of the working directory's first parent).
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1069
    If pattern is specified, the histories of files matching given
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1070
    pattern is followed, including copies.
14343
9ed227f79e47 revset: add follow(filename) to follow a filename's history across copies
Matt Mackall <mpm@selenic.com>
parents: 14342
diff changeset
  1071
    """
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1072
    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
  1073
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1074
@predicate('_followfirst', safe=True)
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
  1075
def _followfirst(repo, subset, x):
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1076
    # ``followfirst([pattern])``
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1077
    # Like ``follow([pattern])`` but follows only the first parent of
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1078
    # every revisions or files revisions.
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1079
    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
  1080
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1081
@predicate('all()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1082
def getall(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1083
    """All changesets, the same as ``0:tip``.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1084
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1085
    # i18n: "all" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1086
    getargs(x, 0, 0, _("all takes no arguments"))
24202
2de9ee016425 revset: have all() filter out null revision
Yuya Nishihara <yuya@tcha.org>
parents: 24201
diff changeset
  1087
    return subset & spanset(repo)  # drop "null" if any
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1088
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1089
@predicate('grep(regex)')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1090
def grep(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1091
    """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
  1092
    to ensure special escape characters are handled correctly. Unlike
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
  1093
    ``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
  1094
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1095
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1096
        # i18n: "grep" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1097
        gr = re.compile(getstring(x, _("grep requires a string")))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
  1098
    except re.error as e:
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1099
        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
  1100
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1101
    def matches(x):
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1102
        c = repo[x]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1103
        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
  1104
            if gr.search(e):
20453
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1105
                return True
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1106
        return False
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1107
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1108
    return subset.filter(matches, condrepr=('<grep %r>', gr.pattern))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1109
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1110
@predicate('_matchfiles', safe=True)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1111
def _matchfiles(repo, subset, x):
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1112
    # _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
  1113
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1114
    #   [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
  1115
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1116
    # 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
  1117
    # 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
  1118
    # 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
  1119
    # 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
  1120
    # 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
  1121
    # 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
  1122
    # 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
  1123
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1124
    l = getargs(x, 1, -1, "_matchfiles requires at least one argument")
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1125
    pats, inc, exc = [], [], []
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1126
    rev, default = None, None
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1127
    for arg in l:
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1128
        s = getstring(arg, "_matchfiles requires string arguments")
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1129
        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
  1130
        if prefix == 'p:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1131
            pats.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1132
        elif prefix == 'i:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1133
            inc.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1134
        elif prefix == 'x:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1135
            exc.append(value)
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
  1136
        elif prefix == 'r:':
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
  1137
            if rev is not None:
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1138
                raise error.ParseError('_matchfiles expected at most one '
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1139
                                       'revision')
23950
caff3675cba5 log: evaluate filesets on working copy, not its parent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23847
diff changeset
  1140
            if value != '': # empty means working directory; leave rev as None
caff3675cba5 log: evaluate filesets on working copy, not its parent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23847
diff changeset
  1141
                rev = value
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1142
        elif prefix == 'd:':
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1143
            if default is not None:
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1144
                raise error.ParseError('_matchfiles expected at most one '
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1145
                                       'default mode')
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1146
            default = value
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1147
        else:
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1148
            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
  1149
    if not default:
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1150
        default = 'glob'
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1151
23061
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1152
    m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1153
                       exclude=exc, ctx=repo[rev], default=default)
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1154
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1155
    # This directly read the changelog data as creating changectx for all
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1156
    # revisions is quite expensive.
27440
ff305ab2e0d7 log: speed up hg log <file|folder>
Laurent Charignon <lcharignon@fb.com>
parents: 27293
diff changeset
  1157
    getfiles = repo.changelog.readfiles
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1158
    wdirrev = node.wdirrev
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1159
    def matches(x):
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1160
        if x == wdirrev:
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1161
            files = repo[x].files()
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1162
        else:
27440
ff305ab2e0d7 log: speed up hg log <file|folder>
Laurent Charignon <lcharignon@fb.com>
parents: 27293
diff changeset
  1163
            files = getfiles(x)
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1164
        for f in files:
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1165
            if m(f):
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1166
                return True
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1167
        return False
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1168
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1169
    return subset.filter(matches,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1170
                         condrepr=('<matchfiles patterns=%r, include=%r '
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1171
                                   'exclude=%r, default=%r, rev=%r>',
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1172
                                   pats, inc, exc, default, rev))
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1173
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1174
@predicate('file(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1175
def hasfile(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1176
    """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
  1177
17265
c30307eeec4b revset: polish explanation of the difference between file() and filelog()
Greg Ward <greg@gerg.ca>
parents: 17259
diff changeset
  1178
    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
  1179
    instead.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1180
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1181
    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
  1182
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1183
    # i18n: "file" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1184
    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
  1185
    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
  1186
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1187
@predicate('head()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1188
def head(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1189
    """Changeset is a named branch head.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1190
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1191
    # i18n: "head" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1192
    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
  1193
    hs = set()
25620
5f87f2305ad0 revset: translate node directly with changelog in 'head'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25619
diff changeset
  1194
    cl = repo.changelog
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1195
    for b, ls in repo.branchmap().iteritems():
25620
5f87f2305ad0 revset: translate node directly with changelog in 'head'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25619
diff changeset
  1196
        hs.update(cl.rev(h) for h in ls)
25553
fa2e91d00e4c revset: mark spot that feeds a set to a baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25552
diff changeset
  1197
    # XXX using a set to feed the baseset is wrong. Sets are not ordered.
fa2e91d00e4c revset: mark spot that feeds a set to a baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25552
diff changeset
  1198
    # This does not break because of other fullreposet misbehavior.
25548
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
  1199
    # XXX We should combine with subset first: 'subset & baseset(...)'. This is
9584bcf27637 revset: mark the place where we are combining sets in the wrong direction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25547
diff changeset
  1200
    # necessary to ensure we preserve the order in subset.
25634
1ddefcfcd3e6 revsets: use '&' instead of '.filter' in head
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25632
diff changeset
  1201
    return baseset(hs) & subset
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1202
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1203
@predicate('heads(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1204
def heads(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1205
    """Members of set with no children in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1206
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1207
    s = getset(repo, subset, x)
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
  1208
    ps = parents(repo, subset, x)
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
  1209
    return s - ps
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1210
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1211
@predicate('hidden()', safe=True)
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1212
def hidden(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1213
    """Hidden changesets.
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1214
    """
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1215
    # i18n: "hidden" is a keyword
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1216
    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
  1217
    hiddenrevs = repoview.filterrevs(repo, 'visible')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1218
    return subset & hiddenrevs
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1219
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1220
@predicate('keyword(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1221
def keyword(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1222
    """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
  1223
    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
  1224
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1225
    # 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
  1226
    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
  1227
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
  1228
    def matches(r):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1229
        c = repo[r]
25551
c1d163ce7394 revset: gratuitous formating fix in keyword
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25550
diff changeset
  1230
        return any(kw in encoding.lower(t)
c1d163ce7394 revset: gratuitous formating fix in keyword
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25550
diff changeset
  1231
                   for t in c.files() + [c.user(), c.description()])
20447
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
  1232
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1233
    return subset.filter(matches, condrepr=('<keyword %r>', kw))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1234
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1235
@predicate('limit(set[, n[, offset]])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1236
def limit(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1237
    """First n members of set, defaulting to 1, starting from offset.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1238
    """
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1239
    args = getargsdict(x, 'limit', 'set n offset')
26637
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1240
    if 'set' not in args:
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1241
        # i18n: "limit" is a keyword
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1242
        raise error.ParseError(_("limit requires one to three arguments"))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1243
    try:
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1244
        lim, ofs = 1, 0
26637
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1245
        if 'n' in args:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1246
            # i18n: "limit" is a keyword
26637
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1247
            lim = int(getstring(args['n'], _("limit requires a number")))
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1248
        if 'offset' in args:
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1249
            # i18n: "limit" is a keyword
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1250
            ofs = int(getstring(args['offset'], _("limit requires a number")))
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1251
        if ofs < 0:
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1252
            raise error.ParseError(_("negative offset"))
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
  1253
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1254
        # i18n: "limit" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1255
        raise error.ParseError(_("limit expects a number"))
26637
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1256
    os = getset(repo, fullreposet(repo), args['set'])
22804
5385314e0b14 revset-limit: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22802
diff changeset
  1257
    result = []
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
  1258
    it = iter(os)
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1259
    for x in xrange(ofs):
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1260
        y = next(it, None)
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1261
        if y is None:
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1262
            break
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
  1263
    for x in xrange(lim):
25144
81a395447b34 revset: use 'next()' to detect end of iteration in 'limit'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25143
diff changeset
  1264
        y = next(it, None)
81a395447b34 revset: use 'next()' to detect end of iteration in 'limit'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25143
diff changeset
  1265
        if y is None:
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
  1266
            break
26636
ff6baf32b3ba revset: eliminate temporary reference to subset in limit() and last()
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
  1267
        elif y in subset:
25144
81a395447b34 revset: use 'next()' to detect end of iteration in 'limit'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25143
diff changeset
  1268
            result.append(y)
28426
3d39ac06af9a revset: add inspection data to limit() and last() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28425
diff changeset
  1269
    return baseset(result, datarepr=('<limit n=%d, offset=%d, %r, %r>',
3d39ac06af9a revset: add inspection data to limit() and last() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28425
diff changeset
  1270
                                     lim, ofs, subset, os))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1271
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1272
@predicate('last(set, [n])', safe=True)
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1273
def last(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1274
    """Last n members of set, defaulting to 1.
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1275
    """
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1276
    # 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
  1277
    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
  1278
    try:
15116
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1279
        lim = 1
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1280
        if len(l) == 2:
d8501bcbb221 revset: add default of 1 to limit and last functions
Matt Mackall <mpm@selenic.com>
parents: 14901
diff changeset
  1281
            # 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
  1282
            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
  1283
    except (TypeError, ValueError):
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1284
        # i18n: "last" is a keyword
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1285
        raise error.ParseError(_("last expects a number"))
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1286
    os = getset(repo, fullreposet(repo), l[0])
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1287
    os.reverse()
22805
e74245b79901 revset-last: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22804
diff changeset
  1288
    result = []
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1289
    it = iter(os)
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1290
    for x in xrange(lim):
25145
3553163bb736 revset: use 'next()' to detect end of iteration in 'last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25144
diff changeset
  1291
        y = next(it, None)
3553163bb736 revset: use 'next()' to detect end of iteration in 'last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25144
diff changeset
  1292
        if y is None:
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1293
            break
26636
ff6baf32b3ba revset: eliminate temporary reference to subset in limit() and last()
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
  1294
        elif y in subset:
25145
3553163bb736 revset: use 'next()' to detect end of iteration in 'last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25144
diff changeset
  1295
            result.append(y)
28426
3d39ac06af9a revset: add inspection data to limit() and last() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28425
diff changeset
  1296
    return baseset(result, datarepr=('<last n=%d, %r, %r>', lim, subset, os))
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1297
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1298
@predicate('max(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1299
def maxrev(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1300
    """Changeset with highest revision number in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1301
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1302
    os = getset(repo, fullreposet(repo), x)
26305
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1303
    try:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1304
        m = os.max()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1305
        if m in subset:
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1306
            return baseset([m], datarepr=('<max %r, %r>', subset, os))
26305
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1307
    except ValueError:
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1308
        # os.max() throws a ValueError when the collection is empty.
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1309
        # Same as python's max().
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1310
        pass
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1311
    return baseset(datarepr=('<max %r, %r>', subset, os))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1312
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1313
@predicate('merge()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1314
def merge(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1315
    """Changeset is a merge changeset.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1316
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1317
    # i18n: "merge" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1318
    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
  1319
    cl = repo.changelog
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1320
    return subset.filter(lambda r: cl.parentrevs(r)[1] != -1,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1321
                         condrepr='<merge>')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1322
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1323
@predicate('branchpoint()', safe=True)
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1324
def branchpoint(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1325
    """Changesets with more than one child.
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1326
    """
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1327
    # i18n: "branchpoint" is a keyword
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1328
    getargs(x, 0, 0, _("branchpoint takes no arguments"))
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1329
    cl = repo.changelog
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1330
    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
  1331
        return baseset()
25549
f93ff3ab8d14 revset: mark spots that should use 'smartset.min()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25548
diff changeset
  1332
    # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset
f93ff3ab8d14 revset: mark spots that should use 'smartset.min()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25548
diff changeset
  1333
    # (and if it is not, it should.)
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1334
    baserev = min(subset)
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1335
    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
  1336
    for r in cl.revs(start=baserev + 1):
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1337
        for p in cl.parentrevs(r):
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1338
            if p >= baserev:
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1339
                parentscount[p - baserev] += 1
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1340
    return subset.filter(lambda r: parentscount[r - baserev] > 1,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1341
                         condrepr='<branchpoint>')
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1342
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1343
@predicate('min(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1344
def minrev(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1345
    """Changeset with lowest revision number in set.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1346
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1347
    os = getset(repo, fullreposet(repo), x)
26305
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1348
    try:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1349
        m = os.min()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1350
        if m in subset:
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1351
            return baseset([m], datarepr=('<min %r, %r>', subset, os))
26305
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1352
    except ValueError:
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1353
        # os.min() throws a ValueError when the collection is empty.
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1354
        # Same as python's min().
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1355
        pass
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1356
    return baseset(datarepr=('<min %r, %r>', subset, os))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1357
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1358
@predicate('modifies(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1359
def modifies(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1360
    """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
  1361
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1362
    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
  1363
    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
  1364
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1365
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1366
    # i18n: "modifies" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1367
    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
  1368
    return checkstatus(repo, subset, pat, 0)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1369
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1370
@predicate('named(namespace)')
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1371
def named(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1372
    """The changesets in a given namespace.
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1373
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1374
    If `namespace` starts with `re:`, the remainder of the string is treated as
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1375
    a regular expression. To match a namespace that actually starts with `re:`,
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1376
    use the prefix `literal:`.
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1377
    """
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1378
    # i18n: "named" is a keyword
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1379
    args = getargs(x, 1, 1, _('named requires a namespace argument'))
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1380
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1381
    ns = getstring(args[0],
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1382
                   # i18n: "named" is a keyword
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1383
                   _('the argument to named must be a string'))
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
  1384
    kind, pattern, matcher = util.stringmatcher(ns)
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1385
    namespaces = set()
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1386
    if kind == 'literal':
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1387
        if pattern not in repo.names:
23978
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  1388
            raise error.RepoLookupError(_("namespace '%s' does not exist")
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  1389
                                        % ns)
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1390
        namespaces.add(repo.names[pattern])
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1391
    else:
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1392
        for name, ns in repo.names.iteritems():
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1393
            if matcher(name):
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1394
                namespaces.add(ns)
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1395
        if not namespaces:
23978
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  1396
            raise error.RepoLookupError(_("no namespace exists"
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  1397
                                          " that match '%s'") % pattern)
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1398
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1399
    names = set()
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1400
    for ns in namespaces:
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1401
        for name in ns.listnames(repo):
24151
38824c53c2f1 revset: mask specific names for named() predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24008
diff changeset
  1402
            if name not in ns.deprecated:
38824c53c2f1 revset: mask specific names for named() predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24008
diff changeset
  1403
                names.update(repo[n].rev() for n in ns.nodes(repo, name))
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1404
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1405
    names -= set([node.nullrev])
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1406
    return subset & names
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1407
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1408
@predicate('id(string)', safe=True)
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1409
def node_(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1410
    """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
  1411
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1412
    # 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
  1413
    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
  1414
    # 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
  1415
    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
  1416
    if len(n) == 40:
24904
b5c227f3e461 revset: id() called with 40-byte strings should give the same results as for short strings
Alexander Drozdov <al.drozdov@gmail.com>
parents: 24777
diff changeset
  1417
        try:
b5c227f3e461 revset: id() called with 40-byte strings should give the same results as for short strings
Alexander Drozdov <al.drozdov@gmail.com>
parents: 24777
diff changeset
  1418
            rn = repo.changelog.rev(node.bin(n))
b5c227f3e461 revset: id() called with 40-byte strings should give the same results as for short strings
Alexander Drozdov <al.drozdov@gmail.com>
parents: 24777
diff changeset
  1419
        except (LookupError, TypeError):
b5c227f3e461 revset: id() called with 40-byte strings should give the same results as for short strings
Alexander Drozdov <al.drozdov@gmail.com>
parents: 24777
diff changeset
  1420
            rn = None
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
  1421
    else:
16735
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1422
        rn = None
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1423
        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
  1424
        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
  1425
            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
  1426
23005
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1427
    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
  1428
        return baseset()
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1429
    result = baseset([rn])
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1430
    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
  1431
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1432
@predicate('obsolete()', safe=True)
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1433
def obsolete(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1434
    """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
  1435
    # i18n: "obsolete" is a keyword
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1436
    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
  1437
    obsoletes = obsmod.getrevs(repo, 'obsolete')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1438
    return subset & obsoletes
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1439
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1440
@predicate('only(set, [set])', safe=True)
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1441
def only(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1442
    """Changesets that are ancestors of the first set that are not ancestors
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1443
    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
  1444
    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
  1445
    (i.e. ::<set1> - ::<set2>).
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1446
    """
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1447
    cl = repo.changelog
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1448
    # i18n: "only" is a keyword
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1449
    args = getargs(x, 1, 2, _('only takes one or two arguments'))
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1450
    include = getset(repo, fullreposet(repo), args[0])
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1451
    if len(args) == 1:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1452
        if not include:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1453
            return baseset()
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1454
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1455
        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
  1456
        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
  1457
            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
  1458
    else:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1459
        exclude = getset(repo, fullreposet(repo), args[1])
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1460
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1461
    results = set(cl.findmissingrevs(common=exclude, heads=include))
25554
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1462
    # XXX we should turn this into a baseset instead of a set, smartset may do
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1463
    # some optimisations from the fact this is a baseset.
23466
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1464
    return subset & results
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1465
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1466
@predicate('origin([set])', safe=True)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1467
def origin(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1468
    """
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1469
    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
  1470
    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
  1471
    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
  1472
    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
  1473
    for the first operation is selected.
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1474
    """
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1475
    if x is not None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1476
        dests = getset(repo, fullreposet(repo), x)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1477
    else:
24201
77ef059b3317 revset: drop unnecessary calls of getall() with empty argument
Yuya Nishihara <yuya@tcha.org>
parents: 24163
diff changeset
  1478
        dests = fullreposet(repo)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1479
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1480
    def _firstsrc(rev):
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1481
        src = _getrevsource(repo, rev)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1482
        if src is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1483
            return None
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1484
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1485
        while True:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1486
            prev = _getrevsource(repo, src)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1487
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1488
            if prev is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1489
                return src
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1490
            src = prev
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1491
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
  1492
    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
  1493
    o -= set([None])
25554
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1494
    # XXX we should turn this into a baseset instead of a set, smartset may do
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1495
    # some optimisations from the fact this is a baseset.
22536
8040a44aab1c revset: use `subset &` in `origin`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22535
diff changeset
  1496
    return subset & o
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1497
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1498
@predicate('outgoing([path])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1499
def outgoing(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1500
    """Changesets not found in the specified destination repository, or the
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1501
    default push location.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1502
    """
24722
02a5618e2fbf revset: don't import discovery at module level
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24708
diff changeset
  1503
    # Avoid cycles.
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1504
    from . import (
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1505
        discovery,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1506
        hg,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1507
    )
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1508
    # 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
  1509
    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
  1510
    # i18n: "outgoing" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1511
    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
  1512
    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
  1513
    dest, branches = hg.parseurl(dest)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1514
    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
  1515
    if revs:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1516
        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
  1517
    other = hg.peer(repo, {}, dest)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1518
    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
  1519
    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
  1520
    repo.ui.popbuffer()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1521
    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
  1522
    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
  1523
    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
  1524
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1525
@predicate('p1([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1526
def p1(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1527
    """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
  1528
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1529
    if x is None:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13873
diff changeset
  1530
        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
  1531
        if p >= 0:
a428db9ab61d revset: use `subset &` in bare `p1()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22537
diff changeset
  1532
            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
  1533
        return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1534
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1535
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1536
    cl = repo.changelog
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1537
    for r in getset(repo, fullreposet(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1538
        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
  1539
    ps -= set([node.nullrev])
25554
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1540
    # XXX we should turn this into a baseset instead of a set, smartset may do
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1541
    # some optimisations from the fact this is a baseset.
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1542
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1543
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1544
@predicate('p2([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1545
def p2(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1546
    """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
  1547
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1548
    if x is None:
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1549
        ps = repo[x].parents()
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1550
        try:
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
  1551
            p = ps[1].rev()
22539
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1552
            if p >= 0:
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1553
                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
  1554
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1555
        except IndexError:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1556
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1557
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1558
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1559
    cl = repo.changelog
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1560
    for r in getset(repo, fullreposet(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1561
        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
  1562
    ps -= set([node.nullrev])
25554
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1563
    # XXX we should turn this into a baseset instead of a set, smartset may do
94441df6206c revset: mark spots that use 'set' instead of 'smartset'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25553
diff changeset
  1564
    # some optimisations from the fact this is a baseset.
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1565
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1566
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1567
@predicate('parents([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1568
def parents(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1569
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1570
    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
  1571
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1572
    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
  1573
        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
  1574
    else:
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1575
        ps = set()
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1576
        cl = repo.changelog
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1577
        up = ps.update
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1578
        parentrevs = cl.parentrevs
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1579
        for r in getset(repo, fullreposet(repo), x):
25765
5e1b0739611c revset: use integer representation of wdir() in revset
Yuya Nishihara <yuya@tcha.org>
parents: 25716
diff changeset
  1580
            if r == node.wdirrev:
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1581
                up(p.rev() for p in repo[r].parents())
25689
1cce81121472 revset: fix a crash in parents() when 'wdir()' is in the set
Matt Harbison <matt_harbison@yahoo.com>
parents: 25660
diff changeset
  1582
            else:
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1583
                up(parentrevs(r))
22497
8ea3f47bcaff revset: remove nullrev from set computed in parents()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22496
diff changeset
  1584
    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
  1585
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1586
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1587
def _phase(repo, subset, target):
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1588
    """helper to select all rev in phase <target>"""
25622
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1589
    repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1590
    if repo._phasecache._phasesets:
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1591
        s = repo._phasecache._phasesets[target] - repo.changelog.filteredrevs
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1592
        s = baseset(s)
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1593
        s.sort() # set are non ordered, so we enforce ascending
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1594
        return subset & s
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1595
    else:
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1596
        phase = repo._phasecache.phase
85294076adce revset: make use of natively-computed set for 'draft()' and 'secret()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25621
diff changeset
  1597
        condition = lambda r: phase(repo, r) == target
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1598
        return subset.filter(condition, condrepr=('<phase %r>', target),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1599
                             cache=False)
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1600
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1601
@predicate('draft()', safe=True)
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1602
def draft(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1603
    """Changeset in draft phase."""
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1604
    # i18n: "draft" is a keyword
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1605
    getargs(x, 0, 0, _("draft takes no arguments"))
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1606
    target = phases.draft
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1607
    return _phase(repo, subset, target)
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1608
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1609
@predicate('secret()', safe=True)
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1610
def secret(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1611
    """Changeset in secret phase."""
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1612
    # i18n: "secret" is a keyword
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1613
    getargs(x, 0, 0, _("secret takes no arguments"))
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1614
    target = phases.secret
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1615
    return _phase(repo, subset, target)
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1616
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1617
def parentspec(repo, subset, x, n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1618
    """``set^0``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1619
    The set.
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1620
    ``set^1`` (or ``set^``), ``set^2``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1621
    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
  1622
    """
12320
40c40c6f20b8 revset: handle re.compile() errors in grep()
Brodie Rao <brodie@bitheap.org>
parents: 11882
diff changeset
  1623
    try:
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1624
        n = int(n[1])
14072
2e4d79dcc0a0 revset: add missing whitespace
Kevin Gessner <kevin@kevingessner.com>
parents: 14070
diff changeset
  1625
        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
  1626
            raise ValueError
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
  1627
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1628
        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
  1629
    ps = set()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1630
    cl = repo.changelog
23165
7e8737e6ab08 revset-parentspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23164
diff changeset
  1631
    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
  1632
        if n == 0:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1633
            ps.add(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1634
        elif n == 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1635
            ps.add(cl.parentrevs(r)[0])
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1636
        elif n == 2:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1637
            parents = cl.parentrevs(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1638
            if len(parents) > 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1639
                ps.add(parents[1])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1640
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1641
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1642
@predicate('present(set)', safe=True)
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1643
def present(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1644
    """An empty set, if any revision in set isn't found; otherwise,
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1645
    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
  1646
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1647
    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
  1648
    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
  1649
    to continue even in such cases.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1650
    """
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1651
    try:
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1652
        return getset(repo, subset, x)
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1653
    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
  1654
        return baseset()
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1655
25224
d032f57936f5 revset: drop docstring from internal _notpublic() function
Yuya Nishihara <yuya@tcha.org>
parents: 25191
diff changeset
  1656
# for internal use
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1657
@predicate('_notpublic', safe=True)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1658
def _notpublic(repo, subset, x):
25225
57fae767c52b revset: drop translation marker from error message of _notpublic()
Yuya Nishihara <yuya@tcha.org>
parents: 25224
diff changeset
  1659
    getargs(x, 0, 0, "_notpublic takes no arguments")
25612
97528adbf74b revset: ensure we have loaded phases data in '_notpublic()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25567
diff changeset
  1660
    repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1661
    if repo._phasecache._phasesets:
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1662
        s = set()
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1663
        for u in repo._phasecache._phasesets[1:]:
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1664
            s.update(u)
25619
833fa28cd949 revset: use a baseset in _notpublic()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25612
diff changeset
  1665
        s = baseset(s - repo.changelog.filteredrevs)
833fa28cd949 revset: use a baseset in _notpublic()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25612
diff changeset
  1666
        s.sort()
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1667
        return subset & s
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1668
    else:
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1669
        phase = repo._phasecache.phase
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1670
        target = phases.public
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1671
        condition = lambda r: phase(repo, r) != target
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1672
        return subset.filter(condition, condrepr=('<phase %r>', target),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1673
                             cache=False)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1674
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1675
@predicate('public()', safe=True)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1676
def public(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1677
    """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
  1678
    # 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
  1679
    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
  1680
    phase = repo._phasecache.phase
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1681
    target = phases.public
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1682
    condition = lambda r: phase(repo, r) == target
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1683
    return subset.filter(condition, condrepr=('<phase %r>', target),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1684
                         cache=False)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1685
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1686
@predicate('remote([id [,path]])', safe=True)
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1687
def remote(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1688
    """Local revision that corresponds to the given identifier in a
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1689
    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
  1690
    synonym for the current local branch.
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1691
    """
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1692
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1693
    from . import hg # avoid start-up nasties
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1694
    # i18n: "remote" is a keyword
27293
9e06e7fb037d grammar: favor zero, one, two over ... or no
timeless <timeless@mozdev.org>
parents: 27028
diff changeset
  1695
    l = getargs(x, 0, 2, _("remote takes zero, one, or two arguments"))
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1696
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1697
    q = '.'
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1698
    if len(l) > 0:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1699
    # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1700
        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
  1701
    if q == '.':
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1702
        q = repo['.'].branch()
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1703
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1704
    dest = ''
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1705
    if len(l) > 1:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1706
        # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1707
        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
  1708
    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
  1709
    dest, branches = hg.parseurl(dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1710
    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
  1711
    if revs:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1712
        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
  1713
    other = hg.peer(repo, {}, dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1714
    n = other.lookup(q)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1715
    if n in repo:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1716
        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
  1717
        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
  1718
            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
  1719
    return baseset()
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1720
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1721
@predicate('removes(pattern)', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1722
def removes(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1723
    """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
  1724
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1725
    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
  1726
    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
  1727
    directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1728
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1729
    # 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
  1730
    pat = getstring(x, _("removes requires a pattern"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1731
    return checkstatus(repo, subset, pat, 2)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1732
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1733
@predicate('rev(number)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1734
def rev(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1735
    """Revision with the given numeric identifier.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1736
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1737
    # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1738
    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
  1739
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1740
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1741
        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
  1742
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1743
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1744
        raise error.ParseError(_("rev expects a number"))
24031
fe1abb5d92f6 revset: have rev() validate input by repo.changelog.__contains__()
Yuya Nishihara <yuya@tcha.org>
parents: 24012
diff changeset
  1745
    if l not in repo.changelog and l != node.nullrev:
23062
ba89f7b542c9 revset: have rev() drop out-of-range or filtered rev explicitly (issue4396)
Yuya Nishihara <yuya@tcha.org>
parents: 23061
diff changeset
  1746
        return baseset()
22537
bbf4f3dfd700 revset: use `subset &` in `rev`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22536
diff changeset
  1747
    return subset & baseset([l])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1748
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1749
@predicate('matching(revision [, field])', safe=True)
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1750
def matching(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1751
    """Changesets in which a given set of fields match the set of fields in the
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1752
    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
  1753
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1754
    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
  1755
    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
  1756
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1757
    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
  1758
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1759
    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
  1760
    ``date``, ``files``, ``phase``, ``parents``, ``substate``, ``user``
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1761
    and ``diff``.
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1762
    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
  1763
    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
  1764
    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
  1765
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1766
    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
  1767
    ``summary`` matches the first line of the description.
16639
00290bd359fe revset: documentation typo "metatadata"
Jesse Glick <jesse.glick@oracle.com>
parents: 16528
diff changeset
  1768
    ``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
  1769
    (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
  1770
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1771
    ``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
  1772
    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
  1773
    """
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
  1774
    # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1775
    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
  1776
23166
30e0dcd7c5ff revset-matching: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23165
diff changeset
  1777
    revs = getset(repo, fullreposet(repo), l[0])
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1778
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1779
    fieldlist = ['metadata']
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1780
    if len(l) > 1:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1781
            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
  1782
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1783
                _("matching requires a string "
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1784
                "as its second argument")).split()
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1785
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1786
    # 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
  1787
    # expand the 'special' 'metadata' field type
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1788
    # 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
  1789
    fields = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1790
    for field in fieldlist:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1791
        if field == 'metadata':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1792
            fields += ['user', 'description', 'date']
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1793
        elif field == 'diff':
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1794
            # 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
  1795
            # 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
  1796
            # also match the files first
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1797
            fields += ['files', 'diff']
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1798
        else:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1799
            if field == 'author':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1800
                field = 'user'
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1801
            fields.append(field)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1802
    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
  1803
    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
  1804
        # 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
  1805
        fields.discard('summary')
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1806
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1807
    # 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
  1808
    # 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
  1809
    # 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
  1810
    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
  1811
        '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
  1812
    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
  1813
        try:
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
  1814
            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
  1815
        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
  1816
            # 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
  1817
            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
  1818
    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
  1819
    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
  1820
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1821
    # 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
  1822
    # 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
  1823
    getfieldfuncs = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1824
    _funcs = {
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1825
        'user': lambda r: repo[r].user(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1826
        'branch': lambda r: repo[r].branch(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1827
        'date': lambda r: repo[r].date(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1828
        'description': lambda r: repo[r].description(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1829
        'files': lambda r: repo[r].files(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1830
        'parents': lambda r: repo[r].parents(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1831
        'phase': lambda r: repo[r].phase(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1832
        'substate': lambda r: repo[r].substate,
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1833
        '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
  1834
        '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
  1835
    }
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1836
    for info in fields:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1837
        getfield = _funcs.get(info, None)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1838
        if getfield is None:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1839
            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
  1840
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1841
                _("unexpected field name passed to matching: %s") % info)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1842
        getfieldfuncs.append(getfield)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1843
    # 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
  1844
    # 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
  1845
    # 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
  1846
    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
  1847
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1848
    def matches(x):
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1849
        for rev in revs:
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1850
            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
  1851
            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
  1852
            for n, f in enumerate(getfieldfuncs):
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1853
                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
  1854
                    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
  1855
            if match:
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1856
                return True
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1857
        return False
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1858
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1859
    return subset.filter(matches, condrepr=('<matching%r %r>', fields, revs))
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1860
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1861
@predicate('reverse(set)', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1862
def reverse(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1863
    """Reverse order of set.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1864
    """
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1865
    l = getset(repo, subset, x)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1866
    l.reverse()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1867
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1868
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1869
@predicate('roots(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1870
def roots(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1871
    """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
  1872
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1873
    s = getset(repo, fullreposet(repo), x)
25647
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1874
    parents = repo.changelog.parentrevs
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1875
    def filter(r):
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1876
        for p in parents(r):
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1877
            if 0 <= p and p in s:
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1878
                return False
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1879
        return True
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1880
    return subset & s.filter(filter, condrepr='<roots>')
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1881
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1882
@predicate('sort(set[, [-]key...])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1883
def sort(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1884
    """Sort set by keys. The default sort order is ascending, specify a key
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1885
    as ``-key`` to sort in descending order.
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1886
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1887
    The keys can be:
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1888
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1889
    - ``rev`` for the revision number,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1890
    - ``branch`` for the branch name,
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1891
    - ``desc`` for the commit message (description),
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1892
    - ``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
  1893
    - ``date`` for the commit date
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1894
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1895
    # 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
  1896
    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
  1897
    keys = "rev"
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1898
    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
  1899
        # i18n: "sort" is a keyword
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1900
        keys = getstring(l[1], _("sort spec must be a string"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1901
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1902
    s = l[0]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1903
    keys = keys.split()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1904
    l = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1905
    def invert(s):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1906
        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
  1907
    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
  1908
    if keys == ["rev"]:
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1909
        revs.sort()
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1910
        return revs
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1911
    elif keys == ["-rev"]:
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1912
        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
  1913
        return revs
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1914
    for r in revs:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1915
        c = repo[r]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1916
        e = []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1917
        for k in keys:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1918
            if k == 'rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1919
                e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1920
            elif k == '-rev':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1921
                e.append(-r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1922
            elif k == 'branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1923
                e.append(c.branch())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1924
            elif k == '-branch':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1925
                e.append(invert(c.branch()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1926
            elif k == 'desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1927
                e.append(c.description())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1928
            elif k == '-desc':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1929
                e.append(invert(c.description()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1930
            elif k in 'user author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1931
                e.append(c.user())
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1932
            elif k in '-user -author':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1933
                e.append(invert(c.user()))
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1934
            elif k == 'date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1935
                e.append(c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1936
            elif k == '-date':
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1937
                e.append(-c.date()[0])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1938
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  1939
                raise error.ParseError(_("unknown sort key %r") % k)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1940
        e.append(r)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1941
        l.append(e)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1942
    l.sort()
20364
a6cf48b2880d revset: added baseset class (still empty) to improve revset performance
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20289
diff changeset
  1943
    return baseset([e[-1] for e in l])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1944
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1945
@predicate('subrepo([pattern])')
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1946
def subrepo(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1947
    """Changesets that add, modify or remove the given subrepo.  If no subrepo
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1948
    pattern is named, any subrepo changes are returned.
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1949
    """
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1950
    # i18n: "subrepo" is a keyword
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1951
    args = getargs(x, 0, 1, _('subrepo takes at most one argument'))
28272
760f9d04842a revset: define "pat" variable unconditionally in subrepo()
Yuya Nishihara <yuya@tcha.org>
parents: 28271
diff changeset
  1952
    pat = None
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1953
    if len(args) != 0:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1954
        pat = getstring(args[0], _("subrepo requires a pattern"))
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1955
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1956
    m = matchmod.exact(repo.root, repo.root, ['.hgsubstate'])
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1957
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1958
    def submatches(names):
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
  1959
        k, p, m = util.stringmatcher(pat)
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1960
        for name in names:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1961
            if m(name):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1962
                yield name
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1963
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1964
    def matches(x):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1965
        c = repo[x]
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1966
        s = repo.status(c.p1().node(), c.node(), match=m)
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1967
28272
760f9d04842a revset: define "pat" variable unconditionally in subrepo()
Yuya Nishihara <yuya@tcha.org>
parents: 28271
diff changeset
  1968
        if pat is None:
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1969
            return s.added or s.modified or s.removed
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1970
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1971
        if s.added:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25146
diff changeset
  1972
            return any(submatches(c.substate.keys()))
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1973
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1974
        if s.modified:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1975
            subs = set(c.p1().substate.keys())
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1976
            subs.update(c.substate.keys())
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1977
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1978
            for path in submatches(subs):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1979
                if c.p1().substate.get(path) != c.substate.get(path):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1980
                    return True
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1981
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1982
        if s.removed:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25146
diff changeset
  1983
            return any(submatches(c.p1().substate.keys()))
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1984
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1985
        return False
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1986
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1987
    return subset.filter(matches, condrepr=('<subrepo %r>', pat))
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  1988
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1989
def _substringmatcher(pattern):
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
  1990
    kind, pattern, matcher = util.stringmatcher(pattern)
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1991
    if kind == 'literal':
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  1992
        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
  1993
    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
  1994
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1995
@predicate('tag([name])', safe=True)
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
  1996
def tag(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1997
    """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
  1998
c57c9cece645 revset: document the regular expression support for tag(name)
Matt Harbison <matt_harbison@yahoo.com>
parents: 20289
diff changeset
  1999
    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
  2000
    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
  2001
    use the prefix `literal:`.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2002
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  2003
    # 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
  2004
    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
  2005
    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
  2006
    if args:
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2007
        pattern = getstring(args[0],
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2008
                            # i18n: "tag" is a keyword
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2009
                            _('the argument to tag must be a string'))
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
  2010
        kind, pattern, matcher = util.stringmatcher(pattern)
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2011
        if kind == 'literal':
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2012
            # avoid resolving all tags
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2013
            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
  2014
            if tn is None:
23978
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  2015
                raise error.RepoLookupError(_("tag '%s' does not exist")
eeb5d5ab14a6 revset: raise RepoLookupError to make present() predicate continue the query
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23956
diff changeset
  2016
                                            % pattern)
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2017
            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
  2018
        else:
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2019
            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
  2020
    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
  2021
        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
  2022
    return subset & s
11280
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  2023
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2024
@predicate('tagged', safe=True)
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2025
def tagged(repo, subset, x):
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2026
    return tag(repo, subset, x)
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2027
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2028
@predicate('unstable()', safe=True)
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2029
def unstable(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  2030
    """Non-obsolete changesets with obsolete ancestors.
17291
2d6bbf87f7b4 revset: minor doc fixes on obsolete related revsets
Patrick Mezard <patrick@mezard.eu>
parents: 17272
diff changeset
  2031
    """
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
  2032
    # 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
  2033
    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
  2034
    unstables = obsmod.getrevs(repo, 'unstable')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  2035
    return subset & unstables
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2036
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2037
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2038
@predicate('user(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  2039
def user(repo, subset, x):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  2040
    """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
  2041
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  2042
    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
  2043
    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
  2044
    the prefix `literal:`.
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  2045
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  2046
    return author(repo, subset, x)
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  2047
24777
077683371b7b revset: undocument wdir() until its command outputs get stable
Yuya Nishihara <yuya@tcha.org>
parents: 24722
diff changeset
  2048
# experimental
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2049
@predicate('wdir', safe=True)
24419
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2050
def wdir(repo, subset, x):
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2051
    # i18n: "wdir" is a keyword
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2052
    getargs(x, 0, 0, _("wdir takes no arguments"))
25765
5e1b0739611c revset: use integer representation of wdir() in revset
Yuya Nishihara <yuya@tcha.org>
parents: 25716
diff changeset
  2053
    if node.wdirrev in subset or isinstance(subset, fullreposet):
5e1b0739611c revset: use integer representation of wdir() in revset
Yuya Nishihara <yuya@tcha.org>
parents: 25716
diff changeset
  2054
        return baseset([node.wdirrev])
24419
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2055
    return baseset()
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2056
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2057
# for internal use
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2058
@predicate('_list', safe=True)
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2059
def _list(repo, subset, x):
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2060
    s = getstring(x, "internal error")
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2061
    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
  2062
        return baseset()
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2063
    # remove duplicates here. it's difficult for caller to deduplicate sets
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2064
    # because different symbols can point to the same rev.
25344
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2065
    cl = repo.changelog
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2066
    ls = []
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2067
    seen = set()
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2068
    for t in s.split('\0'):
25344
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2069
        try:
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2070
            # fast path for integer revision
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2071
            r = int(t)
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2072
            if str(r) != t or r not in cl:
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2073
                raise ValueError
26143
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2074
            revs = [r]
25344
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2075
        except ValueError:
26143
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2076
            revs = stringset(repo, subset, t)
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2077
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2078
        for r in revs:
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2079
            if r in seen:
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2080
                continue
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2081
            if (r in subset
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2082
                or r == node.nullrev and isinstance(subset, fullreposet)):
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2083
                ls.append(r)
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2084
            seen.add(r)
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2085
    return baseset(ls)
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2086
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2087
# for internal use
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2088
@predicate('_intlist', safe=True)
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2089
def _intlist(repo, subset, x):
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2090
    s = getstring(x, "internal error")
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2091
    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
  2092
        return baseset()
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2093
    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
  2094
    s = subset
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2095
    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
  2096
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2097
# for internal use
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2098
@predicate('_hexlist', safe=True)
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2099
def _hexlist(repo, subset, x):
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2100
    s = getstring(x, "internal error")
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2101
    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
  2102
        return baseset()
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2103
    cl = repo.changelog
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2104
    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
  2105
    s = subset
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2106
    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
  2107
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2108
methods = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2109
    "range": rangeset,
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
  2110
    "dagrange": dagrange,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2111
    "string": stringset,
24932
022282152632 revset: don't error out if tokens parse as existing symbols
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24923
diff changeset
  2112
    "symbol": stringset,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2113
    "and": andset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2114
    "or": orset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2115
    "not": notset,
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2116
    "difference": differenceset,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2117
    "list": listset,
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
  2118
    "keyvalue": keyvaluepair,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2119
    "func": func,
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2120
    "ancestor": ancestorspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2121
    "parent": parentspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2122
    "parentpost": p1,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2123
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2124
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2125
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
  2126
    if x is None:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2127
        return 0, x
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2128
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2129
    smallbonus = 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2130
    if small:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2131
        smallbonus = .5
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2132
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2133
    op = x[0]
11283
a6356b2695a3 revset: fix - handling in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 11282
diff changeset
  2134
    if op == 'minus':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2135
        return optimize(('and', x[1], ('not', x[2])), small)
23765
537a2669a113 revset: use '%' as an operator for 'only'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23742
diff changeset
  2136
    elif op == 'only':
537a2669a113 revset: use '%' as an operator for 'only'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23742
diff changeset
  2137
        return optimize(('func', ('symbol', 'only'),
537a2669a113 revset: use '%' as an operator for 'only'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23742
diff changeset
  2138
                         ('list', x[1], x[2])), small)
25094
8b99e9a8db05 revset: map postfix '%' to only() to optimize operand recursively (issue4670)
Yuya Nishihara <yuya@tcha.org>
parents: 24904
diff changeset
  2139
    elif op == 'onlypost':
8b99e9a8db05 revset: map postfix '%' to only() to optimize operand recursively (issue4670)
Yuya Nishihara <yuya@tcha.org>
parents: 24904
diff changeset
  2140
        return optimize(('func', ('symbol', 'only'), x[1]), small)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2141
    elif op == 'dagrangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2142
        return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2143
    elif op == 'dagrangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2144
        return optimize(('func', ('symbol', 'descendants'), x[1]), small)
25819
be29d26e2949 revset: parse nullary ":" operator as "0:tip"
Yuya Nishihara <yuya@tcha.org>
parents: 25815
diff changeset
  2145
    elif op == 'rangeall':
be29d26e2949 revset: parse nullary ":" operator as "0:tip"
Yuya Nishihara <yuya@tcha.org>
parents: 25815
diff changeset
  2146
        return optimize(('range', ('string', '0'), ('string', 'tip')), small)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2147
    elif op == 'rangepre':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2148
        return optimize(('range', ('string', '0'), x[1]), small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2149
    elif op == 'rangepost':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2150
        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
  2151
    elif op == 'negate':
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  2152
        return optimize(('string',
6b836d5c8c9e revset: make negate work for sort specs
Matt Mackall <mpm@selenic.com>
parents: 11456
diff changeset
  2153
                         '-' + 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
  2154
    elif op in 'string symbol negate':
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2155
        return smallbonus, x # single revisions are small
16859
eeb464ed7275 revset: drop unreachable code
Bryan O'Sullivan <bryano@fb.com>
parents: 16838
diff changeset
  2156
    elif op == 'and':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2157
        wa, ta = optimize(x[1], True)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2158
        wb, tb = optimize(x[2], True)
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2159
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2160
        # (::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
  2161
        def isonly(revs, bases):
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2162
            return (
25995
4f703dcc626f revset: prevent crash caused by empty group expression while optimizing "and"
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
  2163
                revs is not None
4f703dcc626f revset: prevent crash caused by empty group expression while optimizing "and"
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
  2164
                and revs[0] == 'func'
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2165
                and getstring(revs[1], _('not a symbol')) == 'ancestors'
25995
4f703dcc626f revset: prevent crash caused by empty group expression while optimizing "and"
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
  2166
                and bases is not None
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2167
                and bases[0] == 'not'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2168
                and bases[1][0] == 'func'
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2169
                and getstring(bases[1][1], _('not a symbol')) == 'ancestors')
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2170
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2171
        w = min(wa, wb)
21893
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  2172
        if isonly(ta, tb):
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  2173
            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
  2174
        if isonly(tb, ta):
e967c3b08705 revset: replace _missingancestors optimization with only revset
Siddharth Agarwal <sid0@fb.com>
parents: 21870
diff changeset
  2175
            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
  2176
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2177
        if tb is not None and tb[0] == 'not':
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2178
            return wa, ('difference', ta, tb[1])
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2179
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2180
        if wa > wb:
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2181
            return w, (op, tb, ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2182
        return w, (op, ta, tb)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2183
    elif op == 'or':
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2184
        # fast path for machine-generated expression, that is likely to have
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2185
        # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2186
        ws, ts, ss = [], [], []
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2187
        def flushss():
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2188
            if not ss:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2189
                return
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2190
            if len(ss) == 1:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2191
                w, t = ss[0]
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2192
            else:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2193
                s = '\0'.join(t[1] for w, t in ss)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2194
                y = ('func', ('symbol', '_list'), ('string', s))
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2195
                w, t = optimize(y, False)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2196
            ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2197
            ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2198
            del ss[:]
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2199
        for y in x[1:]:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2200
            w, t = optimize(y, False)
25996
b12e00a05d57 revset: prevent crash caused by empty group expression while optimizing "or"
Yuya Nishihara <yuya@tcha.org>
parents: 25995
diff changeset
  2201
            if t is not None and (t[0] == 'string' or t[0] == 'symbol'):
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2202
                ss.append((w, t))
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2203
                continue
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2204
            flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2205
            ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2206
            ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2207
        flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2208
        if len(ts) == 1:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2209
            return ws[0], ts[0] # 'or' operation is fully optimized out
25307
4d1e56b29a91 revset: comment that we can't swap 'or' operands by weight
Yuya Nishihara <yuya@tcha.org>
parents: 25270
diff changeset
  2210
        # we can't reorder trees by weight because it would change the order.
4d1e56b29a91 revset: comment that we can't swap 'or' operands by weight
Yuya Nishihara <yuya@tcha.org>
parents: 25270
diff changeset
  2211
        # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a")
25309
b333ca94403d revset: reduce nesting of chained 'or' operations (issue4624)
Yuya Nishihara <yuya@tcha.org>
parents: 25308
diff changeset
  2212
        #   ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0]))
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2213
        return max(ws), (op,) + tuple(ts)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2214
    elif op == 'not':
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2215
        # Optimize not public() to _notpublic() because we have a fast version
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2216
        if x[1] == ('func', ('symbol', 'public'), None):
27637
b502138f5faa cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents: 27587
diff changeset
  2217
            newsym = ('func', ('symbol', '_notpublic'), None)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2218
            o = optimize(newsym, not small)
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2219
            return o[0], o[1]
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2220
        else:
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2221
            o = optimize(x[1], not small)
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2222
            return o[0], (op, o[1])
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2223
    elif op == 'parentpost':
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2224
        o = optimize(x[1], small)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2225
        return o[0], (op, o[1])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2226
    elif op == 'group':
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2227
        return optimize(x[1], small)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2228
    elif op in 'dagrange range parent ancestorspec':
14842
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  2229
        if op == 'parent':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  2230
            # 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
  2231
            post = ('parentpost', x[1])
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  2232
            if x[2][0] == 'dagrangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  2233
                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
  2234
            elif x[2][0] == 'rangepre':
805651777188 revsets: do the right thing with x^:y (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14723
diff changeset
  2235
                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
  2236
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2237
        wa, ta = optimize(x[1], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2238
        wb, tb = optimize(x[2], small)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2239
        return wa + wb, (op, ta, tb)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2240
    elif op == 'list':
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2241
        ws, ts = zip(*(optimize(y, small) for y in x[1:]))
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2242
        return sum(ws), (op,) + ts
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2243
    elif op == 'func':
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
  2244
        f = getstring(x[1], _("not a symbol"))
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2245
        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
  2246
        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
  2247
                 "outgoing user"):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2248
            w = 10 # slow
12351
b913232d13c1 revsets: reduce cost of outgoing in the optimizer
Matt Mackall <mpm@selenic.com>
parents: 12321
diff changeset
  2249
        elif f in "modifies adds removes":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2250
            w = 30 # slower
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2251
        elif f == "contains":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2252
            w = 100 # very slow
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2253
        elif f == "ancestor":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2254
            w = 1 * smallbonus
22451
186fd06283b4 revset: lower weight for _intlist function
Durham Goode <durham@fb.com>
parents: 22450
diff changeset
  2255
        elif f in "reverse limit first _intlist":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2256
            w = 0
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2257
        elif f in "sort":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2258
            w = 10 # assume most sorts look at changelog
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2259
        else:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2260
            w = 1
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2261
        return w + wa, (op, x[1], ta)
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2262
    return 1, x
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2263
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2264
_aliasarg = ('func', ('symbol', '_aliasarg'))
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2265
def _getaliasarg(tree):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2266
    """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
  2267
    return X, None otherwise.
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2268
    """
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2269
    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
  2270
        and tree[2][0] == 'string'):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2271
        return tree[2][1]
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2272
    return None
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2273
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2274
def _checkaliasarg(tree, known=None):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2275
    """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
  2276
    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
  2277
    """
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2278
    if isinstance(tree, tuple):
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2279
        arg = _getaliasarg(tree)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2280
        if arg is not None and (not known or arg not in known):
24219
282c0d8c1880 revset: use UnknownIdentifier where appropriate
Augie Fackler <augie@google.com>
parents: 24204
diff changeset
  2281
            raise error.UnknownIdentifier('_aliasarg', [])
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2282
        for t in tree:
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2283
            _checkaliasarg(t, known)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2284
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2285
# the set of valid characters for the initial letter of symbols in
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2286
# alias declarations and definitions
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2287
_aliassyminitletters = set(c for c in [chr(i) for i in xrange(256)]
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2288
                           if c.isalnum() or c in '._@$' or ord(c) > 127)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2289
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2290
def _tokenizealias(program, lookup=None):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2291
    """Parse alias declaration/definition into a stream of tokens
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2292
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2293
    This allows symbol names to use also ``$`` as an initial letter
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2294
    (for backward compatibility), and callers of this function should
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2295
    examine whether ``$`` is used also for unexpected symbols or not.
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2296
    """
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2297
    return tokenize(program, lookup=lookup,
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2298
                    syminitletters=_aliassyminitletters)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2299
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2300
def _parsealiasdecl(decl):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2301
    """Parse alias declaration ``decl``
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2302
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2303
    This returns ``(name, tree, args, errorstr)`` tuple:
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2304
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2305
    - ``name``: of declared alias (may be ``decl`` itself at error)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2306
    - ``tree``: parse result (or ``None`` at error)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2307
    - ``args``: list of alias argument names (or None for symbol declaration)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2308
    - ``errorstr``: detail about detected error (or None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2309
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2310
    >>> _parsealiasdecl('foo')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2311
    ('foo', ('symbol', 'foo'), None, None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2312
    >>> _parsealiasdecl('$foo')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2313
    ('$foo', None, None, "'$' not for alias arguments")
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2314
    >>> _parsealiasdecl('foo::bar')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2315
    ('foo::bar', None, None, 'invalid format')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2316
    >>> _parsealiasdecl('foo bar')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2317
    ('foo bar', None, None, 'at 4: invalid token')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2318
    >>> _parsealiasdecl('foo()')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2319
    ('foo', ('func', ('symbol', 'foo')), [], None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2320
    >>> _parsealiasdecl('$foo()')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2321
    ('$foo()', None, None, "'$' not for alias arguments")
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2322
    >>> _parsealiasdecl('foo($1, $2)')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2323
    ('foo', ('func', ('symbol', 'foo')), ['$1', '$2'], None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2324
    >>> _parsealiasdecl('foo(bar_bar, baz.baz)')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2325
    ('foo', ('func', ('symbol', 'foo')), ['bar_bar', 'baz.baz'], None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2326
    >>> _parsealiasdecl('foo($1, $2, nested($1, $2))')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2327
    ('foo($1, $2, nested($1, $2))', None, None, 'invalid argument list')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2328
    >>> _parsealiasdecl('foo(bar($1, $2))')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2329
    ('foo(bar($1, $2))', None, None, 'invalid argument list')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2330
    >>> _parsealiasdecl('foo("string")')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2331
    ('foo("string")', None, None, 'invalid argument list')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2332
    >>> _parsealiasdecl('foo($1, $2')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2333
    ('foo($1, $2', None, None, 'at 10: unexpected token: end')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2334
    >>> _parsealiasdecl('foo("string')
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2335
    ('foo("string', None, None, 'at 5: unterminated string')
23847
71402bb8d8b2 revset: check for collisions between alias argument names in the declaration
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23846
diff changeset
  2336
    >>> _parsealiasdecl('foo($1, $2, $1)')
71402bb8d8b2 revset: check for collisions between alias argument names in the declaration
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23846
diff changeset
  2337
    ('foo', None, None, 'argument names collide with each other')
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2338
    """
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2339
    p = parser.parser(elements)
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2340
    try:
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2341
        tree, pos = p.parse(_tokenizealias(decl))
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2342
        if (pos != len(decl)):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2343
            raise error.ParseError(_('invalid token'), pos)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2344
        tree = parser.simplifyinfixops(tree, ('list',))
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2345
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2346
        if isvalidsymbol(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2347
            # "name = ...." style
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2348
            name = getsymbol(tree)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2349
            if name.startswith('$'):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2350
                return (decl, None, None, _("'$' not for alias arguments"))
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2351
            return (name, ('symbol', name), None, None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2352
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2353
        if isvalidfunc(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2354
            # "name(arg, ....) = ...." style
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2355
            name = getfuncname(tree)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2356
            if name.startswith('$'):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2357
                return (decl, None, None, _("'$' not for alias arguments"))
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2358
            args = []
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2359
            for arg in getfuncargs(tree):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2360
                if not isvalidsymbol(arg):
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2361
                    return (decl, None, None, _("invalid argument list"))
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2362
                args.append(getsymbol(arg))
23847
71402bb8d8b2 revset: check for collisions between alias argument names in the declaration
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23846
diff changeset
  2363
            if len(args) != len(set(args)):
71402bb8d8b2 revset: check for collisions between alias argument names in the declaration
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23846
diff changeset
  2364
                return (name, None, None,
71402bb8d8b2 revset: check for collisions between alias argument names in the declaration
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23846
diff changeset
  2365
                        _("argument names collide with each other"))
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2366
            return (name, ('func', ('symbol', name)), args, None)
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2367
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2368
        return (decl, None, None, _("invalid format"))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
  2369
    except error.ParseError as inst:
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2370
        return (decl, None, None, parseerrordetail(inst))
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2371
23993
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2372
def _parsealiasdefn(defn, args):
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2373
    """Parse alias definition ``defn``
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2374
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2375
    This function also replaces alias argument references in the
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2376
    specified definition by ``_aliasarg(ARGNAME)``.
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2377
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2378
    ``args`` is a list of alias argument names, or None if the alias
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2379
    is declared as a symbol.
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2380
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2381
    This returns "tree" as parsing result.
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2382
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2383
    >>> args = ['$1', '$2', 'foo']
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2384
    >>> print prettyformat(_parsealiasdefn('$1 or foo', args))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2385
    (or
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2386
      (func
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2387
        ('symbol', '_aliasarg')
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2388
        ('string', '$1'))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2389
      (func
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2390
        ('symbol', '_aliasarg')
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2391
        ('string', 'foo')))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2392
    >>> try:
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2393
    ...     _parsealiasdefn('$1 or $bar', args)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2394
    ... except error.ParseError, inst:
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2395
    ...     print parseerrordetail(inst)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2396
    at 6: '$' not for alias arguments
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2397
    >>> args = ['$1', '$10', 'foo']
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2398
    >>> print prettyformat(_parsealiasdefn('$10 or foobar', args))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2399
    (or
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2400
      (func
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2401
        ('symbol', '_aliasarg')
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2402
        ('string', '$10'))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2403
      ('symbol', 'foobar'))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2404
    >>> print prettyformat(_parsealiasdefn('"$1" or "foo"', args))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2405
    (or
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2406
      ('string', '$1')
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2407
      ('string', 'foo'))
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2408
    """
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2409
    def tokenizedefn(program, lookup=None):
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2410
        if args:
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2411
            argset = set(args)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2412
        else:
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2413
            argset = set()
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2414
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2415
        for t, value, pos in _tokenizealias(program, lookup=lookup):
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2416
            if t == 'symbol':
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2417
                if value in argset:
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2418
                    # emulate tokenization of "_aliasarg('ARGNAME')":
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2419
                    # "_aliasarg()" is an unknown symbol only used separate
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2420
                    # alias argument placeholders from regular strings.
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2421
                    yield ('symbol', '_aliasarg', pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2422
                    yield ('(', None, pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2423
                    yield ('string', value, pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2424
                    yield (')', None, pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2425
                    continue
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2426
                elif value.startswith('$'):
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2427
                    raise error.ParseError(_("'$' not for alias arguments"),
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2428
                                           pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2429
            yield (t, value, pos)
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2430
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2431
    p = parser.parser(elements)
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2432
    tree, pos = p.parse(tokenizedefn(defn))
23993
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2433
    if pos != len(defn):
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2434
        raise error.ParseError(_('invalid token'), pos)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2435
    return parser.simplifyinfixops(tree, ('list', 'or'))
23993
eedade006458 revset: introduce _parsealiasdefn to parse alias definitions strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23978
diff changeset
  2436
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2437
class revsetalias(object):
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2438
    # whether own `error` information is already shown or not.
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2439
    # this avoids showing same warning multiple times at each `findaliases`.
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2440
    warned = False
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2441
14723
b9faf94ee196 revset: fix aliases with 0 or more than 2 parameters
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
  2442
    def __init__(self, name, value):
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2443
        '''Aliases like:
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2444
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2445
        h = heads(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2446
        b($1) = ancestors($1) - ancestors(default)
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2447
        '''
23846
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2448
        self.name, self.tree, self.args, self.error = _parsealiasdecl(name)
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2449
        if self.error:
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2450
            self.error = _('failed to parse the declaration of revset alias'
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2451
                           ' "%s": %s') % (self.name, self.error)
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2452
            return
aac4a1a7920e revset: parse alias declaration strictly by _parsealiasdecl
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23845
diff changeset
  2453
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2454
        try:
23994
8a2156780839 revset: replace parsing alias definition by _parsealiasdefn to parse strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23993
diff changeset
  2455
            self.replacement = _parsealiasdefn(value, self.args)
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2456
            # Check for placeholder injection
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2457
            _checkaliasarg(self.replacement, self.args)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
  2458
        except error.ParseError as inst:
23844
ddf2172e901d revset: store full detail into revsetalias.error for error source distinction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23843
diff changeset
  2459
            self.error = _('failed to parse the definition of revset alias'
ddf2172e901d revset: store full detail into revsetalias.error for error source distinction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23843
diff changeset
  2460
                           ' "%s": %s') % (self.name, parseerrordetail(inst))
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2461
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2462
def _getalias(aliases, tree):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2463
    """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
  2464
    otherwise.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2465
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2466
    if isinstance(tree, tuple) and tree:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2467
        if tree[0] == 'symbol' and len(tree) == 2:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2468
            name = tree[1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2469
            alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2470
            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
  2471
                return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2472
        if tree[0] == 'func' and len(tree) > 1:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2473
            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
  2474
                name = tree[1][1]
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2475
                alias = aliases.get(name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2476
                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
  2477
                    return alias
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2478
    return None
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2479
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2480
def _expandargs(tree, args):
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2481
    """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
  2482
    same name in args, recursively.
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2483
    """
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2484
    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
  2485
        return tree
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2486
    arg = _getaliasarg(tree)
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2487
    if arg is not None:
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2488
        return args[arg]
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2489
    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
  2490
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2491
def _expandaliases(aliases, tree, expanding, cache):
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2492
    """Expand aliases in tree, recursively.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2493
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2494
    '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
  2495
    revsetalias objects.
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2496
    """
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2497
    if not isinstance(tree, tuple):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2498
        # Do not expand raw strings
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2499
        return tree
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2500
    alias = _getalias(aliases, tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2501
    if alias is not None:
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2502
        if alias.error:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26571
diff changeset
  2503
            raise error.Abort(alias.error)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2504
        if alias in expanding:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2505
            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
  2506
                                     'detected') % alias.name)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2507
        expanding.append(alias)
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2508
        if alias.name not in cache:
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2509
            cache[alias.name] = _expandaliases(aliases, alias.replacement,
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2510
                                               expanding, cache)
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2511
        result = cache[alias.name]
16772
30e46d7138de revset: fix infinite alias expansion detection
Patrick Mezard <patrick@mezard.eu>
parents: 16771
diff changeset
  2512
        expanding.pop()
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2513
        if alias.args is not None:
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2514
            l = getlist(tree[2])
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2515
            if len(l) != len(alias.args):
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2516
                raise error.ParseError(
26778
a95c975f42e3 l10n: use %d instead of %s for numbers
timeless@mozdev.org
parents: 26716
diff changeset
  2517
                    _('invalid number of arguments: %d') % len(l))
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2518
            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
  2519
            result = _expandargs(result, dict(zip(alias.args, l)))
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2520
    else:
16838
d37d221334be revset: cache alias expansions
Patrick Mezard <patrick@mezard.eu>
parents: 16834
diff changeset
  2521
        result = tuple(_expandaliases(aliases, t, expanding, cache)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2522
                       for t in tree)
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2523
    return result
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2524
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2525
def findaliases(ui, tree, showwarning=None):
16771
2f3317d53d51 revset: explicitely tag alias arguments for expansion
Patrick Mezard <patrick@mezard.eu>
parents: 16748
diff changeset
  2526
    _checkaliasarg(tree)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2527
    aliases = {}
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2528
    for k, v in ui.configitems('revsetalias'):
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2529
        alias = revsetalias(k, v)
16096
b8be450638f6 revset: fix alias substitution recursion (issue3240)
Patrick Mezard <patrick@mezard.eu>
parents: 16007
diff changeset
  2530
        aliases[alias.name] = alias
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2531
    tree = _expandaliases(aliases, tree, [], {})
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2532
    if showwarning:
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2533
        # warn about problematic (but not referred) aliases
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2534
        for name, alias in sorted(aliases.iteritems()):
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2535
            if alias.error and not alias.warned:
23844
ddf2172e901d revset: store full detail into revsetalias.error for error source distinction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23843
diff changeset
  2536
                showwarning(_('warning: %s\n') % (alias.error))
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2537
                alias.warned = True
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2538
    return tree
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2539
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2540
def foldconcat(tree):
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2541
    """Fold elements to be concatenated by `##`
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2542
    """
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2543
    if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2544
        return tree
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2545
    if tree[0] == '_concat':
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2546
        pending = [tree]
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2547
        l = []
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2548
        while pending:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2549
            e = pending.pop()
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2550
            if e[0] == '_concat':
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2551
                pending.extend(reversed(e[1:]))
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2552
            elif e[0] in ('string', 'symbol'):
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2553
                l.append(e[1])
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2554
            else:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2555
                msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2556
                raise error.ParseError(msg)
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2557
        return ('string', ''.join(l))
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2558
    else:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2559
        return tuple(foldconcat(t) for t in tree)
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2560
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2561
def parse(spec, lookup=None):
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2562
    p = parser.parser(elements)
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25648
diff changeset
  2563
    tree, pos = p.parse(tokenize(spec, lookup=lookup))
25251
235f6490550c revset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 25225
diff changeset
  2564
    if pos != len(spec):
235f6490550c revset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 25225
diff changeset
  2565
        raise error.ParseError(_("invalid token"), pos)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2566
    return parser.simplifyinfixops(tree, ('list', 'or'))
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2567
24518
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2568
def posttreebuilthook(tree, repo):
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2569
    # hook for extensions to execute code on the optimized tree
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2570
    pass
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2571
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2572
def match(ui, spec, repo=None):
11385
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  2573
    if not spec:
e5a2134c083b revset: nicer exception for empty queries
Matt Mackall <mpm@selenic.com>
parents: 11383
diff changeset
  2574
        raise error.ParseError(_("empty query"))
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2575
    lookup = None
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2576
    if repo:
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2577
        lookup = repo.__contains__
25251
235f6490550c revset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 25225
diff changeset
  2578
    tree = parse(spec, lookup)
25926
996102be8b91 revset: split post-parsing stage from match()
Yuya Nishihara <yuya@tcha.org>
parents: 25902
diff changeset
  2579
    return _makematcher(ui, tree, repo)
996102be8b91 revset: split post-parsing stage from match()
Yuya Nishihara <yuya@tcha.org>
parents: 25902
diff changeset
  2580
25927
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2581
def matchany(ui, specs, repo=None):
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2582
    """Create a matcher that will include any revisions matching one of the
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2583
    given specs"""
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2584
    if not specs:
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2585
        def mfunc(repo, subset=None):
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2586
            return baseset()
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2587
        return mfunc
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2588
    if not all(specs):
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2589
        raise error.ParseError(_("empty query"))
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2590
    lookup = None
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2591
    if repo:
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2592
        lookup = repo.__contains__
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2593
    if len(specs) == 1:
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2594
        tree = parse(specs[0], lookup)
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2595
    else:
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2596
        tree = ('or',) + tuple(parse(s, lookup) for s in specs)
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2597
    return _makematcher(ui, tree, repo)
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2598
25926
996102be8b91 revset: split post-parsing stage from match()
Yuya Nishihara <yuya@tcha.org>
parents: 25902
diff changeset
  2599
def _makematcher(ui, tree, repo):
14900
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  2600
    if ui:
23725
6a81f88758aa revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23720
diff changeset
  2601
        tree = findaliases(ui, tree, showwarning=ui.warn)
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2602
    tree = foldconcat(tree)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2603
    weight, tree = optimize(tree, True)
24518
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2604
    posttreebuilthook(tree, repo)
24114
fafd9a1284cf revset: make match function initiate query from full set by default
Yuya Nishihara <yuya@tcha.org>
parents: 24031
diff changeset
  2605
    def mfunc(repo, subset=None):
fafd9a1284cf revset: make match function initiate query from full set by default
Yuya Nishihara <yuya@tcha.org>
parents: 24031
diff changeset
  2606
        if subset is None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  2607
            subset = fullreposet(repo)
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
  2608
        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
  2609
            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
  2610
        else:
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2611
            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
  2612
        return result
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2613
    return mfunc
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2614
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2615
def formatspec(expr, *args):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2616
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2617
    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
  2618
    escapes arguments appropriately. Aliases are intentionally ignored
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2619
    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
  2620
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2621
    Supported arguments:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2622
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2623
    %r = revset expression, parenthesized
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2624
    %d = int(arg), no quoting
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2625
    %s = string(arg), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2626
    %b = arg.branch(), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2627
    %n = hex(arg), single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2628
    %% = a literal '%'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2629
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2630
    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
  2631
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2632
    >>> 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
  2633
    '(10 or 11):: and ((this()) or (that()))'
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2634
    >>> formatspec('%d:: and not %d::', 10, 20)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2635
    '10:: and not 20::'
15325
cdf1daa3b83f revset: deal with empty lists in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15268
diff changeset
  2636
    >>> formatspec('%ld or %ld', [], [1])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2637
    "_list('') or 1"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2638
    >>> formatspec('keyword(%s)', 'foo\\xe9')
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2639
    "keyword('foo\\\\xe9')"
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2640
    >>> b = lambda: 'default'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2641
    >>> b.branch = b
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2642
    >>> formatspec('branch(%b)', b)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2643
    "branch('default')"
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2644
    >>> 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
  2645
    "root(_list('a\\x00b\\x00c\\x00d'))"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2646
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2647
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2648
    def quote(s):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2649
        return repr(str(s))
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2650
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2651
    def argtype(c, arg):
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2652
        if c == 'd':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2653
            return str(int(arg))
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2654
        elif c == 's':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2655
            return quote(arg)
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2656
        elif c == 'r':
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2657
            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
  2658
            return '(%s)' % arg
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2659
        elif c == 'n':
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  2660
            return quote(node.hex(arg))
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2661
        elif c == 'b':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2662
            return quote(arg.branch())
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2663
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2664
    def listexp(s, t):
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2665
        l = len(s)
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2666
        if l == 0:
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2667
            return "_list('')"
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2668
        elif l == 1:
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2669
            return argtype(t, s[0])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2670
        elif t == 'd':
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2671
            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
  2672
        elif t == 's':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2673
            return "_list('%s')" % "\0".join(s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2674
        elif t == 'n':
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2675
            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
  2676
        elif t == 'b':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2677
            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
  2678
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15726
diff changeset
  2679
        m = l // 2
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2680
        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
  2681
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2682
    ret = ''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2683
    pos = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2684
    arg = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2685
    while pos < len(expr):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2686
        c = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2687
        if c == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2688
            pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2689
            d = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2690
            if d == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2691
                ret += d
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2692
            elif d in 'dsnbr':
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2693
                ret += argtype(d, args[arg])
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2694
                arg += 1
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2695
            elif d == 'l':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2696
                # a list of some type
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2697
                pos += 1
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2698
                d = expr[pos]
15596
2555f441a32f merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15595
diff changeset
  2699
                ret += listexp(list(args[arg]), d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2700
                arg += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2701
            else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26571
diff changeset
  2702
                raise error.Abort('unexpected revspec format character %s' % d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2703
        else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2704
            ret += c
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2705
        pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2706
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2707
    return ret
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2708
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2709
def prettyformat(tree):
25253
3f1a9b44b8c2 parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents: 25251
diff changeset
  2710
    return parser.prettyformat(tree, ('string', 'symbol'))
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2711
19719
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2712
def depth(tree):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2713
    if isinstance(tree, tuple):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2714
        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
  2715
    else:
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2716
        return 0
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2717
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2718
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
  2719
    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
  2720
        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
  2721
    else:
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2722
        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
  2723
        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
  2724
            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
  2725
        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
  2726
            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
  2727
        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
  2728
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2729
def _formatsetrepr(r):
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2730
    """Format an optional printable representation of a set
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2731
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2732
    ========  =================================
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2733
    type(r)   example
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2734
    ========  =================================
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2735
    tuple     ('<not %r>', other)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2736
    str       '<branch closed>'
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2737
    callable  lambda: '<branch %r>' % sorted(b)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2738
    object    other
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2739
    ========  =================================
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2740
    """
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2741
    if r is None:
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2742
        return ''
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2743
    elif isinstance(r, tuple):
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2744
        return r[0] % r[1:]
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2745
    elif isinstance(r, str):
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2746
        return r
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2747
    elif callable(r):
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2748
        return r()
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2749
    else:
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2750
        return repr(r)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2751
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2752
class abstractsmartset(object):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2753
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2754
    def __nonzero__(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2755
        """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
  2756
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2757
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2758
    def __contains__(self, rev):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2759
        """provide fast membership testing"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2760
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2761
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2762
    def __iter__(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2763
        """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
  2764
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2765
22716
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2766
    # 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
  2767
    # 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
  2768
    #
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2769
    # 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
  2770
    # 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
  2771
    fastasc = None
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2772
    fastdesc = None
6877ba8d85ff abstractsmartset: document the `fastasc` and `fastdesc` attributes/methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22715
diff changeset
  2773
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2774
    def isascending(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2775
        """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
  2776
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2777
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2778
    def isdescending(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2779
        """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
  2780
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2781
26099
ab66c1dee405 revset: cache smartset's min/max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26095
diff changeset
  2782
    @util.cachefunc
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2783
    def min(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2784
        """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
  2785
        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
  2786
            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
  2787
                return r
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2788
            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
  2789
        return min(self)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2790
26099
ab66c1dee405 revset: cache smartset's min/max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26095
diff changeset
  2791
    @util.cachefunc
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2792
    def max(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2793
        """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
  2794
        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
  2795
            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
  2796
                return r
e8832cf1abf6 abstractsmartset: add a default implementation for min and max
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22721
diff changeset
  2797
            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
  2798
        return max(self)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2799
22808
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2800
    def first(self):
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2801
        """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
  2802
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2803
        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
  2804
        raise NotImplementedError()
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2805
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2806
    def last(self):
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2807
        """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
  2808
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2809
        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
  2810
        raise NotImplementedError()
228b0aafb1ce smartset: add first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22805
diff changeset
  2811
22995
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2812
    def __len__(self):
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2813
        """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
  2814
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2815
        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
  2816
        raise NotImplementedError()
2587631c5f8a revset: make __len__ part of the offical API
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22944
diff changeset
  2817
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2818
    def reverse(self):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2819
        """reverse the expected iteration order"""
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2820
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2821
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2822
    def sort(self, reverse=True):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2823
        """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
  2824
        raise NotImplementedError()
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2825
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2826
    def __and__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2827
        """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
  2828
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2829
        This is part of the mandatory API for smartset."""
24459
7d369fae098e revset: optimize "x & fullreposet" case
Yuya Nishihara <yuya@tcha.org>
parents: 24458
diff changeset
  2830
        if isinstance(other, fullreposet):
7d369fae098e revset: optimize "x & fullreposet" case
Yuya Nishihara <yuya@tcha.org>
parents: 24458
diff changeset
  2831
            return self
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2832
        return self.filter(other.__contains__, condrepr=other, cache=False)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2833
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2834
    def __add__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2835
        """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
  2836
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2837
        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
  2838
        return addset(self, other)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2839
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2840
    def __sub__(self, other):
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2841
        """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
  2842
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2843
        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
  2844
        c = other.__contains__
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2845
        return self.filter(lambda r: not c(r), condrepr=('<not %r>', other),
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2846
                           cache=False)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2847
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2848
    def filter(self, condition, condrepr=None, cache=True):
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2849
        """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
  2850
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2851
        `condition` is a callable which takes a revision number and returns a
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2852
        boolean. Optional `condrepr` provides a printable representation of
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2853
        the given `condition`.
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2854
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2855
        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
  2856
        # 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
  2857
        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
  2858
            condition = util.cachefunc(condition)
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2859
        return filteredset(self, condition, condrepr)
22692
78c916f24dd9 revset: introduce an abstractsmartset class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22691
diff changeset
  2860
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2861
class baseset(abstractsmartset):
20416
e72bcc245ecb revset: added docstring to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20393
diff changeset
  2862
    """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
  2863
    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
  2864
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2865
    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
  2866
    """
28425
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2867
    def __init__(self, data=(), datarepr=None):
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2868
        """
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2869
        datarepr: a tuple of (format, obj, ...), a function or an object that
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2870
                  provides a printable representation of the given data.
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2871
        """
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2872
        if not isinstance(data, list):
26060
4ee2af2194d4 baseset: keep the input set around
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26053
diff changeset
  2873
            if isinstance(data, set):
4ee2af2194d4 baseset: keep the input set around
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26053
diff changeset
  2874
                self._set = data
22825
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2875
            data = list(data)
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2876
        self._list = data
28425
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2877
        self._datarepr = datarepr
22827
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2878
        self._ascending = None
20365
bc770ee6a351 revset: implemented set caching for revset evaluation
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20364
diff changeset
  2879
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2880
    @util.propertycache
22879
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2881
    def _set(self):
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2882
        return set(self._list)
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2883
efe5062145c1 baseset: make `_set` a property cache
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22877
diff changeset
  2884
    @util.propertycache
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2885
    def _asclist(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2886
        asclist = self._list[:]
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2887
        asclist.sort()
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2888
        return asclist
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2889
22827
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2890
    def __iter__(self):
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2891
        if self._ascending is None:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2892
            return iter(self._list)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2893
        elif self._ascending:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2894
            return iter(self._asclist)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2895
        else:
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2896
            return reversed(self._asclist)
c1107cb21df2 baseset: prepare lazy ordering in __iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22826
diff changeset
  2897
22826
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2898
    def fastasc(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2899
        return iter(self._asclist)
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2900
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2901
    def fastdesc(self):
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2902
        return reversed(self._asclist)
4ffb327e4719 baseset: implement a fastasc and fastdesc
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22825
diff changeset
  2903
22503
300e07582e9b revset: add an optimised baseset.__contains__ (issue4371)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22105
diff changeset
  2904
    @util.propertycache
300e07582e9b revset: add an optimised baseset.__contains__ (issue4371)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22105
diff changeset
  2905
    def __contains__(self):
22880
5b635b44af14 baseset: access `_set` directly for containment check
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22879
diff changeset
  2906
        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
  2907
22691
d8a08b68f754 revset: add a `__nonzero__` to baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22690
diff changeset
  2908
    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
  2909
        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
  2910
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2911
    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
  2912
        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
  2913
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2914
    def reverse(self):
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2915
        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
  2916
            self._list.reverse()
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2917
        else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2918
            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
  2919
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2920
    def __len__(self):
0e8bb81b58b9 baseset: stop inheriting from built-in list class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22817
diff changeset
  2921
        return len(self._list)
22691
d8a08b68f754 revset: add a `__nonzero__` to baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22690
diff changeset
  2922
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2923
    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
  2924
        """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
  2925
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2926
        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
  2927
        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
  2928
            return True
22828
966860f7a1a8 baseset: fix isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22827
diff changeset
  2929
        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
  2930
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  2931
    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
  2932
        """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
  2933
1e59f760d850 revset: added comments to all methods needed to duck-type from baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20726
diff changeset
  2934
        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
  2935
        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
  2936
            return True
22828
966860f7a1a8 baseset: fix isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22827
diff changeset
  2937
        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
  2938
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2939
    def first(self):
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2940
        if self:
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2941
            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
  2942
                return self._list[0]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2943
            elif self._ascending:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2944
                return self._asclist[0]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2945
            else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2946
                return self._asclist[-1]
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2947
        return None
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2948
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2949
    def last(self):
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2950
        if self:
22829
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2951
            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
  2952
                return self._list[-1]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2953
            elif self._ascending:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2954
                return self._asclist[-1]
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2955
            else:
36e09c25f870 baseset: explicitly track order of the baseset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22828
diff changeset
  2956
                return self._asclist[0]
22812
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2957
        return None
fcd12b310148 baseset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22811
diff changeset
  2958
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  2959
    def __repr__(self):
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  2960
        d = {None: '', False: '-', True: '+'}[self._ascending]
28425
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2961
        s = _formatsetrepr(self._datarepr)
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2962
        if not s:
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2963
            s = repr(self._list)
02d7faaf455c revset: stub to add extra data to baseset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28424
diff changeset
  2964
        return '<%s%s %s>' % (type(self).__name__, d, s)
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  2965
22726
169aa5e74b52 lazyset: rename the class to filteredset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22725
diff changeset
  2966
class filteredset(abstractsmartset):
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2967
    """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
  2968
    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
  2969
    revset
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2970
    """
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2971
    def __init__(self, subset, condition=lambda x: True, condrepr=None):
20738
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2972
        """
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2973
        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
  2974
                   belongs to the revset or not.
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2975
        condrepr: a tuple of (format, obj, ...), a function or an object that
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2976
                  provides a printable representation of the given condition.
20738
33943add5d65 revset: add some documentation for lazyset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20737
diff changeset
  2977
        """
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2978
        self._subset = subset
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2979
        self._condition = condition
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  2980
        self._condrepr = condrepr
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2981
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2982
    def __contains__(self, x):
26212
0d8df1f510c6 revset: uncache filteredset.__contains__
Yuya Nishihara <yuya@tcha.org>
parents: 26143
diff changeset
  2983
        return x in self._subset and self._condition(x)
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2984
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2985
    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
  2986
        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
  2987
21fda9dcd4e8 lazyset: split the iteration logic from the condition filtering logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22718
diff changeset
  2988
    def _iterfilter(self, it):
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2989
        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
  2990
        for x in it:
20427
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2991
            if cond(x):
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2992
                yield x
4a9191ca848e revset: added lazyset class with basic operations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20424
diff changeset
  2993
22720
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2994
    @property
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2995
    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
  2996
        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
  2997
        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
  2998
            return None
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  2999
        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
  3000
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  3001
    @property
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  3002
    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
  3003
        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
  3004
        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
  3005
            return None
4388f99c5512 lazyset: inherit the fastasc and fastdesc method from subset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22719
diff changeset
  3006
        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
  3007
20552
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  3008
    def __nonzero__(self):
26307
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3009
        fast = self.fastasc
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3010
        if fast is None:
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3011
            fast = self.fastdesc
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3012
        if fast is not None:
26306
d157e1f18e3f revset: speed up existence checks for ordered filtered sets
Durham Goode <durham@fb.com>
parents: 26305
diff changeset
  3013
            it = fast()
26307
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3014
        else:
428a8747f4ee revset: avoid implicit None testing in revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26306
diff changeset
  3015
            it = self
26306
d157e1f18e3f revset: speed up existence checks for ordered filtered sets
Durham Goode <durham@fb.com>
parents: 26305
diff changeset
  3016
d157e1f18e3f revset: speed up existence checks for ordered filtered sets
Durham Goode <durham@fb.com>
parents: 26305
diff changeset
  3017
        for r in it:
20552
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  3018
            return True
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  3019
        return False
0e99a66eb7bc revset: added __nonzero__ method to lazyset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20540
diff changeset
  3020
20429
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3021
    def __len__(self):
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3022
        # 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
  3023
        l = baseset([r for r in self])
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3024
        return len(l)
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3025
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3026
    def sort(self, reverse=False):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  3027
        self._subset.sort(reverse=reverse)
20429
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3028
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3029
    def reverse(self):
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3030
        self._subset.reverse()
f5b560c60bcd revset: added operations to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20428
diff changeset
  3031
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3032
    def isascending(self):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  3033
        return self._subset.isascending()
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3034
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3035
    def isdescending(self):
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  3036
        return self._subset.isdescending()
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3037
22813
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3038
    def first(self):
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3039
        for x in self:
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3040
            return x
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3041
        return None
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3042
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3043
    def last(self):
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3044
        it = None
25648
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3045
        if self.isascending():
22862
9e5576f822cc filteredset: drop explicit order management
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22861
diff changeset
  3046
            it = self.fastdesc
25648
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3047
        elif self.isdescending():
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3048
            it = self.fastasc
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3049
        if it is not None:
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3050
            for x in it():
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3051
                return x
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3052
            return None #empty case
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3053
        else:
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3054
            x = None
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3055
            for x in self:
9b9877d2b229 revset: rework 'filteredset.last'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25647
diff changeset
  3056
                pass
22813
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3057
            return x
5a96df266b2b filteredset: implement `first` and `last`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22812
diff changeset
  3058
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3059
    def __repr__(self):
28423
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  3060
        xs = [repr(self._subset)]
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  3061
        s = _formatsetrepr(self._condrepr)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  3062
        if s:
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  3063
            xs.append(s)
0d79d91ba7e3 revset: add extra data to filteredset for better inspection
Yuya Nishihara <yuya@tcha.org>
parents: 28395
diff changeset
  3064
        return '<%s %s>' % (type(self).__name__, ', '.join(xs))
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3065
25131
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3066
def _iterordered(ascending, iter1, iter2):
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3067
    """produce an ordered iteration from two iterators with the same order
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3068
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3069
    The ascending is used to indicated the iteration direction.
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3070
    """
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3071
    choice = max
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3072
    if ascending:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3073
        choice = min
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3074
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3075
    val1 = None
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3076
    val2 = None
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3077
    try:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3078
        # Consume both iterators in an ordered way until one is empty
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3079
        while True:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3080
            if val1 is None:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3081
                val1 = iter1.next()
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3082
            if val2 is None:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3083
                val2 = iter2.next()
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3084
            next = choice(val1, val2)
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3085
            yield next
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3086
            if val1 == next:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3087
                val1 = None
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3088
            if val2 == next:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3089
                val2 = None
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3090
    except StopIteration:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3091
        # Flush any remaining values and consume the other one
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3092
        it = iter2
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3093
        if val1 is not None:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3094
            yield val1
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3095
            it = iter1
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3096
        elif val2 is not None:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3097
            # might have been equality and both are empty
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3098
            yield val2
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3099
        for val in it:
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3100
            yield val
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3101
22793
ff6689b47e48 addset: drop the leading underscore from the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22792
diff changeset
  3102
class addset(abstractsmartset):
20708
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  3103
    """Represent the addition of two sets
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  3104
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  3105
    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
  3106
    performance on the __contains__ method
20708
17c89e5a5627 revset: made addset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20707
diff changeset
  3107
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  3108
    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
  3109
    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
  3110
    them maintaining the order by iterating over both at the same time
25024
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3111
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3112
    >>> xs = baseset([0, 3, 2])
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3113
    >>> ys = baseset([5, 2, 4])
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3114
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3115
    >>> rs = addset(xs, ys)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3116
    >>> bool(rs), 0 in rs, 1 in rs, 5 in rs, rs.first(), rs.last()
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3117
    (True, True, False, True, 0, 4)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3118
    >>> rs = addset(xs, baseset([]))
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3119
    >>> bool(rs), 0 in rs, 1 in rs, rs.first(), rs.last()
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3120
    (True, True, False, 0, 2)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3121
    >>> rs = addset(baseset([]), baseset([]))
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3122
    >>> bool(rs), 0 in rs, rs.first(), rs.last()
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3123
    (False, False, None, None)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3124
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3125
    iterate unsorted:
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3126
    >>> rs = addset(xs, ys)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3127
    >>> [x for x in rs]  # without _genlist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3128
    [0, 3, 2, 5, 4]
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3129
    >>> assert not rs._genlist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3130
    >>> len(rs)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3131
    5
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3132
    >>> [x for x in rs]  # with _genlist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3133
    [0, 3, 2, 5, 4]
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3134
    >>> assert rs._genlist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3135
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3136
    iterate ascending:
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3137
    >>> rs = addset(xs, ys, ascending=True)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3138
    >>> [x for x in rs], [x for x in rs.fastasc()]  # without _asclist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3139
    ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3140
    >>> assert not rs._asclist
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3141
    >>> len(rs)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3142
    5
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3143
    >>> [x for x in rs], [x for x in rs.fastasc()]
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3144
    ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
25024
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3145
    >>> assert rs._asclist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3146
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3147
    iterate descending:
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3148
    >>> rs = addset(xs, ys, ascending=False)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3149
    >>> [x for x in rs], [x for x in rs.fastdesc()]  # without _asclist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3150
    ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3151
    >>> assert not rs._asclist
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3152
    >>> len(rs)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3153
    5
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3154
    >>> [x for x in rs], [x for x in rs.fastdesc()]
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3155
    ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
25024
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3156
    >>> assert rs._asclist
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3157
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3158
    iterate ascending without fastasc:
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3159
    >>> rs = addset(xs, generatorset(ys), ascending=True)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3160
    >>> assert rs.fastasc is None
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3161
    >>> [x for x in rs]
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3162
    [0, 2, 3, 4, 5]
25024
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3163
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3164
    iterate descending without fastdesc:
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3165
    >>> rs = addset(generatorset(xs), ys, ascending=False)
263bbed1833c revset: test current behavior of addset class
Yuya Nishihara <yuya@tcha.org>
parents: 25023
diff changeset
  3166
    >>> assert rs.fastdesc is None
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3167
    >>> [x for x in rs]
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3168
    [5, 4, 3, 2, 0]
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3169
    """
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  3170
    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
  3171
        self._r1 = revs1
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3172
        self._r2 = revs2
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3173
        self._iter = None
20712
c152e538b85b revset: added ascending attribute to addset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20711
diff changeset
  3174
        self._ascending = ascending
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3175
        self._genlist = None
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3176
        self._asclist = None
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3177
20845
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  3178
    def __len__(self):
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  3179
        return len(self._list)
bc95143446e8 _addset: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20833
diff changeset
  3180
22743
eccf9907b844 addset: add a __nonzero__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22742
diff changeset
  3181
    def __nonzero__(self):
23100
ac494b087feb revset: fix O(2^n) perf regression in addset
Durham Goode <durham@fb.com>
parents: 23078
diff changeset
  3182
        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
  3183
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3184
    @util.propertycache
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3185
    def _list(self):
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3186
        if not self._genlist:
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3187
            self._genlist = baseset(iter(self))
20720
5f8400efca0b revset: added cached generated list to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20719
diff changeset
  3188
        return self._genlist
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3189
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3190
    def __iter__(self):
20722
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  3191
        """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
  3192
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  3193
        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
  3194
        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
  3195
        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
  3196
6894223ebc38 revset: changed _iterator() method on addset to work with a given order
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20721
diff changeset
  3197
        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
  3198
        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
  3199
        """
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  3200
        if self._ascending is None:
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3201
            if self._genlist:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3202
                return iter(self._genlist)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3203
            def arbitraryordergen():
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  3204
                for r in self._r1:
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  3205
                    yield r
22881
057ebf7714e1 addset: drop `.set()` usage during iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22880
diff changeset
  3206
                inr1 = self._r1.__contains__
22799
bafa371d7af3 addset: drop caching through generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22798
diff changeset
  3207
                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
  3208
                    if not inr1(r):
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3209
                        yield r
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3210
            return arbitraryordergen()
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3211
        # try to use our own fast iterator if it exists
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3212
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3213
        if self._ascending:
25130
a94ef7f517e0 revset: use fastasc/fastdesc switch consistently in addset.__iter__
Yuya Nishihara <yuya@tcha.org>
parents: 25129
diff changeset
  3214
            attr = 'fastasc'
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3215
        else:
25130
a94ef7f517e0 revset: use fastasc/fastdesc switch consistently in addset.__iter__
Yuya Nishihara <yuya@tcha.org>
parents: 25129
diff changeset
  3216
            attr = 'fastdesc'
a94ef7f517e0 revset: use fastasc/fastdesc switch consistently in addset.__iter__
Yuya Nishihara <yuya@tcha.org>
parents: 25129
diff changeset
  3217
        it = getattr(self, attr)
25115
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3218
        if it is not None:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3219
            return it()
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3220
        # maybe half of the component supports fast
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3221
        # get iterator for _r1
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3222
        iter1 = getattr(self._r1, attr)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3223
        if iter1 is None:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3224
            # let's avoid side effect (not sure it matters)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3225
            iter1 = iter(sorted(self._r1, reverse=not self._ascending))
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3226
        else:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3227
            iter1 = iter1()
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3228
        # get iterator for _r2
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3229
        iter2 = getattr(self._r2, attr)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3230
        if iter2 is None:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3231
            # let's avoid side effect (not sure it matters)
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3232
            iter2 = iter(sorted(self._r2, reverse=not self._ascending))
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3233
        else:
5548f558db3d revset: fix iteration over ordered addset composed of non-ordered operands
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25105
diff changeset
  3234
            iter2 = iter2()
25131
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3235
        return _iterordered(self._ascending, iter1, iter2)
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3236
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3237
    def _trysetasclist(self):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  3238
        """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
  3239
        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
  3240
            self._asclist = sorted(self._genlist)
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3241
22742
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3242
    @property
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3243
    def fastasc(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3244
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3245
        if self._asclist is not None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3246
            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
  3247
        iter1 = self._r1.fastasc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3248
        iter2 = self._r2.fastasc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3249
        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
  3250
            return None
25131
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3251
        return lambda: _iterordered(True, iter1(), iter2())
22742
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3252
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3253
    @property
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3254
    def fastdesc(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3255
        self._trysetasclist()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3256
        if self._asclist is not None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3257
            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
  3258
        iter1 = self._r1.fastdesc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3259
        iter2 = self._r2.fastdesc
6bbc26adcc6a addset: offer a fastasc and fastdesc methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22741
diff changeset
  3260
        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
  3261
            return None
25131
adfe4d9680bf revset: extract addset._iterordered to free function
Yuya Nishihara <yuya@tcha.org>
parents: 25130
diff changeset
  3262
        return lambda: _iterordered(False, iter1(), iter2())
22741
ef2c1ea8fb2c addset: split simple and ordered iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22740
diff changeset
  3263
20694
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3264
    def __contains__(self, x):
621c94378d0d revset: added addset class with its basic methods
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20693
diff changeset
  3265
        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
  3266
20724
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  3267
    def sort(self, reverse=False):
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  3268
        """Sort the added set
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  3269
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  3270
        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
  3271
        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
  3272
        """
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3273
        self._ascending = not reverse
20724
e9a64b3f2925 revset: added sort method in addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20723
diff changeset
  3274
20733
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  3275
    def isascending(self):
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  3276
        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
  3277
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  3278
    def isdescending(self):
adf4ec7e6f60 revset: added isascending and isdescending methods to _addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20732
diff changeset
  3279
        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
  3280
20723
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  3281
    def reverse(self):
22859
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3282
        if self._ascending is None:
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3283
            self._list.reverse()
513c0ba61db8 addset: do lazy sorting
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22857
diff changeset
  3284
        else:
20723
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  3285
            self._ascending = not self._ascending
fb9852c46a42 revset: added reverse method to addset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20722
diff changeset
  3286
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  3287
    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
  3288
        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
  3289
            return x
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  3290
        return None
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  3291
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  3292
    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
  3293
        self.reverse()
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  3294
        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
  3295
        self.reverse()
7361d8244efb addset: fix `first` and `last` on sorted addset (issue4426)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23115
diff changeset
  3296
        return val
22810
7f97cb12782f addset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22809
diff changeset
  3297
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3298
    def __repr__(self):
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3299
        d = {None: '', False: '-', True: '+'}[self._ascending]
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3300
        return '<%s%s %r, %r>' % (type(self).__name__, d, self._r1, self._r2)
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3301
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
  3302
class generatorset(abstractsmartset):
20705
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  3303
    """Wrap a generator for lazy iteration
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  3304
9cc2249a9461 revset: made generatorset a private class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20703
diff changeset
  3305
    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
  3306
    be iterated more than once.
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  3307
    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
  3308
    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
  3309
    """
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
  3310
    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
  3311
        """
1b4f2399f3c4 revset: add documentation and comment for _generatorset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20738
diff changeset
  3312
        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
  3313
        """
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3314
        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
  3315
        self._asclist = None
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3316
        self._cache = {}
22796
43f664bf2e1e generatorset: stop using a base as the _genlist
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22795
diff changeset
  3317
        self._genlist = []
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  3318
        self._finished = False
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3319
        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
  3320
        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
  3321
            if iterasc:
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  3322
                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
  3323
                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
  3324
            else:
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  3325
                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
  3326
                self.__contains__ = self._desccontains
20540
fa16c710a3d8 revset: added cached generated list on generatorset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20538
diff changeset
  3327
22739
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  3328
    def __nonzero__(self):
24936
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3329
        # Do not use 'for r in self' because it will enforce the iteration
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3330
        # order (default ascending), possibly unrolling a whole descending
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3331
        # iterator.
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3332
        if self._genlist:
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3333
            return True
2aa94b6fe51c revset: make generatorset.__nonzero__ lazy
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24932
diff changeset
  3334
        for r in self._consumegen():
22739
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  3335
            return True
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  3336
        return False
4ed47a1b2d24 generatorset: implement __nonzero__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22738
diff changeset
  3337
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3338
    def __contains__(self, x):
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3339
        if x in self._cache:
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3340
            return self._cache[x]
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3341
20828
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  3342
        # 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
  3343
        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
  3344
            if l == x:
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  3345
                return True
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3346
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3347
        self._cache[x] = False
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3348
        return False
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3349
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
  3350
    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
  3351
        """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
  3352
        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
  3353
            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
  3354
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  3355
        # 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
  3356
        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
  3357
            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
  3358
                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
  3359
            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
  3360
                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
  3361
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  3362
        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
  3363
        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
  3364
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  3365
    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
  3366
        """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
  3367
        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
  3368
            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
  3369
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  3370
        # 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
  3371
        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
  3372
            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
  3373
                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
  3374
            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
  3375
                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
  3376
d34969a4b1a8 generatorset: move membership testing on ordered gen to the main class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22756
diff changeset
  3377
        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
  3378
        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
  3379
20536
532b114a6e02 revset: added generatorset class with cached __contains__ method
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20534
diff changeset
  3380
    def __iter__(self):
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3381
        if self._ascending:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3382
            it = self.fastasc
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3383
        else:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3384
            it = self.fastdesc
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3385
        if it is not None:
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3386
            return it()
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3387
        # we need to consume the iterator
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3388
        for x in self._consumegen():
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3389
            pass
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3390
        # recall the same code
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3391
        return iter(self)
22797
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  3392
61ecabeeadb3 generatorset: move iteration code into _iterator
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22796
diff changeset
  3393
    def _iterator(self):
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  3394
        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
  3395
            return iter(self._genlist)
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  3396
22494
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  3397
        # 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
  3398
        # 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
  3399
        # 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
  3400
        #
14f6cebfcb8a revset: document the choice made in __generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22487
diff changeset
  3401
        # 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
  3402
        # iteration.
20833
47d43e2323c5 revset: fix generatorset race condition
Durham Goode <durham@fb.com>
parents: 20829
diff changeset
  3403
        genlist = self._genlist
22669
00c8abe64cf3 revset: prefetch an attribute in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22539
diff changeset
  3404
        nextrev = self._consumegen().next
00c8abe64cf3 revset: prefetch an attribute in _generatorset.__iter__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22539
diff changeset
  3405
        _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
  3406
        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
  3407
            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
  3408
            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
  3409
                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
  3410
                    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
  3411
                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
  3412
                    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
  3413
                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
  3414
        return gen()
20828
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  3415
3210b7930899 revset: improve performance of _generatorset.__contains__ (issue 4201)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20780
diff changeset
  3416
    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
  3417
        cache = self._cache
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  3418
        genlist = self._genlist.append
20634
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  3419
        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
  3420
            cache[item] = True
b6dc3b79bb25 revset: avoid in loop lookup in _generatorset._consumegen
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22527
diff changeset
  3421
            genlist(item)
20634
f2bb7ba59456 revset: changed generatorset code to remove unnecesary function call
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20613
diff changeset
  3422
            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
  3423
        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
  3424
            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
  3425
            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
  3426
            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
  3427
            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
  3428
            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
  3429
            self.fastdesc = asc.__reversed__
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  3430
22996
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  3431
    def __len__(self):
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  3432
        for x in self._consumegen():
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  3433
            pass
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  3434
        return len(self._genlist)
a43d929d1fa1 generatorset: implement __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22995
diff changeset
  3435
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  3436
    def sort(self, reverse=False):
22800
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3437
        self._ascending = not reverse
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3438
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3439
    def reverse(self):
29a8c20e14a8 generatorset: explicitly track iteration order
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22799
diff changeset
  3440
        self._ascending = not self._ascending
20703
e07b1fd30805 revset: added sort methods to generatorsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20695
diff changeset
  3441
22801
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3442
    def isascending(self):
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3443
        return self._ascending
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3444
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3445
    def isdescending(self):
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3446
        return not self._ascending
6af9e9b6af39 generatorset: implement isascending and isdescending
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22800
diff changeset
  3447
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3448
    def first(self):
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3449
        if self._ascending:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3450
            it = self.fastasc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3451
        else:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3452
            it = self.fastdesc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3453
        if it is None:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3454
            # 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
  3455
            for x in self._consumegen():
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3456
                pass
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3457
            return self.first()
25146
f542a2c89b60 generatorset: use 'next()' to simplify the code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25145
diff changeset
  3458
        return next(it(), None)
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3459
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3460
    def last(self):
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3461
        if self._ascending:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3462
            it = self.fastdesc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3463
        else:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3464
            it = self.fastasc
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3465
        if it is None:
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3466
            # 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
  3467
            for x in self._consumegen():
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3468
                pass
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3469
            return self.first()
25146
f542a2c89b60 generatorset: use 'next()' to simplify the code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25145
diff changeset
  3470
        return next(it(), None)
22811
c1fd827e1ae0 generatorset: implement first and last methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22810
diff changeset
  3471
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3472
    def __repr__(self):
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3473
        d = {False: '-', True: '+'}[self._ascending]
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3474
        return '<%s%s>' % (type(self).__name__, d)
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3475
24116
8b90a60181d1 revset: drop factory that promotes spanset to fullreposet
Yuya Nishihara <yuya@tcha.org>
parents: 24115
diff changeset
  3476
class spanset(abstractsmartset):
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  3477
    """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
  3478
    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
  3479
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3480
    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
  3481
    notable points:
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3482
    - 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
  3483
    - 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
  3484
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  3485
    """
20525
aa73a6327df4 revset: changed spanset to take a repo argument
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20521
diff changeset
  3486
    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
  3487
        """
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3488
        start: first revision included the set
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3489
               (default to 0)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3490
        end:   first revision excluded (last+1)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3491
               (default to len(repo)
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3492
b141080e70c5 revset: added documentation and comment for spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20734
diff changeset
  3493
        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
  3494
        """
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
  3495
        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
  3496
            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
  3497
        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
  3498
        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
  3499
            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
  3500
        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
  3501
        self._end = end
20525
aa73a6327df4 revset: changed spanset to take a repo argument
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20521
diff changeset
  3502
        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
  3503
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
  3504
    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
  3505
        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
  3506
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  3507
    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
  3508
        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
  3509
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  3510
    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
  3511
        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
  3512
        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
  3513
            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
  3514
                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
  3515
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  3516
    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
  3517
        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
  3518
            return self.fastasc()
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  3519
        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
  3520
            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
  3521
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  3522
    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
  3523
        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
  3524
        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
  3525
            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
  3526
        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
  3527
b89f7e3a414d spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22716
diff changeset
  3528
    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
  3529
        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
  3530
        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
  3531
            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
  3532
        return iter(iterrange)
20482
a979078bd788 revset: added spanset class to represent revision ranges
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20481
diff changeset
  3533
21201
c8b9c6147108 revset: fix revision filtering in spanset.contains (regression)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21199
diff changeset
  3534
    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
  3535
        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
  3536
        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
  3537
                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
  3538
20716
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  3539
    def __nonzero__(self):
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  3540
        for r in self:
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  3541
            return True
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  3542
        return False
fa1ac5faa7c4 revset: added __nonzero__ method to spanset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20714
diff changeset
  3543
20484
0f1ef9e9e904 revset: added operations to spanset to duck type baseset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20483
diff changeset
  3544
    def __len__(self):
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  3545
        if not self._hiddenrevs:
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  3546
            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
  3547
        else:
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  3548
            count = 0
21205
e2031c8ca4f8 revset: also inline spanset._contained in __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21204
diff changeset
  3549
            start = self._start
e2031c8ca4f8 revset: also inline spanset._contained in __len__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21204
diff changeset
  3550
            end = self._end
20521
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  3551
            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
  3552
                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
  3553
                    count += 1
1850a7f5fb66 revset: changed spanset implementation to take hidden revisions into account
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20512
diff changeset
  3554
            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
  3555
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3556
    def isascending(self):
23826
c90d195320c5 revset: fix spanset.isascending() to honor sort() or reverse() request
Yuya Nishihara <yuya@tcha.org>
parents: 23724
diff changeset
  3557
        return self._ascending
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3558
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3559
    def isdescending(self):
23826
c90d195320c5 revset: fix spanset.isascending() to honor sort() or reverse() request
Yuya Nishihara <yuya@tcha.org>
parents: 23724
diff changeset
  3560
        return not self._ascending
20725
cf628b50afbb revset: added isascending and isdescending methods to smartset classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20724
diff changeset
  3561
22809
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3562
    def first(self):
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3563
        if self._ascending:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3564
            it = self.fastasc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3565
        else:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3566
            it = self.fastdesc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3567
        for x in it():
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3568
            return x
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3569
        return None
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3570
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3571
    def last(self):
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3572
        if self._ascending:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3573
            it = self.fastdesc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3574
        else:
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3575
            it = self.fastasc
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3576
        for x in it():
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3577
            return x
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3578
        return None
88dad916c008 spanset: implement `first` and `last` methods
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22808
diff changeset
  3579
24457
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3580
    def __repr__(self):
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3581
        d = {False: '-', True: '+'}[self._ascending]
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3582
        return '<%s%s %d:%d>' % (type(self).__name__, d,
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3583
                                 self._start, self._end - 1)
c5022f3579b9 revset: add __repr__ to all smartset classes
Yuya Nishihara <yuya@tcha.org>
parents: 24446
diff changeset
  3584
24116
8b90a60181d1 revset: drop factory that promotes spanset to fullreposet
Yuya Nishihara <yuya@tcha.org>
parents: 24115
diff changeset
  3585
class fullreposet(spanset):
22508
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3586
    """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
  3587
24204
d2de20e1451f revset: extend fullreposet to make "null" revision magically appears in set
Yuya Nishihara <yuya@tcha.org>
parents: 24203
diff changeset
  3588
    This class exists to host special optimization and magic to handle virtual
d2de20e1451f revset: extend fullreposet to make "null" revision magically appears in set
Yuya Nishihara <yuya@tcha.org>
parents: 24203
diff changeset
  3589
    revisions such as "null".
22508
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3590
    """
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3591
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3592
    def __init__(self, repo):
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3593
        super(fullreposet, self).__init__(repo)
2434c68d82a8 revert: add a fullreposet class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22504
diff changeset
  3594
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3595
    def __and__(self, other):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23127
diff changeset
  3596
        """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
  3597
        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
  3598
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3599
        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
  3600
        """
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3601
        # 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
  3602
        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
  3603
            # filter out hidden revision
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3604
            # (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
  3605
            #
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3606
            # `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
  3607
            # object.
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3608
            other = baseset(other - self._hiddenrevs)
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3609
25547
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3610
        # XXX As fullreposet is also used as bootstrap, this is wrong.
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3611
        #
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3612
        # With a giveme312() revset returning [3,1,2], this makes
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3613
        #   'hg log -r "giveme312()"' -> 1, 2, 3 (wrong)
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3614
        # We cannot just drop it because other usage still need to sort it:
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3615
        #   'hg log -r "all() and giveme312()"' -> 1, 2, 3 (right)
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3616
        #
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3617
        # There is also some faulty revset implementations that rely on it
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3618
        # (eg: children as of its state in e8075329c5fb)
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3619
        #
99a1f73af85b revset: point out wrong behavior in fullreposet
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25344
diff changeset
  3620
        # When we fix the two points above we can move this into the if clause
23827
4982fade9733 revset: simplify fullreposet.__and__ to call sort() with boolean flag
Yuya Nishihara <yuya@tcha.org>
parents: 23822
diff changeset
  3621
        other.sort(reverse=self.isdescending())
22510
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3622
        return other
911f5a6579d1 revset: fast implementation for fullreposet.__and__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22509
diff changeset
  3623
24458
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3624
def prettyformatset(revs):
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3625
    lines = []
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3626
    rs = repr(revs)
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3627
    p = 0
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3628
    while p < len(rs):
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3629
        q = rs.find('<', p + 1)
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3630
        if q < 0:
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3631
            q = len(rs)
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3632
        l = rs.count('<', 0, p) - rs.count('>', 0, p)
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3633
        assert l >= 0
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3634
        lines.append((l, rs[p:q].rstrip()))
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3635
        p = q
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3636
    return '\n'.join('  ' * l + s for l, s in lines)
7d87f672d069 debugrevspec: show nesting structure of smartsets if verbose
Yuya Nishihara <yuya@tcha.org>
parents: 24457
diff changeset
  3637
28393
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3638
def loadpredicate(ui, extname, registrarobj):
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3639
    """Load revset predicates from specified registrarobj
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3640
    """
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3641
    for name, func in registrarobj._table.iteritems():
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3642
        symbols[name] = func
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3643
        if func._safe:
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3644
            safesymbols.add(name)
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  3645
28395
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
  3646
# load built-in predicates explicitly to setup safesymbols
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
  3647
loadpredicate(None, None, predicate)
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
  3648
12823
80deae3bc5ea hggettext: handle i18nfunctions declaration for docstrings translations
Patrick Mezard <pmezard@gmail.com>
parents: 12821
diff changeset
  3649
# 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
  3650
i18nfunctions = symbols.values()