Mercurial > hg
annotate mercurial/grep.py @ 51232:3551f2a1c963
debugindexstats: handle the lack of Rust support better
We don't have any stats in the Rust index. Currently it is not known which
stats would be interesting to get, so if they end up being important, we can
add them later.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Tue, 31 Oct 2023 18:09:43 +0100 |
parents | 2e726c934fcd |
children | f4733654f144 |
rev | line source |
---|---|
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 # grep.py - logic for history walk and grep |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
45721
diff
changeset
|
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com> |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 # |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 import difflib |
45699
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
10 |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
11 from .i18n import _ |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
13 from . import ( |
45699
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
14 error, |
45700
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
15 match as matchmod, |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
16 pycompat, |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
17 scmutil, |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
18 util, |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
19 ) |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 def matchlines(body, regexp): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 begin = 0 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 linenum = 0 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
25 while begin < len(body): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
26 match = regexp.search(body, begin) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
27 if not match: |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
28 break |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 mstart, mend = match.span() |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 linenum += body.count(b'\n', begin, mstart) + 1 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
31 lstart = body.rfind(b'\n', begin, mstart) + 1 or begin |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
32 begin = body.find(b'\n', mend) + 1 or len(body) + 1 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
33 lend = begin - 1 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
34 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend] |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
35 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
37 class linestate: |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
38 def __init__(self, line, linenum, colstart, colend): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 self.line = line |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 self.linenum = linenum |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
41 self.colstart = colstart |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 self.colend = colend |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
43 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
44 def __hash__(self): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
45 return hash(self.line) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
46 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
47 def __eq__(self, other): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
48 return self.line == other.line |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
49 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
50 def findpos(self, regexp): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
51 """Iterate all (start, end) indices of matches""" |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
52 yield self.colstart, self.colend |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
53 p = self.colend |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
54 while p < len(self.line): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
55 m = regexp.search(self.line, p) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
56 if not m: |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
57 break |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
58 if m.end() == p: |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
59 p += 1 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 else: |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 yield m.span() |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 p = m.end() |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
65 def difflinestates(a, b): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 sm = difflib.SequenceMatcher(None, a, b) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 for tag, alo, ahi, blo, bhi in sm.get_opcodes(): |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 if tag == 'insert': |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
69 for i in range(blo, bhi): |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
70 yield (b'+', b[i]) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 elif tag == 'delete': |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
72 for i in range(alo, ahi): |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 yield (b'-', a[i]) |
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 elif tag == 'replace': |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
75 for i in range(alo, ahi): |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 yield (b'-', a[i]) |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
77 for i in range(blo, bhi): |
45696
de6f2afc0247
grep: move match and diff logic to new module
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 yield (b'+', b[i]) |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
79 |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
80 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
81 class grepsearcher: |
45700
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
82 """Search files and revisions for lines matching the given pattern |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
83 |
45700
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
84 Options: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
85 - all_files to search unchanged files at that revision. |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
86 - diff to search files in the parent revision so diffs can be generated. |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
87 - follow to skip files across copies and renames. |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
88 """ |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
89 |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
90 def __init__( |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
91 self, ui, repo, regexp, all_files=False, diff=False, follow=False |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
92 ): |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
93 self._ui = ui |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
94 self._repo = repo |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
95 self._regexp = regexp |
45700
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
96 self._all_files = all_files |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
97 self._diff = diff |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
98 self._follow = follow |
45697
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
99 |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
100 self._getfile = util.lrucachefunc(repo.file) |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
101 self._getrenamed = scmutil.getrenamedfn(repo) |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
102 |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
103 self._matches = {} |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
104 self._copies = {} |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
105 self._skip = set() |
494642ed3c50
grep: add stub class that maintains cache and states of grep operation
Yuya Nishihara <yuya@tcha.org>
parents:
45696
diff
changeset
|
106 self._revfiles = {} |
45698
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
107 |
45719
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
108 def skipfile(self, fn, rev): |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
109 """Exclude the given file (and the copy at the specified revision) |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
110 from future search""" |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
111 copy = self._copies.get(rev, {}).get(fn) |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
112 self._skip.add(fn) |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
113 if copy: |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
114 self._skip.add(copy) |
c10c87c8fe79
grep: extract public function to register file to be skipped
Yuya Nishihara <yuya@tcha.org>
parents:
45700
diff
changeset
|
115 |
45721
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
116 def searchfiles(self, revs, makefilematcher): |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
117 """Walk files and revisions to yield (fn, ctx, pstates, states) |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
118 matches |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
119 |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
120 states is a list of linestate objects. pstates may be empty unless |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
121 diff is True. |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
122 """ |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
123 for ctx in scmutil.walkchangerevs( |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
124 self._repo, revs, makefilematcher, self._prep |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
125 ): |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
126 rev = ctx.rev() |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
127 parent = ctx.p1().rev() |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
128 for fn in sorted(self._revfiles.get(rev, [])): |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
129 states = self._matches[rev][fn] |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
130 copy = self._copies.get(rev, {}).get(fn) |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
131 if fn in self._skip: |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
132 if copy: |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
133 self._skip.add(copy) |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
134 continue |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
135 pstates = self._matches.get(parent, {}).get(copy or fn, []) |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
136 if pstates or states: |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
137 yield fn, ctx, pstates, states |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
138 del self._revfiles[rev] |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
139 # We will keep the matches dict for the duration of the window |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
140 # clear the matches dict once the window is over |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
141 if not self._revfiles: |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
142 self._matches.clear() |
f9d3ff23bfc0
grep: extract main search loop as searcher method
Yuya Nishihara <yuya@tcha.org>
parents:
45719
diff
changeset
|
143 |
45698
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
144 def _grepbody(self, fn, rev, body): |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
145 self._matches[rev].setdefault(fn, []) |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
146 m = self._matches[rev][fn] |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
147 if body is None: |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
148 return |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
149 |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
150 for lnum, cstart, cend, line in matchlines(body, self._regexp): |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
151 s = linestate(line, lnum, cstart, cend) |
41e0cbccb260
grep: move getbody() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45697
diff
changeset
|
152 m.append(s) |
45699
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
153 |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
154 def _readfile(self, ctx, fn): |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
155 rev = ctx.rev() |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
156 if rev is None: |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
157 fctx = ctx[fn] |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
158 try: |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
159 return fctx.data() |
49306
2e726c934fcd
py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents:
49284
diff
changeset
|
160 except FileNotFoundError: |
2e726c934fcd
py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents:
49284
diff
changeset
|
161 pass |
45699
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
162 else: |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
163 flog = self._getfile(fn) |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
164 fnode = ctx.filenode(fn) |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
165 try: |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
166 return flog.read(fnode) |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
167 except error.CensoredNodeError: |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
168 self._ui.warn( |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
169 _( |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
170 b'cannot search in censored file: ' |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
171 b'%(filename)s:%(revnum)s\n' |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
172 ) |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
173 % {b'filename': fn, b'revnum': pycompat.bytestr(rev)} |
888e633f0c1c
grep: move readfile() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45698
diff
changeset
|
174 ) |
45700
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
175 |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
176 def _prep(self, ctx, fmatch): |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
177 rev = ctx.rev() |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
178 pctx = ctx.p1() |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
179 self._matches.setdefault(rev, {}) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
180 if self._diff: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
181 parent = pctx.rev() |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
182 self._matches.setdefault(parent, {}) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
183 files = self._revfiles.setdefault(rev, []) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
184 if rev is None: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
185 # in `hg grep pattern`, 2/3 of the time is spent is spent in |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
186 # pathauditor checks without this in mozilla-central |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
187 contextmanager = self._repo.wvfs.audit.cached |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
188 else: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
189 contextmanager = util.nullcontextmanager |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
190 with contextmanager(): |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
191 # TODO: maybe better to warn missing files? |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
192 if self._all_files: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
193 fmatch = matchmod.badmatch(fmatch, lambda f, msg: None) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
194 filenames = ctx.matches(fmatch) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
195 else: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
196 filenames = (f for f in ctx.files() if fmatch(f)) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
197 for fn in filenames: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
198 # fn might not exist in the revision (could be a file removed by |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
199 # the revision). We could check `fn not in ctx` even when rev is |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
200 # None, but it's less racy to protect againt that in readfile. |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
201 if rev is not None and fn not in ctx: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
202 continue |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
203 |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
204 copy = None |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
205 if self._follow: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
206 copy = self._getrenamed(fn, rev) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
207 if copy: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
208 self._copies.setdefault(rev, {})[fn] = copy |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
209 if fn in self._skip: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
210 self._skip.add(copy) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
211 if fn in self._skip: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
212 continue |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
213 files.append(fn) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
214 |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
215 if fn not in self._matches[rev]: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
216 self._grepbody(fn, rev, self._readfile(ctx, fn)) |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
217 |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
218 if self._diff: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
219 pfn = copy or fn |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
220 if pfn not in self._matches[parent] and pfn in pctx: |
c694b1841a5e
grep: move prep() to grepsearcher class
Yuya Nishihara <yuya@tcha.org>
parents:
45699
diff
changeset
|
221 self._grepbody(pfn, parent, self._readfile(pctx, pfn)) |