Show More
@@ -0,0 +1,228 b'' | |||||
|
1 | $ fileset() { | |||
|
2 | > hg debugfileset "$@" | |||
|
3 | > } | |||
|
4 | ||||
|
5 | $ hg init repo | |||
|
6 | $ cd repo | |||
|
7 | $ echo a > a1 | |||
|
8 | $ echo a > a2 | |||
|
9 | $ echo b > b1 | |||
|
10 | $ echo b > b2 | |||
|
11 | $ hg ci -Am addfiles | |||
|
12 | adding a1 | |||
|
13 | adding a2 | |||
|
14 | adding b1 | |||
|
15 | adding b2 | |||
|
16 | ||||
|
17 | Test operators and basic patterns | |||
|
18 | ||||
|
19 | $ fileset a1 | |||
|
20 | a1 | |||
|
21 | $ fileset 'a*' | |||
|
22 | a1 | |||
|
23 | a2 | |||
|
24 | $ fileset '"re:a\d"' | |||
|
25 | a1 | |||
|
26 | a2 | |||
|
27 | $ fileset 'a1 or a2' | |||
|
28 | a1 | |||
|
29 | a2 | |||
|
30 | $ fileset 'a1 | a2' | |||
|
31 | a1 | |||
|
32 | a2 | |||
|
33 | $ fileset 'a* and "*1"' | |||
|
34 | a1 | |||
|
35 | $ fileset 'a* & "*1"' | |||
|
36 | a1 | |||
|
37 | $ fileset 'not (r"a*")' | |||
|
38 | b1 | |||
|
39 | b2 | |||
|
40 | $ fileset '! ("a*")' | |||
|
41 | b1 | |||
|
42 | b2 | |||
|
43 | $ fileset 'a* - a1' | |||
|
44 | a2 | |||
|
45 | ||||
|
46 | Test files status | |||
|
47 | ||||
|
48 | $ rm a1 | |||
|
49 | $ hg rm a2 | |||
|
50 | $ echo b >> b2 | |||
|
51 | $ hg cp b1 c1 | |||
|
52 | $ echo c > c2 | |||
|
53 | $ echo c > c3 | |||
|
54 | $ cat > .hgignore <<EOF | |||
|
55 | > \.hgignore | |||
|
56 | > 2$ | |||
|
57 | > EOF | |||
|
58 | $ fileset 'modified()' | |||
|
59 | b2 | |||
|
60 | $ fileset 'added()' | |||
|
61 | c1 | |||
|
62 | $ fileset 'removed()' | |||
|
63 | a2 | |||
|
64 | $ fileset 'deleted()' | |||
|
65 | a1 | |||
|
66 | $ fileset 'unknown()' | |||
|
67 | c3 | |||
|
68 | $ fileset 'ignored()' | |||
|
69 | .hgignore | |||
|
70 | c2 | |||
|
71 | $ fileset 'hgignore()' | |||
|
72 | a2 | |||
|
73 | b2 | |||
|
74 | $ fileset 'clean()' | |||
|
75 | b1 | |||
|
76 | $ fileset 'copied()' | |||
|
77 | c1 | |||
|
78 | ||||
|
79 | Test files properties | |||
|
80 | ||||
|
81 | >>> file('bin', 'wb').write('\0a') | |||
|
82 | $ fileset 'binary()' | |||
|
83 | $ fileset 'binary() and unknown()' | |||
|
84 | bin | |||
|
85 | $ echo '^bin$' >> .hgignore | |||
|
86 | $ fileset 'binary() and ignored()' | |||
|
87 | bin | |||
|
88 | $ hg add bin | |||
|
89 | $ fileset 'binary()' | |||
|
90 | bin | |||
|
91 | ||||
|
92 | $ fileset 'grep("b{1}")' | |||
|
93 | b2 | |||
|
94 | c1 | |||
|
95 | b1 | |||
|
96 | $ fileset 'grep("missingparens(")' | |||
|
97 | hg: parse error: invalid match pattern: unbalanced parenthesis | |||
|
98 | [255] | |||
|
99 | ||||
|
100 | #if execbit | |||
|
101 | $ chmod +x b2 | |||
|
102 | $ fileset 'exec()' | |||
|
103 | b2 | |||
|
104 | #endif | |||
|
105 | ||||
|
106 | #if symlink | |||
|
107 | $ ln -s b2 b2link | |||
|
108 | $ fileset 'symlink() and unknown()' | |||
|
109 | b2link | |||
|
110 | $ hg add b2link | |||
|
111 | #endif | |||
|
112 | ||||
|
113 | >>> file('1k', 'wb').write(' '*1024) | |||
|
114 | >>> file('2k', 'wb').write(' '*2048) | |||
|
115 | $ hg add 1k 2k | |||
|
116 | $ fileset 'size("bar")' | |||
|
117 | hg: parse error: couldn't parse size: bar | |||
|
118 | [255] | |||
|
119 | $ fileset 'size(1k)' | |||
|
120 | 1k | |||
|
121 | $ fileset '(1k or 2k) and size("< 2k")' | |||
|
122 | 1k | |||
|
123 | $ fileset '(1k or 2k) and size("<=2k")' | |||
|
124 | 1k | |||
|
125 | 2k | |||
|
126 | $ fileset '(1k or 2k) and size("> 1k")' | |||
|
127 | 2k | |||
|
128 | $ fileset '(1k or 2k) and size(">=1K")' | |||
|
129 | 1k | |||
|
130 | 2k | |||
|
131 | $ fileset '(1k or 2k) and size(".5KB - 1.5kB")' | |||
|
132 | 1k | |||
|
133 | ||||
|
134 | Test merge states | |||
|
135 | ||||
|
136 | $ hg ci -m manychanges | |||
|
137 | $ hg up -C 0 | |||
|
138 | * files updated, 0 files merged, * files removed, 0 files unresolved (glob) | |||
|
139 | $ echo c >> b2 | |||
|
140 | $ hg ci -m diverging b2 | |||
|
141 | created new head | |||
|
142 | $ fileset 'resolved()' | |||
|
143 | $ fileset 'unresolved()' | |||
|
144 | $ hg merge | |||
|
145 | merging b2 | |||
|
146 | warning: conflicts during merge. | |||
|
147 | merging b2 incomplete! (edit conflicts, then use 'hg resolve --mark') | |||
|
148 | * files updated, 0 files merged, * files removed, 1 files unresolved (glob) | |||
|
149 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon | |||
|
150 | [1] | |||
|
151 | $ fileset 'resolved()' | |||
|
152 | $ fileset 'unresolved()' | |||
|
153 | b2 | |||
|
154 | $ echo e > b2 | |||
|
155 | $ hg resolve -m b2 | |||
|
156 | $ fileset 'resolved()' | |||
|
157 | b2 | |||
|
158 | $ fileset 'unresolved()' | |||
|
159 | $ hg ci -m merge | |||
|
160 | ||||
|
161 | Test subrepo predicate | |||
|
162 | ||||
|
163 | $ hg init sub | |||
|
164 | $ echo a > sub/suba | |||
|
165 | $ hg -R sub add sub/suba | |||
|
166 | $ hg -R sub ci -m sub | |||
|
167 | $ echo 'sub = sub' > .hgsub | |||
|
168 | $ fileset 'subrepo()' | |||
|
169 | $ hg add .hgsub | |||
|
170 | $ fileset 'subrepo()' | |||
|
171 | sub | |||
|
172 | $ fileset 'subrepo("sub")' | |||
|
173 | sub | |||
|
174 | $ fileset 'subrepo("glob:*")' | |||
|
175 | sub | |||
|
176 | $ hg ci -m subrepo | |||
|
177 | ||||
|
178 | Test with a revision | |||
|
179 | ||||
|
180 | $ hg log -G --template '{rev} {desc}\n' | |||
|
181 | @ 4 subrepo | |||
|
182 | | | |||
|
183 | o 3 merge | |||
|
184 | |\ | |||
|
185 | | o 2 diverging | |||
|
186 | | | | |||
|
187 | o | 1 manychanges | |||
|
188 | |/ | |||
|
189 | o 0 addfiles | |||
|
190 | ||||
|
191 | $ echo unknown > unknown | |||
|
192 | $ fileset -r1 'modified()' | |||
|
193 | b2 | |||
|
194 | $ fileset -r1 'added() and c1' | |||
|
195 | c1 | |||
|
196 | $ fileset -r1 'removed()' | |||
|
197 | a2 | |||
|
198 | $ fileset -r1 'deleted()' | |||
|
199 | $ fileset -r1 'unknown()' | |||
|
200 | $ fileset -r1 'ignored()' | |||
|
201 | $ fileset -r1 'hgignore()' | |||
|
202 | b2 | |||
|
203 | bin | |||
|
204 | $ fileset -r1 'binary()' | |||
|
205 | bin | |||
|
206 | $ fileset -r1 'size(1k)' | |||
|
207 | 1k | |||
|
208 | $ fileset -r3 'resolved()' | |||
|
209 | $ fileset -r3 'unresolved()' | |||
|
210 | ||||
|
211 | #if execbit | |||
|
212 | $ fileset -r1 'exec()' | |||
|
213 | b2 | |||
|
214 | #endif | |||
|
215 | ||||
|
216 | #if symlink | |||
|
217 | $ fileset -r1 'symlink()' | |||
|
218 | b2link | |||
|
219 | #endif | |||
|
220 | ||||
|
221 | $ fileset -r4 'subrepo("re:su.*")' | |||
|
222 | sub | |||
|
223 | $ fileset -r4 'subrepo("sub")' | |||
|
224 | sub | |||
|
225 | $ fileset -r4 'b2 or c1' | |||
|
226 | b2 | |||
|
227 | c1 | |||
|
228 |
@@ -15,7 +15,7 b'' | |||||
15 | <File Name="mercurial.osutil.pyd" /> |
|
15 | <File Name="mercurial.osutil.pyd" /> | |
16 | <File Name="mercurial.parsers.pyd" /> |
|
16 | <File Name="mercurial.parsers.pyd" /> | |
17 | <File Name="pyexpat.pyd" /> |
|
17 | <File Name="pyexpat.pyd" /> | |
18 |
<File Name="python2 |
|
18 | <File Name="python27.dll" /> | |
19 | <File Name="bz2.pyd" /> |
|
19 | <File Name="bz2.pyd" /> | |
20 | <File Name="select.pyd" /> |
|
20 | <File Name="select.pyd" /> | |
21 | <File Name="unicodedata.pyd" /> |
|
21 | <File Name="unicodedata.pyd" /> |
@@ -276,9 +276,9 b' class commandline(object):' | |||||
276 | pass |
|
276 | pass | |
277 | cmdline = [util.shellquote(arg) for arg in cmdline] |
|
277 | cmdline = [util.shellquote(arg) for arg in cmdline] | |
278 | if not self.ui.debugflag: |
|
278 | if not self.ui.debugflag: | |
279 |
cmdline += ['2>', |
|
279 | cmdline += ['2>', os.devnull] | |
280 | if closestdin: |
|
280 | if closestdin: | |
281 |
cmdline += ['<', |
|
281 | cmdline += ['<', os.devnull] | |
282 | cmdline = ' '.join(cmdline) |
|
282 | cmdline = ' '.join(cmdline) | |
283 | return cmdline |
|
283 | return cmdline | |
284 |
|
284 |
@@ -184,7 +184,7 b' class gnuarch_source(converter_source, c' | |||||
184 | cmdline = [self.execmd, cmd] |
|
184 | cmdline = [self.execmd, cmd] | |
185 | cmdline += args |
|
185 | cmdline += args | |
186 | cmdline = [util.shellquote(arg) for arg in cmdline] |
|
186 | cmdline = [util.shellquote(arg) for arg in cmdline] | |
187 |
cmdline += ['>', |
|
187 | cmdline += ['>', os.devnull, '2>', os.devnull] | |
188 | cmdline = util.quotecommand(' '.join(cmdline)) |
|
188 | cmdline = util.quotecommand(' '.join(cmdline)) | |
189 | self.ui.debug(cmdline, '\n') |
|
189 | self.ui.debug(cmdline, '\n') | |
190 | return os.system(cmdline) |
|
190 | return os.system(cmdline) |
@@ -515,7 +515,7 b' def service(opts, parentfn=None, initfn=' | |||||
515 | sys.stdout.flush() |
|
515 | sys.stdout.flush() | |
516 | sys.stderr.flush() |
|
516 | sys.stderr.flush() | |
517 |
|
517 | |||
518 |
nullfd = os.open( |
|
518 | nullfd = os.open(os.devnull, os.O_RDWR) | |
519 | logfilefd = nullfd |
|
519 | logfilefd = nullfd | |
520 | if logfile: |
|
520 | if logfile: | |
521 | logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND) |
|
521 | logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND) |
@@ -1847,14 +1847,17 b' def debugdiscovery(ui, repo, remoteurl="' | |||||
1847 | localrevs = opts.get('local_head') |
|
1847 | localrevs = opts.get('local_head') | |
1848 | doit(localrevs, remoterevs) |
|
1848 | doit(localrevs, remoterevs) | |
1849 |
|
1849 | |||
1850 |
@command('debugfileset', |
|
1850 | @command('debugfileset', | |
1851 | def debugfileset(ui, repo, expr): |
|
1851 | [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))], | |
|
1852 | _('[-r REV] FILESPEC')) | |||
|
1853 | def debugfileset(ui, repo, expr, **opts): | |||
1852 | '''parse and apply a fileset specification''' |
|
1854 | '''parse and apply a fileset specification''' | |
|
1855 | ctx = scmutil.revsingle(repo, opts.get('rev'), None) | |||
1853 | if ui.verbose: |
|
1856 | if ui.verbose: | |
1854 | tree = fileset.parse(expr)[0] |
|
1857 | tree = fileset.parse(expr)[0] | |
1855 | ui.note(tree, "\n") |
|
1858 | ui.note(tree, "\n") | |
1856 |
|
1859 | |||
1857 |
for f in fileset.getfileset( |
|
1860 | for f in fileset.getfileset(ctx, expr): | |
1858 | ui.write("%s\n" % f) |
|
1861 | ui.write("%s\n" % f) | |
1859 |
|
1862 | |||
1860 | @command('debugfsinfo', [], _('[PATH]')) |
|
1863 | @command('debugfsinfo', [], _('[PATH]')) | |
@@ -1995,6 +1998,10 b' def debuginstall(ui):' | |||||
1995 | ui.write(_(" (check that your locale is properly set)\n")) |
|
1998 | ui.write(_(" (check that your locale is properly set)\n")) | |
1996 | problems += 1 |
|
1999 | problems += 1 | |
1997 |
|
2000 | |||
|
2001 | # Python lib | |||
|
2002 | ui.status(_("checking Python lib (%s)...\n") | |||
|
2003 | % os.path.dirname(os.__file__)) | |||
|
2004 | ||||
1998 | # compiled modules |
|
2005 | # compiled modules | |
1999 | ui.status(_("checking installed modules (%s)...\n") |
|
2006 | ui.status(_("checking installed modules (%s)...\n") | |
2000 | % os.path.dirname(__file__)) |
|
2007 | % os.path.dirname(__file__)) | |
@@ -4266,7 +4273,7 b' def merge(ui, repo, node=None, **opts):' | |||||
4266 | hint=_("run 'hg heads .' to see heads")) |
|
4273 | hint=_("run 'hg heads .' to see heads")) | |
4267 |
|
4274 | |||
4268 | parent = repo.dirstate.p1() |
|
4275 | parent = repo.dirstate.p1() | |
4269 |
if len(nbhs) |
|
4276 | if len(nbhs) <= 1: | |
4270 | if len(bheads) > 1: |
|
4277 | if len(bheads) > 1: | |
4271 | raise util.Abort(_("heads are bookmarked - " |
|
4278 | raise util.Abort(_("heads are bookmarked - " | |
4272 | "please merge with an explicit rev"), |
|
4279 | "please merge with an explicit rev"), |
@@ -107,6 +107,11 b' def notset(mctx, x):' | |||||
107 | s = set(getset(mctx, x)) |
|
107 | s = set(getset(mctx, x)) | |
108 | return [r for r in mctx.subset if r not in s] |
|
108 | return [r for r in mctx.subset if r not in s] | |
109 |
|
109 | |||
|
110 | def minusset(mctx, x, y): | |||
|
111 | xl = getset(mctx, x) | |||
|
112 | yl = set(getset(mctx, y)) | |||
|
113 | return [f for f in xl if f not in yl] | |||
|
114 | ||||
110 | def listset(mctx, a, b): |
|
115 | def listset(mctx, a, b): | |
111 | raise error.ParseError(_("can't use a list in this context")) |
|
116 | raise error.ParseError(_("can't use a list in this context")) | |
112 |
|
117 | |||
@@ -251,8 +256,11 b' def grep(mctx, x):' | |||||
251 | """``grep(regex)`` |
|
256 | """``grep(regex)`` | |
252 | File contains the given regular expression. |
|
257 | File contains the given regular expression. | |
253 | """ |
|
258 | """ | |
254 | pat = getstring(x, _("grep requires a pattern")) |
|
259 | try: | |
255 | r = re.compile(pat) |
|
260 | # i18n: "grep" is a keyword | |
|
261 | r = re.compile(getstring(x, _("grep requires a pattern"))) | |||
|
262 | except re.error, e: | |||
|
263 | raise error.ParseError(_('invalid match pattern: %s') % e) | |||
256 | return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())] |
|
264 | return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())] | |
257 |
|
265 | |||
258 | _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10, |
|
266 | _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10, | |
@@ -406,6 +414,7 b' methods = {' | |||||
406 | 'symbol': stringset, |
|
414 | 'symbol': stringset, | |
407 | 'and': andset, |
|
415 | 'and': andset, | |
408 | 'or': orset, |
|
416 | 'or': orset, | |
|
417 | 'minus': minusset, | |||
409 | 'list': listset, |
|
418 | 'list': listset, | |
410 | 'group': getset, |
|
419 | 'group': getset, | |
411 | 'not': notset, |
|
420 | 'not': notset, | |
@@ -424,7 +433,14 b' class matchctx(object):' | |||||
424 | def filter(self, files): |
|
433 | def filter(self, files): | |
425 | return [f for f in files if f in self.subset] |
|
434 | return [f for f in files if f in self.subset] | |
426 | def existing(self): |
|
435 | def existing(self): | |
427 | return (f for f in self.subset if f in self.ctx) |
|
436 | if self._status is not None: | |
|
437 | removed = set(self._status[3]) | |||
|
438 | unknown = set(self._status[4] + self._status[5]) | |||
|
439 | else: | |||
|
440 | removed = set() | |||
|
441 | unknown = set() | |||
|
442 | return (f for f in self.subset | |||
|
443 | if (f in self.ctx and f not in removed) or f in unknown) | |||
428 | def narrow(self, files): |
|
444 | def narrow(self, files): | |
429 | return matchctx(self.ctx, self.filter(files), self._status) |
|
445 | return matchctx(self.ctx, self.filter(files), self._status) | |
430 |
|
446 | |||
@@ -438,14 +454,26 b' def _intree(funcs, tree):' | |||||
438 | return True |
|
454 | return True | |
439 | return False |
|
455 | return False | |
440 |
|
456 | |||
|
457 | # filesets using matchctx.existing() | |||
|
458 | _existingcallers = [ | |||
|
459 | 'binary', | |||
|
460 | 'exec', | |||
|
461 | 'grep', | |||
|
462 | 'size', | |||
|
463 | 'symlink', | |||
|
464 | ] | |||
|
465 | ||||
441 | def getfileset(ctx, expr): |
|
466 | def getfileset(ctx, expr): | |
442 | tree, pos = parse(expr) |
|
467 | tree, pos = parse(expr) | |
443 | if (pos != len(expr)): |
|
468 | if (pos != len(expr)): | |
444 | raise error.ParseError(_("invalid token"), pos) |
|
469 | raise error.ParseError(_("invalid token"), pos) | |
445 |
|
470 | |||
446 | # do we need status info? |
|
471 | # do we need status info? | |
447 | if _intree(['modified', 'added', 'removed', 'deleted', |
|
472 | if (_intree(['modified', 'added', 'removed', 'deleted', | |
448 |
'unknown', 'ignored', 'clean'], tree) |
|
473 | 'unknown', 'ignored', 'clean'], tree) or | |
|
474 | # Using matchctx.existing() on a workingctx requires us to check | |||
|
475 | # for deleted files. | |||
|
476 | (ctx.rev() is None and _intree(_existingcallers, tree))): | |||
449 | unknown = _intree(['unknown'], tree) |
|
477 | unknown = _intree(['unknown'], tree) | |
450 | ignored = _intree(['ignored'], tree) |
|
478 | ignored = _intree(['ignored'], tree) | |
451 |
|
479 | |||
@@ -457,7 +485,7 b' def getfileset(ctx, expr):' | |||||
457 | subset.extend(c) |
|
485 | subset.extend(c) | |
458 | else: |
|
486 | else: | |
459 | status = None |
|
487 | status = None | |
460 | subset = ctx.walk(ctx.match([])) |
|
488 | subset = list(ctx.walk(ctx.match([]))) | |
461 |
|
489 | |||
462 | return getset(matchctx(ctx, subset, status), tree) |
|
490 | return getset(matchctx(ctx, subset, status), tree) | |
463 |
|
491 |
@@ -1009,7 +1009,7 b' class localrepository(object):' | |||||
1009 | util.rename(self.join('undo.dirstate'), self.join('dirstate')) |
|
1009 | util.rename(self.join('undo.dirstate'), self.join('dirstate')) | |
1010 | try: |
|
1010 | try: | |
1011 | branch = self.opener.read('undo.branch') |
|
1011 | branch = self.opener.read('undo.branch') | |
1012 | self.dirstate.setbranch(branch) |
|
1012 | self.dirstate.setbranch(encoding.tolocal(branch)) | |
1013 | except IOError: |
|
1013 | except IOError: | |
1014 | ui.warn(_('named branch could not be reset: ' |
|
1014 | ui.warn(_('named branch could not be reset: ' | |
1015 | 'current branch is still \'%s\'\n') |
|
1015 | 'current branch is still \'%s\'\n') | |
@@ -1312,6 +1312,7 b' class localrepository(object):' | |||||
1312 | matched = set(changes[0] + changes[1] + changes[2]) |
|
1312 | matched = set(changes[0] + changes[1] + changes[2]) | |
1313 |
|
1313 | |||
1314 | for f in match.files(): |
|
1314 | for f in match.files(): | |
|
1315 | f = self.dirstate.normalize(f) | |||
1315 | if f == '.' or f in matched or f in wctx.substate: |
|
1316 | if f == '.' or f in matched or f in wctx.substate: | |
1316 | continue |
|
1317 | continue | |
1317 | if f in changes[3]: # missing |
|
1318 | if f in changes[3]: # missing |
@@ -52,7 +52,7 b' The header is followed by the markers. E' | |||||
52 | cannot contain '\0'. |
|
52 | cannot contain '\0'. | |
53 | """ |
|
53 | """ | |
54 | import struct |
|
54 | import struct | |
55 |
|
|
55 | import util, base85 | |
56 | from i18n import _ |
|
56 | from i18n import _ | |
57 |
|
57 | |||
58 | # the obsolete feature is not mature enought to be enabled by default. |
|
58 | # the obsolete feature is not mature enought to be enabled by default. |
@@ -1084,8 +1084,10 b' static PyObject *index_partialmatch(inde' | |||||
1084 | return NULL; |
|
1084 | return NULL; | |
1085 | } |
|
1085 | } | |
1086 |
|
1086 | |||
1087 | if (nodelen > 40) |
|
1087 | if (nodelen > 40) { | |
1088 | nodelen = 40; |
|
1088 | PyErr_SetString(PyExc_ValueError, "key too long"); | |
|
1089 | return NULL; | |||
|
1090 | } | |||
1089 |
|
1091 | |||
1090 | for (i = 0; i < nodelen; i++) |
|
1092 | for (i = 0; i < nodelen; i++) | |
1091 | hexdigit(node, i); |
|
1093 | hexdigit(node, i); |
@@ -10,7 +10,6 b' import encoding' | |||||
10 | import os, sys, errno, stat, getpass, pwd, grp, tempfile, unicodedata |
|
10 | import os, sys, errno, stat, getpass, pwd, grp, tempfile, unicodedata | |
11 |
|
11 | |||
12 | posixfile = open |
|
12 | posixfile = open | |
13 | nulldev = '/dev/null' |
|
|||
14 | normpath = os.path.normpath |
|
13 | normpath = os.path.normpath | |
15 | samestat = os.path.samestat |
|
14 | samestat = os.path.samestat | |
16 | oslink = os.link |
|
15 | oslink = os.link |
@@ -7,7 +7,7 b'' | |||||
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | import osutil, scmutil, util |
|
9 | import osutil, scmutil, util | |
10 | import os, stat |
|
10 | import os, stat, errno | |
11 |
|
11 | |||
12 | _sha = util.sha1 |
|
12 | _sha = util.sha1 | |
13 |
|
13 | |||
@@ -398,12 +398,14 b' class fncachestore(basicstore):' | |||||
398 | def datafiles(self): |
|
398 | def datafiles(self): | |
399 | rewrite = False |
|
399 | rewrite = False | |
400 | existing = [] |
|
400 | existing = [] | |
401 | for f in self.fncache: |
|
401 | for f in sorted(self.fncache): | |
402 | ef = self.encode(f) |
|
402 | ef = self.encode(f) | |
403 | try: |
|
403 | try: | |
404 | yield f, ef, self.getsize(ef) |
|
404 | yield f, ef, self.getsize(ef) | |
405 | existing.append(f) |
|
405 | existing.append(f) | |
406 | except OSError: |
|
406 | except OSError, err: | |
|
407 | if err.errno != errno.ENOENT: | |||
|
408 | raise | |||
407 | # nonexistent entry |
|
409 | # nonexistent entry | |
408 | rewrite = True |
|
410 | rewrite = True | |
409 | if rewrite: |
|
411 | if rewrite: |
@@ -45,7 +45,6 b' makedir = platform.makedir' | |||||
45 | nlinks = platform.nlinks |
|
45 | nlinks = platform.nlinks | |
46 | normpath = platform.normpath |
|
46 | normpath = platform.normpath | |
47 | normcase = platform.normcase |
|
47 | normcase = platform.normcase | |
48 | nulldev = platform.nulldev |
|
|||
49 | openhardlinks = platform.openhardlinks |
|
48 | openhardlinks = platform.openhardlinks | |
50 | oslink = platform.oslink |
|
49 | oslink = platform.oslink | |
51 | parsepatchoutput = platform.parsepatchoutput |
|
50 | parsepatchoutput = platform.parsepatchoutput |
@@ -120,6 +120,7 b' def _verify(repo):' | |||||
120 | havemf = len(mf) > 0 |
|
120 | havemf = len(mf) > 0 | |
121 |
|
121 | |||
122 | ui.status(_("checking changesets\n")) |
|
122 | ui.status(_("checking changesets\n")) | |
|
123 | hasmanifest = False | |||
123 | seen = {} |
|
124 | seen = {} | |
124 | checklog(cl, "changelog", 0) |
|
125 | checklog(cl, "changelog", 0) | |
125 | total = len(repo) |
|
126 | total = len(repo) | |
@@ -130,16 +131,22 b' def _verify(repo):' | |||||
130 |
|
131 | |||
131 | try: |
|
132 | try: | |
132 | changes = cl.read(n) |
|
133 | changes = cl.read(n) | |
133 | mflinkrevs.setdefault(changes[0], []).append(i) |
|
134 | if changes[0] != nullid: | |
|
135 | mflinkrevs.setdefault(changes[0], []).append(i) | |||
|
136 | hasmanifest = True | |||
134 | for f in changes[3]: |
|
137 | for f in changes[3]: | |
135 | filelinkrevs.setdefault(f, []).append(i) |
|
138 | filelinkrevs.setdefault(f, []).append(i) | |
136 | except Exception, inst: |
|
139 | except Exception, inst: | |
|
140 | hasmanifest = True | |||
137 | exc(i, _("unpacking changeset %s") % short(n), inst) |
|
141 | exc(i, _("unpacking changeset %s") % short(n), inst) | |
138 | ui.progress(_('checking'), None) |
|
142 | ui.progress(_('checking'), None) | |
139 |
|
143 | |||
140 | ui.status(_("checking manifests\n")) |
|
144 | ui.status(_("checking manifests\n")) | |
141 | seen = {} |
|
145 | seen = {} | |
142 | checklog(mf, "manifest", 0) |
|
146 | if hasmanifest: | |
|
147 | # Do not check manifest if there are only changelog entries with | |||
|
148 | # null manifests. | |||
|
149 | checklog(mf, "manifest", 0) | |||
143 | total = len(mf) |
|
150 | total = len(mf) | |
144 | for i in mf: |
|
151 | for i in mf: | |
145 | ui.progress(_('checking'), i, total=total, unit=_('manifests')) |
|
152 | ui.progress(_('checking'), i, total=total, unit=_('manifests')) |
@@ -24,7 +24,6 b' termwidth = win32.termwidth' | |||||
24 | testpid = win32.testpid |
|
24 | testpid = win32.testpid | |
25 | unlink = win32.unlink |
|
25 | unlink = win32.unlink | |
26 |
|
26 | |||
27 | nulldev = 'NUL:' |
|
|||
28 | umask = 0022 |
|
27 | umask = 0022 | |
29 |
|
28 | |||
30 | # wrap osutil.posixfile to provide friendlier exceptions |
|
29 | # wrap osutil.posixfile to provide friendlier exceptions | |
@@ -174,7 +173,7 b" def popen(command, mode='r'):" | |||||
174 | # Work around "popen spawned process may not write to stdout |
|
173 | # Work around "popen spawned process may not write to stdout | |
175 | # under windows" |
|
174 | # under windows" | |
176 | # http://bugs.python.org/issue1366 |
|
175 | # http://bugs.python.org/issue1366 | |
177 |
command += " 2> %s" % null |
|
176 | command += " 2> %s" % os.devnull | |
178 | return os.popen(quotecommand(command), mode) |
|
177 | return os.popen(quotecommand(command), mode) | |
179 |
|
178 | |||
180 | def explainexit(code): |
|
179 | def explainexit(code): |
@@ -91,3 +91,38 b'' | |||||
91 | b 1:d2ae7f538514 |
|
91 | b 1:d2ae7f538514 | |
92 | c 3:b8f96cf4688b |
|
92 | c 3:b8f96cf4688b | |
93 | * e 7:ca784329f0ba |
|
93 | * e 7:ca784329f0ba | |
|
94 | ||||
|
95 | # test warning when all heads are inactive bookmarks | |||
|
96 | ||||
|
97 | $ hg up -C 6 | |||
|
98 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |||
|
99 | $ echo g > g | |||
|
100 | $ hg commit -Am 'g' | |||
|
101 | adding g | |||
|
102 | $ hg bookmark -i g | |||
|
103 | $ hg bookmarks | |||
|
104 | b 1:d2ae7f538514 | |||
|
105 | c 3:b8f96cf4688b | |||
|
106 | e 7:ca784329f0ba | |||
|
107 | g 8:04dd21731d95 | |||
|
108 | $ hg heads | |||
|
109 | changeset: 8:04dd21731d95 | |||
|
110 | bookmark: g | |||
|
111 | tag: tip | |||
|
112 | parent: 6:be381d1126a0 | |||
|
113 | user: test | |||
|
114 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
115 | summary: g | |||
|
116 | ||||
|
117 | changeset: 7:ca784329f0ba | |||
|
118 | bookmark: e | |||
|
119 | parent: 5:26bee9c5bcf3 | |||
|
120 | parent: 4:a0546fcfe0fb | |||
|
121 | user: test | |||
|
122 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
123 | summary: merge | |||
|
124 | ||||
|
125 | $ hg merge | |||
|
126 | abort: heads are bookmarked - please merge with an explicit rev | |||
|
127 | (run 'hg heads' to see all heads) | |||
|
128 | [255] |
@@ -21,3 +21,14 b'' | |||||
21 | [1] |
|
21 | [1] | |
22 | $ hg cat -r 1 b |
|
22 | $ hg cat -r 1 b | |
23 | 1 |
|
23 | 1 | |
|
24 | ||||
|
25 | Test fileset | |||
|
26 | ||||
|
27 | $ echo 3 > c | |||
|
28 | $ hg ci -Am addmore c | |||
|
29 | $ hg cat 'set:not(b) or a' | |||
|
30 | 3 | |||
|
31 | $ hg cat 'set:c or b' | |||
|
32 | 1 | |||
|
33 | 3 | |||
|
34 |
@@ -229,7 +229,7 b' Show all commands + options' | |||||
229 | debugdata: changelog, manifest |
|
229 | debugdata: changelog, manifest | |
230 | debugdate: extended |
|
230 | debugdate: extended | |
231 | debugdiscovery: old, nonheads, ssh, remotecmd, insecure |
|
231 | debugdiscovery: old, nonheads, ssh, remotecmd, insecure | |
232 | debugfileset: |
|
232 | debugfileset: rev | |
233 | debugfsinfo: |
|
233 | debugfsinfo: | |
234 | debuggetbundle: head, common, type |
|
234 | debuggetbundle: head, common, type | |
235 | debugignore: |
|
235 | debugignore: |
@@ -44,6 +44,10 b' these should work' | |||||
44 | marked working directory as branch \xe9 (esc) |
|
44 | marked working directory as branch \xe9 (esc) | |
45 | (branches are permanent and global, did you want a bookmark?) |
|
45 | (branches are permanent and global, did you want a bookmark?) | |
46 | $ HGENCODING=latin-1 hg ci -m 'latin1 branch' |
|
46 | $ HGENCODING=latin-1 hg ci -m 'latin1 branch' | |
|
47 | $ hg -q rollback | |||
|
48 | $ HGENCODING=latin-1 hg branch | |||
|
49 | \xe9 (esc) | |||
|
50 | $ HGENCODING=latin-1 hg ci -m 'latin1 branch' | |||
47 | $ rm .hg/branch |
|
51 | $ rm .hg/branch | |
48 |
|
52 | |||
49 | hg log (ascii) |
|
53 | hg log (ascii) |
@@ -1,6 +1,7 b'' | |||||
1 | hg debuginstall |
|
1 | hg debuginstall | |
2 | $ hg debuginstall |
|
2 | $ hg debuginstall | |
3 | checking encoding (ascii)... |
|
3 | checking encoding (ascii)... | |
|
4 | checking Python lib (*lib*)... (glob) | |||
4 | checking installed modules (*mercurial)... (glob) |
|
5 | checking installed modules (*mercurial)... (glob) | |
5 | checking templates (*mercurial?templates)... (glob) |
|
6 | checking templates (*mercurial?templates)... (glob) | |
6 | checking commit editor... |
|
7 | checking commit editor... | |
@@ -10,6 +11,7 b' hg debuginstall' | |||||
10 | hg debuginstall with no username |
|
11 | hg debuginstall with no username | |
11 | $ HGUSER= hg debuginstall |
|
12 | $ HGUSER= hg debuginstall | |
12 | checking encoding (ascii)... |
|
13 | checking encoding (ascii)... | |
|
14 | checking Python lib (*lib*)... (glob) | |||
13 | checking installed modules (*mercurial)... (glob) |
|
15 | checking installed modules (*mercurial)... (glob) | |
14 | checking templates (*mercurial?templates)... (glob) |
|
16 | checking templates (*mercurial?templates)... (glob) | |
15 | checking commit editor... |
|
17 | checking commit editor... |
@@ -61,10 +61,22 b' introduce some bugs in repo' | |||||
61 | $ cd ../../.. |
|
61 | $ cd ../../.. | |
62 | $ cd .. |
|
62 | $ cd .. | |
63 |
|
63 | |||
64 | test revlog corruption |
|
64 | test changelog without a manifest | |
65 |
|
65 | |||
66 | $ hg init b |
|
66 | $ hg init b | |
67 | $ cd b |
|
67 | $ cd b | |
|
68 | $ hg branch foo | |||
|
69 | marked working directory as branch foo | |||
|
70 | (branches are permanent and global, did you want a bookmark?) | |||
|
71 | $ hg ci -m branchfoo | |||
|
72 | $ hg verify | |||
|
73 | checking changesets | |||
|
74 | checking manifests | |||
|
75 | crosschecking files in changesets and manifests | |||
|
76 | checking files | |||
|
77 | 0 files, 1 changesets, 0 total revisions | |||
|
78 | ||||
|
79 | test revlog corruption | |||
68 |
|
80 | |||
69 | $ touch a |
|
81 | $ touch a | |
70 | $ hg add a |
|
82 | $ hg add a | |
@@ -79,12 +91,12 b' test revlog corruption' | |||||
79 | checking manifests |
|
91 | checking manifests | |
80 | crosschecking files in changesets and manifests |
|
92 | crosschecking files in changesets and manifests | |
81 | checking files |
|
93 | checking files | |
82 |
a@ |
|
94 | a@1: broken revlog! (index data/a.i is corrupted) | |
83 | warning: orphan revlog 'data/a.i' |
|
95 | warning: orphan revlog 'data/a.i' | |
84 |
1 files, |
|
96 | 1 files, 2 changesets, 0 total revisions | |
85 | 1 warnings encountered! |
|
97 | 1 warnings encountered! | |
86 | 1 integrity errors encountered! |
|
98 | 1 integrity errors encountered! | |
87 |
(first damaged changeset appears to be |
|
99 | (first damaged changeset appears to be 1) | |
88 | [1] |
|
100 | [1] | |
89 |
|
101 | |||
90 | $ cd .. |
|
102 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now