annotate mercurial/grep.py @ 50896:b2b8c25f9462

hgwebmod: use sysstr to check for attribute presence We do not need bytes here.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 30 Aug 2023 13:28:09 +0200
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))