Show More
@@ -0,0 +1,27 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | "$TESTDIR/hghave" inotify || exit 80 | |||
|
4 | ||||
|
5 | hg init | |||
|
6 | ||||
|
7 | touch a b | |||
|
8 | hg add a b | |||
|
9 | rm b | |||
|
10 | ||||
|
11 | echo % status without inotify | |||
|
12 | hg st | |||
|
13 | ||||
|
14 | echo "[extensions]" >> $HGRCPATH | |||
|
15 | echo "inotify=" >> $HGRCPATH | |||
|
16 | ||||
|
17 | echo % inserve | |||
|
18 | hg inserve -d --pid-file=hg.pid 2>&1 | |||
|
19 | cat hg.pid >> "$DAEMON_PIDS" | |||
|
20 | ||||
|
21 | echo % status | |||
|
22 | hg st | |||
|
23 | ||||
|
24 | sleep 1 | |||
|
25 | echo "Are we able to kill the service? if not, the service died on some error" | |||
|
26 | kill `cat hg.pid` | |||
|
27 |
@@ -0,0 +1,9 b'' | |||||
|
1 | % status without inotify | |||
|
2 | A a | |||
|
3 | ! b | |||
|
4 | % inserve | |||
|
5 | % status | |||
|
6 | A a | |||
|
7 | ! b | |||
|
8 | ? hg.pid | |||
|
9 | Are we able to kill the service? if not, the service died on some error |
@@ -250,36 +250,48 b' class repowatcher(object):' | |||||
250 | return 'i' |
|
250 | return 'i' | |
251 | return type_ |
|
251 | return type_ | |
252 |
|
252 | |||
253 |
def update |
|
253 | def updatefile(self, wfn, osstat): | |
|
254 | ''' | |||
|
255 | update the file entry of an existing file. | |||
|
256 | ||||
|
257 | osstat: (mode, size, time) tuple, as returned by os.lstat(wfn) | |||
|
258 | ''' | |||
|
259 | ||||
|
260 | self._updatestatus(wfn, self.filestatus(wfn, osstat)) | |||
|
261 | ||||
|
262 | def deletefile(self, wfn, oldstatus): | |||
|
263 | ''' | |||
|
264 | update the entry of a file which has been deleted. | |||
|
265 | ||||
|
266 | oldstatus: char in statuskeys, status of the file before deletion | |||
|
267 | ''' | |||
|
268 | if oldstatus == 'r': | |||
|
269 | newstatus = 'r' | |||
|
270 | elif oldstatus in 'almn': | |||
|
271 | newstatus = '!' | |||
|
272 | else: | |||
|
273 | newstatus = None | |||
|
274 | ||||
|
275 | self.statcache.pop(wfn, None) | |||
|
276 | self._updatestatus(wfn, newstatus) | |||
|
277 | ||||
|
278 | def _updatestatus(self, wfn, newstatus): | |||
254 | ''' |
|
279 | ''' | |
255 | Update the stored status of a file or directory. |
|
280 | Update the stored status of a file or directory. | |
256 |
|
281 | |||
257 | osstat: (mode, size, time) tuple, as returned by os.lstat(wfn) |
|
282 | newstatus: - char in (statuskeys + 'ni'), new status to apply. | |
258 |
|
283 | - or None, to stop tracking wfn | ||
259 | newstatus: char in statuskeys, new status to apply. |
|
|||
260 | ''' |
|
284 | ''' | |
261 | if osstat: |
|
|||
262 | newstatus = self.filestatus(wfn, osstat) |
|
|||
263 | else: |
|
|||
264 | self.statcache.pop(wfn, None) |
|
|||
265 | root, fn = self.split(wfn) |
|
285 | root, fn = self.split(wfn) | |
266 | d = self.dir(self.tree, root) |
|
286 | d = self.dir(self.tree, root) | |
|
287 | ||||
267 | oldstatus = d.get(fn) |
|
288 | oldstatus = d.get(fn) | |
268 | isdir = False |
|
289 | # oldstatus can be either: | |
269 | if oldstatus: |
|
290 | # - None : fn is new | |
270 | try: |
|
291 | # - a char in statuskeys: fn is a (tracked) file | |
271 | if not newstatus: |
|
292 | # - a dict: fn is a directory | |
272 | if oldstatus in 'almn': |
|
293 | isdir = isinstance(oldstatus, dict) | |
273 | newstatus = '!' |
|
294 | ||
274 | elif oldstatus == 'r': |
|
|||
275 | newstatus = 'r' |
|
|||
276 | except TypeError: |
|
|||
277 | # oldstatus may be a dict left behind by a deleted |
|
|||
278 | # directory |
|
|||
279 | isdir = True |
|
|||
280 | else: |
|
|||
281 | if oldstatus in self.statuskeys and oldstatus != newstatus: |
|
|||
282 | del self.dir(self.statustrees[oldstatus], root)[fn] |
|
|||
283 | if self.ui.debugflag and oldstatus != newstatus: |
|
295 | if self.ui.debugflag and oldstatus != newstatus: | |
284 | if isdir: |
|
296 | if isdir: | |
285 | self.ui.note(_('status: %r dir(%d) -> %s\n') % |
|
297 | self.ui.note(_('status: %r dir(%d) -> %s\n') % | |
@@ -288,6 +300,9 b' class repowatcher(object):' | |||||
288 | self.ui.note(_('status: %r %s -> %s\n') % |
|
300 | self.ui.note(_('status: %r %s -> %s\n') % | |
289 | (wfn, oldstatus, newstatus)) |
|
301 | (wfn, oldstatus, newstatus)) | |
290 | if not isdir: |
|
302 | if not isdir: | |
|
303 | if oldstatus and oldstatus in self.statuskeys \ | |||
|
304 | and oldstatus != newstatus: | |||
|
305 | del self.dir(self.statustrees[oldstatus], root)[fn] | |||
291 | if newstatus and newstatus != 'i': |
|
306 | if newstatus and newstatus != 'i': | |
292 | d[fn] = newstatus |
|
307 | d[fn] = newstatus | |
293 | if newstatus in self.statuskeys: |
|
308 | if newstatus in self.statuskeys: | |
@@ -296,10 +311,6 b' class repowatcher(object):' | |||||
296 | dd[fn] = newstatus |
|
311 | dd[fn] = newstatus | |
297 | else: |
|
312 | else: | |
298 | d.pop(fn, None) |
|
313 | d.pop(fn, None) | |
299 | elif not newstatus: |
|
|||
300 | # a directory is being removed, check its contents |
|
|||
301 | for subfile, b in oldstatus.copy().iteritems(): |
|
|||
302 | self.updatestatus(wfn + '/' + subfile, None) |
|
|||
303 |
|
314 | |||
304 |
|
315 | |||
305 | def check_deleted(self, key): |
|
316 | def check_deleted(self, key): | |
@@ -325,7 +336,7 b' class repowatcher(object):' | |||||
325 | d = self.dir(self.tree, wroot) |
|
336 | d = self.dir(self.tree, wroot) | |
326 | for fn in files: |
|
337 | for fn in files: | |
327 | wfn = join(wroot, fn) |
|
338 | wfn = join(wroot, fn) | |
328 |
self.update |
|
339 | self.updatefile(wfn, self.getstat(wfn)) | |
329 | ds.pop(wfn, None) |
|
340 | ds.pop(wfn, None) | |
330 | wtopdir = topdir |
|
341 | wtopdir = topdir | |
331 | if wtopdir and wtopdir[-1] != '/': |
|
342 | if wtopdir and wtopdir[-1] != '/': | |
@@ -337,9 +348,9 b' class repowatcher(object):' | |||||
337 | st = self.stat(wfn) |
|
348 | st = self.stat(wfn) | |
338 | except OSError: |
|
349 | except OSError: | |
339 | status = state[0] |
|
350 | status = state[0] | |
340 |
self. |
|
351 | self.deletefile(wfn, status) | |
341 | else: |
|
352 | else: | |
342 |
self.update |
|
353 | self.updatefile(wfn, st) | |
343 | self.check_deleted('!') |
|
354 | self.check_deleted('!') | |
344 | self.check_deleted('r') |
|
355 | self.check_deleted('r') | |
345 |
|
356 | |||
@@ -409,7 +420,7 b' class repowatcher(object):' | |||||
409 | try: |
|
420 | try: | |
410 | st = self.stat(wpath) |
|
421 | st = self.stat(wpath) | |
411 | if stat.S_ISREG(st[0]): |
|
422 | if stat.S_ISREG(st[0]): | |
412 |
self.update |
|
423 | self.updatefile(wpath, st) | |
413 | except OSError: |
|
424 | except OSError: | |
414 | pass |
|
425 | pass | |
415 |
|
426 | |||
@@ -420,7 +431,7 b' class repowatcher(object):' | |||||
420 | st = self.stat(wpath) |
|
431 | st = self.stat(wpath) | |
421 | if stat.S_ISREG(st[0]): |
|
432 | if stat.S_ISREG(st[0]): | |
422 | if self.repo.dirstate[wpath] in 'lmn': |
|
433 | if self.repo.dirstate[wpath] in 'lmn': | |
423 |
self.update |
|
434 | self.updatefile(wpath, st) | |
424 | except OSError: |
|
435 | except OSError: | |
425 | pass |
|
436 | pass | |
426 |
|
437 | |||
@@ -432,7 +443,7 b' class repowatcher(object):' | |||||
432 | self.check_dirstate() |
|
443 | self.check_dirstate() | |
433 | return |
|
444 | return | |
434 |
|
445 | |||
435 | self.updatestatus(wpath, None) |
|
446 | self.deletefile(wpath, self.repo.dirstate[wpath]) | |
436 |
|
447 | |||
437 | def schedule_work(self, wpath, evt): |
|
448 | def schedule_work(self, wpath, evt): | |
438 | prev = self.eventq.setdefault(wpath, []) |
|
449 | prev = self.eventq.setdefault(wpath, []) | |
@@ -468,7 +479,11 b' class repowatcher(object):' | |||||
468 | (self.event_time(), wpath)) |
|
479 | (self.event_time(), wpath)) | |
469 |
|
480 | |||
470 | if evt.mask & inotify.IN_ISDIR: |
|
481 | if evt.mask & inotify.IN_ISDIR: | |
|
482 | tree = self.dir(self.tree, wpath).copy() | |||
|
483 | for wfn, ignore in self.walk('?', tree): | |||
|
484 | self.deletefile(join(wpath, wfn), '?') | |||
471 | self.scan(wpath) |
|
485 | self.scan(wpath) | |
|
486 | else: | |||
472 | self.schedule_work(wpath, 'd') |
|
487 | self.schedule_work(wpath, 'd') | |
473 |
|
488 | |||
474 | def process_modify(self, wpath, evt): |
|
489 | def process_modify(self, wpath, evt): |
General Comments 0
You need to be logged in to leave comments.
Login now