mercurial/revset.py
author Jun Wu <quark@fb.com>
Sat, 18 Feb 2017 00:39:31 -0800
changeset 31037 17b5cda5a84a
parent 30982 11c253997b0e
child 31044 0b8356705de6
permissions -rw-r--r--
revset: use phasecache.getrevset This is part of a refactoring that moves some phase query optimization from revset.py to phases.py. See the previous patch for motivation. This patch changes revset code to use phasecache.getrevset so it no longer accesses the private field: _phasecache._phasesets directly. For performance impact, this patch was tested using the following query, on my hg-committed repo: for i in 'public()' 'not public()' 'draft()' 'not draft()'; do echo $i; hg perfrevset "$i"; hg perfrevset "$i" --hidden; done For the CPython implementation, most operations are unchanged (within +/- 1%), while "not public()" and "draft()" is noticeably faster on an unfiltered repo. It may be because the new code avoids a set copy if filteredrevs is empty. revset | public() | not public() | draft() | not draft() hidden | yes | no | yes | no | yes | no | yes | no ------------------------------------------------------------------ before | 19006 | 17352 | 239 | 286 | 180 | 228 | 7690 | 5745 after | 19137 | 17231 | 240 | 207 | 182 | 150 | 7687 | 5658 delta | | -38% | | -52% | (timed in microseconds) For the pure Python implementation, some operations are faster while "not draft()" is noticeably slower: revset | public() | not public() | draft() | not draft() hidden | yes | no | yes | no | yes | no | yes | no ------------------------------------------------------------------------ before | 18852 | 17183 | 17758 | 15921 | 17505 | 15973 | 41521 | 39822 after | 18924 | 17380 | 17558 | 14545 | 16727 | 13593 | 48356 | 43992 delta | | -9% | -5% | -15% | +16% | +10% That may be the different performance characters of generatorset vs. filteredset. The "not draft()" query could be optimized in this case where both "public" and "secret" are passed to "getrevsets" so it won't iterate the whole repo twice.
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
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
    12
