Mercurial > hg-stable
changeset 8599:1f706b1b62f3
inotify: server: refactor updatestatus()
* Instead of one entry point, use two entry points, updatefile()
and deletefile(), both internally calling the helper function _updatestatus
* Do not rely on TypeError to detect the type of oldstatus: use isinstance
* The call updatestatus(wpath, None) in deleted() was a bit particular:
because no osstat and no newstatus was given, the newstatus was determined
using the data stored internally. To replace this exact behavior with the
new code, one would use:
root, fn = self.split(wpath)
d = self.dir(self.tree, root)
self.filedeleted(wpath, d.get(fn))
This, however, duplicates code with _updatestatus(), which led us to an
interesting question: why are we basing ourselves on repowatcher data to
update the status, where everywhere else, we are comparing against dirsate?
There is no reason to do this, which is why the new code is:
self.filedeleted(wpath, self.repo.dirstate[wpath])
Incidentally, after this, the test for issue1371 passes again.
author | Nicolas Dumazet <nicdumz.commits@gmail.com> |
---|---|
date | Sun, 24 May 2009 18:43:05 +0900 |
parents | 67f76a4463ef |
children | d46cdfcecaf1 |
files | hgext/inotify/server.py |
diffstat | 1 files changed, 45 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/inotify/server.py Fri May 08 12:19:57 2009 +0900 +++ b/hgext/inotify/server.py Sun May 24 18:43:05 2009 +0900 @@ -250,36 +250,48 @@ return 'i' return type_ - def updatestatus(self, wfn, osstat=None, newstatus=None): + def updatefile(self, wfn, osstat): + ''' + update the file entry of an existing file. + + osstat: (mode, size, time) tuple, as returned by os.lstat(wfn) + ''' + + self._updatestatus(wfn, self.filestatus(wfn, osstat)) + + def deletefile(self, wfn, oldstatus): + ''' + update the entry of a file which has been deleted. + + oldstatus: char in statuskeys, status of the file before deletion + ''' + if oldstatus == 'r': + newstatus = 'r' + elif oldstatus in 'almn': + newstatus = '!' + else: + newstatus = None + + self.statcache.pop(wfn, None) + self._updatestatus(wfn, newstatus) + + def _updatestatus(self, wfn, newstatus): ''' Update the stored status of a file or directory. - osstat: (mode, size, time) tuple, as returned by os.lstat(wfn) - - newstatus: char in statuskeys, new status to apply. + newstatus: - char in (statuskeys + 'ni'), new status to apply. + - or None, to stop tracking wfn ''' - if osstat: - newstatus = self.filestatus(wfn, osstat) - else: - self.statcache.pop(wfn, None) root, fn = self.split(wfn) d = self.dir(self.tree, root) + oldstatus = d.get(fn) - isdir = False - if oldstatus: - try: - if not newstatus: - if oldstatus in 'almn': - newstatus = '!' - elif oldstatus == 'r': - newstatus = 'r' - except TypeError: - # oldstatus may be a dict left behind by a deleted - # directory - isdir = True - else: - if oldstatus in self.statuskeys and oldstatus != newstatus: - del self.dir(self.statustrees[oldstatus], root)[fn] + # oldstatus can be either: + # - None : fn is new + # - a char in statuskeys: fn is a (tracked) file + # - a dict: fn is a directory + isdir = isinstance(oldstatus, dict) + if self.ui.debugflag and oldstatus != newstatus: if isdir: self.ui.note(_('status: %r dir(%d) -> %s\n') % @@ -288,6 +300,9 @@ self.ui.note(_('status: %r %s -> %s\n') % (wfn, oldstatus, newstatus)) if not isdir: + if oldstatus and oldstatus in self.statuskeys \ + and oldstatus != newstatus: + del self.dir(self.statustrees[oldstatus], root)[fn] if newstatus and newstatus != 'i': d[fn] = newstatus if newstatus in self.statuskeys: @@ -299,7 +314,7 @@ elif not newstatus: # a directory is being removed, check its contents for subfile, b in oldstatus.copy().iteritems(): - self.updatestatus(wfn + '/' + subfile, None) + self._updatestatus(wfn + '/' + subfile, None) def check_deleted(self, key): @@ -325,7 +340,7 @@ d = self.dir(self.tree, wroot) for fn in files: wfn = join(wroot, fn) - self.updatestatus(wfn, self.getstat(wfn)) + self.updatefile(wfn, self.getstat(wfn)) ds.pop(wfn, None) wtopdir = topdir if wtopdir and wtopdir[-1] != '/': @@ -337,9 +352,9 @@ st = self.stat(wfn) except OSError: status = state[0] - self.updatestatus(wfn, None, newstatus=status) + self.deletefile(wfn, status) else: - self.updatestatus(wfn, st) + self.updatefile(wfn, st) self.check_deleted('!') self.check_deleted('r') @@ -409,7 +424,7 @@ try: st = self.stat(wpath) if stat.S_ISREG(st[0]): - self.updatestatus(wpath, st) + self.updatefile(wpath, st) except OSError: pass @@ -420,7 +435,7 @@ st = self.stat(wpath) if stat.S_ISREG(st[0]): if self.repo.dirstate[wpath] in 'lmn': - self.updatestatus(wpath, st) + self.updatefile(wpath, st) except OSError: pass @@ -432,7 +447,7 @@ self.check_dirstate() return - self.updatestatus(wpath, None) + self.deletefile(wpath, self.repo.dirstate[wpath]) def schedule_work(self, wpath, evt): prev = self.eventq.setdefault(wpath, [])