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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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))