##// END OF EJS Templates
inotify: mark directories visited during lookup (issue1844)...
Nicolas Dumazet -
r9854:95e1867f default
parent child Browse files
Show More
@@ -150,7 +150,16 b' class client(object):'
150 if names:
150 if names:
151 return filter(match, names.split('\0'))
151 return filter(match, names.split('\0'))
152 return []
152 return []
153 return map(readnames, resphdr)
153 results = map(readnames, resphdr[:-1])
154
155 if names:
156 nbytes = resphdr[-1]
157 vdirs = cs.read(nbytes)
158 if vdirs:
159 for vdir in vdirs.split('\0'):
160 match.dir(vdir)
161
162 return results
154
163
155 @start_server
164 @start_server
156 def debugquery(self):
165 def debugquery(self):
@@ -24,16 +24,18 b' import cStringIO, socket, struct'
24 1) send protocol version number
24 1) send protocol version number
25 2) send query type
25 2) send query type
26 3) send struct.pack'ed headers describing the length of the content:
26 3) send struct.pack'ed headers describing the length of the content:
27 e.g. for STAT, receive 8 integers describing the length of the
27 e.g. for STAT, receive 9 integers describing the length of the
28 8 \0-separated string lists ( one list for each lmar!?ic status type )
28 9 \0-separated string lists to be read:
29 * one file list for each lmar!?ic status type
30 * one list containing the directories visited during lookup
29
31
30 """
32 """
31
33
32 version = 2
34 version = 3
33
35
34 resphdrfmts = {
36 resphdrfmts = {
35 'STAT': '>llllllll', # status requests
37 'STAT': '>lllllllll', # status requests
36 'DBUG': '>l' # debugging queries
38 'DBUG': '>l' # debugging queries
37 }
39 }
38 resphdrsizes = dict((k, struct.calcsize(v))
40 resphdrsizes = dict((k, struct.calcsize(v))
39 for k, v in resphdrfmts.iteritems())
41 for k, v in resphdrfmts.iteritems())
@@ -237,7 +237,7 b' class directory(object):'
237 ret = d
237 ret = d
238 return ret
238 return ret
239
239
240 def walk(self, states):
240 def walk(self, states, visited=None):
241 """
241 """
242 yield (filename, status) pairs for items in the trees
242 yield (filename, status) pairs for items in the trees
243 that have status in states.
243 that have status in states.
@@ -247,10 +247,12 b' class directory(object):'
247 if st in states:
247 if st in states:
248 yield join(self.path, file), st
248 yield join(self.path, file), st
249 for dir in self.dirs.itervalues():
249 for dir in self.dirs.itervalues():
250 if visited is not None:
251 visited.add(dir.path)
250 for e in dir.walk(states):
252 for e in dir.walk(states):
251 yield e
253 yield e
252
254
253 def lookup(self, states, path):
255 def lookup(self, states, path, visited):
254 """
256 """
255 yield root-relative filenames that match path, and whose
257 yield root-relative filenames that match path, and whose
256 status are in states:
258 status are in states:
@@ -272,16 +274,20 b' class directory(object):'
272 tree = tree.dirs[dir]
274 tree = tree.dirs[dir]
273 except KeyError:
275 except KeyError:
274 # path is not tracked
276 # path is not tracked
277 visited.add(tree.path)
275 return
278 return
276
279
277 try:
280 try:
278 # if path is a directory, walk it
281 # if path is a directory, walk it
279 for file, st in tree.dirs[last].walk(states):
282 target = tree.dirs[last]
283 visited.add(target.path)
284 for file, st in target.walk(states, visited):
280 yield file
285 yield file
281 except KeyError:
286 except KeyError:
282 try:
287 try:
283 if tree.files[last] in states:
288 if tree.files[last] in states:
284 # path is a file
289 # path is a file
290 visited.add(tree.path)
285 yield path
291 yield path
286 except KeyError:
292 except KeyError:
287 # path is not tracked
293 # path is not tracked
@@ -725,6 +731,7 b' class server(pollable):'
725 # answer.
731 # answer.
726 self.repowatcher.handle_timeout()
732 self.repowatcher.handle_timeout()
727
733
734 visited = set()
728 if not names:
735 if not names:
729 def genresult(states, tree):
736 def genresult(states, tree):
730 for fn, state in tree.walk(states):
737 for fn, state in tree.walk(states):
@@ -732,7 +739,7 b' class server(pollable):'
732 else:
739 else:
733 def genresult(states, tree):
740 def genresult(states, tree):
734 for fn in names:
741 for fn in names:
735 for f in tree.lookup(states, fn):
742 for f in tree.lookup(states, fn, visited):
736 yield f
743 yield f
737
744
738 return ['\0'.join(r) for r in [
745 return ['\0'.join(r) for r in [
@@ -746,6 +753,7 b' class server(pollable):'
746 or [],
753 or [],
747 [],
754 [],
748 'c' in states and genresult('n', self.repowatcher.tree) or [],
755 'c' in states and genresult('n', self.repowatcher.tree) or [],
756 visited
749 ]]
757 ]]
750
758
751 def answer_dbug_query(self):
759 def answer_dbug_query(self):
@@ -70,4 +70,14 b' hg st'
70
70
71 HGMERGE=internal:local hg up
71 HGMERGE=internal:local hg up
72 hg st
72 hg st
73
74 # Test for 1844: "hg ci folder" will not commit all changes beneath "folder"
75 mkdir 1844
76 echo a > 1844/foo
77 hg add 1844
78 hg ci -m 'working'
79
80 echo b >> 1844/foo
81 hg ci 1844 -m 'broken'
82
73 kill `cat hg.pid`
83 kill `cat hg.pid`
@@ -44,3 +44,4 b' 1 files updated, 1 files merged, 2 files'
44 M a
44 M a
45 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
45 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
46 M a
46 M a
47 adding 1844/foo
General Comments 0
You need to be logged in to leave comments. Login now