##// END OF EJS Templates
pathauditor: disable cache of audited paths by default (issue5628)...
Yuya Nishihara -
r33722:377e8dda stable
parent child Browse files
Show More
@@ -382,7 +382,7 b' def overridewalk(orig, self, match, subr'
382 visit.update(f for f in copymap
382 visit.update(f for f in copymap
383 if f not in results and matchfn(f))
383 if f not in results and matchfn(f))
384
384
385 audit = pathutil.pathauditor(self._root).check
385 audit = pathutil.pathauditor(self._root, cached=True).check
386 auditpass = [f for f in visit if audit(f)]
386 auditpass = [f for f in visit if audit(f)]
387 auditpass.sort()
387 auditpass.sort()
388 auditfail = visit.difference(auditpass)
388 auditfail = visit.difference(auditpass)
@@ -3538,7 +3538,7 b' def _performrevert(repo, parents, ctx, a'
3538 pass
3538 pass
3539 repo.dirstate.remove(f)
3539 repo.dirstate.remove(f)
3540
3540
3541 audit_path = pathutil.pathauditor(repo.root)
3541 audit_path = pathutil.pathauditor(repo.root, cached=True)
3542 for f in actions['forget'][0]:
3542 for f in actions['forget'][0]:
3543 if interactive:
3543 if interactive:
3544 choice = repo.ui.promptchoice(
3544 choice = repo.ui.promptchoice(
@@ -1153,7 +1153,7 b' class dirstate(object):'
1153 # that wasn't ignored, and everything that matched was stat'ed
1153 # that wasn't ignored, and everything that matched was stat'ed
1154 # and is already in results.
1154 # and is already in results.
1155 # The rest must thus be ignored or under a symlink.
1155 # The rest must thus be ignored or under a symlink.
1156 audit_path = pathutil.pathauditor(self._root)
1156 audit_path = pathutil.pathauditor(self._root, cached=True)
1157
1157
1158 for nf in iter(visit):
1158 for nf in iter(visit):
1159 # If a stat for the same file was already added with a
1159 # If a stat for the same file was already added with a
@@ -339,11 +339,11 b' class localrepository(object):'
339 # only used when writing this comment: basectx.match
339 # only used when writing this comment: basectx.match
340 self.auditor = pathutil.pathauditor(self.root, self._checknested)
340 self.auditor = pathutil.pathauditor(self.root, self._checknested)
341 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
341 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
342 realfs=False)
342 realfs=False, cached=True)
343 self.baseui = baseui
343 self.baseui = baseui
344 self.ui = baseui.copy()
344 self.ui = baseui.copy()
345 self.ui.copy = baseui.copy # prevent copying repo configuration
345 self.ui.copy = baseui.copy # prevent copying repo configuration
346 self.vfs = vfsmod.vfs(self.path)
346 self.vfs = vfsmod.vfs(self.path, cacheaudited=True)
347 if (self.ui.configbool('devel', 'all-warnings') or
347 if (self.ui.configbool('devel', 'all-warnings') or
348 self.ui.configbool('devel', 'check-locks')):
348 self.ui.configbool('devel', 'check-locks')):
349 self.vfs.audit = self._getvfsward(self.vfs.audit)
349 self.vfs.audit = self._getvfsward(self.vfs.audit)
@@ -426,12 +426,13 b' class localrepository(object):'
426 '"sparse" extensions to access'))
426 '"sparse" extensions to access'))
427
427
428 self.store = store.store(
428 self.store = store.store(
429 self.requirements, self.sharedpath, vfsmod.vfs)
429 self.requirements, self.sharedpath,
430 lambda base: vfsmod.vfs(base, cacheaudited=True))
430 self.spath = self.store.path
431 self.spath = self.store.path
431 self.svfs = self.store.vfs
432 self.svfs = self.store.vfs
432 self.sjoin = self.store.join
433 self.sjoin = self.store.join
433 self.vfs.createmode = self.store.createmode
434 self.vfs.createmode = self.store.createmode
434 self.cachevfs = vfsmod.vfs(cachepath)
435 self.cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
435 self.cachevfs.createmode = self.store.createmode
436 self.cachevfs.createmode = self.store.createmode
436 if (self.ui.configbool('devel', 'all-warnings') or
437 if (self.ui.configbool('devel', 'all-warnings') or
437 self.ui.configbool('devel', 'check-locks')):
438 self.ui.configbool('devel', 'check-locks')):
@@ -33,13 +33,18 b' class pathauditor(object):'
33 The file system checks are only done when 'realfs' is set to True (the
33 The file system checks are only done when 'realfs' is set to True (the
34 default). They should be disable then we are auditing path for operation on
34 default). They should be disable then we are auditing path for operation on
35 stored history.
35 stored history.
36
37 If 'cached' is set to True, audited paths and sub-directories are cached.
38 Be careful to not keep the cache of unmanaged directories for long because
39 audited paths may be replaced with symlinks.
36 '''
40 '''
37
41
38 def __init__(self, root, callback=None, realfs=True):
42 def __init__(self, root, callback=None, realfs=True, cached=False):
39 self.audited = set()
43 self.audited = set()
40 self.auditeddir = set()
44 self.auditeddir = set()
41 self.root = root
45 self.root = root
42 self._realfs = realfs
46 self._realfs = realfs
47 self._cached = cached
43 self.callback = callback
48 self.callback = callback
44 if os.path.lexists(root) and not util.fscasesensitive(root):
49 if os.path.lexists(root) and not util.fscasesensitive(root):
45 self.normcase = util.normcase
50 self.normcase = util.normcase
@@ -96,10 +101,11 b' class pathauditor(object):'
96 self._checkfs(prefix, path)
101 self._checkfs(prefix, path)
97 prefixes.append(normprefix)
102 prefixes.append(normprefix)
98
103
99 self.audited.add(normpath)
104 if self._cached:
100 # only add prefixes to the cache after checking everything: we don't
105 self.audited.add(normpath)
101 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
106 # only add prefixes to the cache after checking everything: we don't
102 self.auditeddir.update(prefixes)
107 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
108 self.auditeddir.update(prefixes)
103
109
104 def _checkfs(self, prefix, path):
110 def _checkfs(self, prefix, path):
105 """raise exception if a file system backed check fails"""
111 """raise exception if a file system backed check fails"""
@@ -738,7 +738,7 b' def _interestingfiles(repo, matcher):'
738 This is different from dirstate.status because it doesn't care about
738 This is different from dirstate.status because it doesn't care about
739 whether files are modified or clean.'''
739 whether files are modified or clean.'''
740 added, unknown, deleted, removed, forgotten = [], [], [], [], []
740 added, unknown, deleted, removed, forgotten = [], [], [], [], []
741 audit_path = pathutil.pathauditor(repo.root)
741 audit_path = pathutil.pathauditor(repo.root, cached=True)
742
742
743 ctx = repo[None]
743 ctx = repo[None]
744 dirstate = repo.dirstate
744 dirstate = repo.dirstate
@@ -295,8 +295,13 b' class vfs(abstractvfs):'
295
295
296 This class is used to hide the details of COW semantics and
296 This class is used to hide the details of COW semantics and
297 remote file access from higher level code.
297 remote file access from higher level code.
298
299 'cacheaudited' should be enabled only if (a) vfs object is short-lived, or
300 (b) the base directory is managed by hg and considered sort-of append-only.
301 See pathutil.pathauditor() for details.
298 '''
302 '''
299 def __init__(self, base, audit=True, expandpath=False, realpath=False):
303 def __init__(self, base, audit=True, cacheaudited=False, expandpath=False,
304 realpath=False):
300 if expandpath:
305 if expandpath:
301 base = util.expandpath(base)
306 base = util.expandpath(base)
302 if realpath:
307 if realpath:
@@ -304,7 +309,7 b' class vfs(abstractvfs):'
304 self.base = base
309 self.base = base
305 self._audit = audit
310 self._audit = audit
306 if audit:
311 if audit:
307 self.audit = pathutil.pathauditor(self.base)
312 self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
308 else:
313 else:
309 self.audit = (lambda path, mode=None: True)
314 self.audit = (lambda path, mode=None: True)
310 self.createmode = None
315 self.createmode = None
@@ -169,9 +169,9 b' and the rebase should fail (issue5628)'
169 $ hg up -qC 2
169 $ hg up -qC 2
170 $ hg rebase -s 2 -d 1 --config extensions.rebase=
170 $ hg rebase -s 2 -d 1 --config extensions.rebase=
171 rebasing 2:e73c21d6b244 "file a/poisoned" (tip)
171 rebasing 2:e73c21d6b244 "file a/poisoned" (tip)
172 saved backup bundle to * (glob)
172 abort: path 'a/poisoned' traverses symbolic link 'a'
173 [255]
173 $ ls ../merge-symlink-out
174 $ ls ../merge-symlink-out
174 poisoned
175
175
176 $ cd ..
176 $ cd ..
177
177
@@ -211,10 +211,9 b' audited first by calculateupdates(), whe'
211
211
212 $ hg up -qC null
212 $ hg up -qC null
213 $ hg up 1
213 $ hg up 1
214 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 abort: path 'a/b' traverses symbolic link 'a'
215 [255]
215 $ ls ../update-symlink-out
216 $ ls ../update-symlink-out
216 b
217 $ rm ../update-symlink-out/b
218
217
219 try branch update replacing directory with symlink, and its content: the
218 try branch update replacing directory with symlink, and its content: the
220 path 'a' is audited as a directory first, which should be audited again as
219 path 'a' is audited as a directory first, which should be audited again as
@@ -223,9 +222,9 b' a symlink.'
223 $ rm -f a
222 $ rm -f a
224 $ hg up -qC 2
223 $ hg up -qC 2
225 $ hg up 1
224 $ hg up 1
226 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
225 abort: path 'a/b' traverses symbolic link 'a'
226 [255]
227 $ ls ../update-symlink-out
227 $ ls ../update-symlink-out
228 b
229
228
230 $ cd ..
229 $ cd ..
231
230
@@ -953,10 +953,9 b' and the merge should fail (issue5628)'
953 *** runcommand up -qC 2
953 *** runcommand up -qC 2
954 *** runcommand up -qC 1
954 *** runcommand up -qC 1
955 *** runcommand merge 2
955 *** runcommand merge 2
956 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
956 abort: path 'a/poisoned' traverses symbolic link 'a'
957 (branch merge, don't forget to commit)
957 [255]
958 $ ls ../merge-symlink-out
958 $ ls ../merge-symlink-out
959 poisoned
960
959
961 cache of repo.auditor should be discarded, so matcher would never traverse
960 cache of repo.auditor should be discarded, so matcher would never traverse
962 symlinks:
961 symlinks:
@@ -980,7 +979,8 b' symlinks:'
980 *** runcommand up -qC 0
979 *** runcommand up -qC 0
981 *** runcommand up -qC 1
980 *** runcommand up -qC 1
982 *** runcommand files a/poisoned
981 *** runcommand files a/poisoned
983 [1]
982 abort: path 'a/poisoned' traverses symbolic link 'a'
983 [255]
984
984
985 $ cd ..
985 $ cd ..
986
986
General Comments 0
You need to be logged in to leave comments. Login now