annotate mercurial/match.py @ 26000:9ac4e81b9659 stable

match: fix a caseonly rename + explicit path commit on icasefs (issue4768) The problem was that the former name and the new name are both normalized to the case in dirstate, so matcher._files would be ['ABC.txt', 'ABC.txt']. localrepo.commit() calls localrepo.status(), passing along the matcher. Inside dirstate.status(), _walkexplicit() simply grabs matcher.files() and processes those items. Since the old name isn't present, it is silently dropped. There's a fundamental tension here, because the status command should also accept files that don't match the filesystem, so we can't drop the normalization in status. The problem originated in baa11dde8c0e. Unfortunately with this change, the case of the old file must still be specified exactly, or the old file is again silently excluded. I went back to baa11dde8c0e^, and that had the same behavior, so we are no worse off. I'm open to ideas from a matcher or dirstate expert on how to fix that half.
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 06 Aug 2015 21:00:16 -0400
parents 511e1949d557
children a5f62af29517
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
25875
511e1949d557 ignore: fix path concatenation of .hgignore on Windows
Yuya Nishihara <yuya@tcha.org>
parents: 25870
diff changeset
8 import copy, os, re
20401
906358d0350e match: use ctx.getfileset() instead of fileset.getfileset()
Augie Fackler <raf@durin42.com>
parents: 20033
diff changeset
9 import util, pathutil
12133
b046b90c4ae5 match: mark error messages for translation
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
10 from i18n import _
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
12 propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
13
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
14 def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
15 '''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
16 matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
17 m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
18 try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
19 # 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
20 return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
21 except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
22 return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
23
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
24 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
25 '''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
26 fset = set()
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
27 other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
28
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
29 for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
30 if kind == 'set':
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
31 if not ctx:
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
32 raise util.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
33 s = ctx.getfileset(pat)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
34 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
35
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
36 if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
37 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
38 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
39 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
40
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
41 continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
42 other.append((kind, pat, source))
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
43 return fset, other
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
44
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
45 def _expandsubinclude(kindpats, root):
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
46 '''Returns the list of subinclude matchers and the kindpats without the
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
47 subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
48 relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
49 other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
50
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
51 for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
52 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
53 sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
54 pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
55 path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
56
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
57 newroot = pathutil.dirname(path)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
58 relmatcher = match(newroot, '', [], ['include:%s' % path])
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 prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
61 if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
62 prefix += '/'
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
63 relmatchers.append((prefix, relmatcher))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
64 else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
65 other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
66
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
67 return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
68
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
69 def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
70 """"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
71 'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
72 """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
73 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
74 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
75 return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
76 return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
77
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
78 class match(object):
8567
fea40a677d43 match: add some default args
Matt Mackall <mpm@selenic.com>
parents: 8566
diff changeset
79 def __init__(self, root, cwd, patterns, include=[], exclude=[],
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
80 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
81 listsubrepos=False, warn=None, badfn=None):
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
82 """build an object to match a set of file patterns
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
83
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
84 arguments:
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
85 root - the canonical root of the tree you're matching against
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
86 cwd - the current working directory, if relevant
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
87 patterns - patterns to find
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
88 include - patterns to include (unless they are excluded)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
89 exclude - patterns to exclude (even if they are included)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
90 default - if a pattern in patterns has no explicit type, assume this one
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
91 exact - patterns are actually filenames (include/exclude still apply)
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
92 warn - optional function used for printing warnings
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
93 badfn - optional bad() callback for this matcher instead of the default
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
94
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
95 a pattern is one of:
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
96 'glob:<glob>' - a glob relative to cwd
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
97 're:<regexp>' - a regular expression
17425
e95ec38f86b0 fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 16943
diff changeset
98 'path:<path>' - a path relative to repository root
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
99 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
100 'relpath:<path>' - a path relative to cwd
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
101 'relre:<regexp>' - a regexp that needn't match the start of a name
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
102 'set:<fileset>' - a fileset expression
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
103 'include:<path>' - a file of patterns to read and include
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
104 'subinclude:<path>' - a file of patterns to match against files under
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
105 the same directory
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
106 '<something>' - a pattern of the specified default type
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
107 """
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
108
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
109 self._root = root
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
110 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
111 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
112 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
113 self._always = False
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
114 self._pathrestricted = bool(include or exclude or patterns)
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
115 self._warn = warn
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
116 self._includeroots = set()
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
117 self._includedirs = set(['.'])
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
118 self._excluderoots = set()
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
119
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
120 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
121 self.bad = badfn
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
122
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
123 matchfns = []
8586
347fe1ac4f21 match: add exact flag to match() to unify all match forms
Matt Mackall <mpm@selenic.com>
parents: 8585
diff changeset
124 if include:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
125 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
126 self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
127 listsubrepos, root)
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
128 self._includeroots.update(_roots(kindpats))
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
129 self._includedirs.update(util.dirs(self._includeroots))
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
130 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
131 if exclude:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
132 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
133 self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
134 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
135 if not _anypats(kindpats):
20ad936ac5d2 treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25301
diff changeset
136 self._excluderoots.update(_roots(kindpats))
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
137 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
138 if exact:
16789
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
139 if isinstance(patterns, list):
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
140 self._files = patterns
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
141 else:
c17ce7cd5090 match: make 'match.files()' return list object always
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16182
diff changeset
142 self._files = list(patterns)
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
143 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
144 elif patterns:
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
145 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
146 if not _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
147 self._files = _roots(kindpats)
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
148 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
149 self.patternspat, pm = _buildmatch(ctx, kindpats, '$',
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
150 listsubrepos, root)
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
151 matchfns.append(pm)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
152
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
153 if not matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
154 m = util.always
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
155 self._always = True
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
156 elif len(matchfns) == 1:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
157 m = matchfns[0]
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
158 else:
22513
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
159 def m(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
160 for matchfn in matchfns:
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
161 if not matchfn(f):
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
162 return False
ca709785caf2 match: simplify brittle predicate construction
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 21915
diff changeset
163 return True
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
164
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
165 self.matchfn = m
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
166 self._fileroots = set(self._files)
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
167
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
168 def __call__(self, fn):
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
169 return self.matchfn(fn)
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
170 def __iter__(self):
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
171 for f in self._files:
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
172 yield f
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
173
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
174 # 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
175 # 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
176 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
177 '''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
178 found/accessed, with an error message.'''
8680
b6511055d37b match: ignore return of match.bad
Matt Mackall <mpm@selenic.com>
parents: 8678
diff changeset
179 pass
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
180
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
181 # 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
182 # directory is visited.
19143
3cb9468535bd match: make explicitdir and traversedir None by default
Siddharth Agarwal <sid0@fb.com>
parents: 19141
diff changeset
183 explicitdir = None
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
184
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
185 # 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
186 # by recursive traversal is visited.
19143
3cb9468535bd match: make explicitdir and traversedir None by default
Siddharth Agarwal <sid0@fb.com>
parents: 19141
diff changeset
187 traversedir = None
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
188
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
189 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
190 '''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
191 matcher.'''
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
192 return f
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
193
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
194 def rel(self, f):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
195 '''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
196 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
197
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
198 def uipath(self, f):
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
199 '''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
200 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
201 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
202 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
203
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
204 def files(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
205 '''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
206 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
207 if exact: list exact files,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
208 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
209 else: optimal roots'''
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
210 return self._files
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
211
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
212 @propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
213 def _dirs(self):
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
214 return set(util.dirs(self._fileroots)) | set(['.'])
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
215
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
216 def visitdir(self, dir):
25231
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
217 '''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
218 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
219 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
220
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
221 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
222 one of the dir's parent directories.
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
223 '''
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
224 if dir in self._excluderoots:
8545bd381504 match: have visitdir() consider includes and excludes
Drew Gottlieb <drgott@google.com>
parents: 25216
diff changeset
225 return False
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
226 if (self._includeroots and
25579
b76410eed482 match: don't remove '.' from _includeroots
Martin von Zweigbergk <martinvonz@google.com>
parents: 25578
diff changeset
227 '.' 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
228 dir not in self._includeroots and
25578
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
229 dir not in self._includedirs and
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
230 not any(parent in self._includeroots
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
231 for parent in util.finddirs(dir))):
4b1ec70b9713 match: join two nested if-blocks
Martin von Zweigbergk <martinvonz@google.com>
parents: 25577
diff changeset
232 return False
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
233 return (not self._fileroots or
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
234 '.' in self._fileroots or
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
235 dir in self._fileroots or
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
236 dir in self._dirs or
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
237 any(parentdir in self._fileroots
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
238 for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
239
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
240 def exact(self, f):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
241 '''Returns True if f is in .files().'''
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
242 return f in self._fileroots
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
243
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
244 def anypats(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
245 '''Matcher uses patterns or include/exclude.'''
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
246 return self._anypats
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
247
16645
9a21fc2c7d32 localrepo: optimize internode status calls using match.always
Jesse Glick <jesse.glick@oracle.com>
parents: 16182
diff changeset
248 def always(self):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
249 '''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
250 - 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
251 return self._always
8568
4fa1618bf495 match: refactor patkind
Matt Mackall <mpm@selenic.com>
parents: 8567
diff changeset
252
25114
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
253 def ispartial(self):
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
254 '''True if the matcher won't always match.
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
255
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
256 Although it's just the inverse of _always in this implementation,
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
257 an extenion such as narrowhg might make it return something
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
258 slightly different.'''
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
259 return not self._always
d1d69ca78883 match: add match.ispartial()
Drew Gottlieb <drgott@google.com>
parents: 24790
diff changeset
260
24448
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
261 def isexact(self):
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
262 return self.matchfn == self.exact
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24447
diff changeset
263
25233
9789b4a7c595 match: introduce boolean prefix() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 25231
diff changeset
264 def prefix(self):
9789b4a7c595 match: introduce boolean prefix() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 25231
diff changeset
265 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
266
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
267 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
268 '''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
269 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
270 kindpats = []
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
271 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
272 if kind in ('glob', 'relpath'):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
273 pat = pathutil.canonpath(root, cwd, pat, auditor)
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
274 elif kind in ('relglob', 'path'):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
275 pat = util.normpath(pat)
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
276 elif kind in ('listfile', 'listfile0'):
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
277 try:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
278 files = util.readfile(pat)
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
279 if kind == 'listfile0':
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
280 files = files.split('\0')
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
281 else:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
282 files = files.splitlines()
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
283 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
284 except EnvironmentError:
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
285 raise util.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
286 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
287 auditor):
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
288 kindpats.append((k, p, pat))
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
289 continue
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
290 elif kind == 'include':
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
291 try:
25875
511e1949d557 ignore: fix path concatenation of .hgignore on Windows
Yuya Nishihara <yuya@tcha.org>
parents: 25870
diff changeset
292 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
293 includepats = readpatternfile(fullpath, self._warn)
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
294 for k, p, source in self._normalize(includepats, default,
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
295 root, cwd, auditor):
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
296 kindpats.append((k, p, source or pat))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25579
diff changeset
297 except util.Abort as inst:
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
298 raise util.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
299 except IOError as inst:
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
300 if self._warn:
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
301 self._warn(_("skipping unreadable pattern file "
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
302 "'%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
303 continue
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
304 # 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
305 kindpats.append((kind, pat, ''))
24789
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
306 return kindpats
0b1577c892f2 match: move _normalize() into the match class
Matt Harbison <matt_harbison@yahoo.com>
parents: 24636
diff changeset
307
25464
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
308 def exact(root, cwd, files, badfn=None):
504a1f295677 match: add an optional constructor parameter for a bad() override
Matt Harbison <matt_harbison@yahoo.com>
parents: 25433
diff changeset
309 return match(root, cwd, files, exact=True, badfn=badfn)
8585
bbcd0da50e96 match: redefine always and never in terms of match and exact
Matt Mackall <mpm@selenic.com>
parents: 8584
diff changeset
310
23549
609ecde2778f match: make 'always' and 'exact' functions, not classes
Martin von Zweigbergk <martinvonz@google.com>
parents: 23480
diff changeset
311 def always(root, cwd):
609ecde2778f match: make 'always' and 'exact' functions, not classes
Martin von Zweigbergk <martinvonz@google.com>
parents: 23480
diff changeset
312 return match(root, cwd, [])
8585
bbcd0da50e96 match: redefine always and never in terms of match and exact
Matt Mackall <mpm@selenic.com>
parents: 8584
diff changeset
313
25433
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
314 def badmatch(match, badfn):
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
315 """Make a copy of the given matcher, replacing its bad method with the given
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
316 one.
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
317 """
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
318 m = copy.copy(match)
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
319 m.bad = badfn
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
320 return m
419ac63fe29c match: introduce badmatch() to eliminate long callback chains with subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 25362
diff changeset
321
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
322 class narrowmatcher(match):
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
323 """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
324
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
325 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
326
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
327 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
328 >>> m2 = narrowmatcher('sub', m1)
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
329 >>> bool(m2('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
330 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
331 >>> bool(m2('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
332 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
333 >>> bool(m2.matchfn('a.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
334 False
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
335 >>> bool(m2.matchfn('b.txt'))
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
336 True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
337 >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
338 ['b.txt']
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
339 >>> m2.exact('b.txt')
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
340 True
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
341 >>> util.pconvert(m2.rel('b.txt'))
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
342 'sub/b.txt'
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
343 >>> def bad(f, msg):
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
344 ... print "%s: %s" % (f, msg)
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
345 >>> m1.bad = bad
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
346 >>> m2.bad('x.txt', 'No such file')
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
347 sub/x.txt: No such file
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
348 >>> m2.abs('c.txt')
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
349 'sub/c.txt'
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
350 """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
351
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
352 def __init__(self, path, matcher):
12267
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
353 self._root = matcher._root
69e43c0515f2 narrowmatcher: fix broken rel method
Martin Geisler <mg@lazybytes.net>
parents: 12165
diff changeset
354 self._cwd = matcher._cwd
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
355 self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
356 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
357 self._always = matcher._always
23480
88d2d77eb981 match: introduce uipath() to properly style a file path
Matt Harbison <matt_harbison@yahoo.com>
parents: 22777
diff changeset
358 self._pathrestricted = matcher._pathrestricted
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
359
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
360 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
361 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
362
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
363 # If the parent repo had a path to this subrepo and no patterns are
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
364 # specified, this submatcher always matches.
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
365 if not self._always and not matcher._anypats:
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
366 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
367
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
368 self._anypats = matcher._anypats
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
369 self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
370 self._fileroots = set(self._files)
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
371
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
372 def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
373 return self._matcher.abs(self._path + "/" + f)
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
374
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
375 def bad(self, f, msg):
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
376 self._matcher.bad(self._path + "/" + f, msg)
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
377
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
378 def rel(self, f):
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
379 return self._matcher.rel(self._path + "/" + f)
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
380
24790
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
381 class icasefsmatcher(match):
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
382 """A matcher for wdir on case insensitive filesystems, which normalizes the
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
383 given patterns to the case in the filesystem.
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
384 """
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
385
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
386 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
387 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
388 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
389 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
390 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
391
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
392 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
393 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
394
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
395 # 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
396 # 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
397 if self._files:
25189
1c8c33eaea0a match: rename _fmap to _fileroots for clarity
Drew Gottlieb <drgott@google.com>
parents: 25188
diff changeset
398 self._fileroots = set(_roots(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
399
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
400 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
401 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
402 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
403 kindpats = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
404 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
405 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
406 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
407 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
408
9ac4e81b9659 match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25875
diff changeset
409 # 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
410 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
411 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
412
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
413 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
414 return kindpats
baa11dde8c0e match: add a subclass for dirstate normalizing of the matched patterns
Matt Harbison <matt_harbison@yahoo.com>
parents: 24789
diff changeset
415
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
416 def patkind(pattern, default=None):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
417 '''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
418 return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
419
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
420 def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
421 """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
422 pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
423 if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
424 kind, pat = pattern.split(':', 1)
13218
1f4721de2ca9 match: support reading pattern lists from files
Steve Borho <steve@borho.org>
parents: 12268
diff changeset
425 if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
426 'listfile', 'listfile0', 'set', 'include', 'subinclude'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
427 return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
428 return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
429
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
430 def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
431 r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
432
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
433 >>> print _globre(r'?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
434 .
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
435 >>> print _globre(r'*')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
436 [^/]*
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
437 >>> print _globre(r'**')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
438 .*
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
439 >>> print _globre(r'**/a')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
440 (?:.*/)?a
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
441 >>> print _globre(r'a/**/b')
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
442 a\/(?:.*/)?b
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
443 >>> print _globre(r'[a*?!^][^b][!c]')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
444 [a*?!^][\^b][^c]
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
445 >>> print _globre(r'{a,b}')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
446 (?:a|b)
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
447 >>> print _globre(r'.\*\?')
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
448 \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
449 '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
450 i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
451 res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
452 group = 0
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
453 escape = util.re.escape
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
454 def peek():
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
455 return i < n and pat[i]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
456 while i < n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
457 c = pat[i]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
458 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
459 if c not in '*?[{},\\':
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
460 res += escape(c)
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
461 elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
462 if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
463 i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
464 if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
465 i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
466 res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
467 else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
468 res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
469 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
470 res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
471 elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
472 res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
473 elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
474 j = i
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
475 if j < n and pat[j] in '!]':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
476 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
477 while j < n and pat[j] != ']':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
478 j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
479 if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
480 res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
481 else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
482 stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
483 i = j + 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
484 if stuff[0] == '!':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
485 stuff = '^' + stuff[1:]
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
486 elif stuff[0] == '^':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
487 stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
488 res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
489 elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
490 group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
491 res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
492 elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
493 res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
494 group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
495 elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
496 res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
497 elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
498 p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
499 if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
500 i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
501 res += escape(p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
502 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
503 res += escape(c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
504 else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
505 res += escape(c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
506 return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
507
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
508 def _regex(kind, pat, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
509 '''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
510 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
511 if not pat:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
512 return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
513 if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
514 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
515 if kind == 'path':
25636
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
516 if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
517 return ''
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
518 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
519 if kind == 'relglob':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
520 return '(?:|.*/)' + _globre(pat) + globsuffix
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
521 if kind == 'relpath':
21915
d516b6de3821 match: use util.re.escape instead of re.escape
Siddharth Agarwal <sid0@fb.com>
parents: 21909
diff changeset
522 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
523 if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
524 if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
525 return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
526 return '.*' + pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
527 return _globre(pat) + globsuffix
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
528
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
529 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
530 '''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
531 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
532 matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
533
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
534 subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
535 if subincludes:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
536 def matchsubinclude(f):
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
537 for prefix, mf in subincludes:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
538 if f.startswith(prefix) and mf(f[len(prefix):]):
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
539 return True
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
540 return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
541 matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
542
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
543 fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
544 if fset:
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
545 matchfuncs.append(fset.__contains__)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
546
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
547 regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
548 if kindpats:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
549 regex, mf = _buildregexmatch(kindpats, globsuffix)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
550 matchfuncs.append(mf)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
551
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
552 if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
553 return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
554 else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
555 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
556
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
557 def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
558 """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
559 return regexp string and a matcher function."""
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
560 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
561 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
562 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
563 if len(regex) > 20000:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16645
diff changeset
564 raise OverflowError
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
565 return regex, _rematcher(regex)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
566 except OverflowError:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
567 # 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
568 # 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
569 # until it works
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
570 l = len(kindpats)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
571 if l < 2:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
572 raise
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
573 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
574 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
575 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
576 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
577 for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
578 try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
579 _rematcher('(?:%s)' % _regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
580 except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
581 if s:
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
582 raise util.Abort(_("%s: invalid pattern (%s): %s") %
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
583 (s, k, p))
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
584 else:
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
585 raise util.Abort(_("invalid pattern (%s): %s") % (k, p))
12133
b046b90c4ae5 match: mark error messages for translation
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
586 raise util.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
587
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
588 def _roots(kindpats):
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
589 '''return roots and exact explicitly listed files from patterns
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
590
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
591 >>> _roots([('glob', 'g/*', ''), ('glob', 'g', ''), ('glob', 'g*', '')])
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
592 ['g', 'g', '.']
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
593 >>> _roots([('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
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
594 ['r', 'p/p', '.']
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
595 >>> _roots([('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
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
596 ['.', '.', '.']
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
597 '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
598 r = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
599 for kind, pat, source in kindpats:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
600 if kind == 'glob': # find the non-glob prefix
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
601 root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
602 for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
603 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
604 break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
605 root.append(p)
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
606 r.append('/'.join(root) or '.')
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
607 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
608 r.append(pat or '.')
19107
fcf08023c011 match: fix root calculation for combining regexps with simple paths
Mads Kiilerich <madski@unity3d.com>
parents: 18713
diff changeset
609 else: # relglob, re, relre
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
610 r.append('.')
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
611 return r
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
612
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
613 def _anypats(kindpats):
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
614 for kind, pat, source in kindpats:
16182
bd12ef347680 match: consider filesets as "anypats"
Patrick Mezard <patrick@mezard.eu>
parents: 15029
diff changeset
615 if kind in ('glob', 're', 'relglob', 'relre', 'set'):
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
616 return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
617
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
618 _commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
619
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
620 def readpatternfile(filepath, warn):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
621 '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
622 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
623 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
624
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
625 trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
626 the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
627 comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
628 empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
629
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
630 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
631
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
632 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
633 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
634 re:pattern # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
635 glob:pattern # non-rooted glob
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
636 pattern # pattern of the current default type'''
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
637
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
638 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
639 'include': 'include', 'subinclude': 'subinclude'}
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
640 syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
641 patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
642
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
643 fp = open(filepath)
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
644 for line in fp:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
645 if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
646 global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
647 if not _commentre:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
648 _commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
649 # remove comments prefixed by an even number of escapes
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
650 line = _commentre.sub(r'\1', line)
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
651 # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
652 line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
653 line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
654 if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
655 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
656
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
657 if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
658 s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
659 try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
660 syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
661 except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
662 if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
663 warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
664 (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
665 continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
666
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
667 linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
668 for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
669 if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
670 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
671 line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
672 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
673 elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
674 linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
675 line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
676 break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
677 patterns.append(linesyntax + line)
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
678 fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
679 return patterns