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 | 250 | return 'i' |
|
251 | 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 | 280 | Update the stored status of a file or directory. |
|
256 | 281 | |
|
257 | osstat: (mode, size, time) tuple, as returned by os.lstat(wfn) | |
|
258 | ||
|
259 | newstatus: char in statuskeys, new status to apply. | |
|
282 | newstatus: - char in (statuskeys + 'ni'), new status to apply. | |
|
283 | - or None, to stop tracking wfn | |
|
260 | 284 | ''' |
|
261 | if osstat: | |
|
262 | newstatus = self.filestatus(wfn, osstat) | |
|
263 | else: | |
|
264 | self.statcache.pop(wfn, None) | |
|
265 | 285 | root, fn = self.split(wfn) |
|
266 | 286 | d = self.dir(self.tree, root) |
|
287 | ||
|
267 | 288 | oldstatus = d.get(fn) |
|
268 | isdir = False | |
|
269 | if oldstatus: | |
|
270 | try: | |
|
271 | if not newstatus: | |
|
272 | if oldstatus in 'almn': | |
|
273 | newstatus = '!' | |
|
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] | |
|
289 | # oldstatus can be either: | |
|
290 | # - None : fn is new | |
|
291 | # - a char in statuskeys: fn is a (tracked) file | |
|
292 | # - a dict: fn is a directory | |
|
293 | isdir = isinstance(oldstatus, dict) | |
|
294 | ||
|
283 | 295 | if self.ui.debugflag and oldstatus != newstatus: |
|
284 | 296 | if isdir: |
|
285 | 297 | self.ui.note(_('status: %r dir(%d) -> %s\n') % |
@@ -288,6 +300,9 b' class repowatcher(object):' | |||
|
288 | 300 | self.ui.note(_('status: %r %s -> %s\n') % |
|
289 | 301 | (wfn, oldstatus, newstatus)) |
|
290 | 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 | 306 | if newstatus and newstatus != 'i': |
|
292 | 307 | d[fn] = newstatus |
|
293 | 308 | if newstatus in self.statuskeys: |
@@ -296,10 +311,6 b' class repowatcher(object):' | |||
|
296 | 311 | dd[fn] = newstatus |
|
297 | 312 | else: |
|
298 | 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 | 316 | def check_deleted(self, key): |
@@ -325,7 +336,7 b' class repowatcher(object):' | |||
|
325 | 336 | d = self.dir(self.tree, wroot) |
|
326 | 337 | for fn in files: |
|
327 | 338 | wfn = join(wroot, fn) |
|
328 |
self.update |
|
|
339 | self.updatefile(wfn, self.getstat(wfn)) | |
|
329 | 340 | ds.pop(wfn, None) |
|
330 | 341 | wtopdir = topdir |
|
331 | 342 | if wtopdir and wtopdir[-1] != '/': |
@@ -337,9 +348,9 b' class repowatcher(object):' | |||
|
337 | 348 | st = self.stat(wfn) |
|
338 | 349 | except OSError: |
|
339 | 350 | status = state[0] |
|
340 |
self. |
|
|
351 | self.deletefile(wfn, status) | |
|
341 | 352 | else: |
|
342 |
self.update |
|
|
353 | self.updatefile(wfn, st) | |
|
343 | 354 | self.check_deleted('!') |
|
344 | 355 | self.check_deleted('r') |
|
345 | 356 | |
@@ -409,7 +420,7 b' class repowatcher(object):' | |||
|
409 | 420 | try: |
|
410 | 421 | st = self.stat(wpath) |
|
411 | 422 | if stat.S_ISREG(st[0]): |
|
412 |
self.update |
|
|
423 | self.updatefile(wpath, st) | |
|
413 | 424 | except OSError: |
|
414 | 425 | pass |
|
415 | 426 | |
@@ -420,7 +431,7 b' class repowatcher(object):' | |||
|
420 | 431 | st = self.stat(wpath) |
|
421 | 432 | if stat.S_ISREG(st[0]): |
|
422 | 433 | if self.repo.dirstate[wpath] in 'lmn': |
|
423 |
self.update |
|
|
434 | self.updatefile(wpath, st) | |
|
424 | 435 | except OSError: |
|
425 | 436 | pass |
|
426 | 437 | |
@@ -432,7 +443,7 b' class repowatcher(object):' | |||
|
432 | 443 | self.check_dirstate() |
|
433 | 444 | return |
|
434 | 445 | |
|
435 | self.updatestatus(wpath, None) | |
|
446 | self.deletefile(wpath, self.repo.dirstate[wpath]) | |
|
436 | 447 | |
|
437 | 448 | def schedule_work(self, wpath, evt): |
|
438 | 449 | prev = self.eventq.setdefault(wpath, []) |
@@ -468,8 +479,12 b' class repowatcher(object):' | |||
|
468 | 479 | (self.event_time(), wpath)) |
|
469 | 480 | |
|
470 | 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 | 485 | self.scan(wpath) |
|
472 | self.schedule_work(wpath, 'd') | |
|
486 | else: | |
|
487 | self.schedule_work(wpath, 'd') | |
|
473 | 488 | |
|
474 | 489 | def process_modify(self, wpath, evt): |
|
475 | 490 | if self.ui.debugflag: |
General Comments 0
You need to be logged in to leave comments.
Login now