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)