mercurial/match.py
author Raphaël Gomès <rgomes@octobus.net>
Thu, 10 Oct 2024 10:38:10 +0200
changeset 52162 f2eab4967bfc
parent 51926 70fe33bdab54
permissions -rw-r--r--
rust-index: return an error on a bad index header This is more idiomatic and allows us to better handle the problem later.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8682
diff changeset
     1
# match.py - filename matching
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46064
diff changeset
     3
#  Copyright 2008, 2009 Olivia Mackall <olivia@selenic.com> and others
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     4
#
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9036
diff changeset
     6
# GNU General Public License version 2 or any later version.
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     7
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51757
diff changeset
     8
from __future__ import annotations
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
     9
46872
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
    10
import bisect
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    11
import copy
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
    12
import itertools
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    13
import os
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    14
import re
51926
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    15
import typing
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    16
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    17
from typing import (
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    18
    Any,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    19
    Callable,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    20
    List,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    21
    Tuple,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    22
    Union,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    23
    overload,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    24
)
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    25
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    26
from .i18n import _
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    27
from .pycompat import open
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    28
from . import (
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
    29
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
    30
    error,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    31
    pathutil,
42452
a3a8887e4426 rust: using policy.importrust from Python callers
Georges Racinet <georges.racinet@octobus.net>
parents: 42367
diff changeset
    32
    policy,
36572
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36050
diff changeset
    33
    pycompat,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    34
    util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    35
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    36
from .utils import stringutil
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
44137
3bd77c64bc74 rust-filepatterns: remove bridge code for filepatterns-related functions
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
    38
rustmod = policy.importrust('dirstate')
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
    39
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    40
allpatternkinds = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    41
    b're',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    42
    b'glob',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    43
    b'path',
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
    44
    b'filepath',
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    45
    b'relglob',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    46
    b'relpath',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    47
    b'relre',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    48
    b'rootglob',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    49
    b'listfile',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    50
    b'listfile0',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    51
    b'set',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    52
    b'include',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    53
    b'subinclude',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    54
    b'rootfilesin',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    55
)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    56
cwdrelativepatternkinds = (b'relpath', b'glob')
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    57
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
    58
propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
    59
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    60
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    61
def _rematcher(regex):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
    62
    """compile the regexp with the best available regexp engine and return a
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
    63
    matcher function"""
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
    64
    m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    65
    try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    66
        # slightly faster, provided by facebook's re2 bindings
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    67
        return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    68
    except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    69
        return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    70
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    71
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
    72
def _expandsets(cwd, kindpats, ctx=None, listsubrepos=False, badfn=None):
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
    73
    '''Returns the kindpats list with the 'set' patterns expanded to matchers'''
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
    74
    matchers = []
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    75
    other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    76
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
    77
    for kind, pat, source in kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    78
        if kind == b'set':
41022
481249481392 match: fix assertion for fileset with no context (issue6046)
Yuya Nishihara <yuya@tcha.org>
parents: 40345
diff changeset
    79
            if ctx is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    80
                raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
    81
                    b"fileset expression with no context"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    82
                )
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
    83
            matchers.append(ctx.matchfileset(cwd, pat, badfn=badfn))
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    84
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    85
            if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    86
                for subpath in ctx.substate:
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
    87
                    sm = ctx.sub(subpath).matchfileset(cwd, pat, badfn=badfn)
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
    88
                    pm = prefixdirmatcher(subpath, sm, badfn=badfn)
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
    89
                    matchers.append(pm)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    90
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    91
            continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
    92
        other.append((kind, pat, source))
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
    93
    return matchers, other
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    94
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
    95
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    96
def _expandsubinclude(kindpats, root):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
    97
    """Returns the list of subinclude matcher args and the kindpats without the
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
    98
    subincludes in it."""
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    99
    relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   100
    other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   101
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   102
    for kind, pat, source in kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   103
        if kind == b'subinclude':
