hgext/inotify/server.py
changeset 9854 95e1867f765b
parent 9514 7c01599dd340
child 9897 97eda2133a9b
equal deleted inserted replaced
9853:a033929bd34e 9854:95e1867f765b
   235                 d = directory(join(ret.path, next))
   235                 d = directory(join(ret.path, next))
   236                 ret.dirs[next] = d
   236                 ret.dirs[next] = d
   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.
   244         filenames are relative to the repo root
   244         filenames are relative to the repo root
   245         """
   245         """
   246         for file, st in self.files.iteritems():
   246         for file, st in self.files.iteritems():
   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:
   257         * if path is a file, yield path
   259         * if path is a file, yield path
   258         * if path is a directory, yield directory files
   260         * if path is a directory, yield directory files
   270         try:
   272         try:
   271             for dir in paths:
   273             for dir in paths:
   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
   288                 pass
   294                 pass
   289 
   295 
   723             # We got a query while a rescan is pending.  Make sure we
   729             # We got a query while a rescan is pending.  Make sure we
   724             # rescan before responding, or we could give back a wrong
   730             # rescan before responding, or we could give back a wrong
   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):
   731                     yield fn
   738                     yield fn
   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 [
   739             genresult('l', self.repowatcher.statustrees['l']),
   746             genresult('l', self.repowatcher.statustrees['l']),
   740             genresult('m', self.repowatcher.statustrees['m']),
   747             genresult('m', self.repowatcher.statustrees['m']),
   744             '?' in states
   751             '?' in states
   745                 and genresult('?', self.repowatcher.statustrees['?'])
   752                 and genresult('?', self.repowatcher.statustrees['?'])
   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):
   752         return ['\0'.join(self.repowatcher.debug())]
   760         return ['\0'.join(self.repowatcher.debug())]
   753 
   761