eol: on update, only re-check files if filtering changed

Before, update would mark all files as 'normallookup' in dirstate if .hgeol
changed so all files would get the new filtering applied. That takes some time
... and is pointless if the filtering for that file didn't change.

Instead, keep track of the old filtering and only check files where the
filtering is changed.

To keep the old filtering, change to write the applied .hgeol content to
.hg/eol.cache instead of just touching it. That change is backwards/forwards
compatible.

In a real world test, this takes an update that is changing .hgeol and 30000
files from 12s to 4s - where the remaining eol overhead is 1-2s.
This commit is contained in:
Mads Kiilerich 2016-10-09 15:54:49 +02:00
parent 48ea4c11ea
commit cb6727b739

View File

@ -312,10 +312,15 @@ def reposetup(ui, repo):
self._eolmatch = util.never
return
oldeol = None
try:
cachemtime = os.path.getmtime(self.join("eol.cache"))
except OSError:
cachemtime = 0
else:
olddata = self.vfs.read("eol.cache")
if olddata:
oldeol = eolfile(self.ui, self.root, olddata)
try:
eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
@ -324,17 +329,37 @@ def reposetup(ui, repo):
if eolmtime > cachemtime:
self.ui.debug("eol: detected change in .hgeol\n")
hgeoldata = self.wvfs.read('.hgeol')
neweol = eolfile(self.ui, self.root, hgeoldata)
wlock = None
try:
wlock = self.wlock()
for f in self.dirstate:
if self.dirstate[f] == 'n':
# all normal files need to be looked at
# again since the new .hgeol file might no
# longer match a file it matched before
self.dirstate.normallookup(f)
# Create or touch the cache to update mtime
self.vfs("eol.cache", "w").close()
if self.dirstate[f] != 'n':
continue
if oldeol is not None:
if not oldeol.match(f) and not neweol.match(f):
continue
oldkey = None
for pattern, key, m in oldeol.patterns:
if m(f):
oldkey = key
break
newkey = None
for pattern, key, m in neweol.patterns:
if m(f):
newkey = key
break
if oldkey == newkey:
continue
# all normal files need to be looked at again since
# the new .hgeol file specify a different filter
self.dirstate.normallookup(f)
# Write the cache to update mtime and cache .hgeol
with self.vfs("eol.cache", "w") as f:
f.write(hgeoldata)
wlock.release()
except error.LockUnavailable:
# If we cannot lock the repository and clear the