Mercurial > hg
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']), |