import string
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    13
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    14
from .i18n import _
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    15
from . import (
26713
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
    16
    destutil,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    17
    encoding,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    18
    error,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    19
    hbisect,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    20
    match as matchmod,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    21
    node,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    22
    obsolete as obsmod,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    23
    parser,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    24
    pathutil,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    25
    phases,
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
    26
    pycompat,
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
    27
    registrar,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    28
    repoview,
30913
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    29
    smartset,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    30
    util,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
    31
)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
30913
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    33
baseset = smartset.baseset
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    34
generatorset = smartset.generatorset
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    35
spanset = smartset.spanset
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    36
fullreposet = smartset.fullreposet
1be65deb3d54 smartset: move set classes and related functions from revset module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30850
diff changeset
    37
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    38
def _revancestors(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    39
    """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
    40
    if followfirst:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    41
        cut = 1
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    42
    else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    43
        cut = None
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    44
    cl = repo.changelog
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    45
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    46
    def iterate():
22832
2f1d2a42f040 revancestors: replace `descending` with `sort(reverse=False)`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22831
diff changeset
    47
        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
    48
        irevs = iter(revs)
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    49
        h = []
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    50
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:
24939
85544a52ee84 revset: use an iterator instead of a dequeue in ancestors()
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24938
diff changeset
    53
            heapq.heappush(h, -inputrev)
20691
c1f666e27345 revset: optimized _revancestors method based on order of revisions
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20690
diff changeset
    54
23956
b1e026c25552 revset: fix ancestors(null) to include null revision (issue4512)
Yuya Nishihara <yuya@tcha.org>
parents: 23954
diff changeset
    55
        seen = set()
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    56
        while h:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    57
            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
    58
            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
    59
                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
    60
                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
    61
                    heapq.heappush(h, -inputrev)
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    62
            if current not in seen:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    63
                seen.add(current)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    64
                yield current
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    65
                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
    66
                    if parent != node.nullrev:
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    67
                        heapq.heappush(h, -parent)
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
    68
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    69
    return generatorset(iterate(), iterasc=False)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    70
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    71
def _revdescendants(repo, revs, followfirst):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    72
    """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
    73
    if followfirst:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    74
        cut = 1
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    75
    else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24219
diff changeset
    76
        cut = None
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    77
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    78
    def iterate():
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    79
        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
    80
        # 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
    81
        # 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
    82
        first = min(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    83
        nullrev = node.nullrev
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    84
        if first == nullrev:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    85
            # 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
    86
            # 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
    87
            for i in cl:
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    88
                yield i
20692
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    89
        else:
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    90
            seen = set(revs)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    91
            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
    92
                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
    93
                    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
    94
                        seen.add(i)
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    95
                        yield i
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    96
                        break
7af341082b76 revset: changed descendants revset to use lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20691
diff changeset
    97
22795
c21342159fad generatorset: drop the leading underscore in the class name
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22794
diff changeset
    98
    return generatorset(iterate(), iterasc=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
    99
26095
6eed95ca4c03 revset: mark reachablerootspure as private
Yuya Nishihara <yuya@tcha.org>
parents: 26094
diff changeset
   100
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
   101
    """return (heads(::<roots> and ::<heads>))
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   102
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   103
    If includepath is True, return (<roots>::<heads>)."""
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   104
    if not roots:
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   105
        return []
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   106
    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
   107
    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
   108
    visit = list(heads)
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   109
    reachable = set()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   110
    seen = {}
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   111
    # 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
   112
    reached = reachable.add
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   113
    dovisit = visit.append
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   114
    nextvisit = visit.pop
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   115
    # 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
   116
    # sys.getrecursionlimit()
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   117
    while visit:
25566
15412bba5a68 revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25554
diff changeset
   118
        rev = nextvisit()
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   119
        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
   120
            reached(rev)
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   121
            if not includepath:
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   122
                continue
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   123
        parents = parentrevs(rev)
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   124
        seen[rev] = parents
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   125
        for parent in parents:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   126
            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
   127
                dovisit(parent)
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   128
    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
   129
        return baseset()
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   130
    if not includepath:
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   131
        return reachable
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   132
    for rev in sorted(seen):
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   133
        for parent in seen[rev]:
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   134
            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
   135
                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
   136
    return reachable
16862
b6efeb27e733 revset: introduce and use _revsbetween
Bryan O'Sullivan <bryano@fb.com>
parents: 16861
diff changeset
   137
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   138
def reachableroots(repo, roots, heads, includepath=False):
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   139
    """return (heads(::<roots> and ::<heads>))
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   140
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   141
    If includepath is True, return (<roots>::<heads>)."""
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   142
    if not roots:
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   143
        return baseset()
26093
204131131766 reachableroots: use smartset min
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26091
diff changeset
   144
    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
   145
    roots = list(roots)
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   146
    heads = list(heads)
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   147
    try:
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   148
        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
   149
    except AttributeError:
26095
6eed95ca4c03 revset: mark reachablerootspure as private
Yuya Nishihara <yuya@tcha.org>
parents: 26094
diff changeset
   150
        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
   151
    revs = baseset(revs)
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   152
    revs.sort()
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26093
diff changeset
   153
    return revs
26006
1ffd97cbf9a2 reachableroots: default to the C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 26002
diff changeset
   154
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   156
    # 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
   157
    "(": (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
   158
    "##": (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
   159
    "~": (18, None, None, ("ancestor", 18), None),
29778
e5b794063fd4 parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
   160
    "^": (18, None, None, ("parent", 18), "parentpost"),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   161
    "-": (5, None, ("negate", 19), ("minus", 5), None),
29778
e5b794063fd4 parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
   162
    "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
e5b794063fd4 parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
   163
    "..": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"),
e5b794063fd4 parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
   164
    ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   165
    "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
   166
    "!": (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
   167
    "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
   168
    "&": (5, None, None, ("and", 5), None),
29778
e5b794063fd4 parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
   169
    "%": (5, None, None, ("only", 5), "onlypost"),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   170
    "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
   171
    "|": (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
   172
    "+": (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
   173
    "=": (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
   174
    ",": (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
   175
    ")": (0, None, None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
   176
    "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
   177
    "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
   178
    "end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   180
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   181
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   183
# default set of valid characters for the initial letter of symbols
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
   184
_syminitletters = set(
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
   185
    string.ascii_letters +
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
   186
    string.digits + pycompat.sysstr('._@')) | set(map(chr, xrange(128, 256)))
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   187
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   188
# default set of valid characters for non-initial letters of symbols
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
   189
_symletters = _syminitletters | set(pycompat.sysstr('-/'))
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   190
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   191
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
   192
    '''
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   193
    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
   194
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   195
    ``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
   196
    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
   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 initial
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   199
    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
   200
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   201
    ``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
   202
    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
   203
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   204
    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
   205
    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
   206
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   207
    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
   208
    >>> list(tokenize("@::"))
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   209
    [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   210
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   211
    '''
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   212
    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
   213
        syminitletters = _syminitletters
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
   214
    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
   215
        symletters = _symletters
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
   216
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   217
    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
   218
        # 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
   219
        # 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
   220
        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
   221
        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
   222
            if parts[0]:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   223
                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
   224
            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
   225
                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
   226
                yield (':', None, s)
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   227
                if parts[1]:
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   228
                    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
   229
            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
   230
            return
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
   231
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   232
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   233
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   234
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   235
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   236
            pass
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   237
        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
   238
            yield ('::', None, pos)
11278
7df88cdf47fd revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents: 11275
diff changeset
   239
            pos += 1 # skip ahead
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   240
        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
   241
            yield ('..', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   242
            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
   243
        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
   244
            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
   245
            pos += 1 # skip ahead
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   246
        elif c in "():=,-|&+!~^%": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   247
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   248
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   249
              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
   250
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   251
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   252
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   253
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   254
            else:
26232
43f9976346e9 revset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26212
diff changeset
   255
                decode = parser.unescapestr
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   256
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   257
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   258
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   259
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   260
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   261
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   262
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   263
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
   264
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   265
                    break
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
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   268
                raise error.ParseError(_("unterminated string"), s)
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   269
        # 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
   270
        elif c in syminitletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   271
            s = pos
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
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   274
                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
   275
                if d not in symletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   276
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   277
                if d == '.' and program[pos - 1] == '.': # special case for ..
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   278
                    pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   279
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   280
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   281
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   282
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   283
                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
   284
            elif '-' in sym:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   285
                # 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
   286
                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
   287
                    # 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
   288
                    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
   289
                else:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   290
                    # 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
   291
                    parts = sym.split('-')
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   292
                    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
   293
                        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
   294
                            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
   295
                        s += len(p)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   296
                        yield ('-', None, pos)
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   297
                        s += 1
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
   298
                    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
   299
                        yield ('symbol', parts[-1], s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   300
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   301
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   302
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   303
        else:
24708
fb47816e1a9c revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents: 24518
diff changeset
   304
            raise error.ParseError(_("syntax error in revset '%s'") %
fb47816e1a9c revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents: 24518
diff changeset
   305
                                   program, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   306
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   307
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   308
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   309
# helpers
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   310
30802
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
   311
_notset = object()
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
   312
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   313
def getsymbol(x):
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   314
    if x and x[0] == 'symbol':
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   315
        return x[1]
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   316
    raise error.ParseError(_('not a symbol'))
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   317
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   318
def getstring(x, err):
11406
42408cd43f55 revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents: 11404
diff changeset
   319
    if x and (x[0] == 'string' or x[0] == 'symbol'):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   320
        return x[1]
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
   321
    raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   322
30802
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
   323
def getinteger(x, err, default=_notset):
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
   324
    if not x and default is not _notset:
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
   325
        return default
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   326
    try:
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   327
        return int(getstring(x, err))
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   328
    except ValueError:
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   329
        raise error.ParseError(err)
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   330
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   331
def getlist(x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   332
    if not x:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   333
        return []
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   334
    if x[0] == 'list':
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
   335
        return list(x[1:])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   336
    return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   337
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   338
def getrange(x, err):
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   339
    if not x:
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   340
        raise error.ParseError(err)
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   341
    op = x[0]
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   342
    if op == 'range':
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   343
        return x[1], x[2]
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   344
    elif op == 'rangepre':
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   345
        return None, x[1]
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   346
    elif op == 'rangepost':
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   347
        return x[1], None
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   348
    elif op == 'rangeall':
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   349
        return None, None
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   350
    raise error.ParseError(err)
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
   351
11339
744d5b73f776 revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents: 11304
diff changeset
   352
def getargs(x, min, max, err):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   353
    l = getlist(x)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
   354
    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
   355
        raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   356
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   357
25767
026105c442d7 revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 25766
diff changeset
   358
def getargsdict(x, funcname, keys):
30753
c3a3896a9fa8 parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
   359
    return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys),
25705
48919d246a47 revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25704
diff changeset
   360
                                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
   361
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   362
def getset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   363
    if not x:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
   364
        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
   365
    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
   366
    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
   367
        return s
29098
2822e9a5263b devel: use the new 'config' argument for the revset develwarn
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29074
diff changeset
   368
    # else case should not happen, because all non-func are internal,
2822e9a5263b devel: use the new 'config' argument for the revset develwarn
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29074
diff changeset
   369
    # ignoring for now.
2822e9a5263b devel: use the new 'config' argument for the revset develwarn
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29074
diff changeset
   370
    if x[0] == 'func' and x[1][0] == 'symbol' and x[1][1] in symbols:
29147
ff07da10de4c devel: fix a typo in a deprecation warning
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29146
diff changeset
   371
        repo.ui.deprecwarn('revset "%s" uses list instead of smartset'
29146
b175d9cc3ee8 devel: officially deprecate old style revset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29139
diff changeset
   372
                           % x[1][1],
b175d9cc3ee8 devel: officially deprecate old style revset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29139
diff changeset
   373
                           '3.9')
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 baseset(s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   375
17003
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   376
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
   377
    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
   378
    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
   379
        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
   380
            try:
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   381
                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
   382
            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
   383
                pass
42c472877825 revset: add a utility for obtaining the source of a given rev
Matt Harbison <matt_harbison@yahoo.com>
parents: 17002
diff changeset
   384
    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
   385
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
# operator methods
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   387
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   388
def stringset(repo, subset, x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   389
    x = repo[x].rev()
25265
e16456831516 revset: drop magic of fullreposet membership test (issue4682)
Yuya Nishihara <yuya@tcha.org>
parents: 25094
diff changeset
   390
    if (x in subset
e16456831516 revset: drop magic of fullreposet membership test (issue4682)
Yuya Nishihara <yuya@tcha.org>
parents: 25094
diff changeset
   391
        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
   392
        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
   393
    return baseset()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   394
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   395
def rangeset(repo, subset, x, y, order):
23162
69524a05a7fa revset-rangeset: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   396
    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
   397
    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
   398
88abbb046e66 revset: deal with empty sets in range endpoints
Matt Mackall <mpm@selenic.com>
parents: 11446
diff changeset
   399
    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
   400
        return baseset()
30043
49d5434d68fb revset: extract function that creates range set from computed revisions
Yuya Nishihara <yuya@tcha.org>
parents: 29959
diff changeset
   401
    return _makerangeset(repo, subset, m.first(), n.last(), order)
49d5434d68fb revset: extract function that creates range set from computed revisions
Yuya Nishihara <yuya@tcha.org>
parents: 29959
diff changeset
   402
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   403
def rangeall(repo, subset, x, order):
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   404
    assert x is None
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   405
    return _makerangeset(repo, subset, 0, len(repo) - 1, order)
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   406
30044
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   407
def rangepre(repo, subset, y, order):
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   408
    # ':y' can't be rewritten to '0:y' since '0' may be hidden
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   409
    n = getset(repo, fullreposet(repo), y)
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   410
    if not n:
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   411
        return baseset()
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   412
    return _makerangeset(repo, subset, 0, n.last(), order)
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
   413
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   414
def rangepost(repo, subset, x, order):
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   415
    m = getset(repo, fullreposet(repo), x)
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   416
    if not m:
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   417
        return baseset()
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   418
    return _makerangeset(repo, subset, m.first(), len(repo) - 1, order)
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
   419
30043
49d5434d68fb revset: extract function that creates range set from computed revisions
Yuya Nishihara <yuya@tcha.org>
parents: 29959
diff changeset
   420
def _makerangeset(repo, subset, m, n, order):
25766
d51dac68ec98 revset: work around x:y range where x or y is wdir()
Yuya Nishihara <yuya@tcha.org>
parents: 25765
diff changeset
   421
    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
   422
        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
   423
    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
   424
        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
   425
    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
   426
        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
   427
    elif m < n:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   428
        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
   429
    else:
20526
9ad6dae67845 revset: changed revsets to use spanset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20525
diff changeset
   430
        r = spanset(repo, m, n - 1)
29948
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   431
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   432
    if order == defineorder:
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   433
        return r & subset
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   434
    else:
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   435
        # carrying the sorting over when possible would be more efficient
5f56a3b9675e revset: fix order of nested 'range' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29947
diff changeset
   436
        return subset & r
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   437
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   438
def dagrange(repo, subset, x, y, order):
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   439
    r = fullreposet(repo)
26002
fd92bfbbe02d revset: rename revsbetween to reachableroots and add an argument
Laurent Charignon <lcharignon@fb.com>
parents: 26001
diff changeset
   440
    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
   441
                         includepath=True)
29139
64c1955a0461 revset: make dagrange preserve order of input set
Yuya Nishihara <yuya@tcha.org>
parents: 29119
diff changeset
   442
    return subset & xs
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
   443
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   444
def andset(repo, subset, x, y, order):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   445
    return getset(repo, getset(repo, subset, x), y)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   446
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   447
def differenceset(repo, subset, x, y, order):
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
   448
    return getset(repo, subset, x) - getset(repo, subset, y)
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
   449
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
   450
def _orsetlist(repo, subset, xs):
25929
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   451
    assert xs
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   452
    if len(xs) == 1:
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   453
        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
   454
    p = len(xs) // 2
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
   455
    a = _orsetlist(repo, subset, xs[:p])
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
   456
    b = _orsetlist(repo, subset, xs[p:])
25929
289149111d46 revset: make balanced addsets by orset() without using _combinesets()
Yuya Nishihara <yuya@tcha.org>
parents: 25927
diff changeset
   457
    return a + b
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   458
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   459
def orset(repo, subset, x, order):
29938
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   460
    xs = getlist(x)
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   461
    if order == followorder:
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   462
        # slow path to take the subset order
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   463
        return subset & _orsetlist(repo, fullreposet(repo), xs)
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   464
    else:
2c6a05b938d8 revset: fix order of nested 'or' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29937
diff changeset
   465
        return _orsetlist(repo, subset, xs)
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
   466
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   467
def notset(repo, subset, x, order):
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
   468
    return subset - getset(repo, subset, x)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   469
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
   470
def listset(repo, subset, *xs):
27517
c60a9c16ae25 revset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27440
diff changeset
   471
    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
   472
                           hint=_('see hg help "revsets.x or y"'))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   473
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   474
def keyvaluepair(repo, subset, k, v):
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
   475
    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
   476
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   477
def func(repo, subset, a, b, order):
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   478
    f = getsymbol(a)
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   479
    if f in symbols:
30402
155d7ea98085 revset: avoid shadowing a variable with a list comprehension
Augie Fackler <augie@google.com>
parents: 30342
diff changeset
   480
        func = symbols[f]
155d7ea98085 revset: avoid shadowing a variable with a list comprehension
Augie Fackler <augie@google.com>
parents: 30342
diff changeset
   481
        if getattr(func, '_takeorder', False):
155d7ea98085 revset: avoid shadowing a variable with a list comprehension
Augie Fackler <augie@google.com>
parents: 30342
diff changeset
   482
            return func(repo, subset, b, order)
155d7ea98085 revset: avoid shadowing a variable with a list comprehension
Augie Fackler <augie@google.com>
parents: 30342
diff changeset
   483
        return func(repo, subset, b)
25632
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   484
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   485
    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
   486
015c0d1087a3 revset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25630
diff changeset
   487
    syms = [s for (s, fn) in symbols.items() if keep(fn)]
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
   488
    raise error.UnknownIdentifier(f, syms)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   489
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   490
# functions
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   491
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   492
# 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
   493
#   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
   494
# with:
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   495
#   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
   496
#   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
   497
#   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
   498
symbols = {}
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   499
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   500
# 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
   501
# (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
   502
# 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
   503
safesymbols = set()
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   504
28395
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
   505
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
   506
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   507
@predicate('_destupdate')
26713
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   508
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
   509
    # experimental revset for update destination
30982
11c253997b0e destutil: drop now-unused "check" parameter from destupdate()
Martin von Zweigbergk <martinvonz@google.com>
parents: 30913
diff changeset
   510
    args = getargsdict(x, 'limit', 'clean')
26713
a271925699d6 revset: reintroduce and experimental revset for update destination
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26638
diff changeset
   511
    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
   512
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   513
@predicate('_destmerge')
26716
c027641f8a83 revset: rename and test '_destmerge'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26714
diff changeset
   514
def _destmerge(repo, subset, x):
c027641f8a83 revset: rename and test '_destmerge'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26714
diff changeset
   515
    # 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
   516
    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
   517
    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
   518
        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
   519
    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
   520
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   521
@predicate('adds(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   522
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
   523
    """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
   524
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   525
    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
   526
    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
   527
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   528
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   529
    # i18n: "adds" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   530
    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
   531
    return checkstatus(repo, subset, pat, 1)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   532
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   533
@predicate('ancestor(*changeset)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   534
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
   535
    """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
   536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   537
    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
   538
    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
   539
    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
   540
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   541
    # 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
   542
    l = getlist(x)
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   543
    rl = fullreposet(repo)
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   544
    anc = None
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   545
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   546
    # (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
   547
    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
   548
        for r in revs:
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   549
            if anc is None:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   550
                anc = repo[r]
18536
ae645d4f084c revset: change ancestor to accept 0 or more arguments (issue3750)
Paul Cavallaro <ptc@fb.com>
parents: 18495
diff changeset
   551
            else:
20991
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   552
                anc = anc.ancestor(repo[r])
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   553
a05d694599f9 revlog: use context ancestor instead of changelog ancestor
Mads Kiilerich <madski@unity3d.com>
parents: 20895
diff changeset
   554
    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
   555
        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
   556
    return baseset()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   557
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   558
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
   559
    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
   560
    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
   561
        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
   562
    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
   563
    return subset & s
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   564
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   565
@predicate('ancestors(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   566
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
   567
    """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
   568
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   569
    return _ancestors(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   570
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   571
@predicate('_firstancestors', safe=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   572
def _firstancestors(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   573
    # ``_firstancestors(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   574
    # 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
   575
    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
   576
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
   577
def ancestorspec(repo, subset, x, n, order):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   578
    """``set~n``
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
   579
    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
   580
    in set.
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   581
    """
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
   582
    n = getinteger(n, _("~ expects a number"))
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   583
    ps = set()
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   584
    cl = repo.changelog
23163
6f1b8b3f12fd revset-ancestorspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23162
diff changeset
   585
    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
   586
        for i in range(n):
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   587
            r = cl.parentrevs(r)[0]
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   588
        ps.add(r)
22531
22ba2c0825da revset: use `subset &` in `ancestorspec`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22530
diff changeset
   589
    return subset & ps
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
   590
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   591
@predicate('author(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   592
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
   593
    """Alias for ``user(string)``.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   594
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   595
    # i18n: "author" is a keyword
30782
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
   596
    n = getstring(x, _("author requires a string"))
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
   597
    kind, pattern, matcher = _substringmatcher(n, casesensitive=False)
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
   598
    return subset.filter(lambda x: matcher(repo[x].user()),
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   599
                         condrepr=('<user %r>', n))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   600
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   601
@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
   602
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
   603
    """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
   604
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   605
    - ``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
   606
    - ``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
   607
    - ``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
   608
    - ``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
   609
    - ``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
   610
    - ``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
   611
    - ``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
   612
    """
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
   613
    # 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
   614
    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
   615
    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
   616
    return subset & state
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   617
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   618
# Backward-compatibility
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   619
# - 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
   620
@predicate('bisected', safe=True)
15134
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   621
def bisected(repo, subset, x):
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   622
    return bisect(repo, subset, x)
81adf7777f8f revset: rename bisected() to bisect()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15133
diff changeset
   623
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   624
@predicate('bookmark([name])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   625
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
   626
    """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
   627
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
   628
    Pattern matching is supported for `name`. See :hg:`help revisions.patterns`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   629
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   630
    # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   631
    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
   632
    if args:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   633
        bm = getstring(args[0],
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   634
                       # i18n: "bookmark" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   635
                       _('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
   636
        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
   637
        bms = set()
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   638
        if kind == 'literal':
22105
3efe3c2609e0 revset: bookmark revset interprets 'literal:' prefix correctly (issue4329)
Michael O'Connor <mkoconnor@gmail.com>
parents: 21939
diff changeset
   639
            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
   640
            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
   641
                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
   642
                                            % pattern)
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   643
            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
   644
        else:
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   645
            matchrevs = set()
18495
8260fa9f30b9 bookmarks: don't use bookmarks.listbookmarks in local computations
Kevin Bullock <kbullock@ringworld.org>
parents: 18473
diff changeset
   646
            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
   647
                if matcher(name):
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   648
                    matchrevs.add(bmrev)
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   649
            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
   650
                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
   651
                                              " that match '%s'") % pattern)
16822
da55d8a77390 revset: add pattern matching to 'bookmarks' revset expression
Simon King <simon@simonking.org.uk>
parents: 16821
diff changeset
   652
            for bmrev in matchrevs:
22499
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   653
                bms.add(repo[bmrev].rev())
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   654
    else:
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   655
        bms = set([repo[r].rev()
8c9f9e346acc revset: unify code flow in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22498
diff changeset
   656
                   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
   657
    bms -= set([node.nullrev])
22530
faf4f63533ff revset: use `subset &` in `bookmark`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22529
diff changeset
   658
    return subset & bms
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   659
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   660
@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
   661
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
   662
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   663
    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
   664
    changesets.
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   665
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
   666
    Pattern matching is supported for `string`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
   667
    :hg:`help revisions.patterns`.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   668
    """
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24366
diff changeset
   669
    getbi = repo.revbranchcache().branchinfo
23787
678f53865c68 revset: use localrepo revbranchcache for branch name filtering
Mads Kiilerich <madski@unity3d.com>
parents: 23765
diff changeset
   670
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   671
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   672
        b = getstring(x, '')
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   673
    except error.ParseError:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   674
        # 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
   675
        pass
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   676
    else:
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
   677
        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
   678
        if kind == 'literal':
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   679
            # 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
   680
            # 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
   681
            if pattern in repo.branchmap():
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: matcher(getbi(r)[0]),
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   683
                                     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
   684
            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
   685
                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
   686
                                            % pattern)
16821
0946502fd3d5 revset: add pattern matching to 'branch' revset expression
Simon King <simon@simonking.org.uk>
parents: 16820
diff changeset
   687
        else:
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   688
            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
   689
                                 condrepr=('<branch %r>', b))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   690
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   691
    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
   692
    b = set()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   693
    for r in s:
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24366
diff changeset
   694
        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
   695
    c = s.__contains__
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   696
    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
   697
                         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
   698
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   699
@predicate('bumped()', safe=True)
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   700
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
   701
    """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
   702
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   703
    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
   704
    """
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   705
    # i18n: "bumped" is a keyword
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   706
    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
   707
    bumped = obsmod.getrevs(repo, 'bumped')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   708
    return subset & bumped
17829
c73f7a28953c revset: add a bumped revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17825
diff changeset
   709
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   710
@predicate('bundle()', safe=True)
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   711
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
   712
    """Changesets in the bundle.
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   713
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   714
    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
   715
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   716
    try:
18411
8b0f0dd56cec bundlerepo: improve performance for bundle() revset expression
Mads Kiilerich <madski@unity3d.com>
parents: 18382
diff changeset
   717
        bundlerevs = repo.changelog.bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   718
    except AttributeError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26571
diff changeset
   719
        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
   720
    return subset & bundlerevs
17913
03e552aaae67 bundle: add revset expression to show bundle contents (issue3487)
Tomasz Kleczek <tkleczek@fb.com>
parents: 17886
diff changeset
   721
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   722
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
   723
    hasset = matchmod.patkind(pat) == 'set'
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   724
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   725
    mcache = [None]
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   726
    def matches(x):
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   727
        c = repo[x]
23115
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   728
        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
   729
            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
   730
        m = mcache[0]
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   731
        fname = None
c23c03605c59 revset: don't recreate matcher for every revision
Martin von Zweigbergk <martinvonz@google.com>
parents: 23100
diff changeset
   732
        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
   733
            fname = m.files()[0]
16521
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   734
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   735
            if fname not in c.files():
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   736
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   737
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   738
            for f in c.files():
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   739
                if m(f):
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   740
                    break
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   741
            else:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   742
                return False
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   743
        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
   744
        if fname is not None:
592701c8eac6 revset: fix adds/modifies/removes and patterns (issue3403)
Patrick Mezard <patrick@mezard.eu>
parents: 16467
diff changeset
   745
            if fname in files:
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   746
                return True
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   747
        else:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   748
            for f in files:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   749
                if m(f):
20457
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   750
                    return True
ed7b674824a3 revset: added lazyset implementation to checkstatus
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20456
diff changeset
   751
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   752
    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
   753
29406
c2193e59ef9f revsets: passing a set to baseset() is not wrong
Martin von Zweigbergk <martinvonz@google.com>
parents: 29389
diff changeset
   754
def _children(repo, subset, parentset):
25550
3e9049876ace revset: gratuitous code move in '_children'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25549
diff changeset
   755
    if not parentset:
3e9049876ace revset: gratuitous code move in '_children'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25549
diff changeset
   756
        return baseset()
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   757
    cs = set()
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   758
    pr = repo.changelog.parentrevs
25567
f140d6207cca revset: use parentsets.min in _children
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25566
diff changeset
   759
    minrev = parentset.min()
30699
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   760
    nullrev = node.nullrev
29406
c2193e59ef9f revsets: passing a set to baseset() is not wrong
Martin von Zweigbergk <martinvonz@google.com>
parents: 29389
diff changeset
   761
    for r in subset:
18063
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   762
        if r <= minrev:
34a1a639d835 revset.children: ignore rev numbers that are too low
Siddharth Agarwal <sid0@fb.com>
parents: 17980
diff changeset
   763
            continue
30699
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   764
        p1, p2 = pr(r)
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   765
        if p1 in parentset:
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   766
            cs.add(r)
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   767
        if p2 != nullrev and p2 in parentset:
5bda147c3139 revset: make children() not look at p2 if null (issue5439)
Yuya Nishihara <yuya@tcha.org>
parents: 30402
diff changeset
   768
            cs.add(r)
20709
71df845d86cf revsets: backout d04aac468bf4 due to performance regressions
Matt Mackall <mpm@selenic.com>
parents: 20708
diff changeset
   769
    return baseset(cs)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   770
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   771
@predicate('children(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   772
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
   773
    """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
   774
    """
23164
7a42e5d4c418 revset-children: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23163
diff changeset
   775
    s = getset(repo, fullreposet(repo), x)
15899
476a981fdf34 revset: optimize roots and children
Matt Mackall <mpm@selenic.com>
parents: 15898
diff changeset
   776
    cs = _children(repo, subset, s)
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   777
    return subset & cs
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   778
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   779
@predicate('closed()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   780
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
   781
    """Changeset is closed.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   782
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   783
    # i18n: "closed" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   784
    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
   785
    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
   786
                         condrepr='<branch closed>')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   787
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
   788
@predicate('contains(pattern)')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   789
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
   790
    """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
   791
    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
   792
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   793
    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
   794
    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
   795
    for efficiency.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   796
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   797
    # i18n: "contains" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   798
    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
   799
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   800
    def matches(x):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   801
        if not matchmod.patkind(pat):
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   802
            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
   803
            if pats in repo[x]:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   804
                return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   805
        else:
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   806
            c = repo[x]
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   807
            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
   808
            for f in c.manifest():
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   809
                if m(f):
20461
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   810
                    return True
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   811
        return False
abd8e56a1038 revset: added lazyset implementation to contains revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20460
diff changeset
   812
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   813
    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
   814
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   815
@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
   816
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
   817
    """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
   818
    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
   819
    """
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   820
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   821
    # 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
   822
    # 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
   823
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
   824
    rev = None
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   825
    # i18n: "converted" is a keyword
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   826
    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
   827
    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
   828
        # 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
   829
        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
   830
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   831
    def _matchvalue(r):
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   832
        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
   833
        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
   834
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   835
    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
   836
                         condrepr=('<converted %r>', rev))
17002
0eb522625eb2 revset: add a predicate for finding converted changesets
Matt Harbison <matt_harbison@yahoo.com>
parents: 16862
diff changeset
   837
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   838
@predicate('date(interval)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   839
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
   840
    """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
   841
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   842
    # i18n: "date" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   843
    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
   844
    dm = util.matchdate(ds)
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   845
    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
   846
                         condrepr=('<date %r>', ds))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   847
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   848
@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
   849
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
   850
    """Search commit message for string. The match is case-insensitive.
30783
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   851
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
   852
    Pattern matching is supported for `string`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
   853
    :hg:`help revisions.patterns`.
14650
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   854
    """
93731b3efd0d revset: add desc(string) to search in commit messages
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14649
diff changeset
   855
    # i18n: "desc" is a keyword
30783
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   856
    ds = getstring(x, _("desc requires a string"))
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   857
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   858
    kind, pattern, matcher = _substringmatcher(ds, casesensitive=False)
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   859
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   860
    return subset.filter(lambda r: matcher(repo[r].description()),
931a60880df4 revset: add regular expression support to 'desc'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30782
diff changeset
   861
                         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
   862
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   863
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
   864
    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
   865
    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
   866
        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
   867
    s = _revdescendants(repo, roots, followfirst)
20894
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   868
04e1596d5dbd revset: improve _descendants performance
Durham Goode <durham@fb.com>
parents: 20863
diff changeset
   869
    # 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
   870
    # 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
   871
    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
   872
    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
   873
    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
   874
    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
   875
        result.sort()
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   876
    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
   877
        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
   878
    else:
1dd178277cf5 revset-_descendant: rework the whole sorting and combining logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22859
diff changeset
   879
        result = subset & result
22830
1d1da8abe130 _descendants: directly use smartset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22829
diff changeset
   880
    return result
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   881
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   882
@predicate('descendants(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
   883
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
   884
    """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
   885
    """
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   886
    return _descendants(repo, subset, x)
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   887
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   888
@predicate('_firstdescendants', safe=True)
16409
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   889
def _firstdescendants(repo, subset, x):
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   890
    # ``_firstdescendants(set)``
2cbd7dd0cc1f graphlog: fix --follow-first --rev combinations
Patrick Mezard <patrick@mezard.eu>
parents: 16402
diff changeset
   891
    # 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
   892
    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
   893
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   894
@predicate('destination([set])', safe=True)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   895
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
   896
    """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
   897
    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
   898
    is the same as passing all().
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
    if x is not None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
   901
        sources = getset(repo, fullreposet(repo), x)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   902
    else:
24201
77ef059b3317 revset: drop unnecessary calls of getall() with empty argument
Yuya Nishihara <yuya@tcha.org>
parents: 24163
diff changeset
   903
        sources = fullreposet(repo)
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   904
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   905
    dests = set()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   906
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   907
    # 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
   908
    # 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
   909
    # 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
   910
    # 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
   911
    # 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
   912
    # grafts.
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   913
    for r in subset:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   914
        src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   915
        lineage = None
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   916
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   917
        while src is not None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   918
            if lineage is None:
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   919
                lineage = list()
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   920
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   921
            lineage.append(r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   922
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   923
            # 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
   924
            # set.  Since every candidate dest is visited by way of iterating
17494
74801685aaa2 spelling: further
timeless@mozdev.org
parents: 17291
diff changeset
   925
            # 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
   926
            # 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
   927
            # 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
   928
            # further.
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
   929
            if src in sources or src in dests:
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   930
                dests.update(lineage)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   931
                break
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   932
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   933
            r = src
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   934
            src = _getrevsource(repo, r)
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   935
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   936
    return subset.filter(dests.__contains__,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   937
                         condrepr=lambda: '<destination %r>' % sorted(dests))
17186
a3da6f298592 revset: add destination() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17185
diff changeset
   938
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   939
@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
   940
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
   941
    """
18071
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   942
    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
   943
    """
bea754715961 obsolete: add revset and test for divergent changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18063
diff changeset
   944
    # 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
   945
    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
   946
    divergent = obsmod.getrevs(repo, 'divergent')
22533
5b65429721d5 revset: use `subset &` in `divergent`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22532
diff changeset
   947
    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
   948
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   949
@predicate('extinct()', safe=True)
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   950
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
   951
    """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
   952
    """
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
   953
    # 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
   954
    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
   955
    extincts = obsmod.getrevs(repo, 'extinct')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
   956
    return subset & extincts
17173
c621f84dbb35 obsolete: compute extinct changesets
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17171
diff changeset
   957
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   958
@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
   959
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
   960
    """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
   961
    optional value.
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   962
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
   963
    Pattern matching is supported for `value`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
   964
    :hg:`help revisions.patterns`.
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   965
    """
25767
026105c442d7 revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 25766
diff changeset
   966
    args = getargsdict(x, 'extra', 'label value')
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   967
    if 'label' not in args:
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   968
        # i18n: "extra" is a keyword
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   969
        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
   970
    # i18n: "extra" is a keyword
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   971
    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
   972
                                       'a string'))
16661
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   973
    value = None
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   974
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   975
    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
   976
        # i18n: "extra" is a keyword
25706
b7f53c474e2c revset: port extra() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25705
diff changeset
   977
        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
   978
                                           'a string'))
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
   979
        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
   980
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   981
    def _matchvalue(r):
de4b42daf396 revset: add function for matching extra data (issue2767)
Henrik Stuart <hg@hstuart.dk>
parents: 16657
diff changeset
   982
        extra = repo[r].extra()
16824
f3b8c82a559c revset: add pattern matching to 'extra' revset expression
Simon King <simon@simonking.org.uk>
parents: 16823
diff changeset
   983
        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
   984
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
   985
    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
   986
                         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
   987
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
   988
@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
   989
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
   990
    """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
   991
21199
e9c2f76be74b help: clarify distinction among `contains`/`file`/`filelog`
Greg Hurrell <glh@fb.com>
parents: 21173
diff changeset
   992
    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
   993
    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
   994
    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
   995
    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
   996
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
   997
    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
   998
    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
   999
    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
  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
    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
  1002
    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
  1003
    """
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1004
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
  1005
    # 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
  1006
    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
  1007
    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
  1008
    cl = repo.changelog
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1009
15964
6e37b8282aa2 revsets: provide contexts for filesets
Matt Mackall <mpm@selenic.com>
parents: 15949
diff changeset
  1010
    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
  1011
        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
  1012
        files = [f]
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1013
    else:
20288
b61ad01c4e73 revset: use "canonpath()" for "filelog()" pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20287
diff changeset
  1014
        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
  1015
        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
  1016
34364a4b25eb linkrev: work around linkrev to filtered entry in 'filelog' revset
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23704
diff changeset
  1017
    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
  1018
        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
  1019
        known = {}
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1020
        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
  1021
        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
  1022
            fn = fl.node(fr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1023
            if fn in known:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1024
                s.add(known[fn])
23821
7a7f437ab63d filelog: remove trailing "form feed" character
Martin von Zweigbergk <martinvonz@google.com>
parents: 23820
diff changeset
  1025
                continue
27945
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1026
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1027
            lr = fl.linkrev(fr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1028
            if lr in cl:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1029
                s.add(lr)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1030
            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
  1031
                # 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
  1032
                # ahead in changelog
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1033
                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
  1034
                scanpos = None
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1035
                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
  1036
                    # 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
  1037
                    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
  1038
                        try:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1039
                            # 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
  1040
                            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
  1041
                            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
  1042
                                if n == fn:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1043
                                    s.add(r)
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1044
                                    scanpos = r
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1045
                                    break
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1046
                                else:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1047
                                    known[n] = r
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1048
                        except error.ManifestLookupError:
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1049
                            # deletion in changelog
4186d359046a log: speed up single file log with hidden revs (issue4747)
Matt Mackall <mpm@selenic.com>
parents: 27637
diff changeset
  1050
                            continue
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1051
22534
6261b9c549a2 revset: use `subset &` in `filelog`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22533
diff changeset
  1052
    return subset & s
14342
c0b6a734b4f3 revset: introduce filelog() to emulate log's fast path
Matt Mackall <mpm@selenic.com>
parents: 14318
diff changeset
  1053
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1054
@predicate('first(set, [n])', safe=True)
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1055
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
  1056
    """An alias for limit().
15117
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1057
    """
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1058
    return limit(repo, subset, x)
0ab1c3a1f3b2 revsets: add first alias for last
Matt Mackall <mpm@selenic.com>
parents: 15116
diff changeset
  1059
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1060
def _follow(repo, subset, x, name, followfirst=False):
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1061
    l = getargs(x, 0, 2, _("%s takes no arguments or a pattern "
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1062
                           "and an optional revset") % name)
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1063
    c = repo['.']
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1064
    if l:
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1065
        x = getstring(l[0], _("%s expected a pattern") % name)
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1066
        rev = None
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1067
        if len(l) >= 2:
30178
d61c42c1a35c revset: make follow() reject more than one start revisions
Yuya Nishihara <yuya@tcha.org>
parents: 30071
diff changeset
  1068
            revs = getset(repo, fullreposet(repo), l[1])
d61c42c1a35c revset: make follow() reject more than one start revisions
Yuya Nishihara <yuya@tcha.org>
parents: 30071
diff changeset
  1069
            if len(revs) != 1:
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1070
                raise error.RepoLookupError(
30178
d61c42c1a35c revset: make follow() reject more than one start revisions
Yuya Nishihara <yuya@tcha.org>
parents: 30071
diff changeset
  1071
                        _("%s expected one starting revision") % name)
d61c42c1a35c revset: make follow() reject more than one start revisions
Yuya Nishihara <yuya@tcha.org>
parents: 30071
diff changeset
  1072
            rev = revs.last()
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1073
            c = repo[rev]
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1074
        matcher = matchmod.match(repo.root, repo.getcwd(), [x],
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1075
                                 ctx=repo[rev], default='path')
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1076
28008
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1077
        files = c.manifest().walk(matcher)
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1078
26102
5618858dce26 revsets: makes follow() supports file patterns (issue4757) (BC)
liscju <piotr.listkiewicz@gmail.com>
parents: 26099
diff changeset
  1079
        s = set()
28008
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1080
        for fname in files:
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1081
            fctx = c[fname]
86c4cbdaffee revset: use manifest.matches in _follow revset
Durham Goode <durham@fb.com>
parents: 27945
diff changeset
  1082
            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
  1083
            # 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
  1084
            s.add(fctx.introrev())
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1085
    else:
20690
13c0327eeb6f revset: changed ancestors revset to return lazy generators
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20659
diff changeset
  1086
        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
  1087
22535
44f471102f3a revset: use `subset &` in `follow`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22534
diff changeset
  1088
    return subset & s
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1089
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1090
@predicate('follow([pattern[, startrev]])', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1091
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
  1092
    """
24366
e8ea31131705 revset: replace "working copy" with "working directory" in function help
Yuya Nishihara <yuya@tcha.org>
parents: 24306
diff changeset
  1093
    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
  1094
    If pattern is specified, the histories of files matching given
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1095
    pattern in the revision given by startrev are 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
  1096
    """
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1097
    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
  1098
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1099
@predicate('_followfirst', safe=True)
16174
0a73c4bd9f47 graphlog: implement --follow-first
Patrick Mezard <patrick@mezard.eu>
parents: 16161
diff changeset
  1100
def _followfirst(repo, subset, x):
29825
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1101
    # ``followfirst([pattern[, startrev]])``
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1102
    # Like ``follow([pattern[, startrev]])`` but follows only the first parent
cbf9984a7957 revset: support "follow(renamed.py, e22f4f3f06c3)" (issue5334)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29791
diff changeset
  1103
    # of every revisions or files revisions.
16185
352053e6cd8e context: add followfirst arg to filectx and workingfilectx
Patrick Mezard <patrick@mezard.eu>
parents: 16181
diff changeset
  1104
    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
  1105
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
  1106
@predicate('followlines(file, fromline:toline[, startrev=.])', safe=True)
30719
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1107
def followlines(repo, subset, x):
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1108
    """Changesets modifying `file` in line range ('fromline', 'toline').
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1109
30800
cd23879cbac7 revset: rename rev argument of followlines() to startrev
Yuya Nishihara <yuya@tcha.org>
parents: 30799
diff changeset
  1110
    Line range corresponds to 'file' content at 'startrev' and should hence be
cd23879cbac7 revset: rename rev argument of followlines() to startrev
Yuya Nishihara <yuya@tcha.org>
parents: 30799
diff changeset
  1111
    consistent with file size. If startrev is not specified, working directory's
30719
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1112
    parent is used.
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1113
    """
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1114
    from . import context  # avoid circular import issues
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1115
30800
cd23879cbac7 revset: rename rev argument of followlines() to startrev
Yuya Nishihara <yuya@tcha.org>
parents: 30799
diff changeset
  1116
    args = getargsdict(x, 'followlines', 'file *lines startrev')
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
  1117
    if len(args['lines']) != 1:
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
  1118
        raise error.ParseError(_("followlines requires a line range"))
30719
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1119
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1120
    rev = '.'
30800
cd23879cbac7 revset: rename rev argument of followlines() to startrev
Yuya Nishihara <yuya@tcha.org>
parents: 30799
diff changeset
  1121
    if 'startrev' in args:
cd23879cbac7 revset: rename rev argument of followlines() to startrev
Yuya Nishihara <yuya@tcha.org>
parents: 30799
diff changeset
  1122
        revs = getset(repo, fullreposet(repo), args['startrev'])
30754
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1123
        if len(revs) != 1:
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1124
            raise error.ParseError(
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1125
                _("followlines expects exactly one revision"))
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1126
        rev = revs.last()
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1127
26209cb7184e revset: parse variable-length arguments of followlines() by getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 30753
diff changeset
  1128
    pat = getstring(args['file'], _("followlines requires a pattern"))
30719
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1129
    if not matchmod.patkind(pat):
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1130
        fname = pathutil.canonpath(repo.root, repo.getcwd(), pat)
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1131
    else:
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1132
        m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[rev])
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1133
        files = [f for f in repo[rev] if m(f)]
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1134
        if len(files) != 1:
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1135
            raise error.ParseError(_("followlines expects exactly one file"))
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1136
        fname = files[0]
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1137
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
  1138
    lr = getrange(args['lines'][0], _("followlines expects a line range"))
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1139
    fromline, toline = [getinteger(a, _("line range bounds must be integers"))
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
  1140
                        for a in lr]
30719
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1141
    if toline - fromline < 0:
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1142
        raise error.ParseError(_("line range must be positive"))
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1143
    if fromline < 1:
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1144
        raise error.ParseError(_("fromline must be strictly positive"))
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1145
    fromline -= 1
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1146
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1147
    fctx = repo[rev].filectx(fname)
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1148
    revs = (c.rev() for c in context.blockancestors(fctx, fromline, toline))
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1149
    return subset & generatorset(revs, iterasc=False)
42c75b4fa46a revset: add a followlines(file, fromline, toline[, rev]) revset
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30702
diff changeset
  1150
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1151
@predicate('all()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1152
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
  1153
    """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
  1154
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1155
    # i18n: "all" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1156
    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
  1157
    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
  1158
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1159
@predicate('grep(regex)')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1160
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
  1161
    """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
  1162
    to ensure special escape characters are handled correctly. Unlike
cb4ff8ef466b merge with stable
Martin Geisler <mg@aragost.com>
parents: 14343 14356
diff changeset
  1163
    ``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
  1164
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1165
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1166
        # i18n: "grep" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1167
        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
  1168
    except re.error as e:
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1169
        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
  1170
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1171
    def matches(x):
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1172
        c = repo[x]
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1173
        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
  1174
            if gr.search(e):
20453
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1175
                return True
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1176
        return False
6aa7dcae6bd8 revset: added lazyset implementation to grep revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20452
diff changeset
  1177
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1178
    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
  1179
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1180
@predicate('_matchfiles', safe=True)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1181
def _matchfiles(repo, subset, x):
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1182
    # _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
  1183
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1184
    #   [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
  1185
    #
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1186
    # 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
  1187
    # 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
  1188
    # 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
  1189
    # 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
  1190
    # 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
  1191
    # 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
  1192
    # 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
  1193
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1194
    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
  1195
    pats, inc, exc = [], [], []
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1196
    rev, default = None, None
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1197
    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
  1198
        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
  1199
        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
  1200
        if prefix == 'p:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1201
            pats.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1202
        elif prefix == 'i:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1203
            inc.append(value)
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1204
        elif prefix == 'x:':
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1205
            exc.append(value)
16181
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
  1206
        elif prefix == 'r:':
1fd352aa08fc graphlog: evaluate FILE/-I/-X filesets on the working dir
Patrick Mezard <patrick@mezard.eu>
parents: 16174
diff changeset
  1207
            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
  1208
                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
  1209
                                       'revision')
23950
caff3675cba5 log: evaluate filesets on working copy, not its parent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23847
diff changeset
  1210
            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
  1211
                rev = value
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1212
        elif prefix == 'd:':
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1213
            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
  1214
                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
  1215
                                       'default mode')
16411
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1216
            default = value
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1217
        else:
28271
5c454ab69558 revset: drop translation markers from error messages of internal _matchfiles
Yuya Nishihara <yuya@tcha.org>
parents: 28217
diff changeset
  1218
            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
  1219
    if not default:
4c2edcd84175 graphlog: correctly handle calls in subdirectories
Patrick Mezard <patrick@mezard.eu>
parents: 16409
diff changeset
  1220
        default = 'glob'
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1221
23061
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1222
    m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1223
                       exclude=exc, ctx=repo[rev], default=default)
f2aeff8a87b6 revset: avoid recalculating filesets
Matt Mackall <mpm@selenic.com>
parents: 23019
diff changeset
  1224
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1225
    # 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
  1226
    # revisions is quite expensive.
27440
ff305ab2e0d7 log: speed up hg log <file|folder>
Laurent Charignon <lcharignon@fb.com>
parents: 27293
diff changeset
  1227
    getfiles = repo.changelog.readfiles
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1228
    wdirrev = node.wdirrev
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1229
    def matches(x):
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1230
        if x == wdirrev:
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1231
            files = repo[x].files()
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1232
        else:
27440
ff305ab2e0d7 log: speed up hg log <file|folder>
Laurent Charignon <lcharignon@fb.com>
parents: 27293
diff changeset
  1233
            files = getfiles(x)
27028
f92053df8f0b revset: speed up '_matchfiles'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26778
diff changeset
  1234
        for f in files:
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
  1235
            if m(f):
20458
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1236
                return True
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1237
        return False
8dabcc889e33 revset: added lazyset implementation to _matchfiles
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20457
diff changeset
  1238
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1239
    return subset.filter(matches,
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1240
                         condrepr=('<matchfiles patterns=%r, include=%r '
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1241
                                   'exclude=%r, default=%r, rev=%r>',
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1242
                                   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
  1243
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1244
@predicate('file(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1245
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
  1246
    """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
  1247
17265
c30307eeec4b revset: polish explanation of the difference between file() and filelog()
Greg Ward <greg@gerg.ca>
parents: 17259
diff changeset
  1248
    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
  1249
    instead.
20289
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1250
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1251
    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
  1252
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1253
    # i18n: "file" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1254
    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
  1255
    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
  1256
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1257
@predicate('head()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1258
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
  1259
    """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
  1260
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1261
    # i18n: "head" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1262
    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
  1263
    hs = set()
25620
5f87f2305ad0 revset: translate node directly with changelog in 'head'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25619
diff changeset
  1264
    cl = repo.changelog
29407
20fabe814f89 revsets: use itervalues() where only values are needed
Martin von Zweigbergk <martinvonz@google.com>
parents: 29406
diff changeset
  1265
    for ls in repo.branchmap().itervalues():
25620
5f87f2305ad0 revset: translate node directly with changelog in 'head'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25619
diff changeset
  1266
        hs.update(cl.rev(h) for h in ls)
29408
785cadec2091 revset: make head() honor order of subset
Martin von Zweigbergk <martinvonz@google.com>
parents: 29407
diff changeset
  1267
    return subset & baseset(hs)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1268
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1269
@predicate('heads(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1270
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
  1271
    """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
  1272
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1273
    s = getset(repo, subset, x)
20366
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
  1274
    ps = parents(repo, subset, x)
5ec6321f49a9 revset: added substraction to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20365
diff changeset
  1275
    return s - ps
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1276
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1277
@predicate('hidden()', safe=True)
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1278
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
  1279
    """Hidden changesets.
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1280
    """
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1281
    # i18n: "hidden" is a keyword
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1282
    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
  1283
    hiddenrevs = repoview.filterrevs(repo, 'visible')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1284
    return subset & hiddenrevs
17390
74b44f25b4b1 revset: add hidden() revset
Patrick Mezard <patrick@mezard.eu>
parents: 17291
diff changeset
  1285
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1286
@predicate('keyword(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1287
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
  1288
    """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
  1289
    string. The match is case-insensitive.
30772
b1012cb1bec3 revset: point to 'grep' in the 'keyword' help for regex searches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30754
diff changeset
  1290
b1012cb1bec3 revset: point to 'grep' in the 'keyword' help for regex searches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30754
diff changeset
  1291
    For a regular expression or case sensitive search of these fields, use
b1012cb1bec3 revset: point to 'grep' in the 'keyword' help for regex searches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30754
diff changeset
  1292
    ``grep(regex)``.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1293
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1294
    # 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
  1295
    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
  1296
abb91b74f758 revset: added lazyset implementation to keyword revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20446
diff changeset
  1297
    def matches(r):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1298
        c = repo[r]
25551
c1d163ce7394 revset: gratuitous formating fix in keyword
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25550
diff changeset
  1299
        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
  1300
                   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
  1301
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1302
    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
  1303
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1304
@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
  1305
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
  1306
    """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
  1307
    """
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1308
    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
  1309
    if 'set' not in args:
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1310
        # i18n: "limit" is a keyword
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1311
        raise error.ParseError(_("limit requires one to three arguments"))
30802
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
  1312
    # i18n: "limit" is a keyword
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
  1313
    lim = getinteger(args.get('n'), _("limit expects a number"), default=1)
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
  1314
    # i18n: "limit" is a keyword
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
  1315
    ofs = getinteger(args.get('offset'), _("limit expects a number"), default=0)
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1316
    if ofs < 0:
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1317
        raise error.ParseError(_("negative offset"))
26637
179764469754 revset: port limit() to support keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 26636
diff changeset
  1318
    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
  1319
    result = []
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
  1320
    it = iter(os)
26638
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1321
    for x in xrange(ofs):
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1322
        y = next(it, None)
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1323
        if y is None:
7afaf2566e25 revset: add optional offset argument to limit() predicate
Yuya Nishihara <yuya@tcha.org>
parents: 26637
diff changeset
  1324
            break
20446
d258486604f4 revset: changed limit revset implementation to work with lazy revsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20445
diff changeset
  1325
    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
  1326
        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
  1327
        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
  1328
            break
26636
ff6baf32b3ba revset: eliminate temporary reference to subset in limit() and last()
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
  1329
        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
  1330
            result.append(y)
28426
3d39ac06af9a revset: add inspection data to limit() and last() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28425
diff changeset
  1331
    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
  1332
                                     lim, ofs, subset, os))
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1333
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1334
@predicate('last(set, [n])', safe=True)
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1335
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
  1336
    """Last n members of set, defaulting to 1.
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1337
    """
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1338
    # 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
  1339
    l = getargs(x, 1, 2, _("last requires one or two arguments"))
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1340
    lim = 1
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1341
    if len(l) == 2:
14061
611d2f8a4ba2 revsets: add a last function
Matt Mackall <mpm@selenic.com>
parents: 14057
diff changeset
  1342
        # i18n: "last" is a keyword
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
  1343
        lim = getinteger(l[1], _("last expects a number"))
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1344
    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
  1345
    os.reverse()
22805
e74245b79901 revset-last: remove user of baseset.append
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22804
diff changeset
  1346
    result = []
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1347
    it = iter(os)
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1348
    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
  1349
        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
  1350
        if y is None:
20534
4849f574aa24 revset: changed last implementation to use lazy classes
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20527
diff changeset
  1351
            break
26636
ff6baf32b3ba revset: eliminate temporary reference to subset in limit() and last()
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
  1352
        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
  1353
            result.append(y)
28426
3d39ac06af9a revset: add inspection data to limit() and last() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28425
diff changeset
  1354
    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
  1355
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1356
@predicate('max(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1357
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
  1358
    """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
  1359
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1360
    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
  1361
    try:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1362
        m = os.max()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1363
        if m in subset:
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1364
            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
  1365
    except ValueError:
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1366
        # 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
  1367
        # Same as python's max().
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1368
        pass
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1369
    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
  1370
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1371
@predicate('merge()', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1372
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
  1373
    """Changeset is a merge changeset.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1374
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1375
    # i18n: "merge" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1376
    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
  1377
    cl = repo.changelog
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1378
    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
  1379
                         condrepr='<merge>')
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1380
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1381
@predicate('branchpoint()', safe=True)
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1382
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
  1383
    """Changesets with more than one child.
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1384
    """
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1385
    # i18n: "branchpoint" is a keyword
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1386
    getargs(x, 0, 0, _("branchpoint takes no arguments"))
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1387
    cl = repo.changelog
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1388
    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
  1389
        return baseset()
25549
f93ff3ab8d14 revset: mark spots that should use 'smartset.min()'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25548
diff changeset
  1390
    # 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
  1391
    # (and if it is not, it should.)
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1392
    baserev = min(subset)
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1393
    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
  1394
    for r in cl.revs(start=baserev + 1):
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1395
        for p in cl.parentrevs(r):
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1396
            if p >= baserev:
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1397
                parentscount[p - baserev] += 1
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1398
    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
  1399
                         condrepr='<branchpoint>')
17753
69d5078d760d revsets: add branchpoint() function
Ivan Andrus <darthandrus@gmail.com>
parents: 17675
diff changeset
  1400
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1401
@predicate('min(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1402
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
  1403
    """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
  1404
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1405
    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
  1406
    try:
20754
f15ff553b762 revset: changed minrev and maxrev implementations to use ordered sets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20753
diff changeset
  1407
        m = os.min()
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1408
        if m in subset:
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1409
            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
  1410
    except ValueError:
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1411
        # 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
  1412
        # Same as python's min().
ade5c488d622 revset: remove existence check from min() and max()
Durham Goode <durham@fb.com>
parents: 26304
diff changeset
  1413
        pass
28427
969a4615c4c4 revset: add inspection data to max() and min() functions
Yuya Nishihara <yuya@tcha.org>
parents: 28426
diff changeset
  1414
    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
  1415
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1416
@predicate('modifies(pattern)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1417
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
  1418
    """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
  1419
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1420
    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
  1421
    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
  1422
    directory.
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1423
    """
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1424
    # i18n: "modifies" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1425
    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
  1426
    return checkstatus(repo, subset, pat, 0)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1427
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1428
@predicate('named(namespace)')
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1429
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
  1430
    """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
  1431
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
  1432
    Pattern matching is supported for `namespace`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
  1433
    :hg:`help revisions.patterns`.
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1434
    """
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1435
    # i18n: "named" is a keyword
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1436
    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
  1437
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1438
    ns = getstring(args[0],
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1439
                   # i18n: "named" is a keyword
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1440
                   _('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
  1441
    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
  1442
    namespaces = set()
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1443
    if kind == 'literal':
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1444
        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
  1445
            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
  1446
                                        % ns)
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1447
        namespaces.add(repo.names[pattern])
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1448
    else:
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1449
        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
  1450
            if matcher(name):
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1451
                namespaces.add(ns)
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1452
        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
  1453
            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
  1454
                                          " that match '%s'") % pattern)
23836
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1455
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1456
    names = set()
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1457
    for ns in namespaces:
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1458
        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
  1459
            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
  1460
                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
  1461
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1462
    names -= set([node.nullrev])
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1463
    return subset & names
3fb61fcbc4e4 namespaces: add revset for 'named(namespace)'
Sean Farley <sean.michael.farley@gmail.com>
parents: 23833
diff changeset
  1464
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1465
@predicate('id(string)', safe=True)
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  1466
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
  1467
    """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
  1468
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1469
    # 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
  1470
    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
  1471
    # 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
  1472
    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
  1473
    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
  1474
        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
  1475
            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
  1476
        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
  1477
            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
  1478
    else:
16735
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1479
        rn = None
47b8ec0eb7fb revset: fix traceback for bogus revisions in id(rev)
Matt Harbison <matt_harbison@yahoo.com>
parents: 16640
diff changeset
  1480
        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
  1481
        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
  1482
            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
  1483
23005
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1484
    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
  1485
        return baseset()
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1486
    result = baseset([rn])
9bfe68357c01 revset-node: speedup by a few hundred fold
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23004
diff changeset
  1487
    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
  1488
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1489
@predicate('obsolete()', safe=True)
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1490
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
  1491
    """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
  1492
    # i18n: "obsolete" is a keyword
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1493
    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
  1494
    obsoletes = obsmod.getrevs(repo, 'obsolete')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1495
    return subset & obsoletes
17170
63a4a3871607 revset: add an `obsolete` symbol
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17102
diff changeset
  1496
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1497
@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
  1498
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
  1499
    """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
  1500
    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
  1501
    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
  1502
    (i.e. ::<set1> - ::<set2>).
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1503
    """
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1504
    cl = repo.changelog
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1505
    # i18n: "only" is a keyword
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1506
    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
  1507
    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
  1508
    if len(args) == 1:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1509
        if not include:
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1510
            return baseset()
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1511
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1512
        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
  1513
        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
  1514
            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
  1515
    else:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1516
        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
  1517
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1518
    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
  1519
    # XXX we should turn this into a baseset instead of a set, smartset may do
30342
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30227
diff changeset
  1520
    # some optimizations 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
  1521
    return subset & results
d5b1a452cc32 revset: move 'only' so that functions are sorted alphabetically
Yuya Nishihara <yuya@tcha.org>
parents: 23426
diff changeset
  1522
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1523
@predicate('origin([set])', safe=True)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1524
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
  1525
    """
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1526
    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
  1527
    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
  1528
    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
  1529
    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
  1530
    for the first operation is selected.
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1531
    """
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1532
    if x is not None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1533
        dests = getset(repo, fullreposet(repo), x)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1534
    else:
24201
77ef059b3317 revset: drop unnecessary calls of getall() with empty argument
Yuya Nishihara <yuya@tcha.org>
parents: 24163
diff changeset
  1535
        dests = fullreposet(repo)
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1536
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1537
    def _firstsrc(rev):
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1538
        src = _getrevsource(repo, rev)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1539
        if src is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1540
            return None
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1541
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1542
        while True:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1543
            prev = _getrevsource(repo, src)
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1544
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1545
            if prev is None:
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1546
                return src
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1547
            src = prev
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1548
22944
5aae3dea8044 revset: better naming of variables containing the value of a single argument
Mads Kiilerich <madski@unity3d.com>
parents: 22891
diff changeset
  1549
    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
  1550
    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
  1551
    # XXX we should turn this into a baseset instead of a set, smartset may do
30342
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30227
diff changeset
  1552
    # some optimizations 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
  1553
    return subset & o
17185
2c7c4824969e revset: add origin() predicate
Matt Harbison <matt_harbison@yahoo.com>
parents: 17173
diff changeset
  1554
30850
41e31a6f5296 revset: prevent using outgoing() and remote() in hgweb session (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 30804
diff changeset
  1555
@predicate('outgoing([path])', safe=False)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1556
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
  1557
    """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
  1558
    default push location.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1559
    """
24722
02a5618e2fbf revset: don't import discovery at module level
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24708
diff changeset
  1560
    # Avoid cycles.
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1561
    from . import (
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1562
        discovery,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1563
        hg,
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1564
    )
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1565
    # 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
  1566
    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
  1567
    # i18n: "outgoing" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1568
    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
  1569
    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
  1570
    dest, branches = hg.parseurl(dest)
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1571
    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
  1572
    if revs:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1573
        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
  1574
    other = hg.peer(repo, {}, dest)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1575
    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
  1576
    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
  1577
    repo.ui.popbuffer()
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1578
    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
  1579
    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
  1580
    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
  1581
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1582
@predicate('p1([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1583
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
  1584
    """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
  1585
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1586
    if x is None:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13873
diff changeset
  1587
        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
  1588
        if p >= 0:
a428db9ab61d revset: use `subset &` in bare `p1()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22537
diff changeset
  1589
            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
  1590
        return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1591
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1592
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1593
    cl = repo.changelog
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1594
    for r in getset(repo, fullreposet(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1595
        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
  1596
    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
  1597
    # XXX we should turn this into a baseset instead of a set, smartset may do
30342
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30227
diff changeset
  1598
    # some optimizations from the fact this is a baseset.
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1599
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
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('p2([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1602
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
  1603
    """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
  1604
    """
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1605
    if x is None:
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1606
        ps = repo[x].parents()
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1607
        try:
12935
98b79c892768 revset: fix p1, p2 and parents in dirstate case (a5f7f1e9340e)
Patrick Mezard <pmezard@gmail.com>
parents: 12929
diff changeset
  1608
            p = ps[1].rev()
22539
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1609
            if p >= 0:
6f434ef54222 revset: use `subset &` in bare `p2()`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22538
diff changeset
  1610
                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
  1611
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1612
        except IndexError:
22802
1fcd361efaf4 baseset: use default value instead of [] when possible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22801
diff changeset
  1613
            return baseset()
12928
a5f7f1e9340e revsets: let p1() and p2() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12859
diff changeset
  1614
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1615
    ps = set()
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1616
    cl = repo.changelog
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1617
    for r in getset(repo, fullreposet(repo), x):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1618
        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
  1619
    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
  1620
    # XXX we should turn this into a baseset instead of a set, smartset may do
30342
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30227
diff changeset
  1621
    # some optimizations from the fact this is a baseset.
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1622
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1623
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  1624
def parentpost(repo, subset, x, order):
29935
d2d1be3009ca revset: add stub to handle parentpost operation
Yuya Nishihara <yuya@tcha.org>
parents: 29934
diff changeset
  1625
    return p1(repo, subset, x)
d2d1be3009ca revset: add stub to handle parentpost operation
Yuya Nishihara <yuya@tcha.org>
parents: 29934
diff changeset
  1626
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1627
@predicate('parents([set])', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1628
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
  1629
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1630
    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
  1631
    """
12929
515c2786e1cf revsets: let parents() return parents of working dir
Kevin Bullock <kbullock@ringworld.org>
parents: 12928
diff changeset
  1632
    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
  1633
        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
  1634
    else:
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1635
        ps = set()
35af9361a049 revset: refactor parents() into a single return point
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22495
diff changeset
  1636
        cl = repo.changelog
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1637
        up = ps.update
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1638
        parentrevs = cl.parentrevs
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1639
        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
  1640
            if r == node.wdirrev:
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1641
                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
  1642
            else:
25716
d50677c3bf44 revset: prefetch method in "parents"
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25706
diff changeset
  1643
                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
  1644
    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
  1645
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1646
31037
17b5cda5a84a revset: use phasecache.getrevset
Jun Wu <quark@fb.com>
parents: 30982
diff changeset
  1647
def _phase(repo, subset, *targets):
17b5cda5a84a revset: use phasecache.getrevset
Jun Wu <quark@fb.com>
parents: 30982
diff changeset
  1648
    """helper to select all rev in <targets> phases"""
17b5cda5a84a revset: use phasecache.getrevset
Jun Wu <quark@fb.com>
parents: 30982
diff changeset
  1649
    s = repo._phasecache.getrevset(repo, targets)
17b5cda5a84a revset: use phasecache.getrevset
Jun Wu <quark@fb.com>
parents: 30982
diff changeset
  1650
    return subset & s
25621
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1651
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1652
@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
  1653
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
  1654
    """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
  1655
    # 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
  1656
    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
  1657
    target = phases.draft
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1658
    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
  1659
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1660
@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
  1661
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
  1662
    """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
  1663
    # 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
  1664
    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
  1665
    target = phases.secret
21a874693619 revset: refactor the non-public phase code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25620
diff changeset
  1666
    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
  1667
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  1668
def parentspec(repo, subset, x, n, order):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1669
    """``set^0``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1670
    The set.
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1671
    ``set^1`` (or ``set^``), ``set^2``
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1672
    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
  1673
    """
12320
40c40c6f20b8 revset: handle re.compile() errors in grep()
Brodie Rao <brodie@bitheap.org>
parents: 11882
diff changeset
  1674
    try:
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1675
        n = int(n[1])
14072
2e4d79dcc0a0 revset: add missing whitespace
Kevin Gessner <kevin@kevingessner.com>
parents: 14070
diff changeset
  1676
        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
  1677
            raise ValueError
14851
f96c354493d7 revsets: actually catch type error on tip^p1(tip) (issue2884)
Matt Mackall <mpm@selenic.com>
parents: 14842
diff changeset
  1678
    except (TypeError, ValueError):
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1679
        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
  1680
    ps = set()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1681
    cl = repo.changelog
23165
7e8737e6ab08 revset-parentspec: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23164
diff changeset
  1682
    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
  1683
        if n == 0:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1684
            ps.add(r)
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1685
        elif n == 1:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1686
            ps.add(cl.parentrevs(r)[0])
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1687
        elif n == 2:
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1688
            parents = cl.parentrevs(r)
30179
cdef35b38026 revset: for x^2, do not take null as a valid p2 revision
Yuya Nishihara <yuya@tcha.org>
parents: 30178
diff changeset
  1689
            if parents[1] != node.nullrev:
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  1690
                ps.add(parents[1])
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  1691
    return subset & ps
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1692
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1693
@predicate('present(set)', safe=True)
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1694
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
  1695
    """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
  1696
    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
  1697
0a730d3c5aae doc: add detail explanation for 'present()' predicate of revsets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16735
diff changeset
  1698
    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
  1699
    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
  1700
    to continue even in such cases.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1701
    """
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1702
    try:
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1703
        return getset(repo, subset, x)
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1704
    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
  1705
        return baseset()
11944
df52ff0980fe revset: predicate to avoid lookup errors
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 11886
diff changeset
  1706
25224
d032f57936f5 revset: drop docstring from internal _notpublic() function
Yuya Nishihara <yuya@tcha.org>
parents: 25191
diff changeset
  1707
# 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
  1708
@predicate('_notpublic', safe=True)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1709
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
  1710
    getargs(x, 0, 0, "_notpublic takes no arguments")
31037
17b5cda5a84a revset: use phasecache.getrevset
Jun Wu <quark@fb.com>
parents: 30982
diff changeset
  1711
    return _phase(repo, subset, phases.draft, phases.secret)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  1712
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1713
@predicate('public()', safe=True)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1714
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
  1715
    """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
  1716
    # 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
  1717
    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
  1718
    phase = repo._phasecache.phase
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1719
    target = phases.public
c8f32accd00a revset-phases: prefetch attributes in phasesrelated revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23018
diff changeset
  1720
    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
  1721
    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
  1722
                         cache=False)
15819
33ca11b010e2 phases: implements simple revset symbol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15791
diff changeset
  1723
30850
41e31a6f5296 revset: prevent using outgoing() and remote() in hgweb session (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 30804
diff changeset
  1724
@predicate('remote([id [,path]])', safe=False)
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1725
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
  1726
    """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
  1727
    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
  1728
    synonym for the current local branch.
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1729
    """
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1730
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
  1731
    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
  1732
    # i18n: "remote" is a keyword
27293
9e06e7fb037d grammar: favor zero, one, two over ... or no
timeless <timeless@mozdev.org>
parents: 27028
diff changeset
  1733
    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
  1734
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1735
    q = '.'
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1736
    if len(l) > 0:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1737
    # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1738
        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
  1739
    if q == '.':
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1740
        q = repo['.'].branch()
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1741
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1742
    dest = ''
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1743
    if len(l) > 1:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1744
        # i18n: "remote" is a keyword
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1745
        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
  1746
    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
  1747
    dest, branches = hg.parseurl(dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1748
    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
  1749
    if revs:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1750
        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
  1751
    other = hg.peer(repo, {}, dest)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1752
    n = other.lookup(q)
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1753
    if n in repo:
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1754
        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
  1755
        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
  1756
            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
  1757
    return baseset()
15936
878bc4a62a73 revset: add remote() predicate to lookup remote revisions
Matt Mackall <mpm@selenic.com>
parents: 15903
diff changeset
  1758
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1759
@predicate('removes(pattern)', safe=True)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1760
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
  1761
    """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
  1762
96be25f1da45 revset: add explanation about the pattern without explicit kind
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20288
diff changeset
  1763
    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
  1764
    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
  1765
    directory.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1766
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  1767
    # 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
  1768
    pat = getstring(x, _("removes requires a pattern"))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1769
    return checkstatus(repo, subset, pat, 2)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1770
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1771
@predicate('rev(number)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1772
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
  1773
    """Revision with the given numeric identifier.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1774
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1775
    # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1776
    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
  1777
    try:
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1778
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1779
        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
  1780
    except (TypeError, ValueError):
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1781
        # i18n: "rev" is a keyword
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1782
        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
  1783
    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
  1784
        return baseset()
22537
bbf4f3dfd700 revset: use `subset &` in `rev`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22536
diff changeset
  1785
    return subset & baseset([l])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1786
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1787
@predicate('matching(revision [, field])', safe=True)
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1788
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
  1789
    """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
  1790
    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
  1791
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1792
    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
  1793
    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
  1794
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1795
    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
  1796
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1797
    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
  1798
    ``date``, ``files``, ``phase``, ``parents``, ``substate``, ``user``
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1799
    and ``diff``.
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1800
    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
  1801
    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
  1802
    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
  1803
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1804
    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
  1805
    ``summary`` matches the first line of the description.
16639
00290bd359fe revset: documentation typo "metatadata"
Jesse Glick <jesse.glick@oracle.com>
parents: 16528
diff changeset
  1806
    ``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
  1807
    (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
  1808
5d803620ca05 doc: flatten description of 'matching()' predicate to be formatted well
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16521
diff changeset
  1809
    ``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
  1810
    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
  1811
    """
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
  1812
    # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1813
    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
  1814
23166
30e0dcd7c5ff revset-matching: call 'getset' on a 'fullreposet'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23165
diff changeset
  1815
    revs = getset(repo, fullreposet(repo), l[0])
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1816
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1817
    fieldlist = ['metadata']
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1818
    if len(l) > 1:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1819
            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
  1820
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1821
                _("matching requires a string "
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1822
                "as its second argument")).split()
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1823
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1824
    # 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
  1825
    # expand the 'special' 'metadata' field type
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1826
    # 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
  1827
    fields = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1828
    for field in fieldlist:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1829
        if field == 'metadata':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1830
            fields += ['user', 'description', 'date']
17102
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1831
        elif field == 'diff':
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1832
            # 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
  1833
            # 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
  1834
            # also match the files first
d9a046ae4d8e revset: add "diff" field to "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17100
diff changeset
  1835
            fields += ['files', 'diff']
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1836
        else:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1837
            if field == 'author':
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1838
                field = 'user'
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1839
            fields.append(field)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1840
    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
  1841
    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
  1842
        # 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
  1843
        fields.discard('summary')
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1844
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1845
    # 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
  1846
    # 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
  1847
    # 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
  1848
    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
  1849
        '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
  1850
    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
  1851
        try:
984e0412e82b revset: speedup matching() by first matching fields that take less time to
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16445
diff changeset
  1852
            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
  1853
        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
  1854
            # 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
  1855
            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
  1856
    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
  1857
    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
  1858
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1859
    # 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
  1860
    # 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
  1861
    getfieldfuncs = []
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1862
    _funcs = {
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1863
        'user': lambda r: repo[r].user(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1864
        'branch': lambda r: repo[r].branch(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1865
        'date': lambda r: repo[r].date(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1866
        'description': lambda r: repo[r].description(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1867
        'files': lambda r: repo[r].files(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1868
        'parents': lambda r: repo[r].parents(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1869
        'phase': lambda r: repo[r].phase(),
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1870
        'substate': lambda r: repo[r].substate,
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1871
        '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
  1872
        '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
  1873
    }
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1874
    for info in fields:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1875
        getfield = _funcs.get(info, None)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1876
        if getfield is None:
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1877
            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
  1878
                # i18n: "matching" is a keyword
16402
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1879
                _("unexpected field name passed to matching: %s") % info)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1880
        getfieldfuncs.append(getfield)
1fb2f1400ea8 revset: add "matching" keyword
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16218
diff changeset
  1881
    # 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
  1882
    # 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
  1883
    # 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
  1884
    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
  1885
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1886
    def matches(x):
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1887
        for rev in revs:
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1888
            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
  1889
            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
  1890
            for n, f in enumerate(getfieldfuncs):
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1891
                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
  1892
                    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
  1893
            if match:
20459
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1894
                return True
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1895
        return False
51890507c6b3 revset: added lazyset implementation to matching revset
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20458
diff changeset
  1896
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1897
    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
  1898
29949
89dbae952ec1 revset: make reverse() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29948
diff changeset
  1899
@predicate('reverse(set)', safe=True, takeorder=True)
89dbae952ec1 revset: make reverse() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29948
diff changeset
  1900
def reverse(repo, subset, x, order):
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  1901
    """Reverse order of set.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  1902
    """
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1903
    l = getset(repo, subset, x)
29949
89dbae952ec1 revset: make reverse() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29948
diff changeset
  1904
    if order == defineorder:
89dbae952ec1 revset: make reverse() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29948
diff changeset
  1905
        l.reverse()
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1906
    return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1907
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  1908
@predicate('roots(set)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  1909
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
  1910
    """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
  1911
    """
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  1912
    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
  1913
    parents = repo.changelog.parentrevs
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1914
    def filter(r):
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1915
        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
  1916
            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
  1917
                return False
46a96dd4d976 revset: improves time complexity of 'roots(xxx)'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25634
diff changeset
  1918
        return True
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  1919
    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
  1920
29265
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1921
_sortkeyfuncs = {
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1922
    'rev': lambda c: c.rev(),
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1923
    'branch': lambda c: c.branch(),
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1924
    'desc': lambda c: c.description(),
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1925
    'user': lambda c: c.user(),
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1926
    'author': lambda c: c.user(),
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1927
    'date': lambda c: c.date()[0],
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1928
}
3f9e68864ccc revset: define table of sort() key functions
Yuya Nishihara <yuya@tcha.org>
parents: 29264
diff changeset
  1929
29365
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1930
def _getsortargs(x):
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1931
    """Parse sort options into (set, [(key, reverse)], opts)"""
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1932
    args = getargsdict(x, 'sort', 'set keys topo.firstbranch')
29238
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1933
    if 'set' not in args:
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1934
        # i18n: "sort" is a keyword
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1935
        raise error.ParseError(_('sort requires one or two arguments'))
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1936
    keys = "rev"
29238
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1937
    if 'keys' 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
  1938
        # i18n: "sort" is a keyword
29238
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1939
        keys = getstring(args['keys'], _("sort spec must be a string"))
e150c1d5f262 revset: use getargsdict for sort()
Martijn Pieters <mjpieters@fb.com>
parents: 29216
diff changeset
  1940
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1941
    keyflags = []
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1942
    for k in keys.split():
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1943
        fk = k
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1944
        reverse = (k[0] == '-')
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1945
        if reverse:
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1946
            k = k[1:]
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1947
        if k not in _sortkeyfuncs and k != 'topo':
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1948
            raise error.ParseError(_("unknown sort key %r") % fk)
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1949
        keyflags.append((k, reverse))
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1950
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1951
    if len(keyflags) > 1 and any(k == 'topo' for k, reverse in keyflags):
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1952
        # i18n: "topo" is a keyword
29646
a8a5dd8986f0 revset: refactor to make xgettext put i18n comments into hg.pot file
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29441
diff changeset
  1953
        raise error.ParseError(_('topo sort order cannot be combined '
a8a5dd8986f0 revset: refactor to make xgettext put i18n comments into hg.pot file
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29441
diff changeset
  1954
                                 'with other sort keys'))
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1955
29364
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1956
    opts = {}
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1957
    if 'topo.firstbranch' in args:
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1958
        if any(k == 'topo' for k, reverse in keyflags):
29364
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1959
            opts['topo.firstbranch'] = args['topo.firstbranch']
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1960
        else:
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1961
            # i18n: "topo" and "topo.firstbranch" are keywords
29646
a8a5dd8986f0 revset: refactor to make xgettext put i18n comments into hg.pot file
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29441
diff changeset
  1962
            raise error.ParseError(_('topo.firstbranch can only be used '
a8a5dd8986f0 revset: refactor to make xgettext put i18n comments into hg.pot file
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29441
diff changeset
  1963
                                     'when using the topo sort key'))
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1964
29365
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1965
    return args['set'], keyflags, opts
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1966
29950
285a8c3e53f2 revset: make sort() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
  1967
@predicate('sort(set[, [-]key... [, ...]])', safe=True, takeorder=True)
285a8c3e53f2 revset: make sort() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
  1968
def sort(repo, subset, x, order):
29365
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1969
    """Sort set by keys. The default sort order is ascending, specify a key
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1970
    as ``-key`` to sort in descending order.
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1971
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1972
    The keys can be:
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1973
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1974
    - ``rev`` for the revision number,
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1975
    - ``branch`` for the branch name,
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1976
    - ``desc`` for the commit message (description),
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1977
    - ``user`` for user name (``author`` can be used as an alias),
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1978
    - ``date`` for the commit date
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1979
    - ``topo`` for a reverse topographical sort
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1980
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1981
    The ``topo`` sort order cannot be combined with other sort keys. This sort
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1982
    takes one optional argument, ``topo.firstbranch``, which takes a revset that
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1983
    specifies what topographical branches to prioritize in the sort.
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1984
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1985
    """
f652e84f23f2 revset: extract function that validates sort() arguments
Yuya Nishihara <yuya@tcha.org>
parents: 29364
diff changeset
  1986
    s, keyflags, opts = _getsortargs(x)
29364
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1987
    revs = getset(repo, subset, s)
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1988
29950
285a8c3e53f2 revset: make sort() noop depending on ordering requirement (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
  1989
    if not keyflags or order != defineorder:
20719
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1990
        return revs
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1991
    if len(keyflags) == 1 and keyflags[0][0] == "rev":
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1992
        revs.sort(reverse=keyflags[0][1])
20719
cce8fbedc82a revset: changed sort method to use native sort implementation of smartsets
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20718
diff changeset
  1993
        return revs
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  1994
    elif keyflags[0][0] == "topo":
29364
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1995
        firstbranch = ()
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1996
        if 'topo.firstbranch' in opts:
76a1a703e23d revset: build dict of extra sort options before evaluating set
Yuya Nishihara <yuya@tcha.org>
parents: 29363
diff changeset
  1997
            firstbranch = getset(repo, subset, opts['topo.firstbranch'])
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1998
        revs = baseset(_toposort(revs, repo.changelog.parentrevs, firstbranch),
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  1999
                       istopo=True)
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  2000
        if keyflags[0][1]:
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  2001
            revs.reverse()
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  2002
        return revs
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  2003
29001
923fa9e06ea0 revset: make sort() do dumb multi-pass sorting for multiple keys (issue5218)
Yuya Nishihara <yuya@tcha.org>
parents: 28910
diff changeset
  2004
    # sort() is guaranteed to be stable
923fa9e06ea0 revset: make sort() do dumb multi-pass sorting for multiple keys (issue5218)
Yuya Nishihara <yuya@tcha.org>
parents: 28910
diff changeset
  2005
    ctxs = [repo[r] for r in revs]
29363
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  2006
    for k, reverse in reversed(keyflags):
2d18c61173f1 revset: build list of (key, reverse) pairs before sorting
Yuya Nishihara <yuya@tcha.org>
parents: 29362
diff changeset
  2007
        ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse)
29001
923fa9e06ea0 revset: make sort() do dumb multi-pass sorting for multiple keys (issue5218)
Yuya Nishihara <yuya@tcha.org>
parents: 28910
diff changeset
  2008
    return baseset([c.rev() for c in ctxs])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2009
29348
2188f170f5b6 revset: add new topographical sort
Martijn Pieters <mjpieters@fb.com>
parents: 29347
diff changeset
  2010
def _toposort(revs, parentsfunc, firstbranch=()):
29347
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2011
    """Yield revisions from heads to roots one (topo) branch at a time.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2012
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2013
    This function aims to be used by a graph generator that wishes to minimize
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2014
    the number of parallel branches and their interleaving.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2015
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2016
    Example iteration order (numbers show the "true" order in a changelog):
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2017
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2018
      o  4
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2019
      |
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2020
      o  1
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2021
      |
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2022
      | o  3
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2023
      | |
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2024
      | o  2
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2025
      |/
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2026
      o  0
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2027
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2028
    Note that the ancestors of merges are understood by the current
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2029
    algorithm to be on the same branch. This means no reordering will
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2030
    occur behind a merge.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2031
    """
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2032
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2033
    ### Quick summary of the algorithm
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2034
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2035
    # This function is based around a "retention" principle. We keep revisions
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2036
    # in memory until we are ready to emit a whole branch that immediately
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2037
    # "merges" into an existing one. This reduces the number of parallel
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2038
    # branches with interleaved revisions.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2039
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2040
    # During iteration revs are split into two groups:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2041
    # A) revision already emitted
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2042
    # B) revision in "retention". They are stored as different subgroups.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2043
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2044
    # for each REV, we do the following logic:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2045
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2046
    #   1) if REV is a parent of (A), we will emit it. If there is a
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2047
    #   retention group ((B) above) that is blocked on REV being
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2048
    #   available, we emit all the revisions out of that retention
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2049
    #   group first.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2050
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2051
    #   2) else, we'll search for a subgroup in (B) awaiting for REV to be
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2052
    #   available, if such subgroup exist, we add REV to it and the subgroup is
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2053
    #   now awaiting for REV.parents() to be available.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2054
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2055
    #   3) finally if no such group existed in (B), we create a new subgroup.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2056
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2057
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2058
    # To bootstrap the algorithm, we emit the tipmost revision (which
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2059
    # puts it in group (A) from above).
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2060
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2061
    revs.sort(reverse=True)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2062
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2063
    # Set of parents of revision that have been emitted. They can be considered
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2064
    # unblocked as the graph generator is already aware of them so there is no
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2065
    # need to delay the revisions that reference them.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2066
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2067
    # If someone wants to prioritize a branch over the others, pre-filling this
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2068
    # set will force all other branches to wait until this branch is ready to be
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2069
    # emitted.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2070
    unblocked = set(firstbranch)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2071
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2072
    # list of groups waiting to be displayed, each group is defined by:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2073
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2074
    #   (revs:    lists of revs waiting to be displayed,
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2075
    #    blocked: set of that cannot be displayed before those in 'revs')
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2076
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2077
    # The second value ('blocked') correspond to parents of any revision in the
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2078
    # group ('revs') that is not itself contained in the group. The main idea
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2079
    # of this algorithm is to delay as much as possible the emission of any
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2080
    # revision.  This means waiting for the moment we are about to display
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2081
    # these parents to display the revs in a group.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2082
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2083
    # This first implementation is smart until it encounters a merge: it will
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2084
    # emit revs as soon as any parent is about to be emitted and can grow an
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2085
    # arbitrary number of revs in 'blocked'. In practice this mean we properly
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2086
    # retains new branches but gives up on any special ordering for ancestors
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2087
    # of merges. The implementation can be improved to handle this better.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2088
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2089
    # The first subgroup is special. It corresponds to all the revision that
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2090
    # were already emitted. The 'revs' lists is expected to be empty and the
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2091
    # 'blocked' set contains the parents revisions of already emitted revision.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2092
    #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2093
    # You could pre-seed the <parents> set of groups[0] to a specific
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2094
    # changesets to select what the first emitted branch should be.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2095
    groups = [([], unblocked)]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2096
    pendingheap = []
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2097
    pendingset = set()
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2098
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2099
    heapq.heapify(pendingheap)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2100
    heappop = heapq.heappop
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2101
    heappush = heapq.heappush
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2102
    for currentrev in revs:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2103
        # Heap works with smallest element, we want highest so we invert
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2104
        if currentrev not in pendingset:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2105
            heappush(pendingheap, -currentrev)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2106
            pendingset.add(currentrev)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2107
        # iterates on pending rev until after the current rev have been
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2108
        # processed.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2109
        rev = None
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2110
        while rev != currentrev:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2111
            rev = -heappop(pendingheap)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2112
            pendingset.remove(rev)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2113
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2114
            # Seek for a subgroup blocked, waiting for the current revision.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2115
            matching = [i for i, g in enumerate(groups) if rev in g[1]]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2116
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2117
            if matching:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2118
                # The main idea is to gather together all sets that are blocked
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2119
                # on the same revision.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2120
                #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2121
                # Groups are merged when a common blocking ancestor is
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2122
                # observed. For example, given two groups:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2123
                #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2124
                # revs [5, 4] waiting for 1
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2125
                # revs [3, 2] waiting for 1
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2126
                #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2127
                # These two groups will be merged when we process
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2128
                # 1. In theory, we could have merged the groups when
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2129
                # we added 2 to the group it is now in (we could have
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2130
                # noticed the groups were both blocked on 1 then), but
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2131
                # the way it works now makes the algorithm simpler.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2132
                #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2133
                # We also always keep the oldest subgroup first. We can
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2134
                # probably improve the behavior by having the longest set
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2135
                # first. That way, graph algorithms could minimise the length
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2136
                # of parallel lines their drawing. This is currently not done.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2137
                targetidx = matching.pop(0)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2138
                trevs, tparents = groups[targetidx]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2139
                for i in matching:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2140
                    gr = groups[i]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2141
                    trevs.extend(gr[0])
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2142
                    tparents |= gr[1]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2143
                # delete all merged subgroups (except the one we kept)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2144
                # (starting from the last subgroup for performance and
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2145
                # sanity reasons)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2146
                for i in reversed(matching):
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2147
                    del groups[i]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2148
            else:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2149
                # This is a new head. We create a new subgroup for it.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2150
                targetidx = len(groups)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2151
                groups.append(([], set([rev])))
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2152
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2153
            gr = groups[targetidx]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2154
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2155
            # We now add the current nodes to this subgroups. This is done
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2156
            # after the subgroup merging because all elements from a subgroup
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2157
            # that relied on this rev must precede it.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2158
            #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2159
            # we also update the <parents> set to include the parents of the
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2160
            # new nodes.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2161
            if rev == currentrev: # only display stuff in rev
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2162
                gr[0].append(rev)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2163
            gr[1].remove(rev)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2164
            parents = [p for p in parentsfunc(rev) if p > node.nullrev]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2165
            gr[1].update(parents)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2166
            for p in parents:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2167
                if p not in pendingset:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2168
                    pendingset.add(p)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2169
                    heappush(pendingheap, -p)
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2170
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2171
            # Look for a subgroup to display
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2172
            #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2173
            # When unblocked is empty (if clause), we were not waiting for any
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2174
            # revisions during the first iteration (if no priority was given) or
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2175
            # if we emitted a whole disconnected set of the graph (reached a
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2176
            # root).  In that case we arbitrarily take the oldest known
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2177
            # subgroup. The heuristic could probably be better.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2178
            #
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2179
            # Otherwise (elif clause) if the subgroup is blocked on
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2180
            # a revision we just emitted, we can safely emit it as
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2181
            # well.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2182
            if not unblocked:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2183
                if len(groups) > 1:  # display other subset
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2184
                    targetidx = 1
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2185
                    gr = groups[1]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2186
            elif not gr[1] & unblocked:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2187
                gr = None
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2188
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2189
            if gr is not None:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2190
                # update the set of awaited revisions with the one from the
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2191
                # subgroup
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2192
                unblocked |= gr[1]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2193
                # output all revisions in the subgroup
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2194
                for r in gr[0]:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2195
                    yield r
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2196
                # delete the subgroup that you just output
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2197
                # unless it is groups[0] in which case you just empty it.
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2198
                if targetidx:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2199
                    del groups[targetidx]
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2200
                else:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2201
                    gr[0][:] = []
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2202
    # Check if we have some subgroup waiting for revisions we are not going to
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2203
    # iterate over
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2204
    for g in groups:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2205
        for r in g[0]:
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2206
            yield r
98535ad46fc0 revset: move groupbranchiter over from graphmod
Martijn Pieters <mjpieters@fb.com>
parents: 29346
diff changeset
  2207
27584
fc7c8cac6a4b revset: use decorator to register a function as revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27517
diff changeset
  2208
@predicate('subrepo([pattern])')
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2209
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
  2210
    """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
  2211
    pattern is named, any subrepo changes are returned.
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2212
    """
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2213
    # i18n: "subrepo" is a keyword
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2214
    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
  2215
    pat = None
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2216
    if len(args) != 0:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2217
        pat = getstring(args[0], _("subrepo requires a pattern"))
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2218
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2219
    m = matchmod.exact(repo.root, repo.root, ['.hgsubstate'])
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2220
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2221
    def submatches(names):
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26307
diff changeset
  2222
        k, p, m = util.stringmatcher(pat)
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2223
        for name in names:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2224
            if m(name):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2225
                yield name
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2226
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2227
    def matches(x):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2228
        c = repo[x]
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2229
        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
  2230
28272
760f9d04842a revset: define "pat" variable unconditionally in subrepo()
Yuya Nishihara <yuya@tcha.org>
parents: 28271
diff changeset
  2231
        if pat is None:
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2232
            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
  2233
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2234
        if s.added:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25146
diff changeset
  2235
            return any(submatches(c.substate.keys()))
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2236
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2237
        if s.modified:
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2238
            subs = set(c.p1().substate.keys())
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2239
            subs.update(c.substate.keys())
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2240
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2241
            for path in submatches(subs):
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2242
                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
  2243
                    return True
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2244
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2245
        if s.removed:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25146
diff changeset
  2246
            return any(submatches(c.p1().substate.keys()))
24446
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2247
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2248
        return False
582cfcc843c7 revset: add the 'subrepo' symbol
Matt Harbison <matt_harbison@yahoo.com>
parents: 24419
diff changeset
  2249
28424
534f968d33e5 revset: add inspection data to all filter() calls
Yuya Nishihara <yuya@tcha.org>
parents: 28423
diff changeset
  2250
    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
  2251
30782
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2252
def _substringmatcher(pattern, casesensitive=True):
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2253
    kind, pattern, matcher = util.stringmatcher(pattern,
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2254
                                                casesensitive=casesensitive)
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  2255
    if kind == 'literal':
30782
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2256
        if not casesensitive:
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2257
            pattern = encoding.lower(pattern)
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2258
            matcher = lambda s: pattern in encoding.lower(s)
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2259
        else:
db38cfc7c29d revset: stop lowercasing the regex pattern for 'author'
Matt Harbison <matt_harbison@yahoo.com>
parents: 30772
diff changeset
  2260
            matcher = lambda s: pattern in s
16823
b23bacb230c9 revset: add pattern matching to the 'user' revset expression
Simon King <simon@simonking.org.uk>
parents: 16822
diff changeset
  2261
    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
  2262
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2263
@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
  2264
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
  2265
    """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
  2266
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
  2267
    Pattern matching is supported for `name`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
  2268
    :hg:`help revisions.patterns`.
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2269
    """
12815
079a618ea89d revset: add translator comments to i18n strings
Martin Geisler <mg@lazybytes.net>
parents: 12786
diff changeset
  2270
    # 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
  2271
    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
  2272
    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
  2273
    if args:
16820
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2274
        pattern = getstring(args[0],
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2275
                            # i18n: "tag" is a keyword
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2276
                            _('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
  2277
        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
  2278
        if kind == 'literal':
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2279
            # avoid resolving all tags
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2280
            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
  2281
            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
  2282
                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
  2283
                                            % pattern)
16825
b6ef1395d77f revset: avoid validating all tag nodes for tag(x)
Matt Mackall <mpm@selenic.com>
parents: 16824
diff changeset
  2284
            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
  2285
        else:
20f55613fb2a revset: add pattern matching to 'tag' revset expression
Simon King <simon@simonking.org.uk>
parents: 16819
diff changeset
  2286
            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
  2287
    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
  2288
        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
  2289
    return subset & s
11280
a5eb0bf7e158 revset: add tagged predicate
Matt Mackall <mpm@selenic.com>
parents: 11279
diff changeset
  2290
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2291
@predicate('tagged', safe=True)
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2292
def tagged(repo, subset, x):
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2293
    return tag(repo, subset, x)
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2294
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2295
@predicate('unstable()', safe=True)
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2296
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
  2297
    """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
  2298
    """
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
  2299
    # 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
  2300
    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
  2301
    unstables = obsmod.getrevs(repo, 'unstable')
20367
2ac278aab2b4 revset: added intersection to baseset class
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20366
diff changeset
  2302
    return subset & unstables
17171
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2303
9c750c3e4fac obsolete: compute unstable changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17170
diff changeset
  2304
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2305
@predicate('user(string)', safe=True)
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  2306
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
  2307
    """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
  2308
30784
5dd67f0993ce help: eliminate duplicate text for revset string patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 30783
diff changeset
  2309
    Pattern matching is supported for `string`. See
30799
0b49449a01f4 help: use :hg: role and canonical name to point to revset string patterns
Yuya Nishihara <yuya@tcha.org>
parents: 30784
diff changeset
  2310
    :hg:`help revisions.patterns`.
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  2311
    """
13915
8f81d6f4047f revset: rearrange code so functions are sorted alphabetically
Idan Kamara <idankk86@gmail.com>
parents: 13914
diff changeset
  2312
    return author(repo, subset, x)
13359
87f248e78173 bookmarks: move revset support to core
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  2313
27587
c8dc480142a8 revset: use decorator to mark a predicate as safe
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27586
diff changeset
  2314
@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
  2315
def wdir(repo, subset, x):
30701
8b1d87243710 revset: document wdir() as an experimental function
Yuya Nishihara <yuya@tcha.org>
parents: 30700
diff changeset
  2316
    """Working directory. (EXPERIMENTAL)"""
24419
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2317
    # 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
  2318
    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
  2319
    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
  2320
        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
  2321
    return baseset()
0e41f110e69e revset: add wdir() function to specify workingctx revision by command
Yuya Nishihara <yuya@tcha.org>
parents: 24374
diff changeset
  2322
29939
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2323
def _orderedlist(repo, subset, x):
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2324
    s = getstring(x, "internal error")
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2325
    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
  2326
        return baseset()
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2327
    # 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
  2328
    # 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
  2329
    cl = repo.changelog
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2330
    ls = []
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2331
    seen = set()
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2332
    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
  2333
        try:
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2334
            # fast path for integer revision
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2335
            r = int(t)
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2336
            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
  2337
                raise ValueError
26143
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2338
            revs = [r]
25344
ceaf04bb14ff revset: add fast path for _list() of integer revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25343
diff changeset
  2339
        except ValueError:
26143
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2340
            revs = stringset(repo, subset, t)
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2341
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2342
        for r in revs:
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2343
            if r in seen:
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2344
                continue
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2345
            if (r in subset
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2346
                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
  2347
                ls.append(r)
42bb1812686f revset: fix resolving strings from a list
Durham Goode <durham@fb.com>
parents: 26102
diff changeset
  2348
            seen.add(r)
25341
9d6cc87bd507 revset: make internal _list() expression remove duplicated revisions
Yuya Nishihara <yuya@tcha.org>
parents: 25309
diff changeset
  2349
    return baseset(ls)
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2350
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2351
# for internal use
29939
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2352
@predicate('_list', safe=True, takeorder=True)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2353
def _list(repo, subset, x, order):
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2354
    if order == followorder:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2355
        # slow path to take the subset order
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2356
        return subset & _orderedlist(repo, fullreposet(repo), x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2357
    else:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2358
        return _orderedlist(repo, subset, x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2359
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2360
def _orderedintlist(repo, subset, x):
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2361
    s = getstring(x, "internal error")
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2362
    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
  2363
        return baseset()
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2364
    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
  2365
    s = subset
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2366
    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
  2367
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2368
# for internal use
29939
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2369
@predicate('_intlist', safe=True, takeorder=True)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2370
def _intlist(repo, subset, x, order):
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2371
    if order == followorder:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2372
        # slow path to take the subset order
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2373
        return subset & _orderedintlist(repo, fullreposet(repo), x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2374
    else:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2375
        return _orderedintlist(repo, subset, x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2376
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2377
def _orderedhexlist(repo, subset, x):
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2378
    s = getstring(x, "internal error")
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2379
    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
  2380
        return baseset()
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2381
    cl = repo.changelog
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2382
    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
  2383
    s = subset
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2384
    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
  2385
29939
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2386
# for internal use
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2387
@predicate('_hexlist', safe=True, takeorder=True)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2388
def _hexlist(repo, subset, x, order):
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2389
    if order == followorder:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2390
        # slow path to take the subset order
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2391
        return subset & _orderedhexlist(repo, fullreposet(repo), x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2392
    else:
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2393
        return _orderedhexlist(repo, subset, x)
e34cd85dc5b1 revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 29938
diff changeset
  2394
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2395
methods = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2396
    "range": rangeset,
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2397
    "rangeall": rangeall,
30044
69b61d0bb008 revset: do not rewrite ':y' to '0:y' (issue5385)
Yuya Nishihara <yuya@tcha.org>
parents: 30043
diff changeset
  2398
    "rangepre": rangepre,
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2399
    "rangepost": rangepost,
16860
e1aa1ed30030 revset: turn dagrange into a function
Bryan O'Sullivan <bryano@fb.com>
parents: 16859
diff changeset
  2400
    "dagrange": dagrange,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2401
    "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
  2402
    "symbol": stringset,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2403
    "and": andset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2404
    "or": orset,
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2405
    "not": notset,
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2406
    "difference": differenceset,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2407
    "list": listset,
25704
70a2082f855a revset: add parsing rule for key=value pair
Yuya Nishihara <yuya@tcha.org>
parents: 25689
diff changeset
  2408
    "keyvalue": keyvaluepair,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2409
    "func": func,
14070
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2410
    "ancestor": ancestorspec,
305c97670d7a revset: add ^ and ~ operators from parentrevspec extension
Kevin Gessner <kevin@kevingessner.com>
parents: 14061
diff changeset
  2411
    "parent": parentspec,
29935
d2d1be3009ca revset: add stub to handle parentpost operation
Yuya Nishihara <yuya@tcha.org>
parents: 29934
diff changeset
  2412
    "parentpost": parentpost,
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2413
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2414
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2415
# Constants for ordering requirement, used in _analyze():
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2416
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2417
# If 'define', any nested functions and operations can change the ordering of
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2418
# the entries in the set. If 'follow', any nested functions and operations
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2419
# should take the ordering specified by the first operand to the '&' operator.
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2420
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2421
# For instance,
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2422
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2423
#   X & (Y | Z)
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2424
#   ^   ^^^^^^^
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2425
#   |   follow
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2426
#   define
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2427
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2428
# will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2429
# of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't.
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2430
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2431
# 'any' means the order doesn't matter. For instance,
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2432
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2433
#   X & !Y
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2434
#        ^
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2435
#        any
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2436
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2437
# 'y()' can either enforce its ordering requirement or take the ordering
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2438
# specified by 'x()' because 'not()' doesn't care the order.
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2439
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2440
# Transition of ordering requirement:
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2441
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2442
# 1. starts with 'define'
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2443
# 2. shifts to 'follow' by 'x & y'
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2444
# 3. changes back to 'define' on function call 'f(x)' or function-like
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2445
#    operation 'x (f) y' because 'f' may have its own ordering requirement
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2446
#    for 'x' and 'y' (e.g. 'first(x)')
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2447
#
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2448
anyorder = 'any'        # don't care the order
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2449
defineorder = 'define'  # should define the order
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2450
followorder = 'follow'  # must follow the current order
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2451
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2452
# transition table for 'x & y', from the current expression 'x' to 'y'
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2453
_tofolloworder = {
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2454
    anyorder: anyorder,
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2455
    defineorder: followorder,
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2456
    followorder: followorder,
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2457
}
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2458
29117
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2459
def _matchonly(revs, bases):
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2460
    """
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2461
    >>> f = lambda *args: _matchonly(*map(parse, args))
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2462
    >>> f('ancestors(A)', 'not ancestors(B)')
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2463
    ('list', ('symbol', 'A'), ('symbol', 'B'))
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2464
    """
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2465
    if (revs is not None
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2466
        and revs[0] == 'func'
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
  2467
        and getsymbol(revs[1]) == 'ancestors'
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2468
        and bases is not None
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2469
        and bases[0] == 'not'
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2470
        and bases[1][0] == 'func'
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
  2471
        and getsymbol(bases[1][1]) == 'ancestors'):
29117
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2472
        return ('list', revs[2], bases[1][2])
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2473
29780
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2474
def _fixops(x):
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2475
    """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2476
    handled well by our simple top-down parser"""
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2477
    if not isinstance(x, tuple):
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2478
        return x
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2479
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2480
    op = x[0]
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2481
    if op == 'parent':
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2482
        # x^:y means (x^) : y, not x ^ (:y)
29781
9c51a5de76db revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents: 29780
diff changeset
  2483
        # x^:  means (x^) :,   not x ^ (:)
29780
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2484
        post = ('parentpost', x[1])
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2485
        if x[2][0] == 'dagrangepre':
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2486
            return _fixops(('dagrange', post, x[2][1]))
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2487
        elif x[2][0] == 'rangepre':
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2488
            return _fixops(('range', post, x[2][1]))
29781
9c51a5de76db revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents: 29780
diff changeset
  2489
        elif x[2][0] == 'rangeall':
9c51a5de76db revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents: 29780
diff changeset
  2490
            return _fixops(('rangepost', post))
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2491
    elif op == 'or':
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2492
        # make number of arguments deterministic:
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2493
        # x + y + z -> (or x y z) -> (or (list x y z))
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2494
        return (op, _fixops(('list',) + x[1:]))
29780
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2495
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2496
    return (op,) + tuple(_fixops(y) for y in x[1:])
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2497
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2498
def _analyze(x, order):
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2499
    if x is None:
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2500
        return x
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2501
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2502
    op = x[0]
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2503
    if op == 'minus':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2504
        return _analyze(('and', x[1], ('not', x[2])), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2505
    elif op == 'only':
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2506
        t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2507
        return _analyze(t, order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2508
    elif op == 'onlypost':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2509
        return _analyze(('func', ('symbol', 'only'), x[1]), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2510
    elif op == 'dagrangepre':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2511
        return _analyze(('func', ('symbol', 'ancestors'), x[1]), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2512
    elif op == 'dagrangepost':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2513
        return _analyze(('func', ('symbol', 'descendants'), x[1]), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2514
    elif op == 'negate':
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2515
        s = getstring(x[1], _("can't negate that"))
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2516
        return _analyze(('string', '-' + s), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2517
    elif op in ('string', 'symbol'):
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2518
        return x
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2519
    elif op == 'and':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2520
        ta = _analyze(x[1], order)
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2521
        tb = _analyze(x[2], _tofolloworder[order])
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2522
        return (op, ta, tb, order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2523
    elif op == 'or':
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2524
        return (op, _analyze(x[1], order), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2525
    elif op == 'not':
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2526
        return (op, _analyze(x[1], anyorder), order)
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2527
    elif op == 'rangeall':
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2528
        return (op, None, order)
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2529
    elif op in ('rangepre', 'rangepost', 'parentpost'):
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2530
        return (op, _analyze(x[1], defineorder), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2531
    elif op == 'group':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2532
        return _analyze(x[1], order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2533
    elif op in ('dagrange', 'range', 'parent', 'ancestor'):
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2534
        ta = _analyze(x[1], defineorder)
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2535
        tb = _analyze(x[2], defineorder)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2536
        return (op, ta, tb, order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2537
    elif op == 'list':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2538
        return (op,) + tuple(_analyze(y, order) for y in x[1:])
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2539
    elif op == 'keyvalue':
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2540
        return (op, x[1], _analyze(x[2], order))
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2541
    elif op == 'func':
29947
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2542
        f = getsymbol(x[1])
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2543
        d = defineorder
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2544
        if f == 'present':
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2545
            # 'present(set)' is known to return the argument set with no
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2546
            # modification, so forward the current order to its argument
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2547
            d = order
80c86b9bb40b revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents: 29939
diff changeset
  2548
        return (op, x[1], _analyze(x[2], d), order)
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2549
    raise ValueError('invalid operator %r' % op)
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2550
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2551
def analyze(x, order=defineorder):
29909
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2552
    """Transform raw parsed tree to evaluatable tree which can be fed to
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2553
    optimize() or getset()
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2554
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2555
    All pseudo operations should be mapped to real operations or functions
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2556
    defined in methods or symbols table respectively.
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2557
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2558
    'order' specifies how the current expression 'x' is ordered (see the
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2559
    constants defined above.)
29909
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2560
    """
29934
90455e7bf543 revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents: 29933
diff changeset
  2561
    return _analyze(x, order)
29909
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2562
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2563
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
  2564
    if x is None:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2565
        return 0, x
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2566
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2567
    smallbonus = 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2568
    if small:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2569
        smallbonus = .5
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2570
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2571
    op = x[0]
29908
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29902
diff changeset
  2572
    if op in ('string', 'symbol'):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2573
        return smallbonus, x # single revisions are small
16859
eeb464ed7275 revset: drop unreachable code
Bryan O'Sullivan <bryano@fb.com>
parents: 16838
diff changeset
  2574
    elif op == 'and':
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2575
        wa, ta = _optimize(x[1], True)
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2576
        wb, tb = _optimize(x[2], True)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2577
        order = x[3]
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
  2578
        w = min(wa, wb)
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2579
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2580
        # (::x and not ::y)/(not ::y and ::x) have a fast path
29117
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2581
        tm = _matchonly(ta, tb) or _matchonly(tb, ta)
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
  2582
        if tm:
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2583
            return w, ('func', ('symbol', 'only'), tm, order)
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
  2584
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2585
        if tb is not None and tb[0] == 'not':
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2586
            return wa, ('difference', ta, tb[1], order)
28217
d2ac8b57a75d revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents: 28139
diff changeset
  2587
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2588
        if wa > wb:
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2589
            return w, (op, tb, ta, order)
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2590
        return w, (op, ta, tb, order)
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2591
    elif op == 'or':
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2592
        # 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
  2593
        # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()'
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2594
        order = x[2]
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2595
        ws, ts, ss = [], [], []
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2596
        def flushss():
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2597
            if not ss:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2598
                return
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2599
            if len(ss) == 1:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2600
                w, t = ss[0]
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2601
            else:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2602
                s = '\0'.join(t[1] for w, t in ss)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2603
                y = ('func', ('symbol', '_list'), ('string', s), order)
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2604
                w, t = _optimize(y, False)
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2605
            ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2606
            ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2607
            del ss[:]
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2608
        for y in getlist(x[1]):
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2609
            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
  2610
            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
  2611
                ss.append((w, t))
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2612
                continue
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2613
            flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2614
            ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2615
            ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2616
        flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2617
        if len(ts) == 1:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
  2618
            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
  2619
        # 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
  2620
        # ("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
  2621
        #   ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0]))
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2622
        return max(ws), (op, ('list',) + tuple(ts), order)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2623
    elif op == 'not':
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2624
        # Optimize not public() to _notpublic() because we have a fast version
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2625
        if x[1][:3] == ('func', ('symbol', 'public'), None):
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2626
            order = x[1][3]
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2627
            newsym = ('func', ('symbol', '_notpublic'), None, order)
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2628
            o = _optimize(newsym, not small)
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2629
            return o[0], o[1]
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
  2630
        else:
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2631
            o = _optimize(x[1], not small)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2632
            order = x[2]
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2633
            return o[0], (op, o[1], order)
30803
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2634
    elif op == 'rangeall':
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2635
        return smallbonus, x
d389f19f14aa revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents: 30802
diff changeset
  2636
    elif op in ('rangepre', 'rangepost', 'parentpost'):
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2637
        o = _optimize(x[1], small)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2638
        order = x[2]
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2639
        return o[0], (op, o[1], order)
29902
7203400f91b0 revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29901
diff changeset
  2640
    elif op in ('dagrange', 'range', 'parent', 'ancestor'):
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2641
        wa, ta = _optimize(x[1], small)
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2642
        wb, tb = _optimize(x[2], small)
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2643
        order = x[3]
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2644
        return wa + wb, (op, ta, tb, order)
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2645
    elif op == 'list':
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2646
        ws, ts = zip(*(_optimize(y, small) for y in x[1:]))
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
  2647
        return sum(ws), (op,) + ts
29661
5004ef47f437 revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
  2648
    elif op == 'keyvalue':
5004ef47f437 revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
  2649
        w, t = _optimize(x[2], small)
5004ef47f437 revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents: 29646
diff changeset
  2650
        return w, (op, x[1], t)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2651
    elif op == 'func':
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
  2652
        f = getsymbol(x[1])
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2653
        wa, ta = _optimize(x[2], small)
29902
7203400f91b0 revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29901
diff changeset
  2654
        if f in ('author', 'branch', 'closed', 'date', 'desc', 'file', 'grep',
30205
b4074417b661 revset: optimize for destination() being "inefficient"
Mads Kiilerich <madski@unity3d.com>
parents: 30179
diff changeset
  2655
                 'keyword', 'outgoing', 'user', 'destination'):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2656
            w = 10 # slow
29902
7203400f91b0 revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29901
diff changeset
  2657
        elif f in ('modifies', 'adds', 'removes'):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2658
            w = 30 # slower
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2659
        elif f == "contains":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2660
            w = 100 # very slow
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2661
        elif f == "ancestor":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2662
            w = 1 * smallbonus
30700
323f0c4b43f4 revset: categorize wdir() as very fast function
Yuya Nishihara <yuya@tcha.org>
parents: 30699
diff changeset
  2663
        elif f in ('reverse', 'limit', 'first', 'wdir', '_intlist'):
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2664
            w = 0
29902
7203400f91b0 revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29901
diff changeset
  2665
        elif f == "sort":
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2666
            w = 10 # assume most sorts look at changelog
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2667
        else:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
  2668
            w = 1
29936
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2669
        order = x[3]
09a84e747c88 revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents: 29935
diff changeset
  2670
        return w + wa, (op, x[1], ta, order)
29900
104914b03b83 revset: make optimize() reject unknown operators
Yuya Nishihara <yuya@tcha.org>
parents: 29825
diff changeset
  2671
    raise ValueError('invalid operator %r' % op)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2672
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2673
def optimize(tree):
29909
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2674
    """Optimize evaluatable tree
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2675
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2676
    All pseudo operations should be transformed beforehand.
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29908
diff changeset
  2677
    """
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2678
    _weight, newtree = _optimize(tree, small=True)
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2679
    return newtree
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2680
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2681
# 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
  2682
# alias declarations and definitions
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
  2683
_aliassyminitletters = _syminitletters | set(pycompat.sysstr('$'))
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
  2684
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2685
def _parsewith(spec, lookup=None, syminitletters=None):
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2686
    """Generate a parse tree of given spec with given tokenizing options
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2687
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2688
    >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters)
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2689
    ('func', ('symbol', 'foo'), ('symbol', '$1'))
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2690
    >>> _parsewith('$1')
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2691
    Traceback (most recent call last):
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2692
      ...
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2693
    ParseError: ("syntax error in revset '$1'", 0)
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2694
    >>> _parsewith('foo bar')
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2695
    Traceback (most recent call last):
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2696
      ...
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2697
    ParseError: ('invalid token', 4)
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2698
    """
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2699
    p = parser.parser(elements)
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2700
    tree, pos = p.parse(tokenize(spec, lookup=lookup,
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2701
                                 syminitletters=syminitletters))
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2702
    if pos != len(spec):
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2703
        raise error.ParseError(_('invalid token'), pos)
29780
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29778
diff changeset
  2704
    return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2705
28870
475dad3432fd parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents: 28869
diff changeset
  2706
class _aliasrules(parser.basealiasrules):
475dad3432fd parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents: 28869
diff changeset
  2707
    """Parsing and expansion rule set of revset aliases"""
475dad3432fd parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents: 28869
diff changeset
  2708
    _section = _('revset alias')
29074
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2709
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2710
    @staticmethod
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2711
    def _parse(spec):
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2712
        """Parse alias declaration/definition ``spec``
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2713
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2714
        This allows symbol names to use also ``$`` as an initial letter
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2715
        (for backward compatibility), and callers of this function should
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2716
        examine whether ``$`` is used also for unexpected symbols or not.
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2717
        """
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
  2718
        return _parsewith(spec, syminitletters=_aliassyminitletters)
28910
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
  2719
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
  2720
    @staticmethod
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
  2721
    def _trygetfunc(tree):
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
  2722
        if tree[0] == 'func' and tree[1][0] == 'symbol':
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
  2723
            return tree[1][1], getlist(tree[2])
28870
475dad3432fd parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents: 28869
diff changeset
  2724
29926
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2725
def expandaliases(ui, tree):
28893
ee11167fe1da parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents: 28892
diff changeset
  2726
    aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))
28895
4bf9ed7a260e parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents: 28894
diff changeset
  2727
    tree = _aliasrules.expand(aliases, tree)
29926
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2728
    # warn about problematic (but not referred) aliases
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2729
    for name, alias in sorted(aliases.iteritems()):
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2730
        if alias.error and not alias.warned:
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2731
            ui.warn(_('warning: %s\n') % (alias.error))
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2732
            alias.warned = True
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
  2733
    return tree
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2734
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2735
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
  2736
    """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
  2737
    """
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2738
    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
  2739
        return tree
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2740
    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
  2741
        pending = [tree]
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2742
        l = []
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2743
        while pending:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2744
            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
  2745
            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
  2746
                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
  2747
            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
  2748
                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
  2749
            else:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2750
                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
  2751
                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
  2752
        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
  2753
    else:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2754
        return tuple(foldconcat(t) for t in tree)
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
  2755
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2756
def parse(spec, lookup=None):
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
  2757
    return _parsewith(spec, lookup=lookup)
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
  2758
24518
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2759
def posttreebuilthook(tree, repo):
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2760
    # 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
  2761
    pass
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2762
29959
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2763
def match(ui, spec, repo=None, order=defineorder):
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2764
    """Create a matcher for a single revision spec
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2765
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2766
    If order=followorder, a matcher takes the ordering specified by the input
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2767
    set.
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2768
    """
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2769
    return matchany(ui, [spec], repo=repo, order=order)
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2770
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2771
def matchany(ui, specs, repo=None, order=defineorder):
25927
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2772
    """Create a matcher that will include any revisions matching one of the
29959
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2773
    given specs
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2774
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2775
    If order=followorder, a matcher takes the ordering specified by the input
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2776
    set.
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2777
    """
25927
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2778
    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
  2779
        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
  2780
            return baseset()
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2781
        return mfunc
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2782
    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
  2783
        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
  2784
    lookup = None
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2785
    if repo:
44da63623fca revset: add matchany() to construct OR expression from a list of specs
Yuya Nishihara <yuya@tcha.org>
parents: 25926
diff changeset
  2786
        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
  2787
    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
  2788
        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
  2789
    else:
29933
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29926
diff changeset
  2790
        tree = ('or', ('list',) + tuple(parse(s, lookup) for s in specs))
29910
41491cf936f2 revset: add public function to create matcher from evaluatable tree
Yuya Nishihara <yuya@tcha.org>
parents: 29909
diff changeset
  2791
14900
fc3d6f300d7d revset: allow bypassing alias expansion
Matt Mackall <mpm@selenic.com>
parents: 14851
diff changeset
  2792
    if ui:
29926
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29910
diff changeset
  2793
        tree = expandaliases(ui, tree)
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
  2794
    tree = foldconcat(tree)
29959
1b5931604a5a revset: add option to make matcher takes the ordering of the input set
Yuya Nishihara <yuya@tcha.org>
parents: 29950
diff changeset
  2795
    tree = analyze(tree, order)
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
  2796
    tree = optimize(tree)
24518
dd5e56f08d13 revset: add hook after tree parsing
Laurent Charignon <lcharignon@fb.com>
parents: 24459
diff changeset
  2797
    posttreebuilthook(tree, repo)
29910
41491cf936f2 revset: add public function to create matcher from evaluatable tree
Yuya Nishihara <yuya@tcha.org>
parents: 29909
diff changeset
  2798
    return makematcher(tree)
41491cf936f2 revset: add public function to create matcher from evaluatable tree
Yuya Nishihara <yuya@tcha.org>
parents: 29909
diff changeset
  2799
41491cf936f2 revset: add public function to create matcher from evaluatable tree
Yuya Nishihara <yuya@tcha.org>
parents: 29909
diff changeset
  2800
def makematcher(tree):
41491cf936f2 revset: add public function to create matcher from evaluatable tree
Yuya Nishihara <yuya@tcha.org>
parents: 29909
diff changeset
  2801
    """Create a matcher from an evaluatable tree"""
24114
fafd9a1284cf revset: make match function initiate query from full set by default
Yuya Nishihara <yuya@tcha.org>
parents: 24031
diff changeset
  2802
    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
  2803
        if subset is None:
24115
ff24af40728b revset: specify fullreposet without using spanset factory
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
  2804
            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
  2805
        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
  2806
            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
  2807
        else:
2717dcff7be1 revset: use a single return statement in matcher function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22670
diff changeset
  2808
            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
  2809
        return result
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  2810
    return mfunc
12821
165079e564f0 revsets: generate predicate help dynamically
Patrick Mezard <pmezard@gmail.com>
parents: 12815
diff changeset
  2811
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2812
def formatspec(expr, *args):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2813
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2814
    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
  2815
    escapes arguments appropriately. Aliases are intentionally ignored
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2816
    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
  2817
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2818
    Supported arguments:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2819
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2820
    %r = revset expression, parenthesized
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2821
    %d = int(arg), no quoting
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2822
    %s = string(arg), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2823
    %b = arg.branch(), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2824
    %n = hex(arg), single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2825
    %% = a literal '%'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2826
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2827
    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
  2828
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2829
    >>> 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
  2830
    '(10 or 11):: and ((this()) or (that()))'
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2831
    >>> formatspec('%d:: and not %d::', 10, 20)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2832
    '10:: and not 20::'
15325
cdf1daa3b83f revset: deal with empty lists in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15268
diff changeset
  2833
    >>> formatspec('%ld or %ld', [], [1])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2834
    "_list('') or 1"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2835
    >>> formatspec('keyword(%s)', 'foo\\xe9')
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2836
    "keyword('foo\\\\xe9')"
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2837
    >>> b = lambda: 'default'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2838
    >>> b.branch = b
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2839
    >>> formatspec('branch(%b)', b)
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2840
    "branch('default')"
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2841
    >>> 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
  2842
    "root(_list('a\\x00b\\x00c\\x00d'))"
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2843
    '''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2844
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2845
    def quote(s):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2846
        return repr(str(s))
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2847
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2848
    def argtype(c, arg):
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2849
        if c == 'd':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2850
            return str(int(arg))
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2851
        elif c == 's':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2852
            return quote(arg)
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2853
        elif c == 'r':
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
  2854
            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
  2855
            return '(%s)' % arg
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2856
        elif c == 'n':
16417
b4b0c6931e11 revset: avoid demandimport bug
Matt Mackall <mpm@selenic.com>
parents: 16415
diff changeset
  2857
            return quote(node.hex(arg))
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2858
        elif c == 'b':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2859
            return quote(arg.branch())
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2860
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2861
    def listexp(s, t):
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2862
        l = len(s)
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2863
        if l == 0:
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2864
            return "_list('')"
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2865
        elif l == 1:
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2866
            return argtype(t, s[0])
15898
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2867
        elif t == 'd':
20566
98024950ade0 revset: added _intlist method to replace _list for %ld
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20552
diff changeset
  2868
            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
  2869
        elif t == 's':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2870
            return "_list('%s')" % "\0".join(s)
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2871
        elif t == 'n':
20569
0d4be103c734 revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 20566
diff changeset
  2872
            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
  2873
        elif t == 'b':
6902e13ddd03 revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents: 15837
diff changeset
  2874
            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
  2875
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15726
diff changeset
  2876
        m = l // 2
15595
a585d78e7b2f revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents: 15532
diff changeset
  2877
        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
  2878
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2879
    ret = ''
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2880
    pos = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2881
    arg = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2882
    while pos < len(expr):
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2883
        c = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2884
        if c == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2885
            pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2886
            d = expr[pos]
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2887
            if d == '%':
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2888
                ret += d
15268
bd5103819c2e revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents: 15266
diff changeset
  2889
            elif d in 'dsnbr':
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2890
                ret += argtype(d, args[arg])
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2891
                arg += 1
15140
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2892
            elif d == 'l':
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2893
                # a list of some type
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2894
                pos += 1
353a1ba928f6 revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents: 15138
diff changeset
  2895
                d = expr[pos]
15596
2555f441a32f merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15595
diff changeset
  2896
                ret += listexp(list(args[arg]), d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2897
                arg += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2898
            else:
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29365
diff changeset
  2899
                raise error.Abort(_('unexpected revspec format character %s')
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29365
diff changeset
  2900
                                  % d)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2901
        else:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2902
            ret += c
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2903
        pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2904
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2905
    return ret
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
  2906
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2907
def prettyformat(tree):
25253
3f1a9b44b8c2 parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents: 25251
diff changeset
  2908
    return parser.prettyformat(tree, ('string', 'symbol'))
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
  2909
19719
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2910
def depth(tree):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2911
    if isinstance(tree, tuple):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2912
        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
  2913
    else:
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2914
        return 0
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
  2915
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2916
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
  2917
    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
  2918
        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
  2919
    else:
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
  2920
        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
  2921
        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
  2922
            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
  2923
        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
  2924
            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
  2925
        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
  2926
28393
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2927
def loadpredicate(ui, extname, registrarobj):
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2928
    """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
  2929
    """
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2930
    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
  2931
        symbols[name] = func
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2932
        if func._safe:
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2933
            safesymbols.add(name)
ac11ba7c2e56 registrar: define revsetpredicate to decorate revset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28272
diff changeset
  2934
28395
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
  2935
# 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
  2936
loadpredicate(None, None, predicate)
0383f7a5e86c revset: replace predicate by revsetpredicate of registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28393
diff changeset
  2937
12823
80deae3bc5ea hggettext: handle i18nfunctions declaration for docstrings translations
Patrick Mezard <pmezard@gmail.com>
parents: 12821
diff changeset
  2938
# 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
  2939
i18nfunctions = symbols.values()