annotate mercurial/match.py @ 32433:24245b54aa8a

match: replace match class by match function (API) The matcher class is getting hard to understand. It will be easier to follow if we can break it up into simpler matchers that we then compose. I'm hoping to have one matcher that accepts regular (non-include) patterns, one for exact file matches, one that always matches (and maybe one that never does) and then compose them by intersection and difference. This patch takes a simple but important step towards that goal by making match.match() a function (and renaming the matcher class itself from "match" to "matcher"). The new function will eventually be responsible for creating the simple matchers and composing them. icasefsmatcher similarly gets a factory function (called "icasefsmatch"). I also moved the other factory functions nearby.
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 12 May 2017 23:11:41 -0700
parents 763d72925691
children ec0311a3a4da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 #
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
3 # Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
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
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
8 from __future__ import absolute_import
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
9
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
10 import copy
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
11 import os
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
12 import re
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
13
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
14 from .i18n import _
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
15 from . import (
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
16 error,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
17 pathutil,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
18 util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
19 )
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
21 propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
22
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
23 def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
24 '''compile the regexp with the best available regexp engine and return a
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
25 matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
26 m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
27 try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
28 # 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
29 return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
30 except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
31 return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
32
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
33 def _expandsets(kindpats, ctx, listsubrepos):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
34 '''Returns the kindpats list with the 'set' patterns expanded.'''
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
35 fset = set()
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
36 other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
37
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
38 for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
39 if kind == 'set':
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
40 if not ctx:
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 28128
diff changeset
41 raise error.Abort(_("fileset expression with no context"))
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
42 s = ctx.getfileset(pat)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
43 fset.update(s)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
44
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
45 if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
46 for subpath in ctx.substate:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
47 s = ctx.sub(subpath).getfileset(pat)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
48 fset.update(subpath + '/' + f for f in s)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
49
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
50 continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
51 other.append((kind, pat, source))
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
52 return fset, other
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
53
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
54 def _expandsubinclude(kindpats, root):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
55 '''Returns the list of subinclude matcher args and the kindpats without the
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
56 subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
57 relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
58 other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
59
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
60 for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
61 if kind == 'subinclude':
25301
caaf4045eca8 match: normpath the ignore source when expanding the 'subinclude' kind
Matt Harbison <matt_harbison@yahoo.com>
parents: 25283
diff changeset
62 sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
63 pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
64 path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
65
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
66 newroot = pathutil.dirname(path)
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
67 matcherargs = (newroot, '', [], ['include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
68
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
69 prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
70 if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
71 prefix += '/'
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
72 relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
73 else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
74 other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
75
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
76 return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
77
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
78 def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
79 """"Checks whether the kindspats match everything, as e.g.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
80 'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
81 """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
82 for kind, pat, source in kindpats:
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
83 if pat != '' or kind not in ['relpath', 'glob']:
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
84 return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
85 return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
86
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
87 def match(root, cwd, patterns, include=None, exclude=None, default='glob',
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
88 exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
89 badfn=None):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
90 """build an object to match a set of file patterns
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
91
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
92 arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
93 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: 32365
diff changeset
94 cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
95 patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
96 include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
97 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: 32365
diff changeset
98 default - if a pattern in patterns has no explicit type, assume this one
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
99 exact - patterns are actually filenames (include/exclude still apply)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
100 warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
101 badfn - optional bad() callback for this matcher instead of the default
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
102
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
103 a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
104 'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
105 're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
106 '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: 32365
diff changeset
107 recursively
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
108 '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: 32365
diff changeset
109 matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
110 '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: 32365
diff changeset
111 'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
112 '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: 32365
diff changeset
113 'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
114 '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: 32365
diff changeset
115 '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: 32365
diff changeset
116 the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
117 '<something>' - a pattern of the specified default type
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
118 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
119 return matcher(root, cwd, patterns, include=include, exclude=exclude,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
120 default=default, exact=exact, auditor=auditor, ctx=ctx,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
121 listsubrepos=listsubrepos, warn=warn, badfn=badfn)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
122
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
123 def icasefsmatch(root, cwd, patterns, include=None, exclude=None,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
124 default='glob', auditor=None, ctx=None,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
125 listsubrepos=False, badfn=None):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
126 """A matcher for wdir on case insensitive filesystems, which normalizes the
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
127 given patterns to the case in the filesystem.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
128 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
129 return icasefsmatcher(root, cwd, patterns, include=include, exclude=exclude,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
130 default=default, auditor=auditor, ctx=ctx,
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
131 listsubrepos=listsubrepos, badfn=badfn)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
132
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
133 def exact(root, cwd, files, badfn=None):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
134 return match(root, cwd, files, exact=True, badfn=badfn)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
135
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
136 def always(root, cwd):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
137 return match(root, cwd, [])
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
138
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
139 def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
140 """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: 32365
diff changeset
141 one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
142 """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
143 m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
144 m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
145 return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
146
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
147 class matcher(object):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
148
31401
6168d4b93634 match: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31033
diff changeset
149 def __init__(self, root, cwd, patterns, include=None, exclude=None,
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
150 default='glob', exact=False, auditor=None, ctx=None,
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
151 listsubrepos=False, warn=None, badfn=None):
31442
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31430
diff changeset
152 if include is None:
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31430
diff changeset
153 include = []
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31430
diff changeset
154 if exclude is None:
7aac35ada1cb match: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31430
diff changeset
155 exclude = []
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
156
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
157 self._root = root
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
158 self._cwd = cwd
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
159 self._files = [] # exact files and roots of patterns
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
160 self._anypats = bool(include or exclude)
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
161 self._always = False
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
162 self._pathrestricted = bool(include or exclude or patterns)
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
163 self._warn = warn
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
164
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
165 # roots are directories which are recursively included/excluded.
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
166 self._includeroots = set()
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
167 self._excluderoots = set()
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
168 # dirs are directories which are non-recursively included.
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
169 self._includedirs = set()
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
170
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
171 if badfn is not None:
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
172 self.bad = badfn
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
173
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
174 matchfns = []
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
175 if include:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
176 kindpats = self._normalize(include, 'glob', root, cwd, auditor)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
177 self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
178 listsubrepos, root)
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
179 roots, dirs = _rootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
180 self._includeroots.update(roots)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
181 self._includedirs.update(dirs)
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
182 matchfns.append(im)
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
183 if exclude:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
184 kindpats = self._normalize(exclude, 'glob', root, cwd, auditor)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
185 self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
186 listsubrepos, root)
25362
20ad936ac5d2 treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25301
diff changeset
187 if not _anypats(kindpats):
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
188 # Only consider recursive excludes as such - if a non-recursive
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
189 # exclude is used, we must still recurse into the excluded
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
190 # directory, at least to find subdirectories. In such a case,
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
191 # the regex still won't match the non-recursively-excluded
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
192 # files.
25362
20ad936ac5d2 treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25301
diff changeset
193 self._excluderoots.update(_roots(kindpats))
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
194 matchfns.append(lambda f: not em(f))
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
195 if exact:
16789
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
196 if isinstance(patterns, list):
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
197 self._files = patterns
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
198 else:
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
199 self._files = list(patterns)
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
200 matchfns.append(self.exact)
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
201 elif patterns:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
202 kindpats = self._normalize(patterns, default, root, cwd, auditor)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
203 if not _kindpatsalwaysmatch(kindpats):
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
204 self._files = _explicitfiles(kindpats)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
205 self._anypats = self._anypats or _anypats(kindpats)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
206 self.patternspat, pm = _buildmatch(ctx, kindpats, '$',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
207 listsubrepos, root)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
208 matchfns.append(pm)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
209
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
210 if not matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
211 m = util.always
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
212 self._always = True
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
213 elif len(matchfns) == 1:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
214 m = matchfns[0]
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
215 else:
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
216 def m(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
217 for matchfn in matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
218 if not matchfn(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
219 return False
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
220 return True
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
221
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
222 self.matchfn = m
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
223
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
224 def __call__(self, fn):
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
225 return self.matchfn(fn)
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
226 def __iter__(self):
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
227 for f in self._files:
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
228 yield f
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
229
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
230 # Callbacks related to how the matcher is used by dirstate.walk.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
231 # Subscribers to these events must monkeypatch the matcher object.
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
232 def bad(self, f, msg):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
233 '''Callback from dirstate.walk for each explicit file that can't be
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
234 found/accessed, with an error message.'''
8680
b6511055d37b match: ignore return of match.bad
Matt Mackall <mpm@selenic.com>
parents: 8678
diff changeset
235 pass
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
236
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
237 # If an explicitdir is set, it will be called when an explicitly listed
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
238 # directory is visited.
19143
3cb9468535bd match: make explicitdir and traversedir None by default
Siddharth Agarwal <sid0@fb.com>
parents: 19141
diff changeset
239 explicitdir = None
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
240
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
241 # If an traversedir is set, it will be called when a directory discovered
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
242 # by recursive traversal is visited.
19143
3cb9468535bd match: make explicitdir and traversedir None by default
Siddharth Agarwal <sid0@fb.com>
parents: 19141
diff changeset
243 traversedir = None
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
244
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
245 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
246 '''Convert a repo path back to path that is relative to the root of the
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
247 matcher.'''
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
248 return f
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
249
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
250 def rel(self, f):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
251 '''Convert repo path back to path that is relative to cwd of matcher.'''
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
252 return util.pathto(self._root, self._cwd, f)
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
253
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
254 def uipath(self, f):
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
255 '''Convert repo path to a display path. If patterns or -I/-X were used
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
256 to create this matcher, the display path will be relative to cwd.
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
257 Otherwise it is relative to the root of the repo.'''
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
258 return (self._pathrestricted and self.rel(f)) or self.abs(f)
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
259
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
260 def files(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
261 '''Explicitly listed files or patterns or roots:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
262 if no patterns or .always(): empty list,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
263 if exact: list exact files,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
264 if not .anypats(): list all files and dirs,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
265 else: optimal roots'''
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
266 return self._files
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
267
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
268 @propertycache
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
269 def _fileset(self):
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
270 return set(self._files)
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
271
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
272 @propertycache
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
273 def _dirs(self):
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
274 return set(util.dirs(self._fileset)) | {'.'}
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
275
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
276 def visitdir(self, dir):
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
277 '''Decides whether a directory should be visited based on whether it
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
278 has potential matches in it or one of its subdirectories. This is
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
279 based on the match's primary, included, and excluded patterns.
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
280
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
281 Returns the string 'all' if the given directory and all subdirectories
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
282 should be visited. Otherwise returns True or False indicating whether
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
283 the given directory should be visited.
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
284
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
285 This function's behavior is undefined if it has returned False for
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
286 one of the dir's parent directories.
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
287 '''
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
288 if self.prefix() and dir in self._fileset:
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
289 return 'all'
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
290 if dir in self._excluderoots:
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
291 return False
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
292 if ((self._includeroots or self._includedirs) and
25579
b76410eed482 match: don't remove '.' from _includeroots
Martin von Zweigbergk <martinvonz@google.com>
parents: 25578
diff changeset
293 '.' not in self._includeroots and
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
294 dir not in self._includeroots and
25578
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
295 dir not in self._includedirs and
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
296 not any(parent in self._includeroots
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
297 for parent in util.finddirs(dir))):
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
298 return False
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
299 return (not self._fileset or
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
300 '.' in self._fileset or
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
301 dir in self._fileset or
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
302 dir in self._dirs or
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
303 any(parentdir in self._fileset
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
304 for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
305
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
306 def exact(self, f):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
307 '''Returns True if f is in .files().'''
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
308 return f in self._fileset
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
309
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
310 def anypats(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
311 '''Matcher uses patterns or include/exclude.'''
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
312 return self._anypats
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
313
16645
9a21fc2c7d32 localrepo: optimize internode status calls using match.always
Jesse Glick <jesse.glick@oracle.com>
parents: 16182
diff changeset
314 def always(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
315 '''Matcher will match everything and .files() will be empty
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
316 - optimization might be possible and necessary.'''
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
317 return self._always
8568
4fa1618bf495 match: refactor patkind
Matt Mackall <mpm@selenic.com>
parents: 8567
diff changeset
318
24448
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
319 def isexact(self):
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
320 return self.matchfn == self.exact
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
321
25233
9789b4a7c595 match: introduce boolean prefix() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 25231
diff changeset
322 def prefix(self):
9789b4a7c595 match: introduce boolean prefix() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 25231
diff changeset
323 return not self.always() and not self.isexact() and not self.anypats()
9789b4a7c595 match: introduce boolean prefix() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 25231
diff changeset
324
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
325 def _normalize(self, patterns, default, root, cwd, auditor):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
326 '''Convert 'kind:pat' from the patterns list to tuples with kind and
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
327 normalized and rooted patterns and with listfiles expanded.'''
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
328 kindpats = []
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
329 for kind, pat in [_patsplit(p, default) for p in patterns]:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
330 if kind in ('glob', 'relpath'):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
331 pat = pathutil.canonpath(root, cwd, pat, auditor)
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
332 elif kind in ('relglob', 'path', 'rootfilesin'):
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
333 pat = util.normpath(pat)
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
334 elif kind in ('listfile', 'listfile0'):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
335 try:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
336 files = util.readfile(pat)
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
337 if kind == 'listfile0':
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
338 files = files.split('\0')
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
339 else:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
340 files = files.splitlines()
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
341 files = [f for f in files if f]
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
342 except EnvironmentError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
343 raise error.Abort(_("unable to read file list (%s)") % pat)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
344 for k, p, source in self._normalize(files, default, root, cwd,
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
345 auditor):
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
346 kindpats.append((k, p, pat))
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
347 continue
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
348 elif kind == 'include':
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
349 try:
25875
511e1949d557 ignore: fix path concatenation of .hgignore on Windows
Yuya Nishihara <yuya@tcha.org>
parents: 25870
diff changeset
350 fullpath = os.path.join(root, util.localpath(pat))
25870
3de48ff62733 ignore: fix include: rules depending on current directory (issue4759)
Durham Goode <durham@fb.com>
parents: 25662
diff changeset
351 includepats = readpatternfile(fullpath, self._warn)
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
352 for k, p, source in self._normalize(includepats, default,
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
353 root, cwd, auditor):
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
354 kindpats.append((k, p, source or pat))
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
355 except error.Abort as inst:
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
356 raise error.Abort('%s: %s' % (pat, inst[0]))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25579
diff changeset
357 except IOError as inst:
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
358 if self._warn:
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
359 self._warn(_("skipping unreadable pattern file "
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
360 "'%s': %s\n") % (pat, inst.strerror))
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
361 continue
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
362 # else: re or relre - which cannot be normalized
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
363 kindpats.append((kind, pat, ''))
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
364 return kindpats
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
365
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
366 class subdirmatcher(matcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
367 """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
368
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
369 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
370
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
371 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
28017
d3f1b7ee5e70 match: rename "narrowmatcher" to "subdirmatcher" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27595
diff changeset
372 >>> m2 = subdirmatcher('sub', m1)
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
373 >>> bool(m2('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
374 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
375 >>> bool(m2('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
376 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
377 >>> bool(m2.matchfn('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
378 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
379 >>> bool(m2.matchfn('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
380 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
381 >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
382 ['b.txt']
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
383 >>> m2.exact('b.txt')
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
384 True
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
385 >>> util.pconvert(m2.rel('b.txt'))
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
386 'sub/b.txt'
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
387 >>> def bad(f, msg):
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
388 ... print "%s: %s" % (f, msg)
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
389 >>> m1.bad = bad
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
390 >>> m2.bad('x.txt', 'No such file')
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
391 sub/x.txt: No such file
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
392 >>> m2.abs('c.txt')
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
393 'sub/c.txt'
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
394 """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
395
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
396 def __init__(self, path, matcher):
12267
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
397 self._root = matcher._root
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
398 self._cwd = matcher._cwd
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
399 self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
400 self._matcher = matcher
18713
8728579f6bdc match: more accurately report when we're always going to match
Bryan O'Sullivan <bryano@fb.com>
parents: 17425
diff changeset
401 self._always = matcher._always
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
402
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
403 self._files = [f[len(path) + 1:] for f in matcher._files
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
404 if f.startswith(path + "/")]
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
405
32365
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
406 # 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: 32364
diff changeset
407 # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
408 if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
409 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
410
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
411 self._anypats = matcher._anypats
28128
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
412 # Some information is lost in the superclass's constructor, so we
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
413 # can not accurately create the matching function for the subdirectory
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
414 # from the inputs. Instead, we override matchfn() and visitdir() to
92f2c69ee5a5 match: override 'visitdir' in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 28017
diff changeset
415 # call the original matcher with the subdirectory path prepended.
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
416 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
417
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
418 def bad(self, f, msg):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
419 self._matcher.bad(self._path + "/" + f, msg)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
420
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
421 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
422 return self._matcher.abs(self._path + "/" + f)
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
423
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
424 def rel(self, f):
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
425 return self._matcher.rel(self._path + "/" + f)
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
426
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
427 def uipath(self, f):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
428 return self._matcher.uipath(self._path + "/" + f)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
429
32363
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
430 def visitdir(self, dir):
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
431 if dir == '.':
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
432 dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
433 else:
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
434 dir = self._path + "/" + dir
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
435 return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
436
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
437 class icasefsmatcher(matcher):
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
438
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
439 def __init__(self, root, cwd, patterns, include, exclude, default, auditor,
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
440 ctx, listsubrepos=False, badfn=None):
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
441 init = super(icasefsmatcher, self).__init__
26000
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
442 self._dirstate = ctx.repo().dirstate
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
443 self._dsnormalize = self._dirstate.normalize
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
444
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
445 init(root, cwd, patterns, include, exclude, default, auditor=auditor,
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
446 ctx=ctx, listsubrepos=listsubrepos, badfn=badfn)
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
447
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
448 # m.exact(file) must be based off of the actual user input, otherwise
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
449 # inexact case matches are treated as exact, and not noted without -v.
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
450 if self._files:
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
451 roots, dirs = _rootsanddirs(self._kp)
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
452 self._fileset = set(roots)
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
453 self._fileset.update(dirs)
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
454
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
455 def _normalize(self, patterns, default, root, cwd, auditor):
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
456 self._kp = super(icasefsmatcher, self)._normalize(patterns, default,
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
457 root, cwd, auditor)
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
458 kindpats = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
459 for kind, pats, source in self._kp:
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
460 if kind not in ('re', 'relre'): # regex can't be normalized
26000
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
461 p = pats
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
462 pats = self._dsnormalize(pats)
26000
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
463
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
464 # Preserve the original to handle a case only rename.
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
465 if p != pats and p in self._dirstate:
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
466 kindpats.append((kind, p, source))
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
467
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
468 kindpats.append((kind, pats, source))
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
469 return kindpats
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
470
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
471 def patkind(pattern, default=None):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
472 '''If pattern is 'kind:pat' with a known kind, return kind.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
473 return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
474
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
475 def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
476 """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
477 pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
478 if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
479 kind, pat = pattern.split(':', 1)
13218
1f4721de2ca9 match: support reading pattern lists from files
Steve Borho <steve@borho.org>
parents: 12268
diff changeset
480 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
481 'listfile', 'listfile0', 'set', 'include', 'subinclude',
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
482 'rootfilesin'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
483 return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
484 return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
485
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
486 def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
487 r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
488
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
489 >>> print _globre(r'?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
490 .
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
491 >>> print _globre(r'*')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
492 [^/]*
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
493 >>> print _globre(r'**')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
494 .*
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
495 >>> print _globre(r'**/a')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
496 (?:.*/)?a
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
497 >>> print _globre(r'a/**/b')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
498 a\/(?:.*/)?b
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
499 >>> print _globre(r'[a*?!^][^b][!c]')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
500 [a*?!^][\^b][^c]
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
501 >>> print _globre(r'{a,b}')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
502 (?:a|b)
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
503 >>> print _globre(r'.\*\?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
504 \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
505 '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
506 i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
507 res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
508 group = 0
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
509 escape = util.re.escape
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
510 def peek():
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
511 return i < n and pat[i:i + 1]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
512 while i < n:
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
513 c = pat[i:i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
514 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
515 if c not in '*?[{},\\':
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
516 res += escape(c)
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
517 elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
518 if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
519 i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
520 if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
521 i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
522 res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
523 else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
524 res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
525 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
526 res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
527 elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
528 res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
529 elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
530 j = i
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
531 if j < n and pat[j:j + 1] in '!]':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
532 j += 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
533 while j < n and pat[j:j + 1] != ']':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
534 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
535 if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
536 res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
537 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
538 stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
539 i = j + 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
540 if stuff[0:1] == '!':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
541 stuff = '^' + stuff[1:]
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
542 elif stuff[0:1] == '^':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
543 stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
544 res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
545 elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
546 group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
547 res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
548 elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
549 res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
550 group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
551 elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
552 res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
553 elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
554 p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
555 if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
556 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
557 res += escape(p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
558 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
559 res += escape(c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
560 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
561 res += escape(c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
562 return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
563
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
564 def _regex(kind, pat, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
565 '''Convert a (normalized) pattern of any kind into a regular expression.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
566 globsuffix is appended to the regexp of globs.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
567 if not pat:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
568 return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
569 if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
570 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
571 if kind == 'path':
25636
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
572 if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
573 return ''
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
574 return '^' + util.re.escape(pat) + '(?:/|$)'
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
575 if kind == 'rootfilesin':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
576 if pat == '.':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
577 escaped = ''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
578 else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
579 # Pattern is a directory name.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
580 escaped = util.re.escape(pat) + '/'
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
581 # Anything after the pattern must be a non-directory.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
582 return '^' + escaped + '[^/]+$'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
583 if kind == 'relglob':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
584 return '(?:|.*/)' + _globre(pat) + globsuffix
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
585 if kind == 'relpath':
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
586 return util.re.escape(pat) + '(?:/|$)'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
587 if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
588 if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
589 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
590 return '.*' + pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
591 return _globre(pat) + globsuffix
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
592
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
593 def _buildmatch(ctx, kindpats, globsuffix, listsubrepos, root):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
594 '''Return regexp string and a matcher function for kindpats.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
595 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
596 matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
597
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
598 subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
599 if subincludes:
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
600 submatchers = {}
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
601 def matchsubinclude(f):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
602 for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
603 if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
604 mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
605 if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
606 mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
607 submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
608
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
609 if mf(f[len(prefix):]):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
610 return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
611 return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
612 matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
613
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
614 fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
615 if fset:
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
616 matchfuncs.append(fset.__contains__)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
617
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
618 regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
619 if kindpats:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
620 regex, mf = _buildregexmatch(kindpats, globsuffix)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
621 matchfuncs.append(mf)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
622
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
623 if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
624 return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
625 else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
626 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
627
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
628 def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
629 """Build a match function from a list of kinds and kindpats,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
630 return regexp string and a matcher function."""
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
631 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
632 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
633 for (k, p, s) in kindpats])
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
634 if len(regex) > 20000:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16645
diff changeset
635 raise OverflowError
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
636 return regex, _rematcher(regex)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
637 except OverflowError:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
638 # We're using a Python with a tiny regex engine and we
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
639 # made it explode, so we'll divide the pattern list in two
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
640 # until it works
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
641 l = len(kindpats)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
642 if l < 2:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
643 raise
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
644 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
645 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
21191
a2f4ea82d6d3 match: fix NameError 'pat' on overflow of regex pattern length
Yuya Nishihara <yuya@tcha.org>
parents: 21113
diff changeset
646 return regex, lambda s: a(s) or b(s)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
647 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
648 for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
649 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
650 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
651 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
652 if s:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
653 raise error.Abort(_("%s: invalid pattern (%s): %s") %
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
654 (s, k, p))
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
655 else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
656 raise error.Abort(_("invalid pattern (%s): %s") % (k, p))
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
657 raise error.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
658
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
659 def _patternrootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
660 '''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
661
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
662 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: 31032
diff changeset
663 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: 31032
diff changeset
664 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: 31032
diff changeset
665 directories.
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
666 '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
667 r = []
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
668 d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
669 for kind, pat, source in kindpats:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
670 if kind == 'glob': # find the non-glob prefix
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
671 root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
672 for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
673 if '[' in p or '{' in p or '*' in p or '?' in p:
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
674 break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
675 root.append(p)
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
676 r.append('/'.join(root) or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
677 elif kind in ('relpath', 'path'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
678 r.append(pat or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
679 elif kind in ('rootfilesin',):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
680 d.append(pat or '.')
19107
fcf08023c011 match: fix root calculation for combining regexps with simple paths
Mads Kiilerich <madski@unity3d.com>
parents: 18713
diff changeset
681 else: # relglob, re, relre
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
682 r.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
683 return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
684
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
685 def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
686 '''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: 31032
diff changeset
687 roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
688 return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
689
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
690 def _rootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
691 '''Returns roots and exact directories from patterns.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
692
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
693 roots are directories to match recursively, whereas exact directories should
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
694 be matched non-recursively. The returned (roots, dirs) tuple will also
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
695 include directories that need to be implicitly considered as either, such as
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
696 parent directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
697
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
698 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
699 [('glob', 'g/h/*', ''), ('glob', 'g/h', ''), ('glob', 'g*', '')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
700 (['g/h', 'g/h', '.'], ['g', '.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
701 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
702 [('rootfilesin', 'g/h', ''), ('rootfilesin', '', '')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
703 ([], ['g/h', '.', 'g', '.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
704 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
705 [('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
706 (['r', 'p/p', '.'], ['p', '.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
707 >>> _rootsanddirs(\
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
708 [('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
709 (['.', '.', '.'], ['.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
710 '''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
711 r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
712
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
713 # Append the parents as non-recursive/exact directories, since they must be
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
714 # scanned to get to either the roots or the other exact directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
715 d.extend(util.dirs(d))
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
716 d.extend(util.dirs(r))
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
717 # util.dirs() does not include the root directory, so add it manually
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
718 d.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
719
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
720 return r, d
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
721
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
722 def _explicitfiles(kindpats):
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
723 '''Returns the potential explicit filenames from the patterns.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
724
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
725 >>> _explicitfiles([('path', 'foo/bar', '')])
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
726 ['foo/bar']
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
727 >>> _explicitfiles([('rootfilesin', 'foo/bar', '')])
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
728 []
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
729 '''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
730 # 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: 30409
diff changeset
731 # directory names).
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
732 filable = [kp for kp in kindpats if kp[0] not in ('rootfilesin',)]
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
733 return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
734
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
735 def _anypats(kindpats):
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
736 for kind, pat, source in kindpats:
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
737 if kind in ('glob', 're', 'relglob', 'relre', 'set', 'rootfilesin'):
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
738 return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
739
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
740 _commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
741
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
742 def readpatternfile(filepath, warn, sourceinfo=False):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
743 '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
744 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
745 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
746
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
747 trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
748 the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
749 comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
750 empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
751
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
752 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
753
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
754 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
755 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
756 re:pattern # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
757 glob:pattern # non-rooted glob
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
758 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
759
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
760 if sourceinfo is set, returns a list of tuples:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
761 (pattern, lineno, originalline). This is useful to debug ignore patterns.
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
762 '''
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
763
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
764 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
765 'include': 'include', 'subinclude': 'subinclude'}
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
766 syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
767 patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
768
31412
10c17f8bfcf3 py3: open file in rb mode
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 31401
diff changeset
769 fp = open(filepath, 'rb')
30409
7f3593c29473 match: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 29814
diff changeset
770 for lineno, line in enumerate(util.iterfile(fp), start=1):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
771 if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
772 global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
773 if not _commentre:
31429
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31412
diff changeset
774 _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
775 # 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
776 m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
777 if m:
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
778 line = line[:m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
779 # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
780 line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
781 line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
782 if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
783 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
784
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
785 if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
786 s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
787 try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
788 syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
789 except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
790 if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
791 warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
792 (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
793 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
794
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
795 linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
796 for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
797 if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
798 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
799 line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
800 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
801 elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
802 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
803 line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
804 break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
805 if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
806 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
807 else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
808 patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
809 fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
810 return patterns