Mercurial > hg-stable
comparison mercurial/dirstate.py @ 2953:3d5547845158
fix issue 322.
do not allow to add files that shadow files or directories already in dirstate.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Fri, 18 Aug 2006 21:03:29 -0700 |
parents | 345bac2bc4ec |
children | 882e703eaa94 |
comparison
equal
deleted
inserted
replaced
2949:7356fa3cff2c | 2953:3d5547845158 |
---|---|
8 """ | 8 """ |
9 | 9 |
10 from node import * | 10 from node import * |
11 from i18n import gettext as _ | 11 from i18n import gettext as _ |
12 from demandload import * | 12 from demandload import * |
13 demandload(globals(), "struct os time bisect stat util re errno") | 13 demandload(globals(), "struct os time bisect stat strutil util re errno") |
14 | 14 |
15 class dirstate(object): | 15 class dirstate(object): |
16 format = ">cllll" | 16 format = ">cllll" |
17 | 17 |
18 def __init__(self, opener, ui, root): | 18 def __init__(self, opener, ui, root): |
20 self.root = root | 20 self.root = root |
21 self.dirty = 0 | 21 self.dirty = 0 |
22 self.ui = ui | 22 self.ui = ui |
23 self.map = None | 23 self.map = None |
24 self.pl = None | 24 self.pl = None |
25 self.dirs = None | |
25 self.copies = {} | 26 self.copies = {} |
26 self.ignorefunc = None | 27 self.ignorefunc = None |
27 self.blockignore = False | 28 self.blockignore = False |
28 | 29 |
29 def wjoin(self, f): | 30 def wjoin(self, f): |
195 self.copies[dest] = source | 196 self.copies[dest] = source |
196 | 197 |
197 def copied(self, file): | 198 def copied(self, file): |
198 return self.copies.get(file, None) | 199 return self.copies.get(file, None) |
199 | 200 |
201 def initdirs(self): | |
202 if self.dirs is None: | |
203 self.dirs = {} | |
204 for f in self.map: | |
205 self.updatedirs(f, 1) | |
206 | |
207 def updatedirs(self, path, delta): | |
208 if self.dirs is not None: | |
209 for c in strutil.findall(path, '/'): | |
210 pc = path[:c] | |
211 self.dirs.setdefault(pc, 0) | |
212 self.dirs[pc] += delta | |
213 | |
214 def checkshadows(self, files): | |
215 def prefixes(f): | |
216 for c in strutil.rfindall(f, '/'): | |
217 yield f[:c] | |
218 self.lazyread() | |
219 self.initdirs() | |
220 seendirs = {} | |
221 for f in files: | |
222 if self.dirs.get(f): | |
223 raise util.Abort(_('directory named %r already in dirstate') % | |
224 f) | |
225 for d in prefixes(f): | |
226 if d in seendirs: | |
227 break | |
228 if d in self.map: | |
229 raise util.Abort(_('file named %r already in dirstate') % | |
230 d) | |
231 seendirs[d] = True | |
232 | |
200 def update(self, files, state, **kw): | 233 def update(self, files, state, **kw): |
201 ''' current states: | 234 ''' current states: |
202 n normal | 235 n normal |
203 m needs merging | 236 m needs merging |
204 r marked for removal | 237 r marked for removal |
205 a marked for addition''' | 238 a marked for addition''' |
206 | 239 |
207 if not files: return | 240 if not files: return |
208 self.lazyread() | 241 self.lazyread() |
209 self.markdirty() | 242 self.markdirty() |
243 if state == "a": | |
244 self.initdirs() | |
245 self.checkshadows(files) | |
210 for f in files: | 246 for f in files: |
211 if state == "r": | 247 if state == "r": |
212 self.map[f] = ('r', 0, 0, 0) | 248 self.map[f] = ('r', 0, 0, 0) |
249 self.updatedirs(f, -1) | |
213 else: | 250 else: |
251 if state == "a": | |
252 self.updatedirs(f, 1) | |
214 s = os.lstat(self.wjoin(f)) | 253 s = os.lstat(self.wjoin(f)) |
215 st_size = kw.get('st_size', s.st_size) | 254 st_size = kw.get('st_size', s.st_size) |
216 st_mtime = kw.get('st_mtime', s.st_mtime) | 255 st_mtime = kw.get('st_mtime', s.st_mtime) |
217 self.map[f] = (state, s.st_mode, st_size, st_mtime) | 256 self.map[f] = (state, s.st_mode, st_size, st_mtime) |
218 if self.copies.has_key(f): | 257 if self.copies.has_key(f): |
220 | 259 |
221 def forget(self, files): | 260 def forget(self, files): |
222 if not files: return | 261 if not files: return |
223 self.lazyread() | 262 self.lazyread() |
224 self.markdirty() | 263 self.markdirty() |
264 self.initdirs() | |
225 for f in files: | 265 for f in files: |
226 try: | 266 try: |
227 del self.map[f] | 267 del self.map[f] |
268 self.updatedirs(f, -1) | |
228 except KeyError: | 269 except KeyError: |
229 self.ui.warn(_("not in dirstate: %s!\n") % f) | 270 self.ui.warn(_("not in dirstate: %s!\n") % f) |
230 pass | 271 pass |
231 | 272 |
232 def clear(self): | 273 def clear(self): |
233 self.map = {} | 274 self.map = {} |
234 self.copies = {} | 275 self.copies = {} |
276 self.dirs = None | |
235 self.markdirty() | 277 self.markdirty() |
236 | 278 |
237 def rebuild(self, parent, files): | 279 def rebuild(self, parent, files): |
238 self.clear() | 280 self.clear() |
239 umask = os.umask(0) | 281 umask = os.umask(0) |