Mercurial > hg
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) |