comparison hgext/inotify/server.py @ 7350:c5dbe86b0fee

inotify: fix replacing a folder with a file (issue1375)
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Tue, 11 Nov 2008 23:16:59 +0100
parents fd4bf5269733
children 5ab0abf27dd9
comparison
equal deleted inserted replaced
7349:f711b8e0d2b3 7350:c5dbe86b0fee
16 from linux import watcher 16 from linux import watcher
17 except ImportError: 17 except ImportError:
18 raise 18 raise
19 19
20 class AlreadyStartedException(Exception): pass 20 class AlreadyStartedException(Exception): pass
21
22 class statusdict(dict):
23 status = None
21 24
22 def join(a, b): 25 def join(a, b):
23 if a: 26 if a:
24 if a[-1] == '/': 27 if a[-1] == '/':
25 return a + b 28 return a + b
220 raise 'wtf? ' + path 223 raise 'wtf? ' + path
221 224
222 def dir(self, tree, path): 225 def dir(self, tree, path):
223 if path: 226 if path:
224 for name in path.split('/'): 227 for name in path.split('/'):
225 tree.setdefault(name, {}) 228 tree.setdefault(name, statusdict())
226 tree = tree[name] 229 tree = tree[name]
227 return tree 230 return tree
228 231
229 def lookup(self, path, tree): 232 def lookup(self, path, tree):
230 if path: 233 if path:
231 try: 234 try:
232 for name in path.split('/'): 235 for name in path.split('/'):
233 tree = tree[name] 236 tree = tree[name]
234 except KeyError: 237 except KeyError:
235 return 'x' 238 tree = statusdict()
239 tree.status = 'x'
236 except TypeError: 240 except TypeError:
237 return 'd' 241 tree = statusdict()
242 tree.status = 'd'
238 return tree 243 return tree
239 244
240 def split(self, path): 245 def split(self, path):
241 c = path.rfind('/') 246 c = path.rfind('/')
242 if c == -1: 247 if c == -1:
270 status = self.filestatus(wfn, st) 275 status = self.filestatus(wfn, st)
271 else: 276 else:
272 self.statcache.pop(wfn, None) 277 self.statcache.pop(wfn, None)
273 root, fn = self.split(wfn) 278 root, fn = self.split(wfn)
274 d = self.dir(self.tree, root) 279 d = self.dir(self.tree, root)
275 oldstatus = d.get(fn) 280 oldstatus = d.setdefault(fn, statusdict()).status
276 isdir = False 281 isdir = False
277 if oldstatus: 282 if oldstatus:
278 try: 283 try:
279 if not status: 284 if not status:
280 if oldstatus in 'almn': 285 if oldstatus in 'almn':
295 else: 300 else:
296 self.ui.note(_('status: %r %s -> %s\n') % 301 self.ui.note(_('status: %r %s -> %s\n') %
297 (wfn, oldstatus, status)) 302 (wfn, oldstatus, status))
298 if not isdir: 303 if not isdir:
299 if status and status != 'i': 304 if status and status != 'i':
300 d[fn] = status 305 d[fn].status = status
301 if status in self.statuskeys: 306 if status in self.statuskeys:
302 dd = self.dir(self.statustrees[status], root) 307 dd = self.dir(self.statustrees[status], root)
303 if oldstatus != status or fn not in dd: 308 if oldstatus != status or fn not in dd:
304 dd[fn] = status 309 dd.setdefault(fn, statusdict()).status = status
305 else: 310 else:
306 d.pop(fn, None) 311 d.pop(fn, None)
307 312
308 def check_deleted(self, key): 313 def check_deleted(self, key):
309 # Files that had been deleted but were present in the dirstate 314 # Files that had been deleted but were present in the dirstate
361 def walk(self, states, tree, prefix=''): 366 def walk(self, states, tree, prefix=''):
362 # This is the "inner loop" when talking to the client. 367 # This is the "inner loop" when talking to the client.
363 368
364 for name, val in tree.iteritems(): 369 for name, val in tree.iteritems():
365 path = join(prefix, name) 370 path = join(prefix, name)
366 try: 371 if val.status is not None and val.status in states:
367 if val in states: 372 yield path, val
368 yield path, val 373 for p in self.walk(states, val, path):
369 except TypeError: 374 yield p
370 for p in self.walk(states, val, path):
371 yield p
372 375
373 def update_hgignore(self): 376 def update_hgignore(self):
374 # An update of the ignore file can potentially change the 377 # An update of the ignore file can potentially change the
375 # states of all unknown and ignored files. 378 # states of all unknown and ignored files.
376 379
617 yield fn 620 yield fn
618 else: 621 else:
619 def genresult(states, tree): 622 def genresult(states, tree):
620 for fn in names: 623 for fn in names:
621 l = self.watcher.lookup(fn, tree) 624 l = self.watcher.lookup(fn, tree)
622 try: 625 if l.status is not None and l.status in states:
623 if l in states: 626 yield fn
624 yield fn 627 for f, s in self.watcher.walk(states, l, fn):
625 except TypeError: 628 yield f
626 for f, s in self.watcher.walk(states, l, fn):
627 yield f
628 629
629 results = ['\0'.join(r) for r in [ 630 results = ['\0'.join(r) for r in [
630 genresult('l', self.watcher.statustrees['l']), 631 genresult('l', self.watcher.statustrees['l']),
631 genresult('m', self.watcher.statustrees['m']), 632 genresult('m', self.watcher.statustrees['m']),
632 genresult('a', self.watcher.statustrees['a']), 633 genresult('a', self.watcher.statustrees['a']),