Show More
@@ -34,13 +34,11 b' def split(path):' | |||
|
34 | 34 | |
|
35 | 35 | walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG) |
|
36 | 36 | |
|
37 |
def walkrepodirs( |
|
|
37 | def walkrepodirs(dirstate, absroot): | |
|
38 | 38 | '''Iterate over all subdirectories of this repo. |
|
39 | 39 | Exclude the .hg directory, any nested repos, and ignored dirs.''' |
|
40 | rootslash = repo.root + os.sep | |
|
41 | ||
|
42 | 40 | def walkit(dirname, top): |
|
43 |
fullpath = |
|
|
41 | fullpath = join(absroot, dirname) | |
|
44 | 42 | try: |
|
45 | 43 | for name, kind in osutil.listdir(fullpath): |
|
46 | 44 | if kind == stat.S_IFDIR: |
@@ -49,7 +47,7 b' def walkrepodirs(repo):' | |||
|
49 | 47 | return |
|
50 | 48 | else: |
|
51 | 49 | d = join(dirname, name) |
|
52 |
if |
|
|
50 | if dirstate._ignore(d): | |
|
53 | 51 | continue |
|
54 | 52 | for subdir in walkit(d, False): |
|
55 | 53 | yield subdir |
@@ -60,18 +58,16 b' def walkrepodirs(repo):' | |||
|
60 | 58 | |
|
61 | 59 | return walkit('', True) |
|
62 | 60 | |
|
63 |
def walk( |
|
|
61 | def walk(dirstate, absroot, root): | |
|
64 | 62 | '''Like os.walk, but only yields regular files.''' |
|
65 | 63 | |
|
66 | 64 | # This function is critical to performance during startup. |
|
67 | 65 | |
|
68 | rootslash = repo.root + os.sep | |
|
69 | ||
|
70 | 66 | def walkit(root, reporoot): |
|
71 | 67 | files, dirs = [], [] |
|
72 | 68 | |
|
73 | 69 | try: |
|
74 |
fullpath = |
|
|
70 | fullpath = join(absroot, root) | |
|
75 | 71 | for name, kind in osutil.listdir(fullpath): |
|
76 | 72 | if kind == stat.S_IFDIR: |
|
77 | 73 | if name == '.hg': |
@@ -80,7 +76,7 b' def walk(repo, root):' | |||
|
80 | 76 | else: |
|
81 | 77 | dirs.append(name) |
|
82 | 78 | path = join(root, name) |
|
83 |
if |
|
|
79 | if dirstate._ignore(path): | |
|
84 | 80 | continue |
|
85 | 81 | for result in walkit(path, False): |
|
86 | 82 | yield result |
@@ -98,7 +94,7 b' def walk(repo, root):' | |||
|
98 | 94 | |
|
99 | 95 | return walkit(root, root == '') |
|
100 | 96 | |
|
101 |
def _explain_watch_limit(ui, |
|
|
97 | def _explain_watch_limit(ui, dirstate, rootabs): | |
|
102 | 98 | path = '/proc/sys/fs/inotify/max_user_watches' |
|
103 | 99 | try: |
|
104 | 100 | limit = int(file(path).read()) |
@@ -112,7 +108,7 b' def _explain_watch_limit(ui, repo):' | |||
|
112 | 108 | ui.warn(_('*** this limit is too low to watch every ' |
|
113 | 109 | 'directory in this repository\n')) |
|
114 | 110 | ui.warn(_('*** counting directories: ')) |
|
115 |
ndirs = len(list(walkrepodirs( |
|
|
111 | ndirs = len(list(walkrepodirs(dirstate, rootabs))) | |
|
116 | 112 | ui.warn(_('found %d\n') % ndirs) |
|
117 | 113 | newlimit = min(limit, 1024) |
|
118 | 114 | while newlimit < ((limit + ndirs) * 1.1): |
@@ -121,7 +117,7 b' def _explain_watch_limit(ui, repo):' | |||
|
121 | 117 | (limit, newlimit)) |
|
122 | 118 | ui.warn(_('*** echo %d > %s\n') % (newlimit, path)) |
|
123 | 119 | raise util.Abort(_('cannot watch %s until inotify watch limit is raised') |
|
124 |
% |
|
|
120 | % rootabs) | |
|
125 | 121 | |
|
126 | 122 | class pollable(object): |
|
127 | 123 | """ |
@@ -309,10 +305,11 b' class repowatcher(pollable):' | |||
|
309 | 305 | inotify.IN_UNMOUNT | |
|
310 | 306 | 0) |
|
311 | 307 | |
|
312 |
def __init__(self, ui, |
|
|
308 | def __init__(self, ui, dirstate, root): | |
|
313 | 309 | self.ui = ui |
|
314 |
self.re |
|
|
315 | self.wprefix = join(repo.root, '') | |
|
310 | self.dirstate = dirstate | |
|
311 | ||
|
312 | self.wprefix = join(root, '') | |
|
316 | 313 | self.prefixlen = len(self.wprefix) |
|
317 | 314 | try: |
|
318 | 315 | self.watcher = watcher.watcher() |
@@ -352,7 +349,7 b' class repowatcher(pollable):' | |||
|
352 | 349 | |
|
353 | 350 | def dirstate_info(self): |
|
354 | 351 | try: |
|
355 |
st = os.lstat(self. |
|
|
352 | st = os.lstat(self.wprefix + '.hg/dirstate') | |
|
356 | 353 | return st.st_mtime, st.st_ino |
|
357 | 354 | except OSError, err: |
|
358 | 355 | if err.errno != errno.ENOENT: |
@@ -372,16 +369,16 b' class repowatcher(pollable):' | |||
|
372 | 369 | return |
|
373 | 370 | if err.errno != errno.ENOSPC: |
|
374 | 371 | raise |
|
375 |
_explain_watch_limit(self.ui, self. |
|
|
372 | _explain_watch_limit(self.ui, self.dirstate, self.wprefix) | |
|
376 | 373 | |
|
377 | 374 | def setup(self): |
|
378 | 375 | self.ui.note(_('watching directories under %r\n') % self.wprefix) |
|
379 |
self.add_watch(self. |
|
|
376 | self.add_watch(self.wprefix + '.hg', inotify.IN_DELETE) | |
|
380 | 377 | self.check_dirstate() |
|
381 | 378 | |
|
382 | 379 | def filestatus(self, fn, st): |
|
383 | 380 | try: |
|
384 |
type_, mode, size, time = self. |
|
|
381 | type_, mode, size, time = self.dirstate._map[fn][:4] | |
|
385 | 382 | except KeyError: |
|
386 | 383 | type_ = '?' |
|
387 | 384 | if type_ == 'n': |
@@ -393,7 +390,7 b' class repowatcher(pollable):' | |||
|
393 | 390 | if time != int(st_mtime): |
|
394 | 391 | return 'l' |
|
395 | 392 | return 'n' |
|
396 |
if type_ == '?' and self. |
|
|
393 | if type_ == '?' and self.dirstate._ignore(fn): | |
|
397 | 394 | return 'i' |
|
398 | 395 | return type_ |
|
399 | 396 | |
@@ -458,7 +455,7 b' class repowatcher(pollable):' | |||
|
458 | 455 | # may have vanished from the dirstate; we must clean them up. |
|
459 | 456 | nuke = [] |
|
460 | 457 | for wfn, ignore in self.statustrees[key].walk(key): |
|
461 |
if wfn not in self. |
|
|
458 | if wfn not in self.dirstate: | |
|
462 | 459 | nuke.append(wfn) |
|
463 | 460 | for wfn in nuke: |
|
464 | 461 | root, fn = split(wfn) |
@@ -466,9 +463,9 b' class repowatcher(pollable):' | |||
|
466 | 463 | del self.tree.dir(root).files[fn] |
|
467 | 464 | |
|
468 | 465 | def scan(self, topdir=''): |
|
469 |
ds = self |
|
|
466 | ds = self.dirstate._map.copy() | |
|
470 | 467 | self.add_watch(join(self.wprefix, topdir), self.mask) |
|
471 |
for root, dirs, files in walk(self. |
|
|
468 | for root, dirs, files in walk(self.dirstate, self.wprefix, topdir): | |
|
472 | 469 | for d in dirs: |
|
473 | 470 | self.add_watch(join(root, d), self.mask) |
|
474 | 471 | wroot = root[self.prefixlen:] |
@@ -500,7 +497,7 b' class repowatcher(pollable):' | |||
|
500 | 497 | if not self.ui.debugflag: |
|
501 | 498 | self.last_event = None |
|
502 | 499 | self.ui.note(_('%s dirstate reload\n') % self.event_time()) |
|
503 |
self |
|
|
500 | self.dirstate.invalidate() | |
|
504 | 501 | self.handle_timeout() |
|
505 | 502 | self.scan() |
|
506 | 503 | self.ui.note(_('%s end dirstate reload\n') % self.event_time()) |
@@ -516,8 +513,8 b' class repowatcher(pollable):' | |||
|
516 | 513 | # But it's easier to do nothing than to open that can of |
|
517 | 514 | # worms. |
|
518 | 515 | |
|
519 |
if '_ignore' in self. |
|
|
520 |
delattr(self |
|
|
516 | if '_ignore' in self.dirstate.__dict__: | |
|
517 | delattr(self.dirstate, '_ignore') | |
|
521 | 518 | self.ui.note(_('rescanning due to .hgignore change\n')) |
|
522 | 519 | self.handle_timeout() |
|
523 | 520 | self.scan() |
@@ -560,7 +557,7 b' class repowatcher(pollable):' | |||
|
560 | 557 | try: |
|
561 | 558 | st = self.stat(wpath) |
|
562 | 559 | if stat.S_ISREG(st[0]): |
|
563 |
if self |
|
|
560 | if self.dirstate[wpath] in 'lmn': | |
|
564 | 561 | self.updatefile(wpath, st) |
|
565 | 562 | except OSError: |
|
566 | 563 | pass |
@@ -574,7 +571,7 b' class repowatcher(pollable):' | |||
|
574 | 571 | self.check_dirstate() |
|
575 | 572 | return |
|
576 | 573 | |
|
577 |
self.deletefile(wpath, self. |
|
|
574 | self.deletefile(wpath, self.dirstate[wpath]) | |
|
578 | 575 | |
|
579 | 576 | def process_create(self, wpath, evt): |
|
580 | 577 | if self.ui.debugflag: |
@@ -678,12 +675,11 b' class server(pollable):' | |||
|
678 | 675 | """ |
|
679 | 676 | Listens for client queries on unix socket inotify.sock |
|
680 | 677 | """ |
|
681 |
def __init__(self, ui, r |
|
|
678 | def __init__(self, ui, root, repowatcher, timeout): | |
|
682 | 679 | self.ui = ui |
|
683 | self.repo = repo | |
|
684 | 680 | self.repowatcher = repowatcher |
|
685 | 681 | self.sock = socket.socket(socket.AF_UNIX) |
|
686 |
self.sockpath = |
|
|
682 | self.sockpath = join(root, '.hg/inotify.sock') | |
|
687 | 683 | self.realsockpath = None |
|
688 | 684 | try: |
|
689 | 685 | self.sock.bind(self.sockpath) |
@@ -813,9 +809,8 b' class server(pollable):' | |||
|
813 | 809 | class master(object): |
|
814 | 810 | def __init__(self, ui, repo, timeout=None): |
|
815 | 811 | self.ui = ui |
|
816 | self.repo = repo | |
|
817 | self.repowatcher = repowatcher(ui, repo) | |
|
818 | self.server = server(ui, repo, self.repowatcher, timeout) | |
|
812 | self.repowatcher = repowatcher(ui, repo.dirstate, repo.root) | |
|
813 | self.server = server(ui, repo.root, self.repowatcher, timeout) | |
|
819 | 814 | |
|
820 | 815 | def shutdown(self): |
|
821 | 816 | for obj in pollable.instances.itervalues(): |
General Comments 0
You need to be logged in to leave comments.
Login now