comparison mercurial/dirstate.py @ 7096:6dab29f6df37

dirstate._dirs: fix refcounting broken by 7dfac37cfabf reported by Patrick Waugh
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Wed, 15 Oct 2008 01:14:29 +0200
parents 16bafcebd3d1
children 6f750e76fb46
comparison
equal deleted inserted replaced
7095:0ed11838bd1a 7096:6dab29f6df37
18 def _finddirs(path): 18 def _finddirs(path):
19 pos = path.rfind('/') 19 pos = path.rfind('/')
20 while pos != -1: 20 while pos != -1:
21 yield path[:pos] 21 yield path[:pos]
22 pos = path.rfind('/', 0, pos) 22 pos = path.rfind('/', 0, pos)
23
24 def _incdirs(dirs, path):
25 for base in _finddirs(path):
26 if base in dirs:
27 dirs[base] += 1
28 return
29 dirs[base] = 1
30
31 def _decdirs(dirs, path):
32 for base in _finddirs(path):
33 if dirs[base] > 1:
34 dirs[base] -= 1
35 return
36 del dirs[base]
23 37
24 class dirstate(object): 38 class dirstate(object):
25 39
26 def __init__(self, opener, ui, root): 40 def __init__(self, opener, ui, root):
27 self._opener = opener 41 self._opener = opener
63 return self._pl 77 return self._pl
64 elif name == '_dirs': 78 elif name == '_dirs':
65 dirs = {} 79 dirs = {}
66 for f,s in self._map.iteritems(): 80 for f,s in self._map.iteritems():
67 if s[0] != 'r': 81 if s[0] != 'r':
68 pos = f.rfind('/') 82 _incdirs(dirs, f)
69 while pos != -1:
70 f = f[:pos]
71 if f in dirs:
72 dirs[f] += 1
73 break
74 dirs[f] = 1
75 pos = f.rfind('/')
76 self._dirs = dirs 83 self._dirs = dirs
77 return self._dirs 84 return self._dirs
78 elif name == '_ignore': 85 elif name == '_ignore':
79 files = [self._join('.hgignore')] 86 files = [self._join('.hgignore')]
80 for name, path in self._ui.configitems("ui"): 87 for name, path in self._ui.configitems("ui"):
220 def copies(self): 227 def copies(self):
221 return self._copymap 228 return self._copymap
222 229
223 def _droppath(self, f): 230 def _droppath(self, f):
224 if self[f] not in "?r" and "_dirs" in self.__dict__: 231 if self[f] not in "?r" and "_dirs" in self.__dict__:
225 dirs = self._dirs 232 _decdirs(self._dirs, f)
226 for base in _finddirs(f):
227 if dirs[base] == 1:
228 del dirs[base]
229 return
230 dirs[base] -= 1
231 233
232 def _addpath(self, f, check=False): 234 def _addpath(self, f, check=False):
233 oldstate = self[f] 235 oldstate = self[f]
234 if check or oldstate == "r": 236 if check or oldstate == "r":
235 if '\r' in f or '\n' in f: 237 if '\r' in f or '\n' in f:
243 break 245 break
244 if d in self._map and self[d] != 'r': 246 if d in self._map and self[d] != 'r':
245 raise util.Abort( 247 raise util.Abort(
246 _('file %r in dirstate clashes with %r') % (d, f)) 248 _('file %r in dirstate clashes with %r') % (d, f))
247 if oldstate in "?r" and "_dirs" in self.__dict__: 249 if oldstate in "?r" and "_dirs" in self.__dict__:
248 dirs = self._dirs 250 _incdirs(self._dirs, f)
249 for base in _finddirs(f):
250 dirs[base] = dirs.get(base, 0) + 1
251 251
252 def normal(self, f): 252 def normal(self, f):
253 'mark a file normal and clean' 253 'mark a file normal and clean'
254 self._dirty = True 254 self._dirty = True
255 self._addpath(f) 255 self._addpath(f)