Show More
@@ -9,12 +9,20 b' of the GNU General Public License, incor' | |||||
9 |
|
9 | |||
10 | from node import nullid |
|
10 | from node import nullid | |
11 | from i18n import _ |
|
11 | from i18n import _ | |
12 |
import struct, os, bisect, stat, |
|
12 | import struct, os, bisect, stat, util, errno, ignore | |
13 | import cStringIO, osutil, sys |
|
13 | import cStringIO, osutil, sys | |
14 |
|
14 | |||
15 | _unknown = ('?', 0, 0, 0) |
|
15 | _unknown = ('?', 0, 0, 0) | |
16 | _format = ">cllll" |
|
16 | _format = ">cllll" | |
17 |
|
17 | |||
|
18 | def _finddirs(path): | |||
|
19 | pos = len(path) | |||
|
20 | while 1: | |||
|
21 | pos = path.rfind('/', 0, pos) | |||
|
22 | if pos == -1: | |||
|
23 | break | |||
|
24 | yield path[:pos] | |||
|
25 | ||||
18 | class dirstate(object): |
|
26 | class dirstate(object): | |
19 |
|
27 | |||
20 | def __init__(self, opener, ui, root): |
|
28 | def __init__(self, opener, ui, root): | |
@@ -55,10 +63,12 b' class dirstate(object):' | |||||
55 | if err.errno != errno.ENOENT: raise |
|
63 | if err.errno != errno.ENOENT: raise | |
56 | return self._pl |
|
64 | return self._pl | |
57 | elif name == '_dirs': |
|
65 | elif name == '_dirs': | |
58 |
|
|
66 | dirs = {} | |
59 | for f in self._map: |
|
67 | for f,s in self._map.items(): | |
60 |
if s |
|
68 | if s[0] != 'r': | |
61 |
|
|
69 | for base in _finddirs(f): | |
|
70 | dirs[base] = dirs.get(base, 0) + 1 | |||
|
71 | self._dirs = dirs | |||
62 | return self._dirs |
|
72 | return self._dirs | |
63 | elif name == '_ignore': |
|
73 | elif name == '_ignore': | |
64 | files = [self._join('.hgignore')] |
|
74 | files = [self._join('.hgignore')] | |
@@ -223,67 +233,39 b' class dirstate(object):' | |||||
223 | def copies(self): |
|
233 | def copies(self): | |
224 | return self._copymap |
|
234 | return self._copymap | |
225 |
|
235 | |||
226 |
def _ |
|
236 | def _droppath(self, f): | |
227 | c = path.rfind('/') |
|
237 | if self[f] not in "?r" and "_dirs" in self.__dict__: | |
228 | if c >= 0: |
|
|||
229 | dirs = self._dirs |
|
238 | dirs = self._dirs | |
230 | base = path[:c] |
|
239 | for base in _finddirs(f): | |
231 |
if base |
|
240 | if dirs[base] == 1: | |
232 |
|
|
241 | del dirs[base] | |
233 |
|
|
242 | else: | |
234 | else: |
|
243 | dirs[base] -= 1 | |
235 | dirs[base] += 1 |
|
|||
236 |
|
||||
237 | def _decpath(self, path): |
|
|||
238 | c = path.rfind('/') |
|
|||
239 | if c >= 0: |
|
|||
240 | base = path[:c] |
|
|||
241 | dirs = self._dirs |
|
|||
242 | if dirs[base] == 1: |
|
|||
243 | del dirs[base] |
|
|||
244 | self._decpath(base) |
|
|||
245 | else: |
|
|||
246 | dirs[base] -= 1 |
|
|||
247 |
|
244 | |||
248 |
def _ |
|
245 | def _addpath(self, f, check=False): | |
249 | if '\r' in f or '\n' in f: |
|
|||
250 | raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") |
|
|||
251 | % f) |
|
|||
252 | # shadows |
|
|||
253 | if f in self._dirs: |
|
|||
254 | raise util.Abort(_('directory %r already in dirstate') % f) |
|
|||
255 | for c in strutil.rfindall(f, '/'): |
|
|||
256 | d = f[:c] |
|
|||
257 | if d in self._dirs: |
|
|||
258 | break |
|
|||
259 | if d in self._map and self[d] != 'r': |
|
|||
260 | raise util.Abort(_('file %r in dirstate clashes with %r') % |
|
|||
261 | (d, f)) |
|
|||
262 | self._incpath(f) |
|
|||
263 |
|
||||
264 | def _changepath(self, f, newstate, relaxed=False): |
|
|||
265 | # handle upcoming path changes |
|
|||
266 | oldstate = self[f] |
|
246 | oldstate = self[f] | |
267 | if oldstate not in "?r" and newstate in "?r": |
|
247 | if check or oldstate == "r": | |
268 | if "_dirs" in self.__dict__: |
|
248 | if '\r' in f or '\n' in f: | |
269 |
sel |
|
249 | raise util.Abort( | |
270 | return |
|
250 | _("'\\n' and '\\r' disallowed in filenames: %r") % f) | |
271 | if oldstate in "?r" and newstate not in "?r": |
|
251 | if f in self._dirs: | |
272 | if relaxed and oldstate == '?': |
|
252 | raise util.Abort(_('directory %r already in dirstate') % f) | |
273 |
|
|
253 | # shadows | |
274 | # in relaxed mode we assume the caller knows |
|
254 | for d in _finddirs(f): | |
275 | # what it is doing, workaround for updating |
|
255 | if d in self._dirs: | |
276 |
|
|
256 | break | |
277 |
if |
|
257 | if d in self._map and self[d] != 'r': | |
278 |
sel |
|
258 | raise util.Abort( | |
279 | return |
|
259 | _('file %r in dirstate clashes with %r') % (d, f)) | |
280 | self._incpathcheck(f) |
|
260 | if oldstate in "?r" and "_dirs" in self.__dict__: | |
281 |
|
|
261 | dirs = self._dirs | |
|
262 | for base in _finddirs(f): | |||
|
263 | dirs[base] = dirs.get(base, 0) + 1 | |||
282 |
|
264 | |||
283 | def normal(self, f): |
|
265 | def normal(self, f): | |
284 | 'mark a file normal and clean' |
|
266 | 'mark a file normal and clean' | |
285 | self._dirty = True |
|
267 | self._dirty = True | |
286 |
self._ |
|
268 | self._addpath(f) | |
287 | s = os.lstat(self._join(f)) |
|
269 | s = os.lstat(self._join(f)) | |
288 | self._map[f] = ('n', s.st_mode, s.st_size, s.st_mtime, 0) |
|
270 | self._map[f] = ('n', s.st_mode, s.st_size, s.st_mtime, 0) | |
289 | if f in self._copymap: |
|
271 | if f in self._copymap: | |
@@ -307,7 +289,7 b' class dirstate(object):' | |||||
307 | if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2: |
|
289 | if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2: | |
308 | return |
|
290 | return | |
309 | self._dirty = True |
|
291 | self._dirty = True | |
310 |
self._ |
|
292 | self._addpath(f) | |
311 | self._map[f] = ('n', 0, -1, -1, 0) |
|
293 | self._map[f] = ('n', 0, -1, -1, 0) | |
312 | if f in self._copymap: |
|
294 | if f in self._copymap: | |
313 | del self._copymap[f] |
|
295 | del self._copymap[f] | |
@@ -315,7 +297,7 b' class dirstate(object):' | |||||
315 | def normaldirty(self, f): |
|
297 | def normaldirty(self, f): | |
316 | 'mark a file normal, but dirty' |
|
298 | 'mark a file normal, but dirty' | |
317 | self._dirty = True |
|
299 | self._dirty = True | |
318 |
self._ |
|
300 | self._addpath(f) | |
319 | self._map[f] = ('n', 0, -2, -1, 0) |
|
301 | self._map[f] = ('n', 0, -2, -1, 0) | |
320 | if f in self._copymap: |
|
302 | if f in self._copymap: | |
321 | del self._copymap[f] |
|
303 | del self._copymap[f] | |
@@ -323,7 +305,7 b' class dirstate(object):' | |||||
323 | def add(self, f): |
|
305 | def add(self, f): | |
324 | 'mark a file added' |
|
306 | 'mark a file added' | |
325 | self._dirty = True |
|
307 | self._dirty = True | |
326 |
self._ |
|
308 | self._addpath(f, True) | |
327 | self._map[f] = ('a', 0, -1, -1, 0) |
|
309 | self._map[f] = ('a', 0, -1, -1, 0) | |
328 | if f in self._copymap: |
|
310 | if f in self._copymap: | |
329 | del self._copymap[f] |
|
311 | del self._copymap[f] | |
@@ -331,7 +313,7 b' class dirstate(object):' | |||||
331 | def remove(self, f): |
|
313 | def remove(self, f): | |
332 | 'mark a file removed' |
|
314 | 'mark a file removed' | |
333 | self._dirty = True |
|
315 | self._dirty = True | |
334 |
self._ |
|
316 | self._droppath(f) | |
335 | size = 0 |
|
317 | size = 0 | |
336 | if self._pl[1] != nullid and f in self._map: |
|
318 | if self._pl[1] != nullid and f in self._map: | |
337 | entry = self._map[f] |
|
319 | entry = self._map[f] | |
@@ -347,7 +329,7 b' class dirstate(object):' | |||||
347 | 'mark a file merged' |
|
329 | 'mark a file merged' | |
348 | self._dirty = True |
|
330 | self._dirty = True | |
349 | s = os.lstat(self._join(f)) |
|
331 | s = os.lstat(self._join(f)) | |
350 |
self._ |
|
332 | self._addpath(f) | |
351 | self._map[f] = ('m', s.st_mode, s.st_size, s.st_mtime, 0) |
|
333 | self._map[f] = ('m', s.st_mode, s.st_size, s.st_mtime, 0) | |
352 | if f in self._copymap: |
|
334 | if f in self._copymap: | |
353 | del self._copymap[f] |
|
335 | del self._copymap[f] | |
@@ -356,7 +338,7 b' class dirstate(object):' | |||||
356 | 'forget a file' |
|
338 | 'forget a file' | |
357 | self._dirty = True |
|
339 | self._dirty = True | |
358 | try: |
|
340 | try: | |
359 |
self._ |
|
341 | self._droppath('?') | |
360 | del self._map[f] |
|
342 | del self._map[f] | |
361 | except KeyError: |
|
343 | except KeyError: | |
362 | self._ui.warn(_("not in dirstate: %s\n") % f) |
|
344 | self._ui.warn(_("not in dirstate: %s\n") % f) | |
@@ -467,8 +449,8 b' class dirstate(object):' | |||||
467 | return False |
|
449 | return False | |
468 | if self._ignore(f): |
|
450 | if self._ignore(f): | |
469 | return True |
|
451 | return True | |
470 |
for |
|
452 | for p in _finddirs(f): | |
471 |
if self._ignore( |
|
453 | if self._ignore(p): | |
472 | return True |
|
454 | return True | |
473 | return False |
|
455 | return False | |
474 |
|
456 |
General Comments 0
You need to be logged in to leave comments.
Login now