Show More
@@ -0,0 +1,34 b'' | |||||
|
1 | # strutil.py - string utilities for Mercurial | |||
|
2 | # | |||
|
3 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms | |||
|
6 | # of the GNU General Public License, incorporated herein by reference. | |||
|
7 | ||||
|
8 | def findall(haystack, needle, start=0, end=None): | |||
|
9 | if end is None: | |||
|
10 | end = len(haystack) | |||
|
11 | if end < 0: | |||
|
12 | end += len(haystack) | |||
|
13 | if start < 0: | |||
|
14 | start += len(haystack) | |||
|
15 | while start < end: | |||
|
16 | c = haystack.find(needle, start, end) | |||
|
17 | if c == -1: | |||
|
18 | break | |||
|
19 | yield c | |||
|
20 | start = c + 1 | |||
|
21 | ||||
|
22 | def rfindall(haystack, needle, start=0, end=None): | |||
|
23 | if end is None: | |||
|
24 | end = len(haystack) | |||
|
25 | if end < 0: | |||
|
26 | end += len(haystack) | |||
|
27 | if start < 0: | |||
|
28 | start += len(haystack) | |||
|
29 | while end >= 0: | |||
|
30 | c = haystack.rfind(needle, start, end) | |||
|
31 | if c == -1: | |||
|
32 | break | |||
|
33 | yield c | |||
|
34 | end = c - 1 |
@@ -0,0 +1,12 b'' | |||||
|
1 | % file replaced with directory | |||
|
2 | adding a | |||
|
3 | % should fail - would corrupt dirstate | |||
|
4 | abort: file named 'a' already in dirstate | |||
|
5 | % directory replaced with file | |||
|
6 | adding a/a | |||
|
7 | % should fail - would corrupt dirstate | |||
|
8 | abort: directory named 'a' already in dirstate | |||
|
9 | % directory replaced with file | |||
|
10 | adding b/c/d | |||
|
11 | % should fail - would corrupt dirstate | |||
|
12 | abort: directory named 'b' already in dirstate |
@@ -10,7 +10,7 b' of the GNU General Public License, incor' | |||||
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" | |
@@ -22,6 +22,7 b' class dirstate(object):' | |||||
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 | |
@@ -197,6 +198,38 b' class dirstate(object):' | |||||
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 | |
@@ -207,10 +240,16 b' class dirstate(object):' | |||||
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) | |
@@ -222,9 +261,11 b' class dirstate(object):' | |||||
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 | |
@@ -232,6 +273,7 b' class dirstate(object):' | |||||
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): |
@@ -995,4 +995,3 b' def drop_scheme(scheme, path):' | |||||
995 | if path.startswith('//'): |
|
995 | if path.startswith('//'): | |
996 | path = path[2:] |
|
996 | path = path[2:] | |
997 | return path |
|
997 | return path | |
998 |
|
@@ -14,15 +14,7 b' echo a > a/a' | |||||
14 | echo % should fail - would corrupt dirstate |
|
14 | echo % should fail - would corrupt dirstate | |
15 | hg add a/a |
|
15 | hg add a/a | |
16 |
|
16 | |||
17 | echo % should fail - if add succeeded, would corrupt manifest |
|
|||
18 | hg commit -mb |
|
|||
19 |
|
||||
20 | echo % should fail if commit succeeded - manifest is corrupt |
|
|||
21 | hg verify |
|
|||
22 |
|
||||
23 | cd .. |
|
17 | cd .. | |
24 | echo % should succeed, but manifest is corrupt |
|
|||
25 | hg --debug --traceback clone a b |
|
|||
26 |
|
18 | |||
27 | echo % directory replaced with file |
|
19 | echo % directory replaced with file | |
28 |
|
20 | |||
@@ -38,8 +30,20 b' echo a > a' | |||||
38 | echo % should fail - would corrupt dirstate |
|
30 | echo % should fail - would corrupt dirstate | |
39 | hg add a |
|
31 | hg add a | |
40 |
|
32 | |||
41 | echo % should fail - if add succeeded, would corrupt manifest |
|
33 | cd .. | |
42 | hg commit -mb a |
|
34 | ||
|
35 | echo % directory replaced with file | |||
43 |
|
36 | |||
44 | echo % should fail if commit succeeded - manifest is corrupt |
|
37 | hg init d | |
45 | hg verify |
|
38 | cd d | |
|
39 | mkdir b | |||
|
40 | mkdir b/c | |||
|
41 | echo a > b/c/d | |||
|
42 | hg commit -Ama | |||
|
43 | rm -rf b | |||
|
44 | echo a > b | |||
|
45 | ||||
|
46 | echo % should fail - would corrupt dirstate | |||
|
47 | hg add b | |||
|
48 | ||||
|
49 | exit 0 |
General Comments 0
You need to be logged in to leave comments.
Login now