Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/dirstate.py @ 1584:b3e94785ab69
merge with crew
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Sun, 11 Dec 2005 15:38:42 -0800 |
parents | 34579a67fa71 |
children | 84e9b3484ff6 |
comparison
equal
deleted
inserted
replaced
1583:32a4e6802864 | 1584:b3e94785ab69 |
---|---|
11 from node import * | 11 from node import * |
12 from i18n import gettext as _ | 12 from i18n import gettext as _ |
13 from demandload import * | 13 from demandload import * |
14 demandload(globals(), "time bisect stat util re errno") | 14 demandload(globals(), "time bisect stat util re errno") |
15 | 15 |
16 class dirstate: | 16 class dirstate(object): |
17 def __init__(self, opener, ui, root): | 17 def __init__(self, opener, ui, root): |
18 self.opener = opener | 18 self.opener = opener |
19 self.root = root | 19 self.root = root |
20 self.dirty = 0 | 20 self.dirty = 0 |
21 self.ui = ui | 21 self.ui = ui |
99 | 99 |
100 def __getitem__(self, key): | 100 def __getitem__(self, key): |
101 try: | 101 try: |
102 return self.map[key] | 102 return self.map[key] |
103 except TypeError: | 103 except TypeError: |
104 self.read() | 104 self.lazyread() |
105 return self[key] | 105 return self[key] |
106 | 106 |
107 def __contains__(self, key): | 107 def __contains__(self, key): |
108 if not self.map: self.read() | 108 self.lazyread() |
109 return key in self.map | 109 return key in self.map |
110 | 110 |
111 def parents(self): | 111 def parents(self): |
112 if not self.pl: | 112 self.lazyread() |
113 self.read() | |
114 return self.pl | 113 return self.pl |
115 | 114 |
116 def markdirty(self): | 115 def markdirty(self): |
117 if not self.dirty: | 116 if not self.dirty: |
118 self.dirty = 1 | 117 self.dirty = 1 |
119 | 118 |
120 def setparents(self, p1, p2=nullid): | 119 def setparents(self, p1, p2=nullid): |
121 if not self.pl: | 120 self.lazyread() |
122 self.read() | |
123 self.markdirty() | 121 self.markdirty() |
124 self.pl = p1, p2 | 122 self.pl = p1, p2 |
125 | 123 |
126 def state(self, key): | 124 def state(self, key): |
127 try: | 125 try: |
128 return self[key][0] | 126 return self[key][0] |
129 except KeyError: | 127 except KeyError: |
130 return "?" | 128 return "?" |
131 | 129 |
130 def lazyread(self): | |
131 if self.map is None: | |
132 self.read() | |
133 | |
132 def read(self): | 134 def read(self): |
133 if self.map is not None: return self.map | |
134 | |
135 self.map = {} | 135 self.map = {} |
136 self.pl = [nullid, nullid] | 136 self.pl = [nullid, nullid] |
137 try: | 137 try: |
138 st = self.opener("dirstate").read() | 138 st = self.opener("dirstate").read() |
139 if not st: return | 139 if not st: return |
152 self.copies[f] = c | 152 self.copies[f] = c |
153 self.map[f] = e[:4] | 153 self.map[f] = e[:4] |
154 pos += l | 154 pos += l |
155 | 155 |
156 def copy(self, source, dest): | 156 def copy(self, source, dest): |
157 self.read() | 157 self.lazyread() |
158 self.markdirty() | 158 self.markdirty() |
159 self.copies[dest] = source | 159 self.copies[dest] = source |
160 | 160 |
161 def copied(self, file): | 161 def copied(self, file): |
162 return self.copies.get(file, None) | 162 return self.copies.get(file, None) |
167 m needs merging | 167 m needs merging |
168 r marked for removal | 168 r marked for removal |
169 a marked for addition''' | 169 a marked for addition''' |
170 | 170 |
171 if not files: return | 171 if not files: return |
172 self.read() | 172 self.lazyread() |
173 self.markdirty() | 173 self.markdirty() |
174 for f in files: | 174 for f in files: |
175 if state == "r": | 175 if state == "r": |
176 self.map[f] = ('r', 0, 0, 0) | 176 self.map[f] = ('r', 0, 0, 0) |
177 else: | 177 else: |
178 s = os.lstat(os.path.join(self.root, f)) | 178 s = os.lstat(self.wjoin(f)) |
179 st_size = kw.get('st_size', s.st_size) | 179 st_size = kw.get('st_size', s.st_size) |
180 st_mtime = kw.get('st_mtime', s.st_mtime) | 180 st_mtime = kw.get('st_mtime', s.st_mtime) |
181 self.map[f] = (state, s.st_mode, st_size, st_mtime) | 181 self.map[f] = (state, s.st_mode, st_size, st_mtime) |
182 if self.copies.has_key(f): | 182 if self.copies.has_key(f): |
183 del self.copies[f] | 183 del self.copies[f] |
184 | 184 |
185 def forget(self, files): | 185 def forget(self, files): |
186 if not files: return | 186 if not files: return |
187 self.read() | 187 self.lazyread() |
188 self.markdirty() | 188 self.markdirty() |
189 for f in files: | 189 for f in files: |
190 try: | 190 try: |
191 del self.map[f] | 191 del self.map[f] |
192 except KeyError: | 192 except KeyError: |
196 def clear(self): | 196 def clear(self): |
197 self.map = {} | 197 self.map = {} |
198 self.markdirty() | 198 self.markdirty() |
199 | 199 |
200 def write(self): | 200 def write(self): |
201 st = self.opener("dirstate", "w") | 201 st = self.opener("dirstate", "w", atomic=True) |
202 st.write("".join(self.pl)) | 202 st.write("".join(self.pl)) |
203 for f, e in self.map.items(): | 203 for f, e in self.map.items(): |
204 c = self.copied(f) | 204 c = self.copied(f) |
205 if c: | 205 if c: |
206 f = f + "\0" + c | 206 f = f + "\0" + c |
211 def filterfiles(self, files): | 211 def filterfiles(self, files): |
212 ret = {} | 212 ret = {} |
213 unknown = [] | 213 unknown = [] |
214 | 214 |
215 for x in files: | 215 for x in files: |
216 if x is '.': | 216 if x == '.': |
217 return self.map.copy() | 217 return self.map.copy() |
218 if x not in self.map: | 218 if x not in self.map: |
219 unknown.append(x) | 219 unknown.append(x) |
220 else: | 220 else: |
221 ret[x] = self.map[x] | 221 ret[x] = self.map[x] |
239 else: | 239 else: |
240 break | 240 break |
241 bs += 1 | 241 bs += 1 |
242 return ret | 242 return ret |
243 | 243 |
244 def supported_type(self, f, st, verbose=True): | 244 def supported_type(self, f, st, verbose=False): |
245 if stat.S_ISREG(st.st_mode): | 245 if stat.S_ISREG(st.st_mode): |
246 return True | 246 return True |
247 if verbose: | 247 if verbose: |
248 kind = 'unknown' | 248 kind = 'unknown' |
249 if stat.S_ISCHR(st.st_mode): kind = _('character device') | 249 if stat.S_ISCHR(st.st_mode): kind = _('character device') |
256 util.pathto(self.getcwd(), f), | 256 util.pathto(self.getcwd(), f), |
257 kind)) | 257 kind)) |
258 return False | 258 return False |
259 | 259 |
260 def statwalk(self, files=None, match=util.always, dc=None): | 260 def statwalk(self, files=None, match=util.always, dc=None): |
261 self.read() | 261 self.lazyread() |
262 | 262 |
263 # walk all files by default | 263 # walk all files by default |
264 if not files: | 264 if not files: |
265 files = [self.root] | 265 files = [self.root] |
266 if not dc: | 266 if not dc: |
294 # directly by this function, but might be modified by your statmatch call. | 294 # directly by this function, but might be modified by your statmatch call. |
295 # | 295 # |
296 def walkhelper(self, files, statmatch, dc): | 296 def walkhelper(self, files, statmatch, dc): |
297 # recursion free walker, faster than os.walk. | 297 # recursion free walker, faster than os.walk. |
298 def findfiles(s): | 298 def findfiles(s): |
299 retfiles = [] | |
300 work = [s] | 299 work = [s] |
301 while work: | 300 while work: |
302 top = work.pop() | 301 top = work.pop() |
303 names = os.listdir(top) | 302 names = os.listdir(top) |
304 names.sort() | 303 names.sort() |
305 # nd is the top of the repository dir tree | 304 # nd is the top of the repository dir tree |
306 nd = util.normpath(top[len(self.root) + 1:]) | 305 nd = util.normpath(top[len(self.root) + 1:]) |
307 if nd == '.': nd = '' | 306 if nd == '.': nd = '' |
308 for f in names: | 307 for f in names: |
309 np = os.path.join(nd, f) | 308 np = util.pconvert(os.path.join(nd, f)) |
310 if seen(np): | 309 if seen(np): |
311 continue | 310 continue |
312 p = os.path.join(top, f) | 311 p = os.path.join(top, f) |
313 # don't trip over symlinks | 312 # don't trip over symlinks |
314 st = os.lstat(p) | 313 st = os.lstat(p) |
315 if stat.S_ISDIR(st.st_mode): | 314 if stat.S_ISDIR(st.st_mode): |
316 ds = os.path.join(nd, f +'/') | 315 ds = os.path.join(nd, f +'/') |
317 if statmatch(ds, st): | 316 if statmatch(ds, st): |
318 work.append(p) | 317 work.append(p) |
319 if statmatch(np, st) and np in dc: | 318 if statmatch(np, st) and np in dc: |
320 yield 'm', util.pconvert(np), st | 319 yield 'm', np, st |
321 elif statmatch(np, st): | 320 elif statmatch(np, st): |
322 if self.supported_type(np, st): | 321 if self.supported_type(np, st): |
323 yield 'f', util.pconvert(np), st | 322 yield 'f', np, st |
324 elif np in dc: | 323 elif np in dc: |
325 yield 'm', util.pconvert(np), st | 324 yield 'm', np, st |
326 | 325 |
327 known = {'.hg': 1} | 326 known = {'.hg': 1} |
328 def seen(fn): | 327 def seen(fn): |
329 if fn in known: return True | 328 if fn in known: return True |
330 known[fn] = 1 | 329 known[fn] = 1 |
331 | 330 |
332 # step one, find all files that match our criteria | 331 # step one, find all files that match our criteria |
333 files.sort() | 332 files.sort() |
334 for ff in util.unique(files): | 333 for ff in util.unique(files): |
335 f = os.path.join(self.root, ff) | 334 f = self.wjoin(ff) |
336 try: | 335 try: |
337 st = os.lstat(f) | 336 st = os.lstat(f) |
338 except OSError, inst: | 337 except OSError, inst: |
339 if ff not in dc: self.ui.warn('%s: %s\n' % ( | 338 nf = util.normpath(ff) |
340 util.pathto(self.getcwd(), ff), | 339 found = False |
341 inst.strerror)) | 340 for fn in dc: |
341 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): | |
342 found = True | |
343 break | |
344 if not found: | |
345 self.ui.warn('%s: %s\n' % ( | |
346 util.pathto(self.getcwd(), ff), | |
347 inst.strerror)) | |
342 continue | 348 continue |
343 if stat.S_ISDIR(st.st_mode): | 349 if stat.S_ISDIR(st.st_mode): |
344 cmp1 = (lambda x, y: cmp(x[1], y[1])) | 350 cmp1 = (lambda x, y: cmp(x[1], y[1])) |
345 sorted = [ x for x in findfiles(f) ] | 351 sorted = [ x for x in findfiles(f) ] |
346 sorted.sort(cmp1) | 352 sorted.sort(cmp1) |
350 ff = util.normpath(ff) | 356 ff = util.normpath(ff) |
351 if seen(ff): | 357 if seen(ff): |
352 continue | 358 continue |
353 self.blockignore = True | 359 self.blockignore = True |
354 if statmatch(ff, st): | 360 if statmatch(ff, st): |
355 if self.supported_type(ff, st): | 361 if self.supported_type(ff, st, verbose=True): |
356 yield 'f', ff, st | 362 yield 'f', ff, st |
357 elif ff in dc: | 363 elif ff in dc: |
358 yield 'm', ff, st | 364 yield 'm', ff, st |
359 self.blockignore = False | 365 self.blockignore = False |
360 | 366 |
378 continue | 384 continue |
379 if src == 'm': | 385 if src == 'm': |
380 nonexistent = True | 386 nonexistent = True |
381 if not st: | 387 if not st: |
382 try: | 388 try: |
383 f = os.path.join(self.root, fn) | 389 f = self.wjoin(fn) |
384 st = os.lstat(f) | 390 st = os.lstat(f) |
385 except OSError, inst: | 391 except OSError, inst: |
386 if inst.errno != errno.ENOENT: | 392 if inst.errno != errno.ENOENT: |
387 raise | 393 raise |
388 st = None | 394 st = None |