25301
caaf4045eca8 match: normpath the ignore source when expanding the 'subinclude' kind
Matt Harbison <matt_harbison@yahoo.com>
parents: 25283
diff changeset
   104
            sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   105
            pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   106
            path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   107
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   108
            newroot = pathutil.dirname(path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   109
            matcherargs = (newroot, b'', [], [b'include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   110
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   111
            prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   112
            if prefix:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   113
                prefix += b'/'
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
   114
            relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   115
        else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   116
            other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   117
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   118
    return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   119
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   120
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   121
def _kindpatsalwaysmatch(kindpats):
45946
464539c305aa formatting: drop a few extra double quotes in docstrings
Matt Harbison <matt_harbison@yahoo.com>
parents: 45942
diff changeset
   122
    """Checks whether the kindspats match everything, as e.g.
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   123
    'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   124
    """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   125
    for kind, pat, source in kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   126
        if pat != b'' or kind not in [b'relpath', b'glob']:
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   127
            return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   128
    return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
   129
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   130
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   131
def _buildkindpatsmatcher(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   132
    matchercls,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   133
    root,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   134
    cwd,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   135
    kindpats,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   136
    ctx=None,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   137
    listsubrepos=False,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   138
    badfn=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   139
):
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   140
    matchers = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   141
    fms, kindpats = _expandsets(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   142
        cwd,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   143
        kindpats,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   144
        ctx=ctx,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   145
        listsubrepos=listsubrepos,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   146
        badfn=badfn,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   147
    )
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   148
    if kindpats:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   149
        m = matchercls(root, kindpats, badfn=badfn)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   150
        matchers.append(m)
38612
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
   151
    if fms:
760cc5dc01e8 fileset: restrict getfileset() to not return a computed set (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38611
diff changeset
   152
        matchers.extend(fms)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   153
    if not matchers:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   154
        return nevermatcher(badfn=badfn)
38580
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   155
    if len(matchers) == 1:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   156
        return matchers[0]
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   157
    return unionmatcher(matchers)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38579
diff changeset
   158
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   159
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   160
def match(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   161
    root,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   162
    cwd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   163
    patterns=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   164
    include=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   165
    exclude=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   166
    default=b'glob',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   167
    auditor=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   168
    ctx=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   169
    listsubrepos=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   170
    warn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   171
    badfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   172
    icasefs=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   173
):
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   174
    r"""build an object to match a set of file patterns
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   175
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   176
    arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   177
    root - the canonical root of the tree you're matching against
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   178
    cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   179
    patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   180
    include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   181
    exclude - patterns to exclude (even if they are included)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   182
    default - if a pattern in patterns has no explicit type, assume this one
42083
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
   183
    auditor - optional path auditor
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
   184
    ctx - optional changecontext
bee1647578b7 match: complete documentation of match() parameters
Denis Laxalde <denis@laxalde.org>
parents: 42082
diff changeset
   185
    listsubrepos - if True, recurse into subrepositories
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   186
    warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   187
    badfn - optional bad() callback for this matcher instead of the default
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   188
    icasefs - make a matcher for wdir on case insensitive filesystems, which
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   189
        normalizes the given patterns to the case in the filesystem
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   190
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   191
    a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   192
    'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   193
    're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   194
    'path:<path>' - a path relative to repository root, which is matched
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   195
                    recursively
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   196
    'filepath:<path>' - an exact path to a single file, relative to the
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   197
                        repository root
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   198
    'rootfilesin:<path>' - a path relative to repository root, which is
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   199
                    matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   200
    'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   201
    'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   202
    'relre:<regexp>' - a regexp that needn't match the start of a name
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   203
    'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   204
    'include:<path>' - a file of patterns to read and include
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   205
    'subinclude:<path>' - a file of patterns to match against files under
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   206
                          the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   207
    '<something>' - a pattern of the specified default type
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   208
43964
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   209
    >>> def _match(root, *args, **kwargs):
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   210
    ...     return match(util.localpath(root), *args, **kwargs)
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   211
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   212
    Usually a patternmatcher is returned:
50304
805d4a462abb py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 49805
diff changeset
   213
    >>> _match(b'/foo', b'.', [br're:.*\.c$', b'path:foo/a', b'*.py'])
50337
47686726545d match: sort patterns before compiling them into a regex
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   214
    <patternmatcher patterns='[^/]*\\.py$|foo/a(?:/|$)|.*\\.c$'>
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   215
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   216
    Combining 'patterns' with 'include' (resp. 'exclude') gives an
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   217
    intersectionmatcher (resp. a differencematcher):
50304
805d4a462abb py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 49805
diff changeset
   218
    >>> type(_match(b'/foo', b'.', [br're:.*\.c$'], include=[b'path:lib']))
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   219
    <class 'mercurial.match.intersectionmatcher'>
50304
805d4a462abb py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 49805
diff changeset
   220
    >>> type(_match(b'/foo', b'.', [br're:.*\.c$'], exclude=[b'path:build']))
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   221
    <class 'mercurial.match.differencematcher'>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   222
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   223
    Notice that, if 'patterns' is empty, an alwaysmatcher is returned:
43964
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   224
    >>> _match(b'/foo', b'.', [])
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   225
    <alwaysmatcher>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   226
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   227
    The 'default' argument determines which kind of pattern is assumed if a
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   228
    pattern has no prefix:
50304
805d4a462abb py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 49805
diff changeset
   229
    >>> _match(b'/foo', b'.', [br'.*\.c$'], default=b're')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   230
    <patternmatcher patterns='.*\\.c$'>
43964
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   231
    >>> _match(b'/foo', b'.', [b'main.py'], default=b'relpath')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   232
    <patternmatcher patterns='main\\.py(?:/|$)'>
43964
8f67735344ae tests: convert the `root` arg of matchmod.match() to local path separators
Matt Harbison <matt_harbison@yahoo.com>
parents: 43950
diff changeset
   233
    >>> _match(b'/foo', b'.', [b'main.py'], default=b're')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   234
    <patternmatcher patterns='main.py'>
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   235
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   236
    The primary use of matchers is to check whether a value (usually a file
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   237
    name) matches againset one of the patterns given at initialization. There
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   238
    are two ways of doing this check.
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   239
50304
805d4a462abb py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 49805
diff changeset
   240
    >>> m = _match(b'/foo', b'', [br're:.*\.c$', b'relpath:a'])
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   241
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   242
    1. Calling the matcher with a file name returns True if any pattern
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   243
    matches that file name:
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   244
    >>> m(b'a')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   245
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   246
    >>> m(b'main.c')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   247
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   248
    >>> m(b'test.py')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   249
    False
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   250
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   251
    2. Using the exact() method only returns True if the file name matches one
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   252
    of the exact patterns (i.e. not re: or glob: patterns):
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   253
    >>> m.exact(b'a')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   254
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   255
    >>> m.exact(b'main.c')
42084
42537dfc7a7c match: add doctest examples in match()
Denis Laxalde <denis@laxalde.org>
parents: 42083
diff changeset
   256
    False
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   257
    """
43949
8b1a9ba375e5 match: make sure `root` argument is always an absolute path (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 43735
diff changeset
   258
    assert os.path.isabs(root)
43965
8a81fa44f7bb match: don't util.normpath() cwd
Matt Harbison <matt_harbison@yahoo.com>
parents: 43964
diff changeset
   259
    cwd = os.path.join(root, util.localpath(cwd))
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   260
    normalize = _donormalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   261
    if icasefs:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   262
        dirstate = ctx.repo().dirstate
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   263
        dsnormalize = dirstate.normalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   264
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   265
        def normalize(patterns, default, root, cwd, auditor, warn):
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   266
            kp = _donormalize(patterns, default, root, cwd, auditor, warn)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   267
            kindpats = []
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   268
            for kind, pats, source in kp:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   269
                if kind not in (b're', b'relre'):  # regex can't be normalized
32401
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   270
                    p = pats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   271
                    pats = dsnormalize(pats)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   272
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   273
                    # Preserve the original to handle a case only rename.
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   274
                    if p != pats and p in dirstate:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   275
                        kindpats.append((kind, p, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   276
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   277
                kindpats.append((kind, pats, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   278
            return kindpats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32400
diff changeset
   279
41622
635a12c53ea6 match: remove unused "exact" argument (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41528
diff changeset
   280
    if patterns:
32556
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32555
diff changeset
   281
        kindpats = normalize(patterns, default, root, cwd, auditor, warn)
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
   282
        if _kindpatsalwaysmatch(kindpats):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   283
            m = alwaysmatcher(badfn)
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
   284
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   285
            m = _buildkindpatsmatcher(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   286
                patternmatcher,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   287
                root,
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
   288
                cwd,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   289
                kindpats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   290
                ctx=ctx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   291
                listsubrepos=listsubrepos,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   292
                badfn=badfn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   293
            )
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   294
    else:
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   295
        # It's a little strange that no patterns means to match everything.
32650
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32605
diff changeset
   296
        # Consider changing this to match nothing (probably using nevermatcher).
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   297
        m = alwaysmatcher(badfn)
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   298
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   299
    if include:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   300
        kindpats = normalize(include, b'glob', root, cwd, auditor, warn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   301
        im = _buildkindpatsmatcher(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   302
            includematcher,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   303
            root,
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
   304
            cwd,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   305
            kindpats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   306
            ctx=ctx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   307
            listsubrepos=listsubrepos,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   308
            badfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   309
        )
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   310
        m = intersectmatchers(m, im)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   311
    if exclude:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   312
        kindpats = normalize(exclude, b'glob', root, cwd, auditor, warn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   313
        em = _buildkindpatsmatcher(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   314
            includematcher,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   315
            root,
44009
e685fac56693 match: resolve filesets against the passed `cwd`, not the current one
Matt Harbison <matt_harbison@yahoo.com>
parents: 44002
diff changeset
   316
            cwd,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   317
            kindpats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   318
            ctx=ctx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   319
            listsubrepos=listsubrepos,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   320
            badfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   321
        )
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   322
        m = differencematcher(m, em)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   323
    return m
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   324
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   325
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
   326
def exact(files, badfn=None):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   327
    return exactmatcher(files, badfn=badfn)
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   328
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   329
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
   330
def always(badfn=None):
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
   331
    return alwaysmatcher(badfn)
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   332
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   333
41676
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
   334
def never(badfn=None):
0531dff73d0b match: delete unused root and cwd arguments from {always,never,exact}() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41675
diff changeset
   335
    return nevermatcher(badfn)
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   336
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   337
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   338
def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   339
    """Make a copy of the given matcher, replacing its bad method with the given
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   340
    one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   341
    """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   342
    m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   343
    m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   344
    return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   345
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   346
42085
54e6d7ef5ca5 match: make _donormalize's auditor and warn arguments optional
Denis Laxalde <denis@laxalde.org>
parents: 42084
diff changeset
   347
def _donormalize(patterns, default, root, cwd, auditor=None, warn=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   348
    """Convert 'kind:pat' from the patterns list to tuples with kind and
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   349
    normalized and rooted patterns and with listfiles expanded."""
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   350
    kindpats = []
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   351
    kinds_to_normalize = (
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   352
        b'relglob',
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   353
        b'path',
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   354
        b'filepath',
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   355
        b'rootfilesin',
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   356
        b'rootglob',
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   357
    )
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   358
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   359
    for kind, pat in [_patsplit(p, default) for p in patterns]:
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
   360
        if kind in cwdrelativepatternkinds:
42085
54e6d7ef5ca5 match: make _donormalize's auditor and warn arguments optional
Denis Laxalde <denis@laxalde.org>
parents: 42084
diff changeset
   361
            pat = pathutil.canonpath(root, cwd, pat, auditor=auditor)
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
   362
        elif kind in kinds_to_normalize:
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   363
            pat = util.normpath(pat)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   364
        elif kind in (b'listfile', b'listfile0'):
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   365
            try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   366
                files = util.readfile(pat)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   367
                if kind == b'listfile0':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   368
                    files = files.split(b'\0')
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   369
                else:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   370
                    files = files.splitlines()
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   371
                files = [f for f in files if f]
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   372
            except EnvironmentError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   373
                raise error.Abort(_(b"unable to read file list (%s)") % pat)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   374
            for k, p, source in _donormalize(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   375
                files, default, root, cwd, auditor, warn
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   376
            ):
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   377
                kindpats.append((k, p, pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   378
            continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   379
        elif kind == b'include':
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   380
            try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   381
                fullpath = os.path.join(root, util.localpath(pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   382
                includepats = readpatternfile(fullpath, warn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   383
                for k, p, source in _donormalize(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   384
                    includepats, default, root, cwd, auditor, warn
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   385
                ):
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   386
                    kindpats.append((k, p, source or pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   387
            except error.Abort as inst:
43485
6ff196d2553b match: suppress error about subscripting an exception
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   388
                raise error.Abort(
6ff196d2553b match: suppress error about subscripting an exception
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   389
                    b'%s: %s'
45682
d2e1dcd4490d errors: name arguments to Abort constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 44530
diff changeset
   390
                    % (
d2e1dcd4490d errors: name arguments to Abort constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 44530
diff changeset
   391
                        pat,
d2e1dcd4490d errors: name arguments to Abort constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 44530
diff changeset
   392
                        inst.message,
49805
a06a503e3cf8 typing: drop an unnecessary warning disabling comment in match.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49645
diff changeset
   393
                    )
43485
6ff196d2553b match: suppress error about subscripting an exception
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   394
                )
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   395
            except IOError as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   396
                if warn:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   397
                    warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   398
                        _(b"skipping unreadable pattern file '%s': %s\n")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   399
                        % (pat, stringutil.forcebytestr(inst.strerror))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   400
                    )
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   401
            continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   402
        # else: re or relre - which cannot be normalized
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   403
        kindpats.append((kind, pat, b''))
32397
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   404
    return kindpats
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32396
diff changeset
   405
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   406
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48941
diff changeset
   407
class basematcher:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   408
    def __init__(self, badfn=None):
51601
ea3343104f07 largefiles: track if a matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51569
diff changeset
   409
        self._was_tampered_with = False
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   410
        if badfn is not None:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   411
            self.bad = badfn
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   412
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
   413
    def was_tampered_with_nonrec(self) -> bool:
51601
ea3343104f07 largefiles: track if a matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51569
diff changeset
   414
        # [_was_tampered_with] is used to track if when extensions changed the matcher
ea3343104f07 largefiles: track if a matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51569
diff changeset
   415
        # behavior (crazy stuff!), so we disable the rust fast path.
ea3343104f07 largefiles: track if a matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51569
diff changeset
   416
        return self._was_tampered_with
ea3343104f07 largefiles: track if a matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51569
diff changeset
   417
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
   418
    def was_tampered_with(self) -> bool:
51625
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   419
        return self.was_tampered_with_nonrec()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   420
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   421
    def __call__(self, fn):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   422
        return self.matchfn(fn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   423
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   424
    # Callbacks related to how the matcher is used by dirstate.walk.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   425
    # Subscribers to these events must monkeypatch the matcher object.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   426
    def bad(self, f, msg):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   427
        """Callback from dirstate.walk for each explicit file that can't be
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   428
        found/accessed, with an error message."""
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   429
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   430
    # If an traversedir is set, it will be called when a directory discovered
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   431
    # by recursive traversal is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   432
    traversedir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   433
32459
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
   434
    @propertycache
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
   435
    def _files(self):
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
   436
        return []
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32458
diff changeset
   437
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   438
    def files(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   439
        """Explicitly listed files or patterns or roots:
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   440
        if no patterns or .always(): empty list,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   441
        if exact: list exact files,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   442
        if not .anypats(): list all files and dirs,
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   443
        else: optimal roots"""
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   444
        return self._files
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   445
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   446
    @propertycache
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   447
    def _fileset(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   448
        return set(self._files)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   449
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   450
    def exact(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   451
        '''Returns True if f is in .files().'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   452
        return f in self._fileset
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   453
32463
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
   454
    def matchfn(self, f):
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
   455
        return False
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32461
diff changeset
   456
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   457
    def visitdir(self, dir):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   458
        """Decides whether a directory should be visited based on whether it
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   459
        has potential matches in it or one of its subdirectories. This is
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   460
        based on the match's primary, included, and excluded patterns.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   461
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   462
        Returns the string 'all' if the given directory and all subdirectories
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   463
        should be visited. Otherwise returns True or False indicating whether
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   464
        the given directory should be visited.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   465
        """
33478
cf15c3cc304c match: make base matcher return True for visitdir
Durham Goode <durham@fb.com>
parents: 33448
diff changeset
   466
        return True
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   467
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   468
    def visitchildrenset(self, dir):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   469
        """Decides whether a directory should be visited based on whether it
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   470
        has potential matches in it or one of its subdirectories, and
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   471
        potentially lists which subdirectories of that directory should be
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   472
        visited. This is based on the match's primary, included, and excluded
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   473
        patterns.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   474
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   475
        This function is very similar to 'visitdir', and the following mapping
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   476
        can be applied:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   477
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   478
             visitdir | visitchildrenlist
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   479
            ----------+-------------------
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   480
             False    | set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   481
             'all'    | 'all'
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   482
             True     | 'this' OR non-empty set of subdirs -or files- to visit
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   483
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   484
        Example:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   485
          Assume matchers ['path:foo/bar', 'rootfilesin:qux'], we would return
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   486
          the following values (assuming the implementation of visitchildrenset
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   487
          is capable of recognizing this; some implementations are not).
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   488
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
   489
          '' -> {'foo', 'qux'}
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   490
          'baz' -> set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   491
          'foo' -> {'bar'}
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   492
          # Ideally this would be 'all', but since the prefix nature of matchers
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   493
          # is applied to the entire matcher, we have to downgrade this to
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   494
          # 'this' due to the non-prefix 'rootfilesin'-kind matcher being mixed
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   495
          # in.
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   496
          'foo/bar' -> 'this'
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   497
          'qux' -> 'this'
39260
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   498
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   499
        Important:
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   500
          Most matchers do not know if they're representing files or
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   501
          directories. They see ['path:dir/f'] and don't know whether 'f' is a
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   502
          file or a directory, so visitchildrenset('dir') for most matchers will
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   503
          return {'f'}, but if the matcher knows it's a file (like exactmatcher
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   504
          does), it may return 'this'. Do not rely on the return being a set
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   505
          indicating that there are no files in this dir to investigate (or
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   506
          equivalently that if there are files to investigate in 'dir' that it
27946fca8a05 match: document that visitchildrenset might return files
Kyle Lippincott <spectral@google.com>
parents: 38958
diff changeset
   507
          will always return 'this').
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   508
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   509
        return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   510
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   511
    def always(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   512
        """Matcher will match everything and .files() will be empty --
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   513
        optimization might be possible."""
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   514
        return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   515
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   516
    def isexact(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   517
        """Matcher will match exactly the list of files in .files() --
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   518
        optimization might be possible."""
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   519
        return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   520
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   521
    def prefix(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   522
        """Matcher will match the paths in .files() recursively --
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   523
        optimization might be possible."""
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   524
        return False
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   525
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   526
    def anypats(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   527
        """None of .always(), .isexact(), and .prefix() is true --
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   528
        optimizations will be difficult."""
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   529
        return not self.always() and not self.isexact() and not self.prefix()
32458
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   530
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   531
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   532
class alwaysmatcher(basematcher):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   533
    '''Matches everything.'''
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   534
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   535
    def __init__(self, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   536
        super(alwaysmatcher, self).__init__(badfn)
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   537
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   538
    def always(self):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   539
        return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   540
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   541
    def matchfn(self, f):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   542
        return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   543
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   544
    def visitdir(self, dir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   545
        return b'all'
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   546
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   547
    def visitchildrenset(self, dir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   548
        return b'all'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   549
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   550
    def __repr__(self):
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   551
        return r'<alwaysmatcher>'
32553
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32552
diff changeset
   552
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   553
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   554
class nevermatcher(basematcher):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   555
    '''Matches nothing.'''
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   556
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   557
    def __init__(self, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   558
        super(nevermatcher, self).__init__(badfn)
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   559
33378
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   560
    # It's a little weird to say that the nevermatcher is an exact matcher
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   561
    # or a prefix matcher, but it seems to make sense to let callers take
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   562
    # fast paths based on either. There will be no exact matches, nor any
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   563
    # prefixes (files() returns []), so fast paths iterating over them should
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   564
    # be efficient (and correct).
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   565
    def isexact(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   566
        return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   567
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   568
    def prefix(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   569
        return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   570
33582
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   571
    def visitdir(self, dir):
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   572
        return False
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   573
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   574
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   575
        return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   576
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   577
    def __repr__(self):
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   578
        return r'<nevermatcher>'
32605
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32557
diff changeset
   579
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   580
38577
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   581
class predicatematcher(basematcher):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   582
    """A matcher adapter for a simple boolean function"""
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   583
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   584
    def __init__(self, predfn, predrepr=None, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   585
        super(predicatematcher, self).__init__(badfn)
38577
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   586
        self.matchfn = predfn
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   587
        self._predrepr = predrepr
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   588
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   589
    @encoding.strmethod
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   590
    def __repr__(self):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   591
        s = stringutil.buildrepr(self._predrepr) or pycompat.byterepr(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   592
            self.matchfn
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   593
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   594
        return b'<predicatenmatcher pred=%s>' % s
38577
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38475
diff changeset
   595
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   596
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   597
def path_or_parents_in_set(path, prefix_set):
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   598
    """Returns True if `path` (or any parent of `path`) is in `prefix_set`."""
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   599
    l = len(prefix_set)
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   600
    if l == 0:
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   601
        return False
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   602
    if path in prefix_set:
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   603
        return True
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   604
    # If there's more than 5 paths in prefix_set, it's *probably* quicker to
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   605
    # "walk up" the directory hierarchy instead, with the assumption that most
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   606
    # directory hierarchies are relatively shallow and hash lookup is cheap.
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   607
    if l > 5:
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   608
        return any(
46064
1f0ed7e63c2a formatting: re-blacken match.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 45999
diff changeset
   609
            parentdir in prefix_set for parentdir in pathutil.finddirs(path)
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   610
        )
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   611
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   612
    # FIXME: Ideally we'd never get to this point if this is the case - we'd
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   613
    # recognize ourselves as an 'always' matcher and skip this.
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   614
    if b'' in prefix_set:
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   615
        return True
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   616
48884
7f5e91cdebcd match: delete Python 2 conditional code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   617
    sl = ord(b'/')
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   618
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   619
    # We already checked that path isn't in prefix_set exactly, so
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   620
    # `path[len(pf)] should never raise IndexError.
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   621
    return any(path.startswith(pf) and path[len(pf)] == sl for pf in prefix_set)
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   622
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   623
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   624
class patternmatcher(basematcher):
43721
bfbbf48d51e8 py3: make doc strings containing deprecated '\.' escape sequence raw strings
Daniel Ploch <dploch@google.com>
parents: 43117
diff changeset
   625
    r"""Matches a set of (kind, pat, source) against a 'root' directory.
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   626
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   627
    >>> kindpats = [
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
   628
    ...     (b're', br'.*\.c$', b''),
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   629
    ...     (b'path', b'foo/a', b''),
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   630
    ...     (b'relpath', b'b', b''),
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   631
    ...     (b'glob', b'*.h', b''),
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   632
    ... ]
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   633
    >>> m = patternmatcher(b'foo', kindpats)
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   634
    >>> m(b'main.c')  # matches re:.*\.c$
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   635
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   636
    >>> m(b'b.txt')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   637
    False
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   638
    >>> m(b'foo/a')  # matches path:foo/a
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   639
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   640
    >>> m(b'a')  # does not match path:b, since 'root' is 'foo'
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   641
    False
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   642
    >>> m(b'b')  # matches relpath:b, since 'root' is 'foo'
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   643
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   644
    >>> m(b'lib.h')  # matches glob:*.h
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   645
    True
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   646
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   647
    >>> m.files()
50337
47686726545d match: sort patterns before compiling them into a regex
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   648
    [b'', b'foo/a', b'', b'b']
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   649
    >>> m.exact(b'foo/a')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   650
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   651
    >>> m.exact(b'b')
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   652
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   653
    >>> m.exact(b'lib.h')  # exact matches are for (rel)path kinds
42081
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   654
    False
bf777c1e78dd match: add a docstring with doctest examples to patternmatcher
Denis Laxalde <denis@laxalde.org>
parents: 42080
diff changeset
   655
    """
32395
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32325
diff changeset
   656
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   657
    def __init__(self, root, kindpats, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   658
        super(patternmatcher, self).__init__(badfn)
50337
47686726545d match: sort patterns before compiling them into a regex
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   659
        kindpats.sort()
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
   660
51603
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   661
        if rustmod is not None:
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   662
            # We need to pass the patterns to Rust because they can contain
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   663
            # patterns from the user interface
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   664
            self._kindpats = kindpats
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   665
51569
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   666
        roots, dirs, parents = _rootsdirsandparents(kindpats)
32557
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32556
diff changeset
   667
        self._files = _explicitfiles(kindpats)
51569
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   668
        self._dirs_explicit = set(dirs)
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   669
        self._dirs = parents
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   670
        self._prefix = _prefix(kindpats)
50338
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   671
        self._pats, self._matchfn = _buildmatch(kindpats, b'$', root)
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   672
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   673
    def matchfn(self, fn):
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   674
        if fn in self._fileset:
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   675
            return True
81c7d04f4722 match: match explicit file using a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50337
diff changeset
   676
        return self._matchfn(fn)
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
   677
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   678
    def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   679
        if self._prefix and dir in self._fileset:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   680
            return b'all'
51569
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   681
        return (
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   682
            dir in self._dirs
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   683
            or path_or_parents_in_set(dir, self._fileset)
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   684
            or path_or_parents_in_set(dir, self._dirs_explicit)
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
   685
        )
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   686
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   687
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   688
        ret = self.visitdir(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   689
        if ret is True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   690
            return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   691
        elif not ret:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   692
            return set()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   693
        assert ret == b'all'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   694
        return b'all'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   695
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   696
    def prefix(self):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   697
        return self._prefix
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   698
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   699
    @encoding.strmethod
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
   700
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   701
        return b'<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   702
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   703
43523
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   704
# This is basically a reimplementation of pathutil.dirs that stores the
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   705
# children instead of just a count of them, plus a small optional optimization
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   706
# to avoid some directories we don't need.
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48941
diff changeset
   707
class _dirchildren:
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   708
    def __init__(self, paths, onlyinclude=None):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   709
        self._dirs = {}
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   710
        self._onlyinclude = onlyinclude or []
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   711
        addpath = self.addpath
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   712
        for f in paths:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   713
            addpath(f)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   714
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   715
    def addpath(self, path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   716
        if path == b'':
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   717
            return
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   718
        dirs = self._dirs
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   719
        findsplitdirs = _dirchildren._findsplitdirs
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   720
        for d, b in findsplitdirs(path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   721
            if d not in self._onlyinclude:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   722
                continue
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   723
            dirs.setdefault(d, set()).add(b)
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   724
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   725
    @staticmethod
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   726
    def _findsplitdirs(path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   727
        # yields (dirname, basename) tuples, walking back to the root.  This is
43633
0b7733719d21 utils: move finddirs() to pathutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43595
diff changeset
   728
        # very similar to pathutil.finddirs, except:
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   729
        #  - produces a (dirname, basename) tuple, not just 'dirname'
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   730
        # Unlike manifest._splittopdir, this does not suffix `dirname` with a
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
   731
        # slash.
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   732
        oldpos = len(path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   733
        pos = path.rfind(b'/')
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   734
        while pos != -1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   735
            yield path[:pos], path[pos + 1 : oldpos]
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   736
            oldpos = pos
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   737
            pos = path.rfind(b'/', 0, pos)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   738
        yield b'', path[:oldpos]
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   739
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   740
    def get(self, path):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   741
        return self._dirs.get(path, set())
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   742
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   743
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   744
class includematcher(basematcher):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   745
    def __init__(self, root, kindpats, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   746
        super(includematcher, self).__init__(badfn)
44530
4d1634e59f13 rust-status: use bare hg status fastpath from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 44452
diff changeset
   747
        if rustmod is not None:
4d1634e59f13 rust-status: use bare hg status fastpath from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 44452
diff changeset
   748
            # We need to pass the patterns to Rust because they can contain
4d1634e59f13 rust-status: use bare hg status fastpath from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 44452
diff changeset
   749
            # patterns from the user interface
4d1634e59f13 rust-status: use bare hg status fastpath from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 44452
diff changeset
   750
            self._kindpats = kindpats
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   751
        self._pats, self.matchfn = _buildmatch(kindpats, b'(?:/|$)', root)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   752
        self._prefix = _prefix(kindpats)
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
   753
        roots, dirs, parents = _rootsdirsandparents(kindpats)
32502
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32501
diff changeset
   754
        # roots are directories which are recursively included.
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
   755
        self._roots = set(roots)
32502
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32501
diff changeset
   756
        # dirs are directories which are non-recursively included.
32503
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32502
diff changeset
   757
        self._dirs = set(dirs)
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
   758
        # parents are directories which are non-recursively included because
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
   759
        # they are needed to get to items in _dirs or _roots.
42361
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
   760
        self._parents = parents
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   761
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   762
    def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   763
        if self._prefix and dir in self._roots:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   764
            return b'all'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   765
        return (
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   766
            dir in self._dirs
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   767
            or dir in self._parents
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   768
            or path_or_parents_in_set(dir, self._roots)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   769
        )
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   770
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   771
    @propertycache
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   772
    def _allparentschildren(self):
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   773
        # It may seem odd that we add dirs, roots, and parents, and then
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   774
        # restrict to only parents. This is to catch the case of:
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   775
        #   dirs = ['foo/bar']
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   776
        #   parents = ['foo']
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   777
        # if we asked for the children of 'foo', but had only added
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   778
        # self._parents, we wouldn't be able to respond ['bar'].
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   779
        return _dirchildren(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   780
            itertools.chain(self._dirs, self._roots, self._parents),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   781
            onlyinclude=self._parents,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   782
        )
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   783
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   784
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   785
        if self._prefix and dir in self._roots:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   786
            return b'all'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   787
        # Note: this does *not* include the 'dir in self._parents' case from
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   788
        # visitdir, that's handled below.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   789
        if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   790
            b'' in self._roots
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   791
            or dir in self._dirs
45999
c4c7a6b61146 match: skip walking up the directory hierarchy if the number of pats are small
Kyle Lippincott <spectral@google.com>
parents: 45946
diff changeset
   792
            or path_or_parents_in_set(dir, self._roots)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   793
        ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   794
            return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   795
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   796
        if dir in self._parents:
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   797
            return self._allparentschildren.get(dir) or set()
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
   798
        return set()
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   799
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   800
    @encoding.strmethod
32501
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   801
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   802
        return b'<includematcher includes=%r>' % pycompat.bytestr(self._pats)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   803
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32401
diff changeset
   804
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   805
class exactmatcher(basematcher):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   806
    r"""Matches the input files exactly. They are interpreted as paths, not
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   807
    patterns (so no kind-prefixes).
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   808
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
   809
    >>> m = exactmatcher([b'a.txt', br're:.*\.c$'])
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   810
    >>> m(b'a.txt')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   811
    True
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   812
    >>> m(b'b.txt')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   813
    False
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   814
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   815
    Input files that would be matched are exactly those returned by .files()
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   816
    >>> m.files()
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   817
    ['a.txt', 're:.*\\.c$']
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   818
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   819
    So pattern 're:.*\.c$' is not considered as a regex, but as a file name
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
   820
    >>> m(b'main.c')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   821
    False
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
   822
    >>> m(br're:.*\.c$')
42080
f3db5c805a67 match: add doctest examples for exactmatcher
Denis Laxalde <denis@laxalde.org>
parents: 41676
diff changeset
   823
    True
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   824
    """
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   825
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   826
    def __init__(self, files, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   827
        super(exactmatcher, self).__init__(badfn)
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   828
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   829
        if isinstance(files, list):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   830
            self._files = files
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   831
        else:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   832
            self._files = list(files)
32543
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32542
diff changeset
   833
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32542
diff changeset
   834
    matchfn = basematcher.exact
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   835
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   836
    @propertycache
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   837
    def _dirs(self):
43523
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   838
        return set(pathutil.dirs(self._fileset))
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   839
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   840
    def visitdir(self, dir):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   841
        return dir in self._dirs
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   842
46872
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   843
    @propertycache
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   844
    def _visitchildrenset_candidates(self):
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   845
        """A memoized set of candidates for visitchildrenset."""
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   846
        return self._fileset | self._dirs - {b''}
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   847
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   848
    @propertycache
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   849
    def _sorted_visitchildrenset_candidates(self):
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   850
        """A memoized sorted list of candidates for visitchildrenset."""
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   851
        return sorted(self._visitchildrenset_candidates)
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   852
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   853
    def visitchildrenset(self, dir):
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   854
        if not self._fileset or dir not in self._dirs:
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   855
            return set()
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   856
46872
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   857
        if dir == b'':
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   858
            candidates = self._visitchildrenset_candidates
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   859
        else:
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   860
            candidates = self._sorted_visitchildrenset_candidates
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   861
            d = dir + b'/'
46872
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   862
            # Use bisect to find the first element potentially starting with d
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   863
            # (i.e. >= d). This should always find at least one element (we'll
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   864
            # assert later if this is not the case).
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   865
            first = bisect.bisect_left(candidates, d)
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   866
            # We need a representation of the first element that is > d that
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   867
            # does not start with d, so since we added a `/` on the end of dir,
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   868
            # we'll add whatever comes after slash (we could probably assume
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   869
            # that `0` is after `/`, but let's not) to the end of dir instead.
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   870
            dnext = dir + encoding.strtolocal(chr(ord(b'/') + 1))
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   871
            # Use bisect to find the first element >= d_next
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   872
            last = bisect.bisect_left(candidates, dnext, lo=first)
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   873
            dlen = len(d)
8bca353b1ebc match: convert O(n) to O(log n) in exactmatcher.visitchildrenset
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   874
            candidates = {c[dlen:] for c in candidates[first:last]}
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   875
        # self._dirs includes all of the directories, recursively, so if
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
   876
        # we're attempting to match foo/bar/baz.txt, it'll have '', 'foo',
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   877
        # 'foo/bar' in it. Thus we can safely ignore a candidate that has a
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   878
        # '/' in it, indicating a it's for a subdir-of-a-subdir; the
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   879
        # immediate subdir will be in there without a slash.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   880
        ret = {c for c in candidates if b'/' not in c}
39261
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   881
        # We really do not expect ret to be empty, since that would imply that
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   882
        # there's something in _dirs that didn't have a file in _fileset.
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   883
        assert ret
c9a3f7f5c023 match: make exactmatcher.visitchildrenset return file children as well
Kyle Lippincott <spectral@google.com>
parents: 39260
diff changeset
   884
        return ret
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   885
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   886
    def isexact(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   887
        return True
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   888
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   889
    @encoding.strmethod
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   890
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   891
        return b'<exactmatcher files=%r>' % self._files
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   892
32499
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   893
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   894
class differencematcher(basematcher):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   895
    """Composes two matchers by matching if the first matches and the second
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35164
diff changeset
   896
    does not.
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   897
43715
5e1b0470cee7 match: remove explicitdir attribute
Martin von Zweigbergk <martinvonz@google.com>
parents: 43633
diff changeset
   898
    The second matcher's non-matching-attributes (bad, traversedir) are ignored.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   899
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   900
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   901
    def __init__(self, m1, m2):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   902
        super(differencematcher, self).__init__()
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   903
        self._m1 = m1
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   904
        self._m2 = m2
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   905
        self.bad = m1.bad
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   906
        self.traversedir = m1.traversedir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   907
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
   908
    def was_tampered_with(self) -> bool:
51625
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   909
        return (
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   910
            self.was_tampered_with_nonrec()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   911
            or self._m1.was_tampered_with()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   912
            or self._m2.was_tampered_with()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   913
        )
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   914
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   915
    def matchfn(self, f):
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35164
diff changeset
   916
        return self._m1(f) and not self._m2(f)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   917
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   918
    @propertycache
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   919
    def _files(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   920
        if self.isexact():
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   921
            return [f for f in self._m1.files() if self(f)]
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   922
        # If m1 is not an exact matcher, we can't easily figure out the set of
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   923
        # files, because its files() are not always files. For example, if
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   924
        # m1 is "path:dir" and m2 is "rootfileins:.", we don't
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   925
        # want to remove "dir" from the set even though it would match m2,
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   926
        # because the "dir" in m1 may not be a file.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   927
        return self._m1.files()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   928
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   929
    def visitdir(self, dir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   930
        if self._m2.visitdir(dir) == b'all':
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   931
            return False
41528
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
   932
        elif not self._m2.visitdir(dir):
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
   933
            # m2 does not match dir, we can return 'all' here if possible
b7a0efb3c370 match: teach diffmatcher.visitdir() to return 'all' if possible
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41282
diff changeset
   934
            return self._m1.visitdir(dir)
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   935
        return bool(self._m1.visitdir(dir))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   936
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   937
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   938
        m2_set = self._m2.visitchildrenset(dir)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   939
        if m2_set == b'all':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   940
            return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   941
        m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   942
        # Possible values for m1: 'all', 'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   943
        # Possible values for m2:        'this', set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   944
        # If m2 has nothing under here that we care about, return m1, even if
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   945
        # it's 'all'. This is a change in behavior from visitdir, which would
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   946
        # return True, not 'all', for some reason.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   947
        if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   948
            return m1_set
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   949
        if m1_set in [b'all', b'this']:
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   950
            # Never return 'all' here if m2_set is any kind of non-empty (either
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   951
            # 'this' or set(foo)), since m2 might return set() for a
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   952
            # subdirectory.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   953
            return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   954
        # Possible values for m1:         set(...), set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   955
        # Possible values for m2: 'this', set(...)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   956
        # We ignore m2's set results. They're possibly incorrect:
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
   957
        #  m1 = path:dir/subdir, m2=rootfilesin:dir, visitchildrenset(''):
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   958
        #    m1 returns {'dir'}, m2 returns {'dir'}, if we subtracted we'd
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   959
        #    return set(), which is *not* correct, we still need to visit 'dir'!
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   960
        return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
   961
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   962
    def isexact(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   963
        return self._m1.isexact()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   964
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   965
    @encoding.strmethod
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   966
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   967
        return b'<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   968
32465
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32464
diff changeset
   969
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   970
def intersectmatchers(m1, m2):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   971
    """Composes two matchers by matching if both of them match.
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   972
43715
5e1b0470cee7 match: remove explicitdir attribute
Martin von Zweigbergk <martinvonz@google.com>
parents: 43633
diff changeset
   973
    The second matcher's non-matching-attributes (bad, traversedir) are ignored.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
   974
    """
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   975
    if m1 is None or m2 is None:
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   976
        return m1 or m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   977
    if m1.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   978
        m = copy.copy(m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   979
        # TODO: Consider encapsulating these things in a class so there's only
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   980
        # one thing to copy from m1.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   981
        m.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   982
        m.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   983
        return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   984
    if m2.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   985
        m = copy.copy(m1)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   986
        return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   987
    return intersectionmatcher(m1, m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   988
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
   989
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   990
class intersectionmatcher(basematcher):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   991
    def __init__(self, m1, m2):
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
   992
        super(intersectionmatcher, self).__init__()
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   993
        self._m1 = m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   994
        self._m2 = m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   995
        self.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   996
        self.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
   997
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
   998
    def was_tampered_with(self) -> bool:
51625
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
   999
        return (
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1000
            self.was_tampered_with_nonrec()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1001
            or self._m1.was_tampered_with()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1002
            or self._m2.was_tampered_with()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1003
        )
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1004
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1005
    @propertycache
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1006
    def _files(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1007
        if self.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1008
            m1, m2 = self._m1, self._m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1009
            if not m1.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1010
                m1, m2 = m2, m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1011
            return [f for f in m1.files() if m2(f)]
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1012
        # It neither m1 nor m2 is an exact matcher, we can't easily intersect
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1013
        # the set of files, because their files() are not always files. For
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1014
        # example, if intersecting a matcher "-I glob:foo.txt" with matcher of
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1015
        # "path:dir2", we don't want to remove "dir2" from the set.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1016
        return self._m1.files() + self._m2.files()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1017
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1018
    def matchfn(self, f):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1019
        return self._m1(f) and self._m2(f)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1020
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1021
    def visitdir(self, dir):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1022
        visit1 = self._m1.visitdir(dir)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1023
        if visit1 == b'all':
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1024
            return self._m2.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1025
        # bool() because visit1=True + visit2='all' should not be 'all'
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1026
        return bool(visit1 and self._m2.visitdir(dir))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1027
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1028
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1029
        m1_set = self._m1.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1030
        if not m1_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1031
            return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1032
        m2_set = self._m2.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1033
        if not m2_set:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1034
            return set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1035
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1036
        if m1_set == b'all':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1037
            return m2_set
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1038
        elif m2_set == b'all':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1039
            return m1_set
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1040
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1041
        if m1_set == b'this' or m2_set == b'this':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1042
            return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1043
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1044
        assert isinstance(m1_set, set) and isinstance(m2_set, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1045
        return m1_set.intersection(m2_set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1046
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1047
    def always(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1048
        return self._m1.always() and self._m2.always()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1049
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1050
    def isexact(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1051
        return self._m1.isexact() or self._m2.isexact()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1052
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
  1053
    @encoding.strmethod
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1054
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1055
        return b'<intersectionmatcher m1=%r, m2=%r>' % (self._m1, self._m2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1056
32497
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32496
diff changeset
  1057
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1058
class subdirmatcher(basematcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1059
    """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1060
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1061
    The paths are remapped to remove/insert the path as needed:
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1062
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1063
    >>> from . import pycompat
44002
d9d78e70149a tests: fix failing doctest in match.py by adding dummy auditor
Martin von Zweigbergk <martinvonz@google.com>
parents: 43965
diff changeset
  1064
    >>> m1 = match(util.localpath(b'/root'), b'', [b'a.txt', b'sub/b.txt'], auditor=lambda name: None)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1065
    >>> m2 = subdirmatcher(b'sub', m1)
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1066
    >>> m2(b'a.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1067
    False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1068
    >>> m2(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1069
    True
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1070
    >>> m2.matchfn(b'a.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1071
    False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1072
    >>> m2.matchfn(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1073
    True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1074
    >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1075
    ['b.txt']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1076
    >>> m2.exact(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1077
    True
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
  1078
    >>> def bad(f, msg):
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1079
    ...     print(pycompat.sysstr(b"%s: %s" % (f, msg)))
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
  1080
    >>> m1.bad = bad
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1081
    >>> m2.bad(b'x.txt', b'No such file')
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
  1082
    sub/x.txt: No such file
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1083
    """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1084
51757
a1e4fa9330d8 typing: add type hints around the matcher for subrepo archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 51675
diff changeset
  1085
    def __init__(self, path: bytes, matcher: basematcher) -> None:
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
  1086
        super(subdirmatcher, self).__init__()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1087
        self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1088
        self._matcher = matcher
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1089
        self._always = matcher.always()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
  1090
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1091
        self._files = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1092
            f[len(path) + 1 :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1093
            for f in matcher._files
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1094
            if f.startswith(path + b"/")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1095
        ]
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
  1096
32325
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
  1097
        # If the parent repo had a path to this subrepo and the matcher is
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
  1098
        # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32324
diff changeset
  1099
        if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
  1100
            self._always = any(f == path for f in matcher._files)
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
  1101
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
  1102
    def was_tampered_with(self) -> bool:
51625
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1103
        return (
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1104
            self.was_tampered_with_nonrec() or self._matcher.was_tampered_with()
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1105
        )
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1106
32324
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
  1107
    def bad(self, f, msg):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1108
        self._matcher.bad(self._path + b"/" + f, msg)
32324
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32323
diff changeset
  1109
32464
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1110
    def matchfn(self, f):
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1111
        # Some information is lost in the superclass's constructor, so we
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1112
        # can not accurately create the matching function for the subdirectory
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1113
        # from the inputs. Instead, we override matchfn() and visitdir() to
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1114
        # call the original matcher with the subdirectory path prepended.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1115
        return self._matcher.matchfn(self._path + b"/" + f)
32464
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32463
diff changeset
  1116
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
  1117
    def visitdir(self, dir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1118
        if dir == b'':
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
  1119
            dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
  1120
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1121
            dir = self._path + b"/" + dir
32323
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
  1122
        return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32322
diff changeset
  1123
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1124
    def visitchildrenset(self, dir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1125
        if dir == b'':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1126
            dir = self._path
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1127
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1128
            dir = self._path + b"/" + dir
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1129
        return self._matcher.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1130
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1131
    def always(self):
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1132
        return self._always
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1133
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
  1134
    def prefix(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
  1135
        return self._matcher.prefix() and not self._always
32460
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32459
diff changeset
  1136
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
  1137
    @encoding.strmethod
32552
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
  1138
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1139
        return b'<subdirmatcher path=%r, matcher=%r>' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1140
            self._path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1141
            self._matcher,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1142
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1143
32552
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32543
diff changeset
  1144
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1145
class prefixdirmatcher(basematcher):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1146
    """Adapt a matcher to work on a parent directory.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1147
43715
5e1b0470cee7 match: remove explicitdir attribute
Martin von Zweigbergk <martinvonz@google.com>
parents: 43633
diff changeset
  1148
    The matcher's non-matching-attributes (bad, traversedir) are ignored.
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1149
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1150
    The prefix path should usually be the relative path from the root of
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1151
    this matcher to the root of the wrapped matcher.
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1152
43949
8b1a9ba375e5 match: make sure `root` argument is always an absolute path (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 43735
diff changeset
  1153
    >>> m1 = match(util.localpath(b'/root/d/e'), b'f', [b'../a.txt', b'b.txt'], auditor=lambda name: None)
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
  1154
    >>> m2 = prefixdirmatcher(b'd/e', m1)
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1155
    >>> m2(b'a.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1156
    False
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1157
    >>> m2(b'd/e/a.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1158
    True
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1159
    >>> m2(b'd/e/b.txt')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1160
    False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1161
    >>> m2.files()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1162
    ['d/e/a.txt', 'd/e/f/b.txt']
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1163
    >>> m2.exact(b'd/e/a.txt')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1164
    True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1165
    >>> m2.visitdir(b'd')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1166
    True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1167
    >>> m2.visitdir(b'd/e')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1168
    True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1169
    >>> m2.visitdir(b'd/e/f')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1170
    True
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1171
    >>> m2.visitdir(b'd/e/g')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1172
    False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1173
    >>> m2.visitdir(b'd/ef')
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1174
    False
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1175
    """
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1176
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
  1177
    def __init__(self, path, matcher, badfn=None):
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
  1178
        super(prefixdirmatcher, self).__init__(badfn)
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1179
        if not path:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1180
            raise error.ProgrammingError(b'prefix path must not be empty')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1181
        self._path = path
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1182
        self._pathprefix = path + b'/'
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1183
        self._matcher = matcher
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1184
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1185
    @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1186
    def _files(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1187
        return [self._pathprefix + f for f in self._matcher._files]
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1188
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1189
    def matchfn(self, f):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1190
        if not f.startswith(self._pathprefix):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1191
            return False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1192
        return self._matcher.matchfn(f[len(self._pathprefix) :])
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1193
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1194
    @propertycache
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1195
    def _pathdirs(self):
43633
0b7733719d21 utils: move finddirs() to pathutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43595
diff changeset
  1196
        return set(pathutil.finddirs(self._path))
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1197
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1198
    def visitdir(self, dir):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1199
        if dir == self._path:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1200
            return self._matcher.visitdir(b'')
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1201
        if dir.startswith(self._pathprefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1202
            return self._matcher.visitdir(dir[len(self._pathprefix) :])
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1203
        return dir in self._pathdirs
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1204
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1205
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1206
        if dir == self._path:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1207
            return self._matcher.visitchildrenset(b'')
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1208
        if dir.startswith(self._pathprefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1209
            return self._matcher.visitchildrenset(dir[len(self._pathprefix) :])
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1210
        if dir in self._pathdirs:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1211
            return b'this'
38958
b9f94d67ea73 match: add missing "return set()", add FIXME to test to doc a bug
Kyle Lippincott <spectral@google.com>
parents: 38957
diff changeset
  1212
        return set()
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1213
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1214
    def isexact(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1215
        return self._matcher.isexact()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1216
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1217
    def prefix(self):
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1218
        return self._matcher.prefix()
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1219
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1220
    @encoding.strmethod
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1221
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1222
        return b'<prefixdirmatcher path=%r, matcher=%r>' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1223
            pycompat.bytestr(self._path),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1224
            self._matcher,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1225
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1226
38611
0ba4cf3f088f match: add prefixdirmatcher to adapt subrepo matcher back
Yuya Nishihara <yuya@tcha.org>
parents: 38581
diff changeset
  1227
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1228
class unionmatcher(basematcher):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1229
    """A matcher that is the union of several matchers.
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1230
43715
5e1b0470cee7 match: remove explicitdir attribute
Martin von Zweigbergk <martinvonz@google.com>
parents: 43633
diff changeset
  1231
    The non-matching-attributes (bad, traversedir) are taken from the first
5e1b0470cee7 match: remove explicitdir attribute
Martin von Zweigbergk <martinvonz@google.com>
parents: 43633
diff changeset
  1232
    matcher.
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1233
    """
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1234
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1235
    def __init__(self, matchers):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1236
        m1 = matchers[0]
41675
ddbebce94665 match: delete unused root and cwd arguments to constructors (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41672
diff changeset
  1237
        super(unionmatcher, self).__init__()
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1238
        self.traversedir = m1.traversedir
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1239
        self._matchers = matchers
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1240
51675
bc94cbb49b30 typing: add some trivial type hints to `mercurial/match.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51625
diff changeset
  1241
    def was_tampered_with(self) -> bool:
51625
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1242
        return self.was_tampered_with_nonrec() or any(
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1243
            map(lambda m: m.was_tampered_with(), self._matchers)
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1244
        )
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51603
diff changeset
  1245
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
  1246
    def matchfn(self, f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1247
        for match in self._matchers:
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
  1248
            if match(f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1249
                return True
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1250
        return False
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1251
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1252
    def visitdir(self, dir):
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1253
        r = False
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1254
        for m in self._matchers:
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1255
            v = m.visitdir(dir)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1256
            if v == b'all':
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1257
                return v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1258
            r |= v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1259
        return r
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
  1260
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1261
    def visitchildrenset(self, dir):
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1262
        r = set()
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1263
        this = False
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1264
        for m in self._matchers:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1265
            v = m.visitchildrenset(dir)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1266
            if not v:
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1267
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1268
            if v == b'all':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1269
                return v
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1270
            if this or v == b'this':
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1271
                this = True
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1272
                # don't break, we might have an 'all' in here.
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1273
                continue
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1274
            assert isinstance(v, set)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1275
            r = r.union(v)
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1276
        if this:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1277
            return b'this'
38955
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1278
        return r
081cc9a95b65 match: add visitchildrenset complement to visitdir
spectral <spectral@google.com>
parents: 38954
diff changeset
  1279
36050
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
  1280
    @encoding.strmethod
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1281
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1282
        return b'<unionmatcher matchers=%r>' % self._matchers
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1283
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
  1284
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1285
def patkind(pattern, default=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1286
    r"""If pattern is 'kind:pat' with a known kind, return kind.
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
  1287
42186
fd384911f51b match: use raw strings to avoid illegal baskslash escape
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42099
diff changeset
  1288
    >>> patkind(br're:.*\.c$')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
  1289
    're'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
  1290
    >>> patkind(b'glob:*.c')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
  1291
    'glob'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
  1292
    >>> patkind(b'relpath:test.py')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
  1293
    'relpath'
42098
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
  1294
    >>> patkind(b'main.py')
5753e5949b51 py3: add b'' prefixes to new doctests in match.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42087
diff changeset
  1295
    >>> patkind(b'main.py', default=b're')
42082
413a75da98ce match: add doctest examples for patkind()
Denis Laxalde <denis@laxalde.org>
parents: 42081
diff changeset
  1296
    're'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1297
    """
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1298
    return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1299
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1300
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1301
def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1302
    """Split a string into the optional pattern kind prefix and the actual
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1303
    pattern."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1304
    if b':' in pattern:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1305
        kind, pat = pattern.split(b':', 1)
33684
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
  1306
        if kind in allpatternkinds:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1307
            return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1308
    return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1309
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1310
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
  1311
def _globre(pat):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1312
    r"""Convert an extended glob string to a regexp string.
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1313
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1314
    >>> from . import pycompat
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1315
    >>> def bprint(s):
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1316
    ...     print(pycompat.sysstr(s))
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1317
    >>> bprint(_globre(br'?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1318
    .
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1319
    >>> bprint(_globre(br'*'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1320
    [^/]*
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1321
    >>> bprint(_globre(br'**'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1322
    .*
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1323
    >>> bprint(_globre(br'**/a'))
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
  1324
    (?:.*/)?a
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1325
    >>> bprint(_globre(br'a/**/b'))
38475
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38019
diff changeset
  1326
    a/(?:.*/)?b
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1327
    >>> bprint(_globre(br'[a*?!^][^b][!c]'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1328
    [a*?!^][\^b][^c]
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1329
    >>> bprint(_globre(br'{a,b}'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1330
    (?:a|b)
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
  1331
    >>> bprint(_globre(br'.\*\?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
  1332
    \.\*\?
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1333
    """
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1334
    i, n = 0, len(pat)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1335
    res = b''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1336
    group = 0
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
  1337
    escape = util.stringutil.regexbytesescapemap.get
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1338
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
  1339
    def peek():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1340
        return i < n and pat[i : i + 1]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1341
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1342
    while i < n:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1343
        c = pat[i : i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
  1344
        i += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1345
        if c not in b'*?[{},\\':
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
  1346
            res += escape(c, c)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1347
        elif c == b'*':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1348
            if peek() == b'*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1349
                i += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1350
                if peek() == b'/':
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
  1351
                    i += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1352
                    res += b'(?:.*/)?'
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
  1353
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1354
                    res += b'.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1355
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1356
                res += b'[^/]*'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1357
        elif c == b'?':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1358
            res += b'.'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1359
        elif c == b'[':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1360
            j = i
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1361
            if j < n and pat[j : j + 1] in b'!]':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1362
                j += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1363
            while j < n and pat[j : j + 1] != b']':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1364
                j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1365
            if j >= n:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1366
                res += b'\\['
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1367
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1368
                stuff = pat[i:j].replace(b'\\', b'\\\\')
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1369
                i = j + 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1370
                if stuff[0:1] == b'!':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1371
                    stuff = b'^' + stuff[1:]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1372
                elif stuff[0:1] == b'^':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1373
                    stuff = b'\\' + stuff
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1374
                res = b'%s[%s]' % (res, stuff)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1375
        elif c == b'{':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1376
            group += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1377
            res += b'(?:'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1378
        elif c == b'}' and group:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1379
            res += b')'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1380
            group -= 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1381
        elif c == b',' and group:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1382
            res += b'|'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1383
        elif c == b'\\':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1384
            p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1385
            if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1386
                i += 1
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
  1387
                res += escape(p, p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1388
            else:
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
  1389
                res += escape(c, c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1390
        else:
40684
e6c9ef5e11a0 match: provide and use a quick way to escape a single byte
Boris Feld <boris.feld@octobus.net>
parents: 40345
diff changeset
  1391
            res += escape(c, c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
  1392
    return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
  1393
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1394
49645
c4874ebe8644 match: make the FLAG_RE pattern a raw string
Matt Harbison <matt_harbison@yahoo.com>
parents: 49605
diff changeset
  1395
FLAG_RE = util.re.compile(br'^\(\?([aiLmsux]+)\)(.*)')
49603
3eda36e9b3d6 matcher: fix issues regex flag contained in pattern (issue6759)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
  1396
3eda36e9b3d6 matcher: fix issues regex flag contained in pattern (issue6759)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
  1397
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1398
def _regex(kind, pat, globsuffix):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1399
    """Convert a (normalized) pattern of any kind into a
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
  1400
    regular expression.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1401
    globsuffix is appended to the regexp of globs."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1402
    if not pat and kind in (b'glob', b'relpath'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1403
        return b''
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1404
    if kind == b're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1405
        return pat
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1406
    if kind == b'filepath':
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1407
        raise error.ProgrammingError(
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1408
            "'filepath:' patterns should not be converted to a regex"
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1409
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1410
    if kind in (b'path', b'relpath'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1411
        if pat == b'.':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1412
            return b''
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1413
        return util.stringutil.reescape(pat) + b'(?:/|$)'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1414
    if kind == b'rootfilesin':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1415
        if pat == b'.':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1416
            escaped = b''
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1417
        else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1418
            # Pattern is a directory name.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1419
            escaped = util.stringutil.reescape(pat) + b'/'
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1420
        # Anything after the pattern must be a non-directory.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1421
        return escaped + b'[^/]+$'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1422
    if kind == b'relglob':
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
  1423
        globre = _globre(pat)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1424
        if globre.startswith(b'[^/]*'):
42864
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
  1425
            # When pat has the form *XYZ (common), make the returned regex more
72890d8f9860 match: simplify the regexps created for glob patterns
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42766
diff changeset
  1426
            # legible by returning the regex for **XYZ instead of **/*XYZ.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1427
            return b'.*' + globre[len(b'[^/]*') :] + globsuffix
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1428
        return b'(?:|.*/)' + globre + globsuffix
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1429
    if kind == b'relre':
49605
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1430
        flag = None
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1431
        m = FLAG_RE.match(pat)
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1432
        if m:
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1433
            flag, pat = m.groups()
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1434
        if not pat.startswith(b'^'):
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1435
            pat = b'.*' + pat
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1436
        if flag is not None:
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1437
            pat = br'(?%s:%s)' % (flag, pat)
b3480822a251 matcher: do not prepend '.*' to pattern using ^ after flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49603
diff changeset
  1438
        return pat
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1439
    if kind in (b'glob', b'rootglob'):
38578
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38577
diff changeset
  1440
        return _globre(pat) + globsuffix
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1441
    raise error.ProgrammingError(b'not a regex pattern: %s:%s' % (kind, pat))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1442
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1443
41669
a13268524c25 match: delete unused argument "listsubrepos" from _buildmatch()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41668
diff changeset
  1444
def _buildmatch(kindpats, globsuffix, root):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1445
    """Return regexp string and a matcher function for kindpats.
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1446
    globsuffix is appended to the regexp of globs."""
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1447
    matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1448
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1449
    subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1450
    if subincludes:
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1451
        submatchers = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1452
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1453
        def matchsubinclude(f):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1454
            for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1455
                if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1456
                    mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1457
                    if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1458
                        mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1459
                        submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1460
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1461
                    if mf(f[len(prefix) :]):
32132
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31433
diff changeset
  1462
                        return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1463
            return False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1464
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1465
        matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
  1466
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1467
    regex = b''
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1468
    if kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1469
        if all(k == b'rootfilesin' for k, p, s in kindpats):
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1470
            dirs = {p for k, p, s in kindpats}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1471
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1472
            def mf(f):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1473
                i = f.rfind(b'/')
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1474
                if i >= 0:
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1475
                    dir = f[:i]
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1476
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1477
                    dir = b'.'
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1478
                return dir in dirs
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1479
40345
d30a19d10441 match: fix up a repr to not crash on Python 3
Augie Fackler <augie@google.com>
parents: 40242
diff changeset
  1480
            regex = b'rootfilesin: %s' % stringutil.pprint(list(sorted(dirs)))
40242
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1481
            matchfuncs.append(mf)
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1482
        else:
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1483
            regex, mf = _buildregexmatch(kindpats, globsuffix)
19ed212de2d1 match: optimize matcher when all patterns are of rootfilesin kind
Martin von Zweigbergk <martinvonz@google.com>
parents: 39460
diff changeset
  1484
            matchfuncs.append(mf)
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1485
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1486
    if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1487
        return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1488
    else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
  1489
        return regex, lambda f: any(mf(f) for mf in matchfuncs)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
  1490
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1491
40774
8306dac48061 match: extract a literal constant into a symbolic one
Boris Feld <boris.feld@octobus.net>
parents: 40757
diff changeset
  1492
MAX_RE_SIZE = 20000
8306dac48061 match: extract a literal constant into a symbolic one
Boris Feld <boris.feld@octobus.net>
parents: 40757
diff changeset
  1493
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1494
40776
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
  1495
def _joinregexes(regexps):
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
  1496
    """gather multiple regular expressions into a single one"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1497
    return b'|'.join(regexps)
40776
ce401300f981 match: extract function that group regexps
Boris Feld <boris.feld@octobus.net>
parents: 40775
diff changeset
  1498
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1499
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1500
def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
  1501
    """Build a match function from a list of kinds and kindpats,
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1502
    return regexp string and a matcher function.
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1503
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1504
    Test too large input
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1505
    >>> _buildregexmatch([
40947
9e462fb88f79 match: fix doctest to use bytes instead of str
Augie Fackler <augie@google.com>
parents: 40782
diff changeset
  1506
    ...     (b'relglob', b'?' * MAX_RE_SIZE, b'')
9e462fb88f79 match: fix doctest to use bytes instead of str
Augie Fackler <augie@google.com>
parents: 40782
diff changeset
  1507
    ... ], b'$')
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1508
    Traceback (most recent call last):
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1509
    ...
40778
69bd3176da7c match: raise an Abort error instead of OverflowError
Boris Feld <boris.feld@octobus.net>
parents: 40777
diff changeset
  1510
    Abort: matcher pattern is too long (20009 bytes)
40775
4e02f25f31c6 match: test for overflow error in pattern
Boris Feld <boris.feld@octobus.net>
parents: 40774
diff changeset
  1511
    """
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1512
    try:
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1513
        allgroups = []
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1514
        regexps = []
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1515
        exact = set()
51569
b32c3146ec34 match: fix the "visitdir" method on "rootfilesin" matchers
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50695
diff changeset
  1516
        for kind, pattern, _source in kindpats:
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1517
            if kind == b'filepath':
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1518
                exact.add(pattern)
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1519
                continue
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1520
            regexps.append(_regex(kind, pattern, globsuffix))
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1521
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1522
        fullregexp = _joinregexes(regexps)
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1523
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1524
        startidx = 0
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
  1525
        groupsize = 0
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1526
        for idx, r in enumerate(regexps):
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1527
            piecesize = len(r)
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
  1528
            if piecesize > MAX_RE_SIZE:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1529
                msg = _(b"matcher pattern is too long (%d bytes)") % piecesize
40778
69bd3176da7c match: raise an Abort error instead of OverflowError
Boris Feld <boris.feld@octobus.net>
parents: 40777
diff changeset
  1530
                raise error.Abort(msg)
40780
1e019f45fa88 match: make "groupsize" include the trailing "|"
Martin von Zweigbergk <martinvonz@google.com>
parents: 40779
diff changeset
  1531
            elif (groupsize + piecesize) > MAX_RE_SIZE:
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1532
                group = regexps[startidx:idx]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1533
                allgroups.append(_joinregexes(group))
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1534
                startidx = idx
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
  1535
                groupsize = 0
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1536
            groupsize += piecesize + 1
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1537
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1538
        if startidx == 0:
42087
2e2699af5649 match: let regex match function return a boolean
Denis Laxalde <denis@laxalde.org>
parents: 42086
diff changeset
  1539
            matcher = _rematcher(fullregexp)
42099
bccb322f1496 match: fix re2 compability broken in 2e2699af5649
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42098
diff changeset
  1540
            func = lambda s: bool(matcher(s))
40777
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1541
        else:
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1542
            group = regexps[startidx:]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1543
            allgroups.append(_joinregexes(group))
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1544
            allmatchers = [_rematcher(g) for g in allgroups]
3c842749debc match: avoid translating glob to matcher multiple times for large sets
Boris Feld <boris.feld@octobus.net>
parents: 40776
diff changeset
  1545
            func = lambda s: any(m(s) for m in allmatchers)
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1546
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1547
        actualfunc = func
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1548
        if exact:
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1549
            # An empty regex will always match, so only call the regex if
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1550
            # there were any actual patterns to match.
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1551
            if not regexps:
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1552
                actualfunc = lambda s: s in exact
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1553
            else:
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1554
                actualfunc = lambda s: s in exact or func(s)
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1555
        return fullregexp, actualfunc
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1556
    except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
  1557
        for k, p, s in kindpats:
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1558
            if k == b'filepath':
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1559
                continue
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1560
            try:
40782
3984409e144b match: drop unnecessary wrapping of regex in group
Martin von Zweigbergk <martinvonz@google.com>
parents: 40781
diff changeset
  1561
                _rematcher(_regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1562
            except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
  1563
                if s:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1564
                    raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1565
                        _(b"%s: invalid pattern (%s): %s") % (s, k, p)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1566
                    )
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
  1567
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1568
                    raise error.Abort(_(b"invalid pattern (%s): %s") % (k, p))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1569
        raise error.Abort(_(b"invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
  1570
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1571
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1572
def _patternrootsanddirs(kindpats):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1573
    """Returns roots and directories corresponding to each pattern.
21079
b02ab6486a78 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com>
parents: 20401
diff changeset
  1574
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1575
    This calculates the roots and directories exactly matching the patterns and
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1576
    returns a tuple of (roots, dirs) for each. It does not return other
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1577
    directories which may also need to be considered, like the parent
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1578
    directories.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1579
    """
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
  1580
    r = []
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1581
    d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
  1582
    for kind, pat, source in kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1583
        if kind in (b'glob', b'rootglob'):  # find the non-glob prefix
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
  1584
            root = []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1585
            for p in pat.split(b'/'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1586
                if b'[' in p or b'{' in p or b'*' in p or b'?' in p:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
  1587
                    break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
  1588
                root.append(p)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1589
            r.append(b'/'.join(root))
50695
1c31b343e514 match: add `filepath:` pattern to match an exact filepath relative to the root
Raphaël Gomès <rgomes@octobus.net>
parents: 50338
diff changeset
  1590
        elif kind in (b'relpath', b'path', b'filepath'):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1591
            if pat == b'.':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1592
                pat = b''
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
  1593
            r.append(pat)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1594
        elif kind in (b'rootfilesin',):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1595
            if pat == b'.':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1596
                pat = b''
42341
27d6956d386b match: use '' instead of '.' for root directory (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42329
diff changeset
  1597
            d.append(pat)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1598
        else:  # relglob, re, relre
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1599
            r.append(b'')
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1600
    return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1601
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1602
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1603
def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1604
    '''Returns root directories to match recursively from the given patterns.'''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1605
    roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1606
    return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1607
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1608
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
  1609
def _rootsdirsandparents(kindpats):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1610
    """Returns roots and exact directories from patterns.
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1611
38957
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
  1612
    `roots` are directories to match recursively, `dirs` should
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
  1613
    be matched non-recursively, and `parents` are the implicitly required
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
  1614
    directories to walk to items in either roots or dirs.
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
  1615
f356be1a7ba3 match: correct doc for _rootsdirsandparents after 5a7df82de142
Kyle Lippincott <spectral@google.com>
parents: 38955
diff changeset
  1616
    Returns a tuple of (roots, dirs, parents).
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1617
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1618
    >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1619
    ...     [(b'glob', b'g/h/*', b''), (b'glob', b'g/h', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1620
    ...      (b'glob', b'g*', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1621
    >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1622
    (['g/h', 'g/h', ''], []) ['', 'g']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1623
    >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1624
    ...     [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1625
    >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1626
    ([], ['g/h', '']) ['', 'g']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1627
    >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1628
    ...     [(b'relpath', b'r', b''), (b'path', b'p/p', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1629
    ...      (b'path', b'', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1630
    >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1631
    (['r', 'p/p', ''], []) ['', 'p']
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1632
    >>> r = _rootsdirsandparents(
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1633
    ...     [(b'relglob', b'rg*', b''), (b're', b're/', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1634
    ...      (b'relre', b'rr', b'')])
42367
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1635
    >>> print(r[0:2], sorted(r[2])) # the set has an unstable output
96fc696a9cb2 match: stabilize _rootsdirsandparents doctest
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42362
diff changeset
  1636
    (['', '', ''], []) ['']
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1637
    """
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1638
    r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1639
42361
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
  1640
    p = set()
c4b8f8637d7a match: de-flake test-doctest.py by not depending on util.dirs() order
Martin von Zweigbergk <martinvonz@google.com>
parents: 42346
diff changeset
  1641
    # Add the parents as non-recursive/exact directories, since they must be
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1642
    # scanned to get to either the roots or the other exact directories.
43523
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
  1643
    p.update(pathutil.dirs(d))
c21aca51b392 utils: move the `dirs` definition in pathutil (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
  1644
    p.update(pathutil.dirs(r))
31013
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31012
diff changeset
  1645
39460
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
  1646
    # FIXME: all uses of this function convert these to sets, do so before
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
  1647
    # returning.
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
  1648
    # FIXME: all uses of this function do not need anything in 'roots' and
35ecaa999a12 match: improve includematcher.visitchildrenset to be much faster and cached
Kyle Lippincott <spectral@google.com>
parents: 39261
diff changeset
  1649
    # 'dirs' to also be in 'parents', consider removing them before returning.
38954
5a7df82de142 includematcher: separate "parents" from "dirs"
spectral <spectral@google.com>
parents: 38750
diff changeset
  1650
    return r, d, p
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
  1651
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1652
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1653
def _explicitfiles(kindpats):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1654
    """Returns the potential explicit filenames from the patterns.
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1655
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1656
    >>> _explicitfiles([(b'path', b'foo/bar', b'')])
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1657
    ['foo/bar']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33684
diff changeset
  1658
    >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1659
    []
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1660
    """
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1661
    # Keep only the pattern kinds where one can specify filenames (vs only
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1662
    # directory names).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1663
    filable = [kp for kp in kindpats if kp[0] not in (b'rootfilesin',)]
31012
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1664
    return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30399
diff changeset
  1665
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1666
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
  1667
def _prefix(kindpats):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
  1668
    '''Whether all the patterns match a prefix (i.e. recursively)'''
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
  1669
    for kind, pat, source in kindpats:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1670
        if kind not in (b'path', b'relpath'):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
  1671
            return False
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
  1672
    return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1673
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1674
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1675
_commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1676
51926
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1677
if typing.TYPE_CHECKING:
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1678
    from typing_extensions import (
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1679
        Literal,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1680
    )
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1681
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1682
    @overload
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1683
    def readpatternfile(
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1684
        filepath: bytes, warn: Callable[[bytes], Any], sourceinfo: Literal[True]
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1685
    ) -> List[Tuple[bytes, int, bytes]]:
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1686
        ...
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1687
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1688
    @overload
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1689
    def readpatternfile(
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1690
        filepath: bytes,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1691
        warn: Callable[[bytes], Any],
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1692
        sourceinfo: Literal[False],
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1693
    ) -> List[bytes]:
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1694
        ...
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1695
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1696
    @overload
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1697
    def readpatternfile(
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1698
        filepath: bytes,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1699
        warn: Callable[[bytes], Any],
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1700
        sourceinfo: bool = False,
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1701
    ) -> List[Union[Tuple[bytes, int, bytes], bytes]]:
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1702
        ...
70fe33bdab54 typing: add type hints for the overloads of `matchmod.readpatternfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1703
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1704
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1705
def readpatternfile(filepath, warn, sourceinfo=False):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1706
    """parse a pattern file, returning a list of
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1707
    patterns. These patterns should be given to compile()
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1708
    to be validated and converted into a match function.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1709
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1710
    trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1711
    the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1712
    comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1713
    empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1714
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1715
    lines can be of the following formats:
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1716
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1717
    syntax: regexp # defaults following lines to non-rooted regexps
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1718
    syntax: glob   # defaults following lines to non-rooted globs
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1719
    re:pattern     # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1720
    glob:pattern   # non-rooted glob
41282
4fab8a7d2d72 match: support rooted globs in hgignore
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 41129
diff changeset
  1721
    rootglob:pat   # rooted glob (same root as ^ in regexps)
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1722
    pattern        # pattern of the current default type
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1723
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1724
    if sourceinfo is set, returns a list of tuples:
42329
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
  1725
    (pattern, lineno, originalline).
c7652f7440d9 rust-filepatterns: call new Rust implementations from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42195
diff changeset
  1726
    This is useful to debug ignore patterns.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45682
diff changeset
  1727
    """
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1728
40685
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
  1729
    syntaxes = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1730
        b're': b'relre:',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1731
        b'regexp': b'relre:',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1732
        b'glob': b'relglob:',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1733
        b'rootglob': b'rootglob:',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1734
        b'include': b'include',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1735
        b'subinclude': b'subinclude',
40685
e41f6c2e69c4 match: reformat `syntaxes` dictionary for better maintainability
Boris Feld <boris.feld@octobus.net>
parents: 40684
diff changeset
  1736
    }
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1737
    syntax = b'relre:'
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1738
    patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1739
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1740
    fp = open(filepath, b'rb')
48941
fd5b8e696b75 py3: stop using util.iterfile()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1741
    for lineno, line in enumerate(fp, start=1):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1742
        if b"#" in line:
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1743
            global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1744
            if not _commentre:
31420
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31403
diff changeset
  1745
                _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1746
            # remove comments prefixed by an even number of escapes
27327
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
  1747
            m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
  1748
            if m:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1749
                line = line[: m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1750
            # fixup properly escaped comments that survived the above
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1751
            line = line.replace(b"\\#", b"#")
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1752
        line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1753
        if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1754
            continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1755
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1756
        if line.startswith(b'syntax:'):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1757
            s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1758
            try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1759
                syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1760
            except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
  1761
                if warn:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1762
                    warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1763
                        _(b"%s: ignoring invalid syntax '%s'\n") % (filepath, s)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1764
                    )
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1765
            continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1766
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1767
        linesyntax = syntax
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48884
diff changeset
  1768
        for s, rels in syntaxes.items():
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1769
            if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1770
                linesyntax = rels
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1771
                line = line[len(rels) :]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1772
                break
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1773
            elif line.startswith(s + b':'):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1774
                linesyntax = rels
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42864
diff changeset
  1775
                line = line[len(s) + 1 :]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1776
                break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1777
        if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1778
            patterns.append((linesyntax + line, lineno, line))
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1779
        else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1780
            patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1781
    fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1782
    return patterns