hgext/fsmonitor/state.py
changeset 32816 1b25c648d5b7
parent 31215 15c998528c36
child 34463 718f7acd6d5e
equal deleted inserted replaced
32815:15e85dded933 32816:1b25c648d5b7
    11 import os
    11 import os
    12 import socket
    12 import socket
    13 import struct
    13 import struct
    14 
    14 
    15 from mercurial.i18n import _
    15 from mercurial.i18n import _
    16 from mercurial import pathutil
    16 from mercurial import (
       
    17     pathutil,
       
    18     util,
       
    19 )
    17 
    20 
    18 _version = 4
    21 _version = 4
    19 _versionformat = ">I"
    22 _versionformat = ">I"
    20 
    23 
    21 class state(object):
    24 class state(object):
    22     def __init__(self, repo):
    25     def __init__(self, repo):
    23         self._vfs = repo.vfs
    26         self._vfs = repo.vfs
    24         self._ui = repo.ui
    27         self._ui = repo.ui
    25         self._rootdir = pathutil.normasprefix(repo.root)
    28         self._rootdir = pathutil.normasprefix(repo.root)
    26         self._lastclock = None
    29         self._lastclock = None
       
    30         self._identity = util.filestat(None)
    27 
    31 
    28         self.mode = self._ui.config('fsmonitor', 'mode', default='on')
    32         self.mode = self._ui.config('fsmonitor', 'mode', default='on')
    29         self.walk_on_invalidate = self._ui.configbool(
    33         self.walk_on_invalidate = self._ui.configbool(
    30             'fsmonitor', 'walk_on_invalidate', False)
    34             'fsmonitor', 'walk_on_invalidate', False)
    31         self.timeout = float(self._ui.config(
    35         self.timeout = float(self._ui.config(
    33 
    37 
    34     def get(self):
    38     def get(self):
    35         try:
    39         try:
    36             file = self._vfs('fsmonitor.state', 'rb')
    40             file = self._vfs('fsmonitor.state', 'rb')
    37         except IOError as inst:
    41         except IOError as inst:
       
    42             self._identity = util.filestat(None)
    38             if inst.errno != errno.ENOENT:
    43             if inst.errno != errno.ENOENT:
    39                 raise
    44                 raise
    40             return None, None, None
    45             return None, None, None
       
    46 
       
    47         self._identity = util.filestat.fromfp(file)
    41 
    48 
    42         versionbytes = file.read(4)
    49         versionbytes = file.read(4)
    43         if len(versionbytes) < 4:
    50         if len(versionbytes) < 4:
    44             self._ui.log(
    51             self._ui.log(
    45                 'fsmonitor', 'fsmonitor: state file only has %d bytes, '
    52                 'fsmonitor', 'fsmonitor: state file only has %d bytes, '
    88     def set(self, clock, ignorehash, notefiles):
    95     def set(self, clock, ignorehash, notefiles):
    89         if clock is None:
    96         if clock is None:
    90             self.invalidate()
    97             self.invalidate()
    91             return
    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         try:
   107         try:
    94             file = self._vfs('fsmonitor.state', 'wb', atomictemp=True)
   108             file = self._vfs('fsmonitor.state', 'wb', atomictemp=True,
       
   109                 checkambig=True)
    95         except (IOError, OSError):
   110         except (IOError, OSError):
    96             self._ui.warn(_("warning: unable to write out fsmonitor state\n"))
   111             self._ui.warn(_("warning: unable to write out fsmonitor state\n"))
    97             return
   112             return
    98 
   113 
    99         with file:
   114         with file:
   109         try:
   124         try:
   110             os.unlink(os.path.join(self._rootdir, '.hg', 'fsmonitor.state'))
   125             os.unlink(os.path.join(self._rootdir, '.hg', 'fsmonitor.state'))
   111         except OSError as inst:
   126         except OSError as inst:
   112             if inst.errno != errno.ENOENT:
   127             if inst.errno != errno.ENOENT:
   113                 raise
   128                 raise
       
   129         self._identity = util.filestat(None)
   114 
   130 
   115     def setlastclock(self, clock):
   131     def setlastclock(self, clock):
   116         self._lastclock = clock
   132         self._lastclock = clock
   117 
   133 
   118     def getlastclock(self):
   134     def getlastclock(self):