Mercurial > hg
changeset 9854:95e1867f765b
inotify: mark directories visited during lookup (issue1844)
Emulate the match.dir calls that are made in dirstate.walk:
* first mark the visited directories on the server side
* then extend the transmitted response to include this directory list
* and lastly call match.dir on each directory
author | Nicolas Dumazet <nicdumz.commits@gmail.com> |
---|---|
date | Fri, 13 Nov 2009 08:31:10 +0900 |
parents | a033929bd34e |
children | f47c0881b16e |
files | hgext/inotify/client.py hgext/inotify/common.py hgext/inotify/server.py tests/test-inotify tests/test-inotify.out |
diffstat | 5 files changed, 40 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/inotify/client.py Fri Nov 13 06:36:26 2009 +0100 +++ b/hgext/inotify/client.py Fri Nov 13 08:31:10 2009 +0900 @@ -150,7 +150,16 @@ if names: return filter(match, names.split('\0')) return [] - return map(readnames, resphdr) + results = map(readnames, resphdr[:-1]) + + if names: + nbytes = resphdr[-1] + vdirs = cs.read(nbytes) + if vdirs: + for vdir in vdirs.split('\0'): + match.dir(vdir) + + return results @start_server def debugquery(self):
--- a/hgext/inotify/common.py Fri Nov 13 06:36:26 2009 +0100 +++ b/hgext/inotify/common.py Fri Nov 13 08:31:10 2009 +0900 @@ -24,16 +24,18 @@ 1) send protocol version number 2) send query type 3) send struct.pack'ed headers describing the length of the content: - e.g. for STAT, receive 8 integers describing the length of the - 8 \0-separated string lists ( one list for each lmar!?ic status type ) + e.g. for STAT, receive 9 integers describing the length of the + 9 \0-separated string lists to be read: + * one file list for each lmar!?ic status type + * one list containing the directories visited during lookup """ -version = 2 +version = 3 resphdrfmts = { - 'STAT': '>llllllll', # status requests - 'DBUG': '>l' # debugging queries + 'STAT': '>lllllllll', # status requests + 'DBUG': '>l' # debugging queries } resphdrsizes = dict((k, struct.calcsize(v)) for k, v in resphdrfmts.iteritems())
--- a/hgext/inotify/server.py Fri Nov 13 06:36:26 2009 +0100 +++ b/hgext/inotify/server.py Fri Nov 13 08:31:10 2009 +0900 @@ -237,7 +237,7 @@ ret = d return ret - def walk(self, states): + def walk(self, states, visited=None): """ yield (filename, status) pairs for items in the trees that have status in states. @@ -247,10 +247,12 @@ if st in states: yield join(self.path, file), st for dir in self.dirs.itervalues(): + if visited is not None: + visited.add(dir.path) for e in dir.walk(states): yield e - def lookup(self, states, path): + def lookup(self, states, path, visited): """ yield root-relative filenames that match path, and whose status are in states: @@ -272,16 +274,20 @@ tree = tree.dirs[dir] except KeyError: # path is not tracked + visited.add(tree.path) return try: # if path is a directory, walk it - for file, st in tree.dirs[last].walk(states): + target = tree.dirs[last] + visited.add(target.path) + for file, st in target.walk(states, visited): yield file except KeyError: try: if tree.files[last] in states: # path is a file + visited.add(tree.path) yield path except KeyError: # path is not tracked @@ -725,6 +731,7 @@ # answer. self.repowatcher.handle_timeout() + visited = set() if not names: def genresult(states, tree): for fn, state in tree.walk(states): @@ -732,7 +739,7 @@ else: def genresult(states, tree): for fn in names: - for f in tree.lookup(states, fn): + for f in tree.lookup(states, fn, visited): yield f return ['\0'.join(r) for r in [ @@ -746,6 +753,7 @@ or [], [], 'c' in states and genresult('n', self.repowatcher.tree) or [], + visited ]] def answer_dbug_query(self):
--- a/tests/test-inotify Fri Nov 13 06:36:26 2009 +0100 +++ b/tests/test-inotify Fri Nov 13 08:31:10 2009 +0900 @@ -70,4 +70,14 @@ HGMERGE=internal:local hg up hg st + +# Test for 1844: "hg ci folder" will not commit all changes beneath "folder" +mkdir 1844 +echo a > 1844/foo +hg add 1844 +hg ci -m 'working' + +echo b >> 1844/foo +hg ci 1844 -m 'broken' + kill `cat hg.pid`