author | Pierre-Yves David <pierre-yves.david@octobus.net> |
Tue, 10 Oct 2023 11:16:07 +0200 | |
changeset 51058 | 8bdb2478c4bc |
parent 49306 | 2e726c934fcd |
child 51863 | f4733654f144 |
permissions | -rw-r--r-- |
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)) |