inotify: fix replacing a folder with a file (issue1375)
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Tue, 11 Nov 2008 23:16:59 +0100
changeset 7350 c5dbe86b0fee
parent 7349 f711b8e0d2b3
child 7351 5ab0abf27dd9
inotify: fix replacing a folder with a file (issue1375)
hgext/inotify/server.py
tests/test-inotify
tests/test-inotify-issue1371
tests/test-inotify.out
--- a/hgext/inotify/server.py	Sun Nov 09 12:15:32 2008 +0100
+++ b/hgext/inotify/server.py	Tue Nov 11 23:16:59 2008 +0100
@@ -19,6 +19,9 @@
 
 class AlreadyStartedException(Exception): pass
 
+class statusdict(dict):
+    status = None
+
 def join(a, b):
     if a:
         if a[-1] == '/':
@@ -222,7 +225,7 @@
     def dir(self, tree, path):
         if path:
             for name in path.split('/'):
-                tree.setdefault(name, {})
+                tree.setdefault(name, statusdict())
                 tree = tree[name]
         return tree
 
@@ -232,9 +235,11 @@
                 for name in path.split('/'):
                     tree = tree[name]
             except KeyError:
-                return 'x'
+                tree = statusdict()
+                tree.status = 'x'
             except TypeError:
-                return 'd'
+                tree = statusdict()
+                tree.status = 'd'
         return tree
 
     def split(self, path):
@@ -272,7 +277,7 @@
             self.statcache.pop(wfn, None)
         root, fn = self.split(wfn)
         d = self.dir(self.tree, root)
-        oldstatus = d.get(fn)
+        oldstatus = d.setdefault(fn, statusdict()).status
         isdir = False
         if oldstatus:
             try:
@@ -297,11 +302,11 @@
                              (wfn, oldstatus, status))
         if not isdir:
             if status and status != 'i':
-                d[fn] = status
+                d[fn].status = status
                 if status in self.statuskeys:
                     dd = self.dir(self.statustrees[status], root)
                     if oldstatus != status or fn not in dd:
-                        dd[fn] = status
+                        dd.setdefault(fn, statusdict()).status = status
             else:
                 d.pop(fn, None)
 
@@ -363,12 +368,10 @@
 
         for name, val in tree.iteritems():
             path = join(prefix, name)
-            try:
-                if val in states:
-                    yield path, val
-            except TypeError:
-                for p in self.walk(states, val, path):
-                    yield p
+            if val.status is not None and val.status in states:
+                yield path, val
+            for p in self.walk(states, val, path):
+                yield p
 
     def update_hgignore(self):
         # An update of the ignore file can potentially change the
@@ -619,12 +622,10 @@
             def genresult(states, tree):
                 for fn in names:
                     l = self.watcher.lookup(fn, tree)
-                    try:
-                        if l in states:
-                            yield fn
-                    except TypeError:
-                        for f, s in self.watcher.walk(states, l, fn):
-                            yield f
+                    if l.status is not None and l.status in states:
+                        yield fn
+                    for f, s in self.watcher.walk(states, l, fn):
+                        yield f
 
         results = ['\0'.join(r) for r in [
             genresult('l', self.watcher.statustrees['l']),
--- a/tests/test-inotify	Sun Nov 09 12:15:32 2008 +0100
+++ b/tests/test-inotify	Tue Nov 11 23:16:59 2008 +0100
@@ -13,6 +13,9 @@
 
 echo "[extensions]" >> $HGRCPATH
 echo "inotify=" >> $HGRCPATH
+echo "[inotify]" >> $HGRCPATH
+echo "debug=1" >> $HGRCPATH
+echo "log=/tmp/inot.log" >> $HGRCPATH
 
 echo % inserve
 hg inserve -d --pid-file=hg.pid
@@ -27,4 +30,28 @@
 echo % all
 hg status -A
 
+#issue 1375
+#Testing that we can remove a folder and then add a file with the same name
+
+mkdir h f g
+echo h > h/h
+echo f > f/f
+echo g > g/g
+
+hg ci -Am t
+sleep 1
+hg rm h
+hg rm f
+sleep 1
+echo h >h
+ln -s g f
+
+hg add h
+sleep 1
+hg add f
+
+hg status
+hg ci -m0
+hg status
 kill `cat hg.pid`
+
--- a/tests/test-inotify-issue1371	Sun Nov 09 12:15:32 2008 +0100
+++ b/tests/test-inotify-issue1371	Tue Nov 11 23:16:59 2008 +0100
@@ -8,6 +8,8 @@
 
 echo "[extensions]" >> $HGRCPATH
 echo "inotify=" >> $HGRCPATH
+echo "[inotify]" >> $HGRCPATH
+echo "debug = 1" >> $HGRCPATH
 echo inserv1
 
 echo % inserve
@@ -27,6 +29,7 @@
 touch g
 hg add g
 hg mv e h
+sleep 1
 hg status
 
 sleep 1
--- a/tests/test-inotify.out	Sun Nov 09 12:15:32 2008 +0100
+++ b/tests/test-inotify.out	Tue Nov 11 23:16:59 2008 +0100
@@ -27,3 +27,13 @@
 C dir/x
 C dir/y
 C e
+adding f/f
+adding g/g
+adding h/h
+adding hg.pid
+removing h/h
+removing f/f
+A f
+A h
+R f/f
+R h/h