Commit e1a18bae authored by Yuya Nishihara's avatar Yuya Nishihara
Browse files

grep: extract main search loop as searcher method

Still displayer part is in commands.grep(), the core grep logic is now
reusable. I'll revisit the displayer stuff later since it will be another
long series.
parent 508dfd1c18df
......@@ -3403,8 +3403,6 @@ def grep(ui, repo, pattern, *pats, **opts):
)
getfile = searcher._getfile
matches = searcher._matches
copies = searcher._copies
uipathfn = scmutil.getuipathfn(repo)
......@@ -3514,8 +3512,6 @@ def grep(ui, repo, pattern, *pats, **opts):
fm.data(matched=False)
fm.end()
skip = searcher._skip
revfiles = searcher._revfiles
found = False
wopts = logcmdutil.walkopts(
......@@ -3532,29 +3528,11 @@ def grep(ui, repo, pattern, *pats, **opts):
ui.pager(b'grep')
fm = ui.formatter(b'grep', opts)
for ctx in scmutil.walkchangerevs(
repo, revs, makefilematcher, searcher._prep
):
rev = ctx.rev()
parent = ctx.p1().rev()
for fn in sorted(revfiles.get(rev, [])):
states = matches[rev][fn]
copy = copies.get(rev, {}).get(fn)
if fn in skip:
if copy:
skip.add(copy)
continue
pstates = matches.get(parent, {}).get(copy or fn, [])
if pstates or states:
for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
r = display(fm, fn, ctx, pstates, states)
found = found or r
if r and not diff and not all_files:
searcher.skipfile(fn, rev)
del revfiles[rev]
# We will keep the matches dict for the duration of the window
# clear the matches dict once the window is over
if not revfiles:
matches.clear()
searcher.skipfile(fn, ctx.rev())
fm.end()
return not found
......
......@@ -115,6 +115,34 @@ class grepsearcher(object):
if copy:
self._skip.add(copy)
def searchfiles(self, revs, makefilematcher):
"""Walk files and revisions to yield (fn, ctx, pstates, states)
matches
states is a list of linestate objects. pstates may be empty unless
diff is True.
"""
for ctx in scmutil.walkchangerevs(
self._repo, revs, makefilematcher, self._prep
):
rev = ctx.rev()
parent = ctx.p1().rev()
for fn in sorted(self._revfiles.get(rev, [])):
states = self._matches[rev][fn]
copy = self._copies.get(rev, {}).get(fn)
if fn in self._skip:
if copy:
self._skip.add(copy)
continue
pstates = self._matches.get(parent, {}).get(copy or fn, [])
if pstates or states:
yield fn, ctx, pstates, states
del self._revfiles[rev]
# We will keep the matches dict for the duration of the window
# clear the matches dict once the window is over
if not self._revfiles:
self._matches.clear()
def _grepbody(self, fn, rev, body):
self._matches[rev].setdefault(fn, [])
m = self._matches[rev][fn]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment