##// END OF EJS Templates
grep: reduce the cost of pathauditor checks when grepping working copy...
Valentin Gatien-Baron -
r45392:233ee525 default
parent child Browse files
Show More
@@ -3609,31 +3609,38 b' def grep(ui, repo, pattern, *pats, **opt'
3609 parent = pctx.rev()
3609 parent = pctx.rev()
3610 matches.setdefault(parent, {})
3610 matches.setdefault(parent, {})
3611 files = revfiles.setdefault(rev, [])
3611 files = revfiles.setdefault(rev, [])
3612 for fn in fns:
3612 if rev is None:
3613 # fn might not exist in the revision (could be a file removed by the
3613 # in `hg grep pattern`, 2/3 of the time is spent is spent in
3614 # revision). We could check `fn not in ctx` even when rev is None,
3614 # pathauditor checks without this in mozilla-central
3615 # but it's less racy to protect againt that in readfile.
3615 contextmanager = repo.wvfs.audit.cached
3616 if rev is not None and fn not in ctx:
3616 else:
3617 continue
3617 contextmanager = util.nullcontextmanager
3618
3618 with contextmanager():
3619 copy = None
3619 for fn in fns:
3620 if follow:
3620 # fn might not exist in the revision (could be a file removed by
3621 copy = getrenamed(fn, rev)
3621 # the revision). We could check `fn not in ctx` even when rev is
3622 if copy:
3622 # None, but it's less racy to protect againt that in readfile.
3623 copies.setdefault(rev, {})[fn] = copy
3623 if rev is not None and fn not in ctx:
3624 if fn in skip:
3624 continue
3625 skip.add(copy)
3625
3626 if fn in skip:
3626 copy = None
3627 continue
3627 if follow:
3628 files.append(fn)
3628 copy = getrenamed(fn, rev)
3629
3629 if copy:
3630 if fn not in matches[rev]:
3630 copies.setdefault(rev, {})[fn] = copy
3631 grepbody(fn, rev, readfile(ctx, fn))
3631 if fn in skip:
3632
3632 skip.add(copy)
3633 if diff:
3633 if fn in skip:
3634 pfn = copy or fn
3634 continue
3635 if pfn not in matches[parent] and pfn in pctx:
3635 files.append(fn)
3636 grepbody(pfn, parent, readfile(pctx, pfn))
3636
3637 if fn not in matches[rev]:
3638 grepbody(fn, rev, readfile(ctx, fn))
3639
3640 if diff:
3641 pfn = copy or fn
3642 if pfn not in matches[parent] and pfn in pctx:
3643 grepbody(pfn, parent, readfile(pctx, pfn))
3637
3644
3638 ui.pager(b'grep')
3645 ui.pager(b'grep')
3639 fm = ui.formatter(b'grep', opts)
3646 fm = ui.formatter(b'grep', opts)
@@ -1,5 +1,6 b''
1 from __future__ import absolute_import
1 from __future__ import absolute_import
2
2
3 import contextlib
3 import errno
4 import errno
4 import os
5 import os
5 import posixpath
6 import posixpath
@@ -148,6 +149,19 b' class pathauditor(object):'
148 except (OSError, error.Abort):
149 except (OSError, error.Abort):
149 return False
150 return False
150
151
152 @contextlib.contextmanager
153 def cached(self):
154 if self._cached:
155 yield
156 else:
157 try:
158 self._cached = True
159 yield
160 finally:
161 self.audited.clear()
162 self.auditeddir.clear()
163 self._cached = False
164
151
165
152 def canonpath(root, cwd, myname, auditor=None):
166 def canonpath(root, cwd, myname, auditor=None):
153 '''return the canonical path of myname, given cwd and root
167 '''return the canonical path of myname, given cwd and root
General Comments 0
You need to be logged in to leave comments. Login now