##// END OF EJS Templates
fsmonitor: don't write out state if identity has changed (issue5581)...
Siddharth Agarwal -
r32816:1b25c648 default
parent child Browse files
Show More
@@ -13,7 +13,10 b' import socket'
13 13 import struct
14 14
15 15 from mercurial.i18n import _
16 from mercurial import pathutil
16 from mercurial import (
17 pathutil,
18 util,
19 )
17 20
18 21 _version = 4
19 22 _versionformat = ">I"
@@ -24,6 +27,7 b' class state(object):'
24 27 self._ui = repo.ui
25 28 self._rootdir = pathutil.normasprefix(repo.root)
26 29 self._lastclock = None
30 self._identity = util.filestat(None)
27 31
28 32 self.mode = self._ui.config('fsmonitor', 'mode', default='on')
29 33 self.walk_on_invalidate = self._ui.configbool(
@@ -35,10 +39,13 b' class state(object):'
35 39 try:
36 40 file = self._vfs('fsmonitor.state', 'rb')
37 41 except IOError as inst:
42 self._identity = util.filestat(None)
38 43 if inst.errno != errno.ENOENT:
39 44 raise
40 45 return None, None, None
41 46
47 self._identity = util.filestat.fromfp(file)
48
42 49 versionbytes = file.read(4)
43 50 if len(versionbytes) < 4:
44 51 self._ui.log(
@@ -90,8 +97,16 b' class state(object):'
90 97 self.invalidate()
91 98 return
92 99
100 # Read the identity from the file on disk rather than from the open file
101 # pointer below, because the latter is actually a brand new file.
102 identity = util.filestat.frompath(self._vfs.join('fsmonitor.state'))
103 if identity != self._identity:
104 self._ui.debug('skip updating fsmonitor.state: identity mismatch\n')
105 return
106
93 107 try:
94 file = self._vfs('fsmonitor.state', 'wb', atomictemp=True)
108 file = self._vfs('fsmonitor.state', 'wb', atomictemp=True,
109 checkambig=True)
95 110 except (IOError, OSError):
96 111 self._ui.warn(_("warning: unable to write out fsmonitor state\n"))
97 112 return
@@ -111,6 +126,7 b' class state(object):'
111 126 except OSError as inst:
112 127 if inst.errno != errno.ENOENT:
113 128 raise
129 self._identity = util.filestat(None)
114 130
115 131 def setlastclock(self, clock):
116 132 self._lastclock = clock
@@ -1519,6 +1519,11 b' class filestat(object):'
1519 1519 stat = None
1520 1520 return cls(stat)
1521 1521
1522 @classmethod
1523 def fromfp(cls, fp):
1524 stat = os.fstat(fp.fileno())
1525 return cls(stat)
1526
1522 1527 __hash__ = object.__hash__
1523 1528
1524 1529 def __eq__(self, old):
@@ -160,6 +160,34 b' treated differently in _checklookup() ac'
160 160
161 161 $ rm b
162 162
163 #if fsmonitor
164
165 Create fsmonitor state.
166
167 $ hg status
168 $ f --type .hg/fsmonitor.state
169 .hg/fsmonitor.state: file
170
171 Test that invalidating fsmonitor state in the middle (which doesn't require the
172 wlock) causes the fsmonitor update to be skipped.
173 hg debugrebuilddirstate ensures that the dirstaterace hook will be called, but
174 it also invalidates the fsmonitor state. So back it up and restore it.
175
176 $ mv .hg/fsmonitor.state .hg/fsmonitor.state.tmp
177 $ hg debugrebuilddirstate
178 $ mv .hg/fsmonitor.state.tmp .hg/fsmonitor.state
179
180 $ cat > $TESTTMP/dirstaterace.sh <<EOF
181 > rm .hg/fsmonitor.state
182 > EOF
183
184 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py --debug
185 skip updating fsmonitor.state: identity mismatch
186 $ f .hg/fsmonitor.state
187 .hg/fsmonitor.state: file not found
188
189 #endif
190
163 191 Set up a rebase situation for issue5581.
164 192
165 193 $ echo c2 > a
General Comments 0
You need to be logged in to leave comments. Login now