##// END OF EJS Templates
check-code: fix issues with finding patterns in unified tests, fix tests...
Matt Mackall -
r15372:695ac6ac stable
parent child Browse files
Show More
@@ -1,414 +1,423 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # check-code - a style and portability checker for Mercurial
3 # check-code - a style and portability checker for Mercurial
4 #
4 #
5 # Copyright 2010 Matt Mackall <mpm@selenic.com>
5 # Copyright 2010 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 import re, glob, os, sys
10 import re, glob, os, sys
11 import keyword
11 import keyword
12 import optparse
12 import optparse
13
13
14 def repquote(m):
14 def repquote(m):
15 t = re.sub(r"\w", "x", m.group('text'))
15 t = re.sub(r"\w", "x", m.group('text'))
16 t = re.sub(r"[^\s\nx]", "o", t)
16 t = re.sub(r"[^\s\nx]", "o", t)
17 return m.group('quote') + t + m.group('quote')
17 return m.group('quote') + t + m.group('quote')
18
18
19 def reppython(m):
19 def reppython(m):
20 comment = m.group('comment')
20 comment = m.group('comment')
21 if comment:
21 if comment:
22 return "#" * len(comment)
22 return "#" * len(comment)
23 return repquote(m)
23 return repquote(m)
24
24
25 def repcomment(m):
25 def repcomment(m):
26 return m.group(1) + "#" * len(m.group(2))
26 return m.group(1) + "#" * len(m.group(2))
27
27
28 def repccomment(m):
28 def repccomment(m):
29 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
29 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
30 return m.group(1) + t + "*/"
30 return m.group(1) + t + "*/"
31
31
32 def repcallspaces(m):
32 def repcallspaces(m):
33 t = re.sub(r"\n\s+", "\n", m.group(2))
33 t = re.sub(r"\n\s+", "\n", m.group(2))
34 return m.group(1) + t
34 return m.group(1) + t
35
35
36 def repinclude(m):
36 def repinclude(m):
37 return m.group(1) + "<foo>"
37 return m.group(1) + "<foo>"
38
38
39 def rephere(m):
39 def rephere(m):
40 t = re.sub(r"\S", "x", m.group(2))
40 t = re.sub(r"\S", "x", m.group(2))
41 return m.group(1) + t
41 return m.group(1) + t
42
42
43
43
44 testpats = [
44 testpats = [
45 [
45 [
46 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"),
46 (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"),
47 (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
47 (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
48 (r'(^|\n)function', "don't use 'function', use old style"),
48 (r'^function', "don't use 'function', use old style"),
49 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
49 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
50 (r'echo.*\\n', "don't use 'echo \\n', use printf"),
50 (r'echo.*\\n', "don't use 'echo \\n', use printf"),
51 (r'echo -n', "don't use 'echo -n', use printf"),
51 (r'echo -n', "don't use 'echo -n', use printf"),
52 (r'(^|\n)diff.*-\w*N', "don't use 'diff -N'"),
52 (r'^diff.*-\w*N', "don't use 'diff -N'"),
53 (r'(^| )wc[^|\n]*$', "filter wc output"),
53 (r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"),
54 (r'head -c', "don't use 'head -c', use 'dd'"),
54 (r'head -c', "don't use 'head -c', use 'dd'"),
55 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
55 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
56 (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"),
56 (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"),
57 (r'printf.*\\x', "don't use printf \\x, use Python"),
57 (r'printf.*\\x', "don't use printf \\x, use Python"),
58 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
58 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
59 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
59 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
60 (r'(^|\|\s*)grep (-\w\s+)*[^|\n]*[(|]\w',
60 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
61 "use egrep for extended grep syntax"),
61 "use egrep for extended grep syntax"),
62 (r'/bin/', "don't use explicit paths for tools"),
62 (r'/bin/', "don't use explicit paths for tools"),
63 (r'\$PWD', "don't use $PWD, use `pwd`"),
63 (r'\$PWD', "don't use $PWD, use `pwd`"),
64 (r'[^\n]\Z', "no trailing newline"),
64 (r'[^\n]\Z', "no trailing newline"),
65 (r'export.*=', "don't export and assign at once"),
65 (r'export.*=', "don't export and assign at once"),
66 ('(^|\n)([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\\^', "^ must be quoted"),
66 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\\^', "^ must be quoted"),
67 (r'(^|\n)source\b', "don't use 'source', use '.'"),
67 (r'^source\b', "don't use 'source', use '.'"),
68 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
68 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
69 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
69 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
70 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
70 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
71 (r'stop\(\)', "don't use 'stop' as a shell function name"),
71 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
72 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
72 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
73 ],
73 ],
74 # warnings
74 # warnings
75 []
75 []
76 ]
76 ]
77
77
78 testfilters = [
78 testfilters = [
79 (r"( *)(#([^\n]*\S)?)", repcomment),
79 (r"( *)(#([^\n]*\S)?)", repcomment),
80 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
80 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
81 ]
81 ]
82
82
83 uprefix = r"(^|\n) \$\s*"
83 uprefix = r"^ \$ "
84 uprefixc = r"(^|\n) > "
84 uprefixc = r"^ > "
85 utestpats = [
85 utestpats = [
86 [
86 [
87 (r'(^|\n)(\S| $ ).*(\S[ \t]+|^[ \t]+)\n', "trailing whitespace on non-output"),
87 (r'^(\S| $ ).*(\S[ \t]+|^[ \t]+)\n', "trailing whitespace on non-output"),
88 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"),
88 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"),
89 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
89 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
90 (uprefix + r'.*\$\?', "explicit exit code checks unnecessary"),
90 (uprefix + r'.*\$\?', "explicit exit code checks unnecessary"),
91 (uprefix + r'.*\|\| echo.*(fail|error)',
91 (uprefix + r'.*\|\| echo.*(fail|error)',
92 "explicit exit code checks unnecessary"),
92 "explicit exit code checks unnecessary"),
93 (uprefix + r'set -e', "don't use set -e"),
93 (uprefix + r'set -e', "don't use set -e"),
94 (uprefixc + r'( *)\t', "don't use tabs to indent"),
94 (uprefixc + r'( *)\t', "don't use tabs to indent"),
95 ],
95 ],
96 # warnings
96 # warnings
97 []
97 []
98 ]
98 ]
99
99
100 for i in [0, 1]:
100 for i in [0, 1]:
101 for p, m in testpats[i]:
101 for p, m in testpats[i]:
102 if p.startswith(r'(^|\n)'):
102 if p.startswith(r'^'):
103 p = uprefix + p[6:]
103 p = uprefix + p[1:]
104 else:
104 else:
105 p = uprefix + p
105 p = uprefix + ".*" + p
106 utestpats[i].append((p, m))
106 utestpats[i].append((p, m))
107
107
108 utestfilters = [
108 utestfilters = [
109 (r"( *)(#([^\n]*\S)?)", repcomment),
109 (r"( *)(#([^\n]*\S)?)", repcomment),
110 ]
110 ]
111
111
112 pypats = [
112 pypats = [
113 [
113 [
114 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
114 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
115 "tuple parameter unpacking not available in Python 3+"),
115 "tuple parameter unpacking not available in Python 3+"),
116 (r'lambda\s*\(.*,.*\)',
116 (r'lambda\s*\(.*,.*\)',
117 "tuple parameter unpacking not available in Python 3+"),
117 "tuple parameter unpacking not available in Python 3+"),
118 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
118 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
119 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
119 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
120 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
120 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
121 (r'^\s*\t', "don't use tabs"),
121 (r'^\s*\t', "don't use tabs"),
122 (r'\S;\s*\n', "semicolon"),
122 (r'\S;\s*\n', "semicolon"),
123 (r'\w,\w', "missing whitespace after ,"),
123 (r'\w,\w', "missing whitespace after ,"),
124 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
124 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
125 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
125 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
126 (r'(?m)(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
126 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
127 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Py2.4'),
127 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Py2.4'),
128 (r'.{85}', "line too long"),
128 (r'.{85}', "line too long"),
129 (r'(?m) x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
129 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
130 (r'[^\n]\Z', "no trailing newline"),
130 (r'[^\n]\Z', "no trailing newline"),
131 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
131 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
132 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"),
132 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"),
133 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"),
133 # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"),
134 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
134 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
135 "linebreak after :"),
135 "linebreak after :"),
136 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
136 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
137 (r'class\s[^( \n]+\(\):',
137 (r'class\s[^( \n]+\(\):',
138 "class foo() not available in Python 2.4, use class foo(object)"),
138 "class foo() not available in Python 2.4, use class foo(object)"),
139 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
139 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
140 "Python keyword is not a function"),
140 "Python keyword is not a function"),
141 (r',]', "unneeded trailing ',' in list"),
141 (r',]', "unneeded trailing ',' in list"),
142 # (r'class\s[A-Z][^\(]*\((?!Exception)',
142 # (r'class\s[A-Z][^\(]*\((?!Exception)',
143 # "don't capitalize non-exception classes"),
143 # "don't capitalize non-exception classes"),
144 # (r'in range\(', "use xrange"),
144 # (r'in range\(', "use xrange"),
145 # (r'^\s*print\s+', "avoid using print in core and extensions"),
145 # (r'^\s*print\s+', "avoid using print in core and extensions"),
146 (r'[\x80-\xff]', "non-ASCII character literal"),
146 (r'[\x80-\xff]', "non-ASCII character literal"),
147 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
147 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
148 (r'^\s*with\s+', "with not available in Python 2.4"),
148 (r'^\s*with\s+', "with not available in Python 2.4"),
149 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
149 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
150 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
150 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
151 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
151 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
152 (r'(?<!def)\s+(any|all|format)\(',
152 (r'(?<!def)\s+(any|all|format)\(',
153 "any/all/format not available in Python 2.4"),
153 "any/all/format not available in Python 2.4"),
154 (r'(?<!def)\s+(callable)\(',
154 (r'(?<!def)\s+(callable)\(',
155 "callable not available in Python 3, use getattr(f, '__call__', None)"),
155 "callable not available in Python 3, use getattr(f, '__call__', None)"),
156 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
156 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
157 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
157 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
158 "gratuitous whitespace after Python keyword"),
158 "gratuitous whitespace after Python keyword"),
159 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
159 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
160 # (r'\s\s=', "gratuitous whitespace before ="),
160 # (r'\s\s=', "gratuitous whitespace before ="),
161 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
161 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
162 "missing whitespace around operator"),
162 "missing whitespace around operator"),
163 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s',
163 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s',
164 "missing whitespace around operator"),
164 "missing whitespace around operator"),
165 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
165 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
166 "missing whitespace around operator"),
166 "missing whitespace around operator"),
167 (r'[^+=*/!<>&| -](\s=|=\s)[^= ]',
167 (r'[^+=*/!<>&| -](\s=|=\s)[^= ]',
168 "wrong whitespace around ="),
168 "wrong whitespace around ="),
169 (r'raise Exception', "don't raise generic exceptions"),
169 (r'raise Exception', "don't raise generic exceptions"),
170 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
170 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
171 (r' [=!]=\s+(True|False|None)',
171 (r' [=!]=\s+(True|False|None)',
172 "comparison with singleton, use 'is' or 'is not' instead"),
172 "comparison with singleton, use 'is' or 'is not' instead"),
173 (r'^\s*(while|if) [01]:',
173 (r'^\s*(while|if) [01]:',
174 "use True/False for constant Boolean expression"),
174 "use True/False for constant Boolean expression"),
175 (r'(?<!def)\s+hasattr',
175 (r'(?<!def)\s+hasattr',
176 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
176 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
177 (r'opener\([^)]*\).read\(',
177 (r'opener\([^)]*\).read\(',
178 "use opener.read() instead"),
178 "use opener.read() instead"),
179 (r'BaseException', 'not in Py2.4, use Exception'),
179 (r'BaseException', 'not in Py2.4, use Exception'),
180 (r'os\.path\.relpath', 'os.path.relpath is not in Py2.5'),
180 (r'os\.path\.relpath', 'os.path.relpath is not in Py2.5'),
181 (r'opener\([^)]*\).write\(',
181 (r'opener\([^)]*\).write\(',
182 "use opener.write() instead"),
182 "use opener.write() instead"),
183 (r'[\s\(](open|file)\([^)]*\)\.read\(',
183 (r'[\s\(](open|file)\([^)]*\)\.read\(',
184 "use util.readfile() instead"),
184 "use util.readfile() instead"),
185 (r'[\s\(](open|file)\([^)]*\)\.write\(',
185 (r'[\s\(](open|file)\([^)]*\)\.write\(',
186 "use util.readfile() instead"),
186 "use util.readfile() instead"),
187 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
187 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
188 "always assign an opened file to a variable, and close it afterwards"),
188 "always assign an opened file to a variable, and close it afterwards"),
189 (r'[\s\(](open|file)\([^)]*\)\.',
189 (r'[\s\(](open|file)\([^)]*\)\.',
190 "always assign an opened file to a variable, and close it afterwards"),
190 "always assign an opened file to a variable, and close it afterwards"),
191 (r'(?i)descendent', "the proper spelling is descendAnt"),
191 (r'(?i)descendent', "the proper spelling is descendAnt"),
192 (r'\.debug\(\_', "don't mark debug messages for translation"),
192 (r'\.debug\(\_', "don't mark debug messages for translation"),
193 ],
193 ],
194 # warnings
194 # warnings
195 [
195 [
196 (r'.{81}', "warning: line over 80 characters"),
196 (r'.{81}', "warning: line over 80 characters"),
197 (r'^\s*except:$', "warning: naked except clause"),
197 (r'^\s*except:$', "warning: naked except clause"),
198 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
198 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
199 "warning: unwrapped ui message"),
199 "warning: unwrapped ui message"),
200 ]
200 ]
201 ]
201 ]
202
202
203 pyfilters = [
203 pyfilters = [
204 (r"""(?msx)(?P<comment>\#.*?$)|
204 (r"""(?msx)(?P<comment>\#.*?$)|
205 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
205 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
206 (?P<text>(([^\\]|\\.)*?))
206 (?P<text>(([^\\]|\\.)*?))
207 (?P=quote))""", reppython),
207 (?P=quote))""", reppython),
208 ]
208 ]
209
209
210 cpats = [
210 cpats = [
211 [
211 [
212 (r'//', "don't use //-style comments"),
212 (r'//', "don't use //-style comments"),
213 (r'^ ', "don't use spaces to indent"),
213 (r'^ ', "don't use spaces to indent"),
214 (r'\S\t', "don't use tabs except for indent"),
214 (r'\S\t', "don't use tabs except for indent"),
215 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
215 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
216 (r'.{85}', "line too long"),
216 (r'.{85}', "line too long"),
217 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
217 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
218 (r'return\(', "return is not a function"),
218 (r'return\(', "return is not a function"),
219 (r' ;', "no space before ;"),
219 (r' ;', "no space before ;"),
220 (r'\w+\* \w+', "use int *foo, not int* foo"),
220 (r'\w+\* \w+', "use int *foo, not int* foo"),
221 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
221 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
222 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
222 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
223 (r'\w,\w', "missing whitespace after ,"),
223 (r'\w,\w', "missing whitespace after ,"),
224 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
224 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
225 (r'^#\s+\w', "use #foo, not # foo"),
225 (r'^#\s+\w', "use #foo, not # foo"),
226 (r'[^\n]\Z', "no trailing newline"),
226 (r'[^\n]\Z', "no trailing newline"),
227 (r'^\s*#import\b', "use only #include in standard C code"),
227 (r'^\s*#import\b', "use only #include in standard C code"),
228 ],
228 ],
229 # warnings
229 # warnings
230 []
230 []
231 ]
231 ]
232
232
233 cfilters = [
233 cfilters = [
234 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
234 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
235 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
235 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
236 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
236 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
237 (r'(\()([^)]+\))', repcallspaces),
237 (r'(\()([^)]+\))', repcallspaces),
238 ]
238 ]
239
239
240 inutilpats = [
240 inutilpats = [
241 [
241 [
242 (r'\bui\.', "don't use ui in util"),
242 (r'\bui\.', "don't use ui in util"),
243 ],
243 ],
244 # warnings
244 # warnings
245 []
245 []
246 ]
246 ]
247
247
248 inrevlogpats = [
248 inrevlogpats = [
249 [
249 [
250 (r'\brepo\.', "don't use repo in revlog"),
250 (r'\brepo\.', "don't use repo in revlog"),
251 ],
251 ],
252 # warnings
252 # warnings
253 []
253 []
254 ]
254 ]
255
255
256 checks = [
256 checks = [
257 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
257 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
258 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
258 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
259 ('c', r'.*\.c$', cfilters, cpats),
259 ('c', r'.*\.c$', cfilters, cpats),
260 ('unified test', r'.*\.t$', utestfilters, utestpats),
260 ('unified test', r'.*\.t$', utestfilters, utestpats),
261 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
261 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
262 inrevlogpats),
262 inrevlogpats),
263 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
263 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
264 inutilpats),
264 inutilpats),
265 ]
265 ]
266
266
267 class norepeatlogger(object):
267 class norepeatlogger(object):
268 def __init__(self):
268 def __init__(self):
269 self._lastseen = None
269 self._lastseen = None
270
270
271 def log(self, fname, lineno, line, msg, blame):
271 def log(self, fname, lineno, line, msg, blame):
272 """print error related a to given line of a given file.
272 """print error related a to given line of a given file.
273
273
274 The faulty line will also be printed but only once in the case
274 The faulty line will also be printed but only once in the case
275 of multiple errors.
275 of multiple errors.
276
276
277 :fname: filename
277 :fname: filename
278 :lineno: line number
278 :lineno: line number
279 :line: actual content of the line
279 :line: actual content of the line
280 :msg: error message
280 :msg: error message
281 """
281 """
282 msgid = fname, lineno, line
282 msgid = fname, lineno, line
283 if msgid != self._lastseen:
283 if msgid != self._lastseen:
284 if blame:
284 if blame:
285 print "%s:%d (%s):" % (fname, lineno, blame)
285 print "%s:%d (%s):" % (fname, lineno, blame)
286 else:
286 else:
287 print "%s:%d:" % (fname, lineno)
287 print "%s:%d:" % (fname, lineno)
288 print " > %s" % line
288 print " > %s" % line
289 self._lastseen = msgid
289 self._lastseen = msgid
290 print " " + msg
290 print " " + msg
291
291
292 _defaultlogger = norepeatlogger()
292 _defaultlogger = norepeatlogger()
293
293
294 def getblame(f):
294 def getblame(f):
295 lines = []
295 lines = []
296 for l in os.popen('hg annotate -un %s' % f):
296 for l in os.popen('hg annotate -un %s' % f):
297 start, line = l.split(':', 1)
297 start, line = l.split(':', 1)
298 user, rev = start.split()
298 user, rev = start.split()
299 lines.append((line[1:-1], user, rev))
299 lines.append((line[1:-1], user, rev))
300 return lines
300 return lines
301
301
302 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
302 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
303 blame=False, debug=False):
303 blame=False, debug=False):
304 """checks style and portability of a given file
304 """checks style and portability of a given file
305
305
306 :f: filepath
306 :f: filepath
307 :logfunc: function used to report error
307 :logfunc: function used to report error
308 logfunc(filename, linenumber, linecontent, errormessage)
308 logfunc(filename, linenumber, linecontent, errormessage)
309 :maxerr: number of error to display before arborting.
309 :maxerr: number of error to display before arborting.
310 Set to None (default) to report all errors
310 Set to None (default) to report all errors
311
311
312 return True if no error is found, False otherwise.
312 return True if no error is found, False otherwise.
313 """
313 """
314 blamecache = None
314 blamecache = None
315 result = True
315 result = True
316 for name, match, filters, pats in checks:
316 for name, match, filters, pats in checks:
317 if debug:
317 if debug:
318 print name, f
318 print name, f
319 fc = 0
319 fc = 0
320 if not re.match(match, f):
320 if not re.match(match, f):
321 if debug:
321 if debug:
322 print "Skipping %s for %s it doesn't match %s" % (
322 print "Skipping %s for %s it doesn't match %s" % (
323 name, match, f)
323 name, match, f)
324 continue
324 continue
325 fp = open(f)
325 fp = open(f)
326 pre = post = fp.read()
326 pre = post = fp.read()
327 fp.close()
327 fp.close()
328 if "no-" + "check-code" in pre:
328 if "no-" + "check-code" in pre:
329 if debug:
329 if debug:
330 print "Skipping %s for %s it has no- and check-code" % (
330 print "Skipping %s for %s it has no- and check-code" % (
331 name, f)
331 name, f)
332 break
332 break
333 for p, r in filters:
333 for p, r in filters:
334 post = re.sub(p, r, post)
334 post = re.sub(p, r, post)
335 if warnings:
335 if warnings:
336 pats = pats[0] + pats[1]
336 pats = pats[0] + pats[1]
337 else:
337 else:
338 pats = pats[0]
338 pats = pats[0]
339 # print post # uncomment to show filtered version
339 # print post # uncomment to show filtered version
340
340
341 if debug:
341 if debug:
342 print "Checking %s for %s" % (name, f)
342 print "Checking %s for %s" % (name, f)
343
343
344 prelines = None
344 prelines = None
345 errors = []
345 errors = []
346 for p, msg in pats:
346 for p, msg in pats:
347 # fix-up regexes for multiline searches
348 po = p
349 # \s doesn't match \n
350 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
351 # [^...] doesn't match newline
352 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
353
354 #print po, '=>', p
355
347 pos = 0
356 pos = 0
348 n = 0
357 n = 0
349 for m in re.finditer(p, post):
358 for m in re.finditer(p, post, re.MULTILINE):
350 if prelines is None:
359 if prelines is None:
351 prelines = pre.splitlines()
360 prelines = pre.splitlines()
352 postlines = post.splitlines(True)
361 postlines = post.splitlines(True)
353
362
354 start = m.start()
363 start = m.start()
355 while n < len(postlines):
364 while n < len(postlines):
356 step = len(postlines[n])
365 step = len(postlines[n])
357 if pos + step > start:
366 if pos + step > start:
358 break
367 break
359 pos += step
368 pos += step
360 n += 1
369 n += 1
361 l = prelines[n]
370 l = prelines[n]
362
371
363 if "check-code" + "-ignore" in l:
372 if "check-code" + "-ignore" in l:
364 if debug:
373 if debug:
365 print "Skipping %s for %s:%s (check-code -ignore)" % (
374 print "Skipping %s for %s:%s (check-code -ignore)" % (
366 name, f, n)
375 name, f, n)
367 continue
376 continue
368 bd = ""
377 bd = ""
369 if blame:
378 if blame:
370 bd = 'working directory'
379 bd = 'working directory'
371 if not blamecache:
380 if not blamecache:
372 blamecache = getblame(f)
381 blamecache = getblame(f)
373 if n < len(blamecache):
382 if n < len(blamecache):
374 bl, bu, br = blamecache[n]
383 bl, bu, br = blamecache[n]
375 if bl == l:
384 if bl == l:
376 bd = '%s@%s' % (bu, br)
385 bd = '%s@%s' % (bu, br)
377 errors.append((f, n + 1, l, msg, bd))
386 errors.append((f, n + 1, l, msg, bd))
378 result = False
387 result = False
379
388
380 errors.sort()
389 errors.sort()
381 for e in errors:
390 for e in errors:
382 logfunc(*e)
391 logfunc(*e)
383 fc += 1
392 fc += 1
384 if maxerr is not None and fc >= maxerr:
393 if maxerr is not None and fc >= maxerr:
385 print " (too many errors, giving up)"
394 print " (too many errors, giving up)"
386 break
395 break
387
396
388 return result
397 return result
389
398
390 if __name__ == "__main__":
399 if __name__ == "__main__":
391 parser = optparse.OptionParser("%prog [options] [files]")
400 parser = optparse.OptionParser("%prog [options] [files]")
392 parser.add_option("-w", "--warnings", action="store_true",
401 parser.add_option("-w", "--warnings", action="store_true",
393 help="include warning-level checks")
402 help="include warning-level checks")
394 parser.add_option("-p", "--per-file", type="int",
403 parser.add_option("-p", "--per-file", type="int",
395 help="max warnings per file")
404 help="max warnings per file")
396 parser.add_option("-b", "--blame", action="store_true",
405 parser.add_option("-b", "--blame", action="store_true",
397 help="use annotate to generate blame info")
406 help="use annotate to generate blame info")
398 parser.add_option("", "--debug", action="store_true",
407 parser.add_option("", "--debug", action="store_true",
399 help="show debug information")
408 help="show debug information")
400
409
401 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False)
410 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False)
402 (options, args) = parser.parse_args()
411 (options, args) = parser.parse_args()
403
412
404 if len(args) == 0:
413 if len(args) == 0:
405 check = glob.glob("*")
414 check = glob.glob("*")
406 else:
415 else:
407 check = args
416 check = args
408
417
409 for f in check:
418 for f in check:
410 ret = 0
419 ret = 0
411 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
420 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
412 blame=options.blame, debug=options.debug):
421 blame=options.blame, debug=options.debug):
413 ret = 1
422 ret = 1
414 sys.exit(ret)
423 sys.exit(ret)
@@ -1,6 +1,6 b''
1 $ "$TESTDIR/hghave" pyflakes || exit 80
1 $ "$TESTDIR/hghave" pyflakes || exit 80
2 $ cd $(dirname $TESTDIR)
2 $ cd `dirname $TESTDIR`
3 $ pyflakes mercurial hgext 2>&1 | $TESTDIR/filterpyflakes.py
3 $ pyflakes mercurial hgext 2>&1 | $TESTDIR/filterpyflakes.py
4 hgext/inotify/linux/__init__.py:*: 'from _inotify import *' used; unable to detect undefined names (glob)
4 hgext/inotify/linux/__init__.py:*: 'from _inotify import *' used; unable to detect undefined names (glob)
5
5
6
6
@@ -1,189 +1,195 b''
1 Use hgrc within $TESTTMP
1 Use hgrc within $TESTTMP
2
2
3 $ HGRCPATH=`pwd`/hgrc
3 $ HGRCPATH=`pwd`/hgrc
4 $ export HGRCPATH
4 $ export HGRCPATH
5
5
6 Use an alternate var for scribbling on hgrc to keep check-code from
7 complaining about the important settings we may be overwriting:
8
9 $ HGRC=`pwd`/hgrc
10 $ export HGRC
11
6 Basic syntax error
12 Basic syntax error
7
13
8 $ echo "invalid" > $HGRCPATH
14 $ echo "invalid" > $HGRC
9 $ hg version
15 $ hg version
10 hg: parse error at $TESTTMP/hgrc:1: invalid
16 hg: parse error at $TESTTMP/hgrc:1: invalid
11 [255]
17 [255]
12 $ echo "" > $HGRCPATH
18 $ echo "" > $HGRC
13
19
14 Issue1199: Can't use '%' in hgrc (eg url encoded username)
20 Issue1199: Can't use '%' in hgrc (eg url encoded username)
15
21
16 $ hg init "foo%bar"
22 $ hg init "foo%bar"
17 $ hg clone "foo%bar" foobar
23 $ hg clone "foo%bar" foobar
18 updating to branch default
24 updating to branch default
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd foobar
26 $ cd foobar
21 $ cat .hg/hgrc
27 $ cat .hg/hgrc
22 [paths]
28 [paths]
23 default = $TESTTMP/foo%bar
29 default = $TESTTMP/foo%bar
24 $ hg paths
30 $ hg paths
25 default = $TESTTMP/foo%bar
31 default = $TESTTMP/foo%bar
26 $ hg showconfig
32 $ hg showconfig
27 bundle.mainreporoot=$TESTTMP/foobar
33 bundle.mainreporoot=$TESTTMP/foobar
28 paths.default=$TESTTMP/foo%bar
34 paths.default=$TESTTMP/foo%bar
29 $ cd ..
35 $ cd ..
30
36
31 issue1829: wrong indentation
37 issue1829: wrong indentation
32
38
33 $ echo '[foo]' > $HGRCPATH
39 $ echo '[foo]' > $HGRC
34 $ echo ' x = y' >> $HGRCPATH
40 $ echo ' x = y' >> $HGRC
35 $ hg version
41 $ hg version
36 hg: parse error at $TESTTMP/hgrc:2: x = y
42 hg: parse error at $TESTTMP/hgrc:2: x = y
37 [255]
43 [255]
38
44
39 $ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
45 $ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
40 > > $HGRCPATH
46 > > $HGRC
41 $ hg showconfig foo
47 $ hg showconfig foo
42 foo.bar=a\nb\nc\nde\nfg
48 foo.bar=a\nb\nc\nde\nfg
43 foo.baz=bif cb
49 foo.baz=bif cb
44
50
45 $ FAKEPATH=/path/to/nowhere
51 $ FAKEPATH=/path/to/nowhere
46 $ export FAKEPATH
52 $ export FAKEPATH
47 $ echo '%include $FAKEPATH/no-such-file' > $HGRCPATH
53 $ echo '%include $FAKEPATH/no-such-file' > $HGRC
48 $ hg version
54 $ hg version
49 Mercurial Distributed SCM (version *) (glob)
55 Mercurial Distributed SCM (version *) (glob)
50 (see http://mercurial.selenic.com for more information)
56 (see http://mercurial.selenic.com for more information)
51
57
52 Copyright (C) 2005-2011 Matt Mackall and others
58 Copyright (C) 2005-2011 Matt Mackall and others
53 This is free software; see the source for copying conditions. There is NO
59 This is free software; see the source for copying conditions. There is NO
54 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
60 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
55 $ unset FAKEPATH
61 $ unset FAKEPATH
56
62
57 make sure global options given on the cmdline take precedence
63 make sure global options given on the cmdline take precedence
58
64
59 $ hg showconfig --config ui.verbose=True --quiet
65 $ hg showconfig --config ui.verbose=True --quiet
60 ui.verbose=False
66 ui.verbose=False
61 ui.debug=False
67 ui.debug=False
62 ui.quiet=True
68 ui.quiet=True
63
69
64 $ touch foobar/untracked
70 $ touch foobar/untracked
65 $ cat >> foobar/.hg/hgrc <<EOF
71 $ cat >> foobar/.hg/hgrc <<EOF
66 > [ui]
72 > [ui]
67 > verbose=True
73 > verbose=True
68 > EOF
74 > EOF
69 $ hg -R foobar st -q
75 $ hg -R foobar st -q
70
76
71 username expansion
77 username expansion
72
78
73 $ olduser=$HGUSER
79 $ olduser=$HGUSER
74 $ unset HGUSER
80 $ unset HGUSER
75
81
76 $ FAKEUSER='John Doe'
82 $ FAKEUSER='John Doe'
77 $ export FAKEUSER
83 $ export FAKEUSER
78 $ echo '[ui]' > $HGRCPATH
84 $ echo '[ui]' > $HGRC
79 $ echo 'username = $FAKEUSER' >> $HGRCPATH
85 $ echo 'username = $FAKEUSER' >> $HGRC
80
86
81 $ hg init usertest
87 $ hg init usertest
82 $ cd usertest
88 $ cd usertest
83 $ touch bar
89 $ touch bar
84 $ hg commit --addremove --quiet -m "added bar"
90 $ hg commit --addremove --quiet -m "added bar"
85 $ hg log --template "{author}\n"
91 $ hg log --template "{author}\n"
86 John Doe
92 John Doe
87 $ cd ..
93 $ cd ..
88
94
89 $ hg showconfig
95 $ hg showconfig
90 ui.username=$FAKEUSER
96 ui.username=$FAKEUSER
91
97
92 $ unset FAKEUSER
98 $ unset FAKEUSER
93 $ HGUSER=$olduser
99 $ HGUSER=$olduser
94 $ export HGUSER
100 $ export HGUSER
95
101
96 showconfig with multiple arguments
102 showconfig with multiple arguments
97
103
98 $ echo "[alias]" > $HGRCPATH
104 $ echo "[alias]" > $HGRC
99 $ echo "log = log -g" >> $HGRCPATH
105 $ echo "log = log -g" >> $HGRC
100 $ echo "[defaults]" >> $HGRCPATH
106 $ echo "[defaults]" >> $HGRC
101 $ echo "identify = -n" >> $HGRCPATH
107 $ echo "identify = -n" >> $HGRC
102 $ hg showconfig alias defaults
108 $ hg showconfig alias defaults
103 alias.log=log -g
109 alias.log=log -g
104 defaults.identify=-n
110 defaults.identify=-n
105 $ hg showconfig alias defaults.identify
111 $ hg showconfig alias defaults.identify
106 abort: only one config item permitted
112 abort: only one config item permitted
107 [255]
113 [255]
108 $ hg showconfig alias.log defaults.identify
114 $ hg showconfig alias.log defaults.identify
109 abort: only one config item permitted
115 abort: only one config item permitted
110 [255]
116 [255]
111
117
112 HGPLAIN
118 HGPLAIN
113
119
114 $ cd ..
120 $ cd ..
115 $ p=`pwd`
121 $ p=`pwd`
116 $ echo "[ui]" > $HGRCPATH
122 $ echo "[ui]" > $HGRC
117 $ echo "debug=true" >> $HGRCPATH
123 $ echo "debug=true" >> $HGRC
118 $ echo "fallbackencoding=ASCII" >> $HGRCPATH
124 $ echo "fallbackencoding=ASCII" >> $HGRC
119 $ echo "quiet=true" >> $HGRCPATH
125 $ echo "quiet=true" >> $HGRC
120 $ echo "slash=true" >> $HGRCPATH
126 $ echo "slash=true" >> $HGRC
121 $ echo "traceback=true" >> $HGRCPATH
127 $ echo "traceback=true" >> $HGRC
122 $ echo "verbose=true" >> $HGRCPATH
128 $ echo "verbose=true" >> $HGRC
123 $ echo "style=~/.hgstyle" >> $HGRCPATH
129 $ echo "style=~/.hgstyle" >> $HGRC
124 $ echo "logtemplate={node}" >> $HGRCPATH
130 $ echo "logtemplate={node}" >> $HGRC
125 $ echo "[defaults]" >> $HGRCPATH
131 $ echo "[defaults]" >> $HGRC
126 $ echo "identify=-n" >> $HGRCPATH
132 $ echo "identify=-n" >> $HGRC
127 $ echo "[alias]" >> $HGRCPATH
133 $ echo "[alias]" >> $HGRC
128 $ echo "log=log -g" >> $HGRCPATH
134 $ echo "log=log -g" >> $HGRC
129
135
130 customized hgrc
136 customized hgrc
131
137
132 $ hg showconfig
138 $ hg showconfig
133 read config from: $TESTTMP/hgrc
139 read config from: $TESTTMP/hgrc
134 $TESTTMP/hgrc:13: alias.log=log -g
140 $TESTTMP/hgrc:13: alias.log=log -g
135 $TESTTMP/hgrc:11: defaults.identify=-n
141 $TESTTMP/hgrc:11: defaults.identify=-n
136 $TESTTMP/hgrc:2: ui.debug=true
142 $TESTTMP/hgrc:2: ui.debug=true
137 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
143 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
138 $TESTTMP/hgrc:4: ui.quiet=true
144 $TESTTMP/hgrc:4: ui.quiet=true
139 $TESTTMP/hgrc:5: ui.slash=true
145 $TESTTMP/hgrc:5: ui.slash=true
140 $TESTTMP/hgrc:6: ui.traceback=true
146 $TESTTMP/hgrc:6: ui.traceback=true
141 $TESTTMP/hgrc:7: ui.verbose=true
147 $TESTTMP/hgrc:7: ui.verbose=true
142 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
148 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
143 $TESTTMP/hgrc:9: ui.logtemplate={node}
149 $TESTTMP/hgrc:9: ui.logtemplate={node}
144
150
145 plain hgrc
151 plain hgrc
146
152
147 $ HGPLAIN=; export HGPLAIN
153 $ HGPLAIN=; export HGPLAIN
148 $ hg showconfig --config ui.traceback=True --debug
154 $ hg showconfig --config ui.traceback=True --debug
149 read config from: $TESTTMP/hgrc
155 read config from: $TESTTMP/hgrc
150 none: ui.traceback=True
156 none: ui.traceback=True
151 none: ui.verbose=False
157 none: ui.verbose=False
152 none: ui.debug=True
158 none: ui.debug=True
153 none: ui.quiet=False
159 none: ui.quiet=False
154
160
155 plain mode with exceptions
161 plain mode with exceptions
156
162
157 $ cat > plain.py <<EOF
163 $ cat > plain.py <<EOF
158 > def uisetup(ui):
164 > def uisetup(ui):
159 > ui.write('plain: %r\n' % ui.plain())
165 > ui.write('plain: %r\n' % ui.plain())
160 > EOF
166 > EOF
161 $ echo "[extensions]" >> $HGRCPATH
167 $ echo "[extensions]" >> $HGRC
162 $ echo "plain=./plain.py" >> $HGRCPATH
168 $ echo "plain=./plain.py" >> $HGRC
163 $ HGPLAINEXCEPT=; export HGPLAINEXCEPT
169 $ HGPLAINEXCEPT=; export HGPLAINEXCEPT
164 $ hg showconfig --config ui.traceback=True --debug
170 $ hg showconfig --config ui.traceback=True --debug
165 plain: True
171 plain: True
166 read config from: $TESTTMP/hgrc
172 read config from: $TESTTMP/hgrc
167 $TESTTMP/hgrc:15: extensions.plain=./plain.py
173 $TESTTMP/hgrc:15: extensions.plain=./plain.py
168 none: ui.traceback=True
174 none: ui.traceback=True
169 none: ui.verbose=False
175 none: ui.verbose=False
170 none: ui.debug=True
176 none: ui.debug=True
171 none: ui.quiet=False
177 none: ui.quiet=False
172 $ unset HGPLAIN
178 $ unset HGPLAIN
173 $ hg showconfig --config ui.traceback=True --debug
179 $ hg showconfig --config ui.traceback=True --debug
174 plain: True
180 plain: True
175 read config from: $TESTTMP/hgrc
181 read config from: $TESTTMP/hgrc
176 $TESTTMP/hgrc:15: extensions.plain=./plain.py
182 $TESTTMP/hgrc:15: extensions.plain=./plain.py
177 none: ui.traceback=True
183 none: ui.traceback=True
178 none: ui.verbose=False
184 none: ui.verbose=False
179 none: ui.debug=True
185 none: ui.debug=True
180 none: ui.quiet=False
186 none: ui.quiet=False
181 $ HGPLAINEXCEPT=i18n; export HGPLAINEXCEPT
187 $ HGPLAINEXCEPT=i18n; export HGPLAINEXCEPT
182 $ hg showconfig --config ui.traceback=True --debug
188 $ hg showconfig --config ui.traceback=True --debug
183 plain: True
189 plain: True
184 read config from: $TESTTMP/hgrc
190 read config from: $TESTTMP/hgrc
185 $TESTTMP/hgrc:15: extensions.plain=./plain.py
191 $TESTTMP/hgrc:15: extensions.plain=./plain.py
186 none: ui.traceback=True
192 none: ui.traceback=True
187 none: ui.verbose=False
193 none: ui.verbose=False
188 none: ui.debug=True
194 none: ui.debug=True
189 none: ui.quiet=False
195 none: ui.quiet=False
@@ -1,877 +1,877 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > largefiles=
3 > largefiles=
4 > purge=
4 > purge=
5 > rebase=
5 > rebase=
6 > [largefiles]
6 > [largefiles]
7 > minsize=2
7 > minsize=2
8 > patterns=glob:**.dat
8 > patterns=glob:**.dat
9 > EOF
9 > EOF
10
10
11 Create the repo with a couple of revisions of both large and normal
11 Create the repo with a couple of revisions of both large and normal
12 files, testing that status correctly shows largefiles.
12 files, testing that status correctly shows largefiles.
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ mkdir sub
16 $ mkdir sub
17 $ echo normal1 > normal1
17 $ echo normal1 > normal1
18 $ echo normal2 > sub/normal2
18 $ echo normal2 > sub/normal2
19 $ echo large1 > large1
19 $ echo large1 > large1
20 $ echo large2 > sub/large2
20 $ echo large2 > sub/large2
21 $ hg add normal1 sub/normal2
21 $ hg add normal1 sub/normal2
22 $ hg add --large large1 sub/large2
22 $ hg add --large large1 sub/large2
23 $ hg commit -m "add files"
23 $ hg commit -m "add files"
24 $ echo normal11 > normal1
24 $ echo normal11 > normal1
25 $ echo normal22 > sub/normal2
25 $ echo normal22 > sub/normal2
26 $ echo large11 > large1
26 $ echo large11 > large1
27 $ echo large22 > sub/large2
27 $ echo large22 > sub/large2
28 $ hg st
28 $ hg st
29 M large1
29 M large1
30 M normal1
30 M normal1
31 M sub/large2
31 M sub/large2
32 M sub/normal2
32 M sub/normal2
33 $ hg commit -m "edit files"
33 $ hg commit -m "edit files"
34
34
35 Commit preserved largefile contents.
35 Commit preserved largefile contents.
36
36
37 $ cat normal1
37 $ cat normal1
38 normal11
38 normal11
39 $ cat large1
39 $ cat large1
40 large11
40 large11
41 $ cat sub/normal2
41 $ cat sub/normal2
42 normal22
42 normal22
43 $ cat sub/large2
43 $ cat sub/large2
44 large22
44 large22
45
45
46 Remove both largefiles and normal files.
46 Remove both largefiles and normal files.
47
47
48 $ hg remove normal1 large1
48 $ hg remove normal1 large1
49 $ hg commit -m "remove files"
49 $ hg commit -m "remove files"
50 $ ls
50 $ ls
51 sub
51 sub
52
52
53 Copy both largefiles and normal files.
53 Copy both largefiles and normal files.
54
54
55 $ hg cp sub/normal2 normal1
55 $ hg cp sub/normal2 normal1
56 $ hg cp sub/large2 large1
56 $ hg cp sub/large2 large1
57 $ hg commit -m "copy files"
57 $ hg commit -m "copy files"
58 $ cat normal1
58 $ cat normal1
59 normal22
59 normal22
60 $ cat large1
60 $ cat large1
61 large22
61 large22
62
62
63 Test moving largefiles and verify that normal files are also unaffected.
63 Test moving largefiles and verify that normal files are also unaffected.
64
64
65 $ hg mv normal1 normal3
65 $ hg mv normal1 normal3
66 $ hg mv large1 large3
66 $ hg mv large1 large3
67 $ hg mv sub/normal2 sub/normal4
67 $ hg mv sub/normal2 sub/normal4
68 $ hg mv sub/large2 sub/large4
68 $ hg mv sub/large2 sub/large4
69 $ hg commit -m "move files"
69 $ hg commit -m "move files"
70 $ cat normal3
70 $ cat normal3
71 normal22
71 normal22
72 $ cat large3
72 $ cat large3
73 large22
73 large22
74 $ cat sub/normal4
74 $ cat sub/normal4
75 normal22
75 normal22
76 $ cat sub/large4
76 $ cat sub/large4
77 large22
77 large22
78
78
79 Test archiving the various revisions. These hit corner cases known with
79 Test archiving the various revisions. These hit corner cases known with
80 archiving.
80 archiving.
81
81
82 $ hg archive -r 0 ../archive0
82 $ hg archive -r 0 ../archive0
83 $ hg archive -r 1 ../archive1
83 $ hg archive -r 1 ../archive1
84 $ hg archive -r 2 ../archive2
84 $ hg archive -r 2 ../archive2
85 $ hg archive -r 3 ../archive3
85 $ hg archive -r 3 ../archive3
86 $ hg archive -r 4 ../archive4
86 $ hg archive -r 4 ../archive4
87 $ cd ../archive0
87 $ cd ../archive0
88 $ cat normal1
88 $ cat normal1
89 normal1
89 normal1
90 $ cat large1
90 $ cat large1
91 large1
91 large1
92 $ cat sub/normal2
92 $ cat sub/normal2
93 normal2
93 normal2
94 $ cat sub/large2
94 $ cat sub/large2
95 large2
95 large2
96 $ cd ../archive1
96 $ cd ../archive1
97 $ cat normal1
97 $ cat normal1
98 normal11
98 normal11
99 $ cat large1
99 $ cat large1
100 large11
100 large11
101 $ cat sub/normal2
101 $ cat sub/normal2
102 normal22
102 normal22
103 $ cat sub/large2
103 $ cat sub/large2
104 large22
104 large22
105 $ cd ../archive2
105 $ cd ../archive2
106 $ ls
106 $ ls
107 sub
107 sub
108 $ cat sub/normal2
108 $ cat sub/normal2
109 normal22
109 normal22
110 $ cat sub/large2
110 $ cat sub/large2
111 large22
111 large22
112 $ cd ../archive3
112 $ cd ../archive3
113 $ cat normal1
113 $ cat normal1
114 normal22
114 normal22
115 $ cat large1
115 $ cat large1
116 large22
116 large22
117 $ cat sub/normal2
117 $ cat sub/normal2
118 normal22
118 normal22
119 $ cat sub/large2
119 $ cat sub/large2
120 large22
120 large22
121 $ cd ../archive4
121 $ cd ../archive4
122 $ cat normal3
122 $ cat normal3
123 normal22
123 normal22
124 $ cat large3
124 $ cat large3
125 large22
125 large22
126 $ cat sub/normal4
126 $ cat sub/normal4
127 normal22
127 normal22
128 $ cat sub/large4
128 $ cat sub/large4
129 large22
129 large22
130
130
131 Commit corner case: specify files to commit.
131 Commit corner case: specify files to commit.
132
132
133 $ cd ../a
133 $ cd ../a
134 $ echo normal3 > normal3
134 $ echo normal3 > normal3
135 $ echo large3 > large3
135 $ echo large3 > large3
136 $ echo normal4 > sub/normal4
136 $ echo normal4 > sub/normal4
137 $ echo large4 > sub/large4
137 $ echo large4 > sub/large4
138 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
138 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
139 $ cat normal3
139 $ cat normal3
140 normal3
140 normal3
141 $ cat large3
141 $ cat large3
142 large3
142 large3
143 $ cat sub/normal4
143 $ cat sub/normal4
144 normal4
144 normal4
145 $ cat sub/large4
145 $ cat sub/large4
146 large4
146 large4
147
147
148 One more commit corner case: commit from a subdirectory.
148 One more commit corner case: commit from a subdirectory.
149
149
150 $ cd ../a
150 $ cd ../a
151 $ echo normal33 > normal3
151 $ echo normal33 > normal3
152 $ echo large33 > large3
152 $ echo large33 > large3
153 $ echo normal44 > sub/normal4
153 $ echo normal44 > sub/normal4
154 $ echo large44 > sub/large4
154 $ echo large44 > sub/large4
155 $ cd sub
155 $ cd sub
156 $ hg commit -m "edit files yet again"
156 $ hg commit -m "edit files yet again"
157 $ cat ../normal3
157 $ cat ../normal3
158 normal33
158 normal33
159 $ cat ../large3
159 $ cat ../large3
160 large33
160 large33
161 $ cat normal4
161 $ cat normal4
162 normal44
162 normal44
163 $ cat large4
163 $ cat large4
164 large44
164 large44
165
165
166 Committing standins is not allowed.
166 Committing standins is not allowed.
167
167
168 $ cd ..
168 $ cd ..
169 $ echo large3 > large3
169 $ echo large3 > large3
170 $ hg commit .hglf/large3 -m "try to commit standin"
170 $ hg commit .hglf/large3 -m "try to commit standin"
171 abort: file ".hglf/large3" is a largefile standin
171 abort: file ".hglf/large3" is a largefile standin
172 (commit the largefile itself instead)
172 (commit the largefile itself instead)
173 [255]
173 [255]
174
174
175 Corner cases for adding largefiles.
175 Corner cases for adding largefiles.
176
176
177 $ echo large5 > large5
177 $ echo large5 > large5
178 $ hg add --large large5
178 $ hg add --large large5
179 $ hg add --large large5
179 $ hg add --large large5
180 large5 already a largefile
180 large5 already a largefile
181 $ mkdir sub2
181 $ mkdir sub2
182 $ echo large6 > sub2/large6
182 $ echo large6 > sub2/large6
183 $ echo large7 > sub2/large7
183 $ echo large7 > sub2/large7
184 $ hg add --large sub2
184 $ hg add --large sub2
185 adding sub2/large6 as a largefile
185 adding sub2/large6 as a largefile
186 adding sub2/large7 as a largefile
186 adding sub2/large7 as a largefile
187 $ hg st
187 $ hg st
188 M large3
188 M large3
189 A large5
189 A large5
190 A sub2/large6
190 A sub2/large6
191 A sub2/large7
191 A sub2/large7
192
192
193 Config settings (pattern **.dat, minsize 2 MB) are respected.
193 Config settings (pattern **.dat, minsize 2 MB) are respected.
194
194
195 $ echo testdata > test.dat
195 $ echo testdata > test.dat
196 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
196 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
197 $ hg add
197 $ hg add
198 adding reallylarge as a largefile
198 adding reallylarge as a largefile
199 adding test.dat as a largefile
199 adding test.dat as a largefile
200
200
201 Test that minsize and --lfsize handle float values;
201 Test that minsize and --lfsize handle float values;
202 also tests that --lfsize overrides largefiles.minsize.
202 also tests that --lfsize overrides largefiles.minsize.
203 (0.250 MB = 256 kB = 262144 B)
203 (0.250 MB = 256 kB = 262144 B)
204
204
205 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
205 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
206 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
206 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
207 $ hg --config largefiles.minsize=.25 add
207 $ hg --config largefiles.minsize=.25 add
208 adding ratherlarge as a largefile
208 adding ratherlarge as a largefile
209 adding medium
209 adding medium
210 $ hg forget medium
210 $ hg forget medium
211 $ hg --config largefiles.minsize=.25 add --lfsize=.125
211 $ hg --config largefiles.minsize=.25 add --lfsize=.125
212 adding medium as a largefile
212 adding medium as a largefile
213 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
213 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
214 $ hg --config largefiles.minsize=.25 add --lfsize=.125
214 $ hg --config largefiles.minsize=.25 add --lfsize=.125
215 adding notlarge
215 adding notlarge
216 $ hg forget notlarge
216 $ hg forget notlarge
217
217
218 Test forget on largefiles.
218 Test forget on largefiles.
219
219
220 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
220 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
221 $ hg st
221 $ hg st
222 A sub2/large6
222 A sub2/large6
223 A sub2/large7
223 A sub2/large7
224 R large3
224 R large3
225 ? large5
225 ? large5
226 ? medium
226 ? medium
227 ? notlarge
227 ? notlarge
228 ? ratherlarge
228 ? ratherlarge
229 ? reallylarge
229 ? reallylarge
230 ? test.dat
230 ? test.dat
231 $ hg commit -m "add/edit more largefiles"
231 $ hg commit -m "add/edit more largefiles"
232 $ hg st
232 $ hg st
233 ? large3
233 ? large3
234 ? large5
234 ? large5
235 ? medium
235 ? medium
236 ? notlarge
236 ? notlarge
237 ? ratherlarge
237 ? ratherlarge
238 ? reallylarge
238 ? reallylarge
239 ? test.dat
239 ? test.dat
240
240
241 Purge with largefiles: verify that largefiles are still in the working
241 Purge with largefiles: verify that largefiles are still in the working
242 dir after a purge.
242 dir after a purge.
243
243
244 $ hg purge --all
244 $ hg purge --all
245 $ cat sub/large4
245 $ cat sub/large4
246 large44
246 large44
247 $ cat sub2/large6
247 $ cat sub2/large6
248 large6
248 large6
249 $ cat sub2/large7
249 $ cat sub2/large7
250 large7
250 large7
251
251
252 Clone a largefiles repo.
252 Clone a largefiles repo.
253
253
254 $ cd ..
254 $ cd ..
255 $ hg clone a b
255 $ hg clone a b
256 updating to branch default
256 updating to branch default
257 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 getting changed largefiles
258 getting changed largefiles
259 3 largefiles updated, 0 removed
259 3 largefiles updated, 0 removed
260 $ cd b
260 $ cd b
261 $ hg log
261 $ hg log
262 changeset: 7:daea875e9014
262 changeset: 7:daea875e9014
263 tag: tip
263 tag: tip
264 user: test
264 user: test
265 date: Thu Jan 01 00:00:00 1970 +0000
265 date: Thu Jan 01 00:00:00 1970 +0000
266 summary: add/edit more largefiles
266 summary: add/edit more largefiles
267
267
268 changeset: 6:4355d653f84f
268 changeset: 6:4355d653f84f
269 user: test
269 user: test
270 date: Thu Jan 01 00:00:00 1970 +0000
270 date: Thu Jan 01 00:00:00 1970 +0000
271 summary: edit files yet again
271 summary: edit files yet again
272
272
273 changeset: 5:9d5af5072dbd
273 changeset: 5:9d5af5072dbd
274 user: test
274 user: test
275 date: Thu Jan 01 00:00:00 1970 +0000
275 date: Thu Jan 01 00:00:00 1970 +0000
276 summary: edit files again
276 summary: edit files again
277
277
278 changeset: 4:74c02385b94c
278 changeset: 4:74c02385b94c
279 user: test
279 user: test
280 date: Thu Jan 01 00:00:00 1970 +0000
280 date: Thu Jan 01 00:00:00 1970 +0000
281 summary: move files
281 summary: move files
282
282
283 changeset: 3:9e8fbc4bce62
283 changeset: 3:9e8fbc4bce62
284 user: test
284 user: test
285 date: Thu Jan 01 00:00:00 1970 +0000
285 date: Thu Jan 01 00:00:00 1970 +0000
286 summary: copy files
286 summary: copy files
287
287
288 changeset: 2:51a0ae4d5864
288 changeset: 2:51a0ae4d5864
289 user: test
289 user: test
290 date: Thu Jan 01 00:00:00 1970 +0000
290 date: Thu Jan 01 00:00:00 1970 +0000
291 summary: remove files
291 summary: remove files
292
292
293 changeset: 1:ce8896473775
293 changeset: 1:ce8896473775
294 user: test
294 user: test
295 date: Thu Jan 01 00:00:00 1970 +0000
295 date: Thu Jan 01 00:00:00 1970 +0000
296 summary: edit files
296 summary: edit files
297
297
298 changeset: 0:30d30fe6a5be
298 changeset: 0:30d30fe6a5be
299 user: test
299 user: test
300 date: Thu Jan 01 00:00:00 1970 +0000
300 date: Thu Jan 01 00:00:00 1970 +0000
301 summary: add files
301 summary: add files
302
302
303 $ cat normal3
303 $ cat normal3
304 normal33
304 normal33
305 $ cat sub/normal4
305 $ cat sub/normal4
306 normal44
306 normal44
307 $ cat sub/large4
307 $ cat sub/large4
308 large44
308 large44
309 $ cat sub2/large6
309 $ cat sub2/large6
310 large6
310 large6
311 $ cat sub2/large7
311 $ cat sub2/large7
312 large7
312 large7
313 $ cd ..
313 $ cd ..
314 $ hg clone a -r 3 c
314 $ hg clone a -r 3 c
315 adding changesets
315 adding changesets
316 adding manifests
316 adding manifests
317 adding file changes
317 adding file changes
318 added 4 changesets with 10 changes to 4 files
318 added 4 changesets with 10 changes to 4 files
319 updating to branch default
319 updating to branch default
320 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 getting changed largefiles
321 getting changed largefiles
322 2 largefiles updated, 0 removed
322 2 largefiles updated, 0 removed
323 $ cd c
323 $ cd c
324 $ hg log
324 $ hg log
325 changeset: 3:9e8fbc4bce62
325 changeset: 3:9e8fbc4bce62
326 tag: tip
326 tag: tip
327 user: test
327 user: test
328 date: Thu Jan 01 00:00:00 1970 +0000
328 date: Thu Jan 01 00:00:00 1970 +0000
329 summary: copy files
329 summary: copy files
330
330
331 changeset: 2:51a0ae4d5864
331 changeset: 2:51a0ae4d5864
332 user: test
332 user: test
333 date: Thu Jan 01 00:00:00 1970 +0000
333 date: Thu Jan 01 00:00:00 1970 +0000
334 summary: remove files
334 summary: remove files
335
335
336 changeset: 1:ce8896473775
336 changeset: 1:ce8896473775
337 user: test
337 user: test
338 date: Thu Jan 01 00:00:00 1970 +0000
338 date: Thu Jan 01 00:00:00 1970 +0000
339 summary: edit files
339 summary: edit files
340
340
341 changeset: 0:30d30fe6a5be
341 changeset: 0:30d30fe6a5be
342 user: test
342 user: test
343 date: Thu Jan 01 00:00:00 1970 +0000
343 date: Thu Jan 01 00:00:00 1970 +0000
344 summary: add files
344 summary: add files
345
345
346 $ cat normal1
346 $ cat normal1
347 normal22
347 normal22
348 $ cat large1
348 $ cat large1
349 large22
349 large22
350 $ cat sub/normal2
350 $ cat sub/normal2
351 normal22
351 normal22
352 $ cat sub/large2
352 $ cat sub/large2
353 large22
353 large22
354
354
355 Old revisions of a clone have correct largefiles content (this also
355 Old revisions of a clone have correct largefiles content (this also
356 tests update).
356 tests update).
357
357
358 $ hg update -r 1
358 $ hg update -r 1
359 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
359 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
360 getting changed largefiles
360 getting changed largefiles
361 1 largefiles updated, 0 removed
361 1 largefiles updated, 0 removed
362 $ cat large1
362 $ cat large1
363 large11
363 large11
364 $ cat sub/large2
364 $ cat sub/large2
365 large22
365 large22
366
366
367 Rebasing between two repositories does not revert largefiles to old
367 Rebasing between two repositories does not revert largefiles to old
368 revisions (this was a very bad bug that took a lot of work to fix).
368 revisions (this was a very bad bug that took a lot of work to fix).
369
369
370 $ cd ..
370 $ cd ..
371 $ hg clone a d
371 $ hg clone a d
372 updating to branch default
372 updating to branch default
373 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
373 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 getting changed largefiles
374 getting changed largefiles
375 3 largefiles updated, 0 removed
375 3 largefiles updated, 0 removed
376 $ cd b
376 $ cd b
377 $ echo large4-modified > sub/large4
377 $ echo large4-modified > sub/large4
378 $ echo normal3-modified > normal3
378 $ echo normal3-modified > normal3
379 $ hg commit -m "modify normal file and largefile in repo b"
379 $ hg commit -m "modify normal file and largefile in repo b"
380 $ cd ../d
380 $ cd ../d
381 $ echo large6-modified > sub2/large6
381 $ echo large6-modified > sub2/large6
382 $ echo normal4-modified > sub/normal4
382 $ echo normal4-modified > sub/normal4
383 $ hg commit -m "modify normal file largefile in repo d"
383 $ hg commit -m "modify normal file largefile in repo d"
384 $ cd ..
384 $ cd ..
385 $ hg clone d e
385 $ hg clone d e
386 updating to branch default
386 updating to branch default
387 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 getting changed largefiles
388 getting changed largefiles
389 3 largefiles updated, 0 removed
389 3 largefiles updated, 0 removed
390 $ cd d
390 $ cd d
391 $ hg pull --rebase ../b
391 $ hg pull --rebase ../b
392 pulling from ../b
392 pulling from ../b
393 searching for changes
393 searching for changes
394 adding changesets
394 adding changesets
395 adding manifests
395 adding manifests
396 adding file changes
396 adding file changes
397 added 1 changesets with 2 changes to 2 files (+1 heads)
397 added 1 changesets with 2 changes to 2 files (+1 heads)
398 getting changed largefiles
398 getting changed largefiles
399 1 largefiles updated, 0 removed
399 1 largefiles updated, 0 removed
400 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
400 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
401 nothing to rebase
401 nothing to rebase
402 $ hg log
402 $ hg log
403 changeset: 9:598410d3eb9a
403 changeset: 9:598410d3eb9a
404 tag: tip
404 tag: tip
405 user: test
405 user: test
406 date: Thu Jan 01 00:00:00 1970 +0000
406 date: Thu Jan 01 00:00:00 1970 +0000
407 summary: modify normal file largefile in repo d
407 summary: modify normal file largefile in repo d
408
408
409 changeset: 8:a381d2c8c80e
409 changeset: 8:a381d2c8c80e
410 user: test
410 user: test
411 date: Thu Jan 01 00:00:00 1970 +0000
411 date: Thu Jan 01 00:00:00 1970 +0000
412 summary: modify normal file and largefile in repo b
412 summary: modify normal file and largefile in repo b
413
413
414 changeset: 7:daea875e9014
414 changeset: 7:daea875e9014
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
417 summary: add/edit more largefiles
417 summary: add/edit more largefiles
418
418
419 changeset: 6:4355d653f84f
419 changeset: 6:4355d653f84f
420 user: test
420 user: test
421 date: Thu Jan 01 00:00:00 1970 +0000
421 date: Thu Jan 01 00:00:00 1970 +0000
422 summary: edit files yet again
422 summary: edit files yet again
423
423
424 changeset: 5:9d5af5072dbd
424 changeset: 5:9d5af5072dbd
425 user: test
425 user: test
426 date: Thu Jan 01 00:00:00 1970 +0000
426 date: Thu Jan 01 00:00:00 1970 +0000
427 summary: edit files again
427 summary: edit files again
428
428
429 changeset: 4:74c02385b94c
429 changeset: 4:74c02385b94c
430 user: test
430 user: test
431 date: Thu Jan 01 00:00:00 1970 +0000
431 date: Thu Jan 01 00:00:00 1970 +0000
432 summary: move files
432 summary: move files
433
433
434 changeset: 3:9e8fbc4bce62
434 changeset: 3:9e8fbc4bce62
435 user: test
435 user: test
436 date: Thu Jan 01 00:00:00 1970 +0000
436 date: Thu Jan 01 00:00:00 1970 +0000
437 summary: copy files
437 summary: copy files
438
438
439 changeset: 2:51a0ae4d5864
439 changeset: 2:51a0ae4d5864
440 user: test
440 user: test
441 date: Thu Jan 01 00:00:00 1970 +0000
441 date: Thu Jan 01 00:00:00 1970 +0000
442 summary: remove files
442 summary: remove files
443
443
444 changeset: 1:ce8896473775
444 changeset: 1:ce8896473775
445 user: test
445 user: test
446 date: Thu Jan 01 00:00:00 1970 +0000
446 date: Thu Jan 01 00:00:00 1970 +0000
447 summary: edit files
447 summary: edit files
448
448
449 changeset: 0:30d30fe6a5be
449 changeset: 0:30d30fe6a5be
450 user: test
450 user: test
451 date: Thu Jan 01 00:00:00 1970 +0000
451 date: Thu Jan 01 00:00:00 1970 +0000
452 summary: add files
452 summary: add files
453
453
454 $ cat normal3
454 $ cat normal3
455 normal3-modified
455 normal3-modified
456 $ cat sub/normal4
456 $ cat sub/normal4
457 normal4-modified
457 normal4-modified
458 $ cat sub/large4
458 $ cat sub/large4
459 large4-modified
459 large4-modified
460 $ cat sub2/large6
460 $ cat sub2/large6
461 large6-modified
461 large6-modified
462 $ cat sub2/large7
462 $ cat sub2/large7
463 large7
463 large7
464 $ cd ../e
464 $ cd ../e
465 $ hg pull ../b
465 $ hg pull ../b
466 pulling from ../b
466 pulling from ../b
467 searching for changes
467 searching for changes
468 adding changesets
468 adding changesets
469 adding manifests
469 adding manifests
470 adding file changes
470 adding file changes
471 added 1 changesets with 2 changes to 2 files (+1 heads)
471 added 1 changesets with 2 changes to 2 files (+1 heads)
472 (run 'hg heads' to see heads, 'hg merge' to merge)
472 (run 'hg heads' to see heads, 'hg merge' to merge)
473 $ hg rebase
473 $ hg rebase
474 getting changed largefiles
474 getting changed largefiles
475 1 largefiles updated, 0 removed
475 1 largefiles updated, 0 removed
476 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
476 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
477 $ hg log
477 $ hg log
478 changeset: 9:598410d3eb9a
478 changeset: 9:598410d3eb9a
479 tag: tip
479 tag: tip
480 user: test
480 user: test
481 date: Thu Jan 01 00:00:00 1970 +0000
481 date: Thu Jan 01 00:00:00 1970 +0000
482 summary: modify normal file largefile in repo d
482 summary: modify normal file largefile in repo d
483
483
484 changeset: 8:a381d2c8c80e
484 changeset: 8:a381d2c8c80e
485 user: test
485 user: test
486 date: Thu Jan 01 00:00:00 1970 +0000
486 date: Thu Jan 01 00:00:00 1970 +0000
487 summary: modify normal file and largefile in repo b
487 summary: modify normal file and largefile in repo b
488
488
489 changeset: 7:daea875e9014
489 changeset: 7:daea875e9014
490 user: test
490 user: test
491 date: Thu Jan 01 00:00:00 1970 +0000
491 date: Thu Jan 01 00:00:00 1970 +0000
492 summary: add/edit more largefiles
492 summary: add/edit more largefiles
493
493
494 changeset: 6:4355d653f84f
494 changeset: 6:4355d653f84f
495 user: test
495 user: test
496 date: Thu Jan 01 00:00:00 1970 +0000
496 date: Thu Jan 01 00:00:00 1970 +0000
497 summary: edit files yet again
497 summary: edit files yet again
498
498
499 changeset: 5:9d5af5072dbd
499 changeset: 5:9d5af5072dbd
500 user: test
500 user: test
501 date: Thu Jan 01 00:00:00 1970 +0000
501 date: Thu Jan 01 00:00:00 1970 +0000
502 summary: edit files again
502 summary: edit files again
503
503
504 changeset: 4:74c02385b94c
504 changeset: 4:74c02385b94c
505 user: test
505 user: test
506 date: Thu Jan 01 00:00:00 1970 +0000
506 date: Thu Jan 01 00:00:00 1970 +0000
507 summary: move files
507 summary: move files
508
508
509 changeset: 3:9e8fbc4bce62
509 changeset: 3:9e8fbc4bce62
510 user: test
510 user: test
511 date: Thu Jan 01 00:00:00 1970 +0000
511 date: Thu Jan 01 00:00:00 1970 +0000
512 summary: copy files
512 summary: copy files
513
513
514 changeset: 2:51a0ae4d5864
514 changeset: 2:51a0ae4d5864
515 user: test
515 user: test
516 date: Thu Jan 01 00:00:00 1970 +0000
516 date: Thu Jan 01 00:00:00 1970 +0000
517 summary: remove files
517 summary: remove files
518
518
519 changeset: 1:ce8896473775
519 changeset: 1:ce8896473775
520 user: test
520 user: test
521 date: Thu Jan 01 00:00:00 1970 +0000
521 date: Thu Jan 01 00:00:00 1970 +0000
522 summary: edit files
522 summary: edit files
523
523
524 changeset: 0:30d30fe6a5be
524 changeset: 0:30d30fe6a5be
525 user: test
525 user: test
526 date: Thu Jan 01 00:00:00 1970 +0000
526 date: Thu Jan 01 00:00:00 1970 +0000
527 summary: add files
527 summary: add files
528
528
529 $ cat normal3
529 $ cat normal3
530 normal3-modified
530 normal3-modified
531 $ cat sub/normal4
531 $ cat sub/normal4
532 normal4-modified
532 normal4-modified
533 $ cat sub/large4
533 $ cat sub/large4
534 large4-modified
534 large4-modified
535 $ cat sub2/large6
535 $ cat sub2/large6
536 large6-modified
536 large6-modified
537 $ cat sub2/large7
537 $ cat sub2/large7
538 large7
538 large7
539
539
540 Rollback on largefiles.
540 Rollback on largefiles.
541
541
542 $ echo large4-modified-again > sub/large4
542 $ echo large4-modified-again > sub/large4
543 $ hg commit -m "Modify large4 again"
543 $ hg commit -m "Modify large4 again"
544 $ hg rollback
544 $ hg rollback
545 repository tip rolled back to revision 9 (undo commit)
545 repository tip rolled back to revision 9 (undo commit)
546 working directory now based on revision 9
546 working directory now based on revision 9
547 $ hg st
547 $ hg st
548 M sub/large4
548 M sub/large4
549 $ hg log
549 $ hg log
550 changeset: 9:598410d3eb9a
550 changeset: 9:598410d3eb9a
551 tag: tip
551 tag: tip
552 user: test
552 user: test
553 date: Thu Jan 01 00:00:00 1970 +0000
553 date: Thu Jan 01 00:00:00 1970 +0000
554 summary: modify normal file largefile in repo d
554 summary: modify normal file largefile in repo d
555
555
556 changeset: 8:a381d2c8c80e
556 changeset: 8:a381d2c8c80e
557 user: test
557 user: test
558 date: Thu Jan 01 00:00:00 1970 +0000
558 date: Thu Jan 01 00:00:00 1970 +0000
559 summary: modify normal file and largefile in repo b
559 summary: modify normal file and largefile in repo b
560
560
561 changeset: 7:daea875e9014
561 changeset: 7:daea875e9014
562 user: test
562 user: test
563 date: Thu Jan 01 00:00:00 1970 +0000
563 date: Thu Jan 01 00:00:00 1970 +0000
564 summary: add/edit more largefiles
564 summary: add/edit more largefiles
565
565
566 changeset: 6:4355d653f84f
566 changeset: 6:4355d653f84f
567 user: test
567 user: test
568 date: Thu Jan 01 00:00:00 1970 +0000
568 date: Thu Jan 01 00:00:00 1970 +0000
569 summary: edit files yet again
569 summary: edit files yet again
570
570
571 changeset: 5:9d5af5072dbd
571 changeset: 5:9d5af5072dbd
572 user: test
572 user: test
573 date: Thu Jan 01 00:00:00 1970 +0000
573 date: Thu Jan 01 00:00:00 1970 +0000
574 summary: edit files again
574 summary: edit files again
575
575
576 changeset: 4:74c02385b94c
576 changeset: 4:74c02385b94c
577 user: test
577 user: test
578 date: Thu Jan 01 00:00:00 1970 +0000
578 date: Thu Jan 01 00:00:00 1970 +0000
579 summary: move files
579 summary: move files
580
580
581 changeset: 3:9e8fbc4bce62
581 changeset: 3:9e8fbc4bce62
582 user: test
582 user: test
583 date: Thu Jan 01 00:00:00 1970 +0000
583 date: Thu Jan 01 00:00:00 1970 +0000
584 summary: copy files
584 summary: copy files
585
585
586 changeset: 2:51a0ae4d5864
586 changeset: 2:51a0ae4d5864
587 user: test
587 user: test
588 date: Thu Jan 01 00:00:00 1970 +0000
588 date: Thu Jan 01 00:00:00 1970 +0000
589 summary: remove files
589 summary: remove files
590
590
591 changeset: 1:ce8896473775
591 changeset: 1:ce8896473775
592 user: test
592 user: test
593 date: Thu Jan 01 00:00:00 1970 +0000
593 date: Thu Jan 01 00:00:00 1970 +0000
594 summary: edit files
594 summary: edit files
595
595
596 changeset: 0:30d30fe6a5be
596 changeset: 0:30d30fe6a5be
597 user: test
597 user: test
598 date: Thu Jan 01 00:00:00 1970 +0000
598 date: Thu Jan 01 00:00:00 1970 +0000
599 summary: add files
599 summary: add files
600
600
601 $ cat sub/large4
601 $ cat sub/large4
602 large4-modified-again
602 large4-modified-again
603
603
604 "update --check" refuses to update with uncommitted changes.
604 "update --check" refuses to update with uncommitted changes.
605 $ hg update --check 8
605 $ hg update --check 8
606 abort: uncommitted local changes
606 abort: uncommitted local changes
607 [255]
607 [255]
608
608
609 "update --clean" leaves correct largefiles in working copy.
609 "update --clean" leaves correct largefiles in working copy.
610
610
611 $ hg update --clean
611 $ hg update --clean
612 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
612 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 getting changed largefiles
613 getting changed largefiles
614 1 largefiles updated, 0 removed
614 1 largefiles updated, 0 removed
615 $ cat normal3
615 $ cat normal3
616 normal3-modified
616 normal3-modified
617 $ cat sub/normal4
617 $ cat sub/normal4
618 normal4-modified
618 normal4-modified
619 $ cat sub/large4
619 $ cat sub/large4
620 large4-modified
620 large4-modified
621 $ cat sub2/large6
621 $ cat sub2/large6
622 large6-modified
622 large6-modified
623 $ cat sub2/large7
623 $ cat sub2/large7
624 large7
624 large7
625
625
626 Now "update check" is happy.
626 Now "update check" is happy.
627 $ hg update --check 8
627 $ hg update --check 8
628 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
628 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
629 getting changed largefiles
629 getting changed largefiles
630 1 largefiles updated, 0 removed
630 1 largefiles updated, 0 removed
631 $ hg update --check
631 $ hg update --check
632 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
632 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
633 getting changed largefiles
633 getting changed largefiles
634 1 largefiles updated, 0 removed
634 1 largefiles updated, 0 removed
635
635
636 "revert" works on largefiles (and normal files too).
636 "revert" works on largefiles (and normal files too).
637 $ echo hack3 >> normal3
637 $ echo hack3 >> normal3
638 $ echo hack4 >> sub/normal4
638 $ echo hack4 >> sub/normal4
639 $ echo hack4 >> sub/large4
639 $ echo hack4 >> sub/large4
640 $ hg rm sub2/large6
640 $ hg rm sub2/large6
641 $ echo new >> sub2/large8
641 $ echo new >> sub2/large8
642 $ hg add --large sub2/large8
642 $ hg add --large sub2/large8
643 # XXX we don't really want to report that we're reverting the standin;
643 # XXX we don't really want to report that we're reverting the standin;
644 # that's just an implementation detail. But I don't see an obvious fix. ;-(
644 # that's just an implementation detail. But I don't see an obvious fix. ;-(
645 $ hg revert sub
645 $ hg revert sub
646 reverting .hglf/sub/large4
646 reverting .hglf/sub/large4
647 reverting sub/normal4
647 reverting sub/normal4
648 $ hg status
648 $ hg status
649 M normal3
649 M normal3
650 A sub2/large8
650 A sub2/large8
651 R sub2/large6
651 R sub2/large6
652 ? sub/large4.orig
652 ? sub/large4.orig
653 ? sub/normal4.orig
653 ? sub/normal4.orig
654 $ cat sub/normal4
654 $ cat sub/normal4
655 normal4-modified
655 normal4-modified
656 $ cat sub/large4
656 $ cat sub/large4
657 large4-modified
657 large4-modified
658 $ hg revert -a --no-backup
658 $ hg revert -a --no-backup
659 undeleting .hglf/sub2/large6
659 undeleting .hglf/sub2/large6
660 forgetting .hglf/sub2/large8
660 forgetting .hglf/sub2/large8
661 reverting normal3
661 reverting normal3
662 $ hg status
662 $ hg status
663 ? sub/large4.orig
663 ? sub/large4.orig
664 ? sub/normal4.orig
664 ? sub/normal4.orig
665 ? sub2/large8
665 ? sub2/large8
666 $ cat normal3
666 $ cat normal3
667 normal3-modified
667 normal3-modified
668 $ cat sub2/large6
668 $ cat sub2/large6
669 large6-modified
669 large6-modified
670 $ rm sub/*.orig sub2/large8
670 $ rm sub/*.orig sub2/large8
671
671
672 revert some files to an older revision
672 revert some files to an older revision
673 $ hg revert --no-backup -r 8 sub2
673 $ hg revert --no-backup -r 8 sub2
674 reverting .hglf/sub2/large6
674 reverting .hglf/sub2/large6
675 $ cat sub2/large6
675 $ cat sub2/large6
676 large6
676 large6
677 $ hg revert --no-backup sub2
677 $ hg revert --no-backup sub2
678 reverting .hglf/sub2/large6
678 reverting .hglf/sub2/large6
679 $ hg status
679 $ hg status
680
680
681 "verify --large" actually verifies largefiles
681 "verify --large" actually verifies largefiles
682
682
683 $ hg verify --large
683 $ hg verify --large
684 checking changesets
684 checking changesets
685 checking manifests
685 checking manifests
686 crosschecking files in changesets and manifests
686 crosschecking files in changesets and manifests
687 checking files
687 checking files
688 10 files, 10 changesets, 28 total revisions
688 10 files, 10 changesets, 28 total revisions
689 searching 1 changesets for largefiles
689 searching 1 changesets for largefiles
690 verified existence of 3 revisions of 3 largefiles
690 verified existence of 3 revisions of 3 largefiles
691
691
692 Merging does not revert to old versions of largefiles (this has also
692 Merging does not revert to old versions of largefiles (this has also
693 been very problematic).
693 been very problematic).
694
694
695 $ cd ..
695 $ cd ..
696 $ hg clone -r 7 e f
696 $ hg clone -r 7 e f
697 adding changesets
697 adding changesets
698 adding manifests
698 adding manifests
699 adding file changes
699 adding file changes
700 added 8 changesets with 24 changes to 10 files
700 added 8 changesets with 24 changes to 10 files
701 updating to branch default
701 updating to branch default
702 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
702 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
703 getting changed largefiles
703 getting changed largefiles
704 3 largefiles updated, 0 removed
704 3 largefiles updated, 0 removed
705 $ cd f
705 $ cd f
706 $ echo "large4-merge-test" > sub/large4
706 $ echo "large4-merge-test" > sub/large4
707 $ hg commit -m "Modify large4 to test merge"
707 $ hg commit -m "Modify large4 to test merge"
708 $ hg pull ../e
708 $ hg pull ../e
709 pulling from ../e
709 pulling from ../e
710 searching for changes
710 searching for changes
711 adding changesets
711 adding changesets
712 adding manifests
712 adding manifests
713 adding file changes
713 adding file changes
714 added 2 changesets with 4 changes to 4 files (+1 heads)
714 added 2 changesets with 4 changes to 4 files (+1 heads)
715 (run 'hg heads' to see heads, 'hg merge' to merge)
715 (run 'hg heads' to see heads, 'hg merge' to merge)
716 $ hg merge
716 $ hg merge
717 merging sub/large4
717 merging sub/large4
718 largefile sub/large4 has a merge conflict
718 largefile sub/large4 has a merge conflict
719 keep (l)ocal or take (o)ther? l
719 keep (l)ocal or take (o)ther? l
720 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
720 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
721 (branch merge, don't forget to commit)
721 (branch merge, don't forget to commit)
722 getting changed largefiles
722 getting changed largefiles
723 1 largefiles updated, 0 removed
723 1 largefiles updated, 0 removed
724 $ hg commit -m "Merge repos e and f"
724 $ hg commit -m "Merge repos e and f"
725 $ cat normal3
725 $ cat normal3
726 normal3-modified
726 normal3-modified
727 $ cat sub/normal4
727 $ cat sub/normal4
728 normal4-modified
728 normal4-modified
729 $ cat sub/large4
729 $ cat sub/large4
730 large4-merge-test
730 large4-merge-test
731 $ cat sub2/large6
731 $ cat sub2/large6
732 large6-modified
732 large6-modified
733 $ cat sub2/large7
733 $ cat sub2/large7
734 large7
734 large7
735 $ cd ..
735 $ cd ..
736
736
737 vanilla clients not locked out from largefiles servers on vanilla repos
737 vanilla clients not locked out from largefiles servers on vanilla repos
738 $ mkdir r1
738 $ mkdir r1
739 $ cd r1
739 $ cd r1
740 $ hg init
740 $ hg init
741 $ echo c1 > f1
741 $ echo c1 > f1
742 $ hg add f1
742 $ hg add f1
743 $ hg com -m "m1"
743 $ hg com -m "m1"
744 $ cd ..
744 $ cd ..
745 $ hg serve -R r1 -d -p 8001 --pid-file serve.pid
745 $ hg serve -R r1 -d -p 8001 --pid-file serve.pid
746 $ hg --config extensions.largefiles=! clone http://localhost:8001 r2
746 $ hg --config extensions.largefiles=! clone http://localhost:8001 r2
747 requesting all changes
747 requesting all changes
748 adding changesets
748 adding changesets
749 adding manifests
749 adding manifests
750 adding file changes
750 adding file changes
751 added 1 changesets with 1 changes to 1 files
751 added 1 changesets with 1 changes to 1 files
752 updating to branch default
752 updating to branch default
753 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
754 $ kill $(cat serve.pid)
754 $ kill `cat serve.pid`
755
755
756 largefiles clients still work with vanilla servers
756 largefiles clients still work with vanilla servers
757 $ hg --config extensions.largefiles=! serve -R r1 -d -p 8001 --pid-file serve.pid
757 $ hg --config extensions.largefiles=! serve -R r1 -d -p 8001 --pid-file serve.pid
758 $ hg clone http://localhost:8001 r3
758 $ hg clone http://localhost:8001 r3
759 requesting all changes
759 requesting all changes
760 adding changesets
760 adding changesets
761 adding manifests
761 adding manifests
762 adding file changes
762 adding file changes
763 added 1 changesets with 1 changes to 1 files
763 added 1 changesets with 1 changes to 1 files
764 updating to branch default
764 updating to branch default
765 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
765 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
766 $ kill $(cat serve.pid)
766 $ kill `cat serve.pid`
767
767
768 vanilla clients locked out from largefiles http repos
768 vanilla clients locked out from largefiles http repos
769 $ mkdir r4
769 $ mkdir r4
770 $ cd r4
770 $ cd r4
771 $ hg init
771 $ hg init
772 $ echo c1 > f1
772 $ echo c1 > f1
773 $ hg add --large f1
773 $ hg add --large f1
774 $ hg com -m "m1"
774 $ hg com -m "m1"
775 $ cd ..
775 $ cd ..
776 $ hg serve -R r4 -d -p 8001 --pid-file serve.pid
776 $ hg serve -R r4 -d -p 8001 --pid-file serve.pid
777 $ hg --config extensions.largefiles=! clone http://localhost:8001 r5
777 $ hg --config extensions.largefiles=! clone http://localhost:8001 r5
778 abort: remote error:
778 abort: remote error:
779
779
780 This repository uses the largefiles extension.
780 This repository uses the largefiles extension.
781
781
782 Please enable it in your Mercurial config file.
782 Please enable it in your Mercurial config file.
783 [255]
783 [255]
784 $ kill $(cat serve.pid)
784 $ kill `cat serve.pid`
785
785
786 vanilla clients locked out from largefiles ssh repos
786 vanilla clients locked out from largefiles ssh repos
787 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
787 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
788 abort: remote error:
788 abort: remote error:
789
789
790 This repository uses the largefiles extension.
790 This repository uses the largefiles extension.
791
791
792 Please enable it in your Mercurial config file.
792 Please enable it in your Mercurial config file.
793 [255]
793 [255]
794
794
795 largefiles clients refuse to push largefiles repos to vanilla servers
795 largefiles clients refuse to push largefiles repos to vanilla servers
796 $ mkdir r6
796 $ mkdir r6
797 $ cd r6
797 $ cd r6
798 $ hg init
798 $ hg init
799 $ echo c1 > f1
799 $ echo c1 > f1
800 $ hg add f1
800 $ hg add f1
801 $ hg com -m "m1"
801 $ hg com -m "m1"
802 $ cat >> .hg/hgrc <<!
802 $ cat >> .hg/hgrc <<!
803 > [web]
803 > [web]
804 > push_ssl = false
804 > push_ssl = false
805 > allow_push = *
805 > allow_push = *
806 > !
806 > !
807 $ cd ..
807 $ cd ..
808 $ hg clone r6 r7
808 $ hg clone r6 r7
809 updating to branch default
809 updating to branch default
810 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
810 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
811 $ cd r7
811 $ cd r7
812 $ echo c2 > f2
812 $ echo c2 > f2
813 $ hg add --large f2
813 $ hg add --large f2
814 $ hg com -m "m2"
814 $ hg com -m "m2"
815 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p 8001 --pid-file ../serve.pid
815 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p 8001 --pid-file ../serve.pid
816 $ hg push http://localhost:8001
816 $ hg push http://localhost:8001
817 pushing to http://localhost:8001/
817 pushing to http://localhost:8001/
818 searching for changes
818 searching for changes
819 abort: http://localhost:8001/ does not appear to be a largefile store
819 abort: http://localhost:8001/ does not appear to be a largefile store
820 [255]
820 [255]
821 $ cd ..
821 $ cd ..
822 $ kill $(cat serve.pid)
822 $ kill `cat serve.pid`
823
823
824 $ cd ..
824 $ cd ..
825
825
826 Clone a local repository owned by another user
826 Clone a local repository owned by another user
827 We have to simulate that here by setting $HOME and removing write permissions
827 We have to simulate that here by setting $HOME and removing write permissions
828 $ ORIGHOME="$HOME"
828 $ ORIGHOME="$HOME"
829 $ mkdir alice
829 $ mkdir alice
830 $ HOME="`pwd`/alice"
830 $ HOME="`pwd`/alice"
831 $ cd alice
831 $ cd alice
832 $ hg init pubrepo
832 $ hg init pubrepo
833 $ cd pubrepo
833 $ cd pubrepo
834 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
834 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
835 $ hg add --large a-large-file
835 $ hg add --large a-large-file
836 $ hg commit -m "Add a large file"
836 $ hg commit -m "Add a large file"
837 $ cd ..
837 $ cd ..
838 $ chmod -R a-w pubrepo
838 $ chmod -R a-w pubrepo
839 $ cd ..
839 $ cd ..
840 $ mkdir bob
840 $ mkdir bob
841 $ HOME="`pwd`/bob"
841 $ HOME="`pwd`/bob"
842 $ cd bob
842 $ cd bob
843 $ hg clone ../alice/pubrepo pubrepo
843 $ hg clone ../alice/pubrepo pubrepo
844 requesting all changes
844 requesting all changes
845 adding changesets
845 adding changesets
846 adding manifests
846 adding manifests
847 adding file changes
847 adding file changes
848 added 1 changesets with 1 changes to 1 files
848 added 1 changesets with 1 changes to 1 files
849 updating to branch default
849 updating to branch default
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 getting changed largefiles
851 getting changed largefiles
852 1 largefiles updated, 0 removed
852 1 largefiles updated, 0 removed
853 $ cd ..
853 $ cd ..
854 $ HOME="$ORIGHOME"
854 $ HOME="$ORIGHOME"
855
855
856 Symlink to a large largefile should behave the same as a symlink to a normal file
856 Symlink to a large largefile should behave the same as a symlink to a normal file
857 $ hg init largesymlink
857 $ hg init largesymlink
858 $ cd largesymlink
858 $ cd largesymlink
859 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
859 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
860 $ hg add --large largefile
860 $ hg add --large largefile
861 $ hg commit -m "commit a large file"
861 $ hg commit -m "commit a large file"
862 $ ln -s largefile largelink
862 $ ln -s largefile largelink
863 $ hg add largelink
863 $ hg add largelink
864 $ hg commit -m "commit a large symlink"
864 $ hg commit -m "commit a large symlink"
865 $ rm -f largelink
865 $ rm -f largelink
866 $ hg up >/dev/null
866 $ hg up >/dev/null
867 $ test -e largelink
867 $ test -f largelink
868 [1]
868 [1]
869 $ test -L largelink
869 $ test -L largelink
870 [1]
870 [1]
871 $ rm -f largelink # make next part of the test independent of the previous
871 $ rm -f largelink # make next part of the test independent of the previous
872 $ hg up -C >/dev/null
872 $ hg up -C >/dev/null
873 $ test -e largelink
873 $ test -f largelink
874 $ test -L largelink
874 $ test -L largelink
875 $ cd ..
875 $ cd ..
876
876
877
877
@@ -1,214 +1,216 b''
1
1
2 $ cat > loop.py <<EOF
2 $ cat > loop.py <<EOF
3 > from mercurial import commands
3 > from mercurial import commands
4 >
4 >
5 > def loop(ui, loops, **opts):
5 > def loop(ui, loops, **opts):
6 > loops = int(loops)
6 > loops = int(loops)
7 > total = None
7 > total = None
8 > if loops >= 0:
8 > if loops >= 0:
9 > total = loops
9 > total = loops
10 > if opts.get('total', None):
10 > if opts.get('total', None):
11 > total = int(opts.get('total'))
11 > total = int(opts.get('total'))
12 > nested = False
12 > nested = False
13 > if opts.get('nested', None):
13 > if opts.get('nested', None):
14 > nested = True
14 > nested = True
15 > loops = abs(loops)
15 > loops = abs(loops)
16 >
16 >
17 > for i in range(loops):
17 > for i in range(loops):
18 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
18 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
19 > if opts.get('parallel'):
19 > if opts.get('parallel'):
20 > ui.progress('other', i, 'other.%d' % i, 'othernum', total)
20 > ui.progress('other', i, 'other.%d' % i, 'othernum', total)
21 > if nested:
21 > if nested:
22 > for j in range(2):
22 > for j in range(2):
23 > ui.progress('nested', j, 'nested.%d' % j, 'nestnum', 2)
23 > ui.progress('nested', j, 'nested.%d' % j, 'nestnum', 2)
24 > ui.progress('nested', None, 'nested.done', 'nestnum', 2)
24 > ui.progress('nested', None, 'nested.done', 'nestnum', 2)
25 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
25 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
26 >
26 >
27 > commands.norepo += " loop"
27 > commands.norepo += " loop"
28 >
28 >
29 > cmdtable = {
29 > cmdtable = {
30 > "loop": (loop, [('', 'total', '', 'override for total'),
30 > "loop": (loop, [('', 'total', '', 'override for total'),
31 > ('', 'nested', False, 'show nested results'),
31 > ('', 'nested', False, 'show nested results'),
32 > ('', 'parallel', False, 'show parallel sets of results'),
32 > ('', 'parallel', False, 'show parallel sets of results'),
33 > ],
33 > ],
34 > 'hg loop LOOPS'),
34 > 'hg loop LOOPS'),
35 > }
35 > }
36 > EOF
36 > EOF
37
37
38 $ cp $HGRCPATH $HGRCPATH.orig
38 $ echo "[extensions]" >> $HGRCPATH
39 $ echo "[extensions]" >> $HGRCPATH
39 $ echo "progress=" >> $HGRCPATH
40 $ echo "progress=" >> $HGRCPATH
40 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
41 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
41 $ echo "[progress]" >> $HGRCPATH
42 $ echo "[progress]" >> $HGRCPATH
42 $ echo "format = topic bar number" >> $HGRCPATH
43 $ echo "format = topic bar number" >> $HGRCPATH
43 $ echo "assume-tty=1" >> $HGRCPATH
44 $ echo "assume-tty=1" >> $HGRCPATH
44 $ echo "width=60" >> $HGRCPATH
45 $ echo "width=60" >> $HGRCPATH
45
46
46 test default params, display nothing because of delay
47 test default params, display nothing because of delay
47
48
48 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
49 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
49
50
50 $ echo "delay=0" >> $HGRCPATH
51 $ echo "delay=0" >> $HGRCPATH
51 $ echo "refresh=0" >> $HGRCPATH
52 $ echo "refresh=0" >> $HGRCPATH
52
53
53 test with delay=0, refresh=0
54 test with delay=0, refresh=0
54
55
55 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
56 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
56
57
57 loop [ ] 0/3
58 loop [ ] 0/3
58 loop [===============> ] 1/3
59 loop [===============> ] 1/3
59 loop [===============================> ] 2/3
60 loop [===============================> ] 2/3
60 \r (esc)
61 \r (esc)
61
62
62
63
63 test nested short-lived topics (which shouldn't display with nestdelay):
64 test nested short-lived topics (which shouldn't display with nestdelay):
64
65
65 $ hg -y loop 3 --nested 2>&1 | \
66 $ hg -y loop 3 --nested 2>&1 | \
66 > python $TESTDIR/filtercr.py
67 > python $TESTDIR/filtercr.py
67
68
68 loop [ ] 0/3
69 loop [ ] 0/3
69 loop [===============> ] 1/3
70 loop [===============> ] 1/3
70 loop [===============================> ] 2/3
71 loop [===============================> ] 2/3
71 \r (esc)
72 \r (esc)
72
73
73
74
74 $ hg --config progress.changedelay=0 -y loop 3 --nested 2>&1 | \
75 $ hg --config progress.changedelay=0 -y loop 3 --nested 2>&1 | \
75 > python $TESTDIR/filtercr.py
76 > python $TESTDIR/filtercr.py
76
77
77 loop [ ] 0/3
78 loop [ ] 0/3
78 nested [ ] 0/2
79 nested [ ] 0/2
79 nested [======================> ] 1/2
80 nested [======================> ] 1/2
80 loop [===============> ] 1/3
81 loop [===============> ] 1/3
81 nested [ ] 0/2
82 nested [ ] 0/2
82 nested [======================> ] 1/2
83 nested [======================> ] 1/2
83 loop [===============================> ] 2/3
84 loop [===============================> ] 2/3
84 nested [ ] 0/2
85 nested [ ] 0/2
85 nested [======================> ] 1/2
86 nested [======================> ] 1/2
86 \r (esc)
87 \r (esc)
87
88
88
89
89 test two topics being printed in parallel (as when we're doing a local
90 test two topics being printed in parallel (as when we're doing a local
90 --pull clone, where you get the unbundle and bundle progress at the
91 --pull clone, where you get the unbundle and bundle progress at the
91 same time):
92 same time):
92 $ hg loop 3 --parallel 2>&1 | python $TESTDIR/filtercr.py
93 $ hg loop 3 --parallel 2>&1 | python $TESTDIR/filtercr.py
93
94
94 loop [ ] 0/3
95 loop [ ] 0/3
95 loop [===============> ] 1/3
96 loop [===============> ] 1/3
96 loop [===============================> ] 2/3
97 loop [===============================> ] 2/3
97 \r (esc)
98 \r (esc)
98 test refresh is taken in account
99 test refresh is taken in account
99
100
100 $ hg -y --config progress.refresh=100 loop 3 2>&1 | $TESTDIR/filtercr.py
101 $ hg -y --config progress.refresh=100 loop 3 2>&1 | $TESTDIR/filtercr.py
101
102
102
103
103 test format options 1
104 test format options 1
104
105
105 $ hg -y --config 'progress.format=number topic item+2' loop 2 2>&1 \
106 $ hg -y --config 'progress.format=number topic item+2' loop 2 2>&1 \
106 > | $TESTDIR/filtercr.py
107 > | $TESTDIR/filtercr.py
107
108
108 0/2 loop lo
109 0/2 loop lo
109 1/2 loop lo
110 1/2 loop lo
110 \r (esc)
111 \r (esc)
111
112
112 test format options 2
113 test format options 2
113
114
114 $ hg -y --config 'progress.format=number item-3 bar' loop 2 2>&1 \
115 $ hg -y --config 'progress.format=number item-3 bar' loop 2 2>&1 \
115 > | $TESTDIR/filtercr.py
116 > | $TESTDIR/filtercr.py
116
117
117 0/2 p.0 [ ]
118 0/2 p.0 [ ]
118 1/2 p.1 [=======================> ]
119 1/2 p.1 [=======================> ]
119 \r (esc)
120 \r (esc)
120
121
121 test format options and indeterminate progress
122 test format options and indeterminate progress
122
123
123 $ hg -y --config 'progress.format=number item bar' loop -- -2 2>&1 \
124 $ hg -y --config 'progress.format=number item bar' loop -- -2 2>&1 \
124 > | $TESTDIR/filtercr.py
125 > | $TESTDIR/filtercr.py
125
126
126 0 loop.0 [ <=> ]
127 0 loop.0 [ <=> ]
127 1 loop.1 [ <=> ]
128 1 loop.1 [ <=> ]
128 \r (esc)
129 \r (esc)
129
130
130 make sure things don't fall over if count > total
131 make sure things don't fall over if count > total
131
132
132 $ hg -y loop --total 4 6 2>&1 | $TESTDIR/filtercr.py
133 $ hg -y loop --total 4 6 2>&1 | $TESTDIR/filtercr.py
133
134
134 loop [ ] 0/4
135 loop [ ] 0/4
135 loop [===========> ] 1/4
136 loop [===========> ] 1/4
136 loop [=======================> ] 2/4
137 loop [=======================> ] 2/4
137 loop [===================================> ] 3/4
138 loop [===================================> ] 3/4
138 loop [===============================================>] 4/4
139 loop [===============================================>] 4/4
139 loop [ <=> ] 5/4
140 loop [ <=> ] 5/4
140 \r (esc)
141 \r (esc)
141
142
142 test immediate progress completion
143 test immediate progress completion
143
144
144 $ hg -y loop 0 2>&1 | $TESTDIR/filtercr.py
145 $ hg -y loop 0 2>&1 | $TESTDIR/filtercr.py
145
146
146
147
147 test delay time estimates
148 test delay time estimates
148
149
149 $ cat > mocktime.py <<EOF
150 $ cat > mocktime.py <<EOF
150 > import os
151 > import os
151 > import time
152 > import time
152 >
153 >
153 > class mocktime(object):
154 > class mocktime(object):
154 > def __init__(self, increment):
155 > def __init__(self, increment):
155 > self.time = 0
156 > self.time = 0
156 > self.increment = increment
157 > self.increment = increment
157 > def __call__(self):
158 > def __call__(self):
158 > self.time += self.increment
159 > self.time += self.increment
159 > return self.time
160 > return self.time
160 >
161 >
161 > def uisetup(ui):
162 > def uisetup(ui):
162 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
163 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
163 > EOF
164 > EOF
164
165
165 $ echo "[extensions]" > $HGRCPATH
166 $ cp $HGRCPATH.orig $HGRCPATH
167 $ echo "[extensions]" >> $HGRCPATH
166 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
168 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
167 $ echo "progress=" >> $HGRCPATH
169 $ echo "progress=" >> $HGRCPATH
168 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
170 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
169 $ echo "[progress]" >> $HGRCPATH
171 $ echo "[progress]" >> $HGRCPATH
170 $ echo "assume-tty=1" >> $HGRCPATH
172 $ echo "assume-tty=1" >> $HGRCPATH
171 $ echo "delay=25" >> $HGRCPATH
173 $ echo "delay=25" >> $HGRCPATH
172 $ echo "width=60" >> $HGRCPATH
174 $ echo "width=60" >> $HGRCPATH
173
175
174 $ hg -y loop 8 2>&1 | python $TESTDIR/filtercr.py
176 $ hg -y loop 8 2>&1 | python $TESTDIR/filtercr.py
175
177
176 loop [=========> ] 2/8 1m07s
178 loop [=========> ] 2/8 1m07s
177 loop [===============> ] 3/8 56s
179 loop [===============> ] 3/8 56s
178 loop [=====================> ] 4/8 45s
180 loop [=====================> ] 4/8 45s
179 loop [==========================> ] 5/8 34s
181 loop [==========================> ] 5/8 34s
180 loop [================================> ] 6/8 23s
182 loop [================================> ] 6/8 23s
181 loop [=====================================> ] 7/8 12s
183 loop [=====================================> ] 7/8 12s
182 \r (esc)
184 \r (esc)
183
185
184 $ MOCKTIME=10000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
186 $ MOCKTIME=10000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
185
187
186 loop [ ] 0/4
188 loop [ ] 0/4
187 loop [=========> ] 1/4 8h21m
189 loop [=========> ] 1/4 8h21m
188 loop [====================> ] 2/4 5h34m
190 loop [====================> ] 2/4 5h34m
189 loop [==============================> ] 3/4 2h47m
191 loop [==============================> ] 3/4 2h47m
190 \r (esc)
192 \r (esc)
191
193
192 $ MOCKTIME=1000000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
194 $ MOCKTIME=1000000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
193
195
194 loop [ ] 0/4
196 loop [ ] 0/4
195 loop [=========> ] 1/4 5w00d
197 loop [=========> ] 1/4 5w00d
196 loop [====================> ] 2/4 3w03d
198 loop [====================> ] 2/4 3w03d
197 loop [=============================> ] 3/4 11d14h
199 loop [=============================> ] 3/4 11d14h
198 \r (esc)
200 \r (esc)
199
201
200
202
201 $ MOCKTIME=14000000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
203 $ MOCKTIME=14000000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
202
204
203 loop [ ] 0/4
205 loop [ ] 0/4
204 loop [=========> ] 1/4 1y18w
206 loop [=========> ] 1/4 1y18w
205 loop [===================> ] 2/4 46w03d
207 loop [===================> ] 2/4 46w03d
206 loop [=============================> ] 3/4 23w02d
208 loop [=============================> ] 3/4 23w02d
207 \r (esc)
209 \r (esc)
208
210
209 Time estimates should not fail when there's no end point:
211 Time estimates should not fail when there's no end point:
210 $ hg -y loop -- -4 2>&1 | python $TESTDIR/filtercr.py
212 $ hg -y loop -- -4 2>&1 | python $TESTDIR/filtercr.py
211
213
212 loop [ <=> ] 2
214 loop [ <=> ] 2
213 loop [ <=> ] 3
215 loop [ <=> ] 3
214 \r (esc)
216 \r (esc)
@@ -1,585 +1,585 b''
1 $ "$TESTDIR/hghave" svn15 || exit 80
1 $ "$TESTDIR/hghave" svn15 || exit 80
2
2
3 $ fix_path()
3 $ fix_path()
4 > {
4 > {
5 > tr '\\' /
5 > tr '\\' /
6 > }
6 > }
7
7
8 SVN wants all paths to start with a slash. Unfortunately, Windows ones
8 SVN wants all paths to start with a slash. Unfortunately, Windows ones
9 don't. Handle that.
9 don't. Handle that.
10
10
11 $ escapedwd=`pwd | fix_path`
11 $ escapedwd=`pwd | fix_path`
12 $ expr "$escapedwd" : '\/' > /dev/null || escapedwd="/$escapedwd"
12 $ expr "$escapedwd" : '\/' > /dev/null || escapedwd="/$escapedwd"
13 $ escapedwd=`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$escapedwd"`
13 $ escapedwd=`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$escapedwd"`
14
14
15 create subversion repo
15 create subversion repo
16
16
17 $ SVNREPO="file://$escapedwd/svn-repo"
17 $ SVNREPO="file://$escapedwd/svn-repo"
18 $ WCROOT="`pwd`/svn-wc"
18 $ WCROOT="`pwd`/svn-wc"
19 $ svnadmin create svn-repo
19 $ svnadmin create svn-repo
20 $ svn co "$SVNREPO" svn-wc
20 $ svn co "$SVNREPO" svn-wc
21 Checked out revision 0.
21 Checked out revision 0.
22 $ cd svn-wc
22 $ cd svn-wc
23 $ mkdir src
23 $ mkdir src
24 $ echo alpha > src/alpha
24 $ echo alpha > src/alpha
25 $ svn add src
25 $ svn add src
26 A src
26 A src
27 A src/alpha
27 A src/alpha
28 $ mkdir externals
28 $ mkdir externals
29 $ echo other > externals/other
29 $ echo other > externals/other
30 $ svn add externals
30 $ svn add externals
31 A externals
31 A externals
32 A externals/other
32 A externals/other
33 $ svn ci -m 'Add alpha'
33 $ svn ci -m 'Add alpha'
34 Adding externals
34 Adding externals
35 Adding externals/other
35 Adding externals/other
36 Adding src
36 Adding src
37 Adding src/alpha
37 Adding src/alpha
38 Transmitting file data ..
38 Transmitting file data ..
39 Committed revision 1.
39 Committed revision 1.
40 $ svn up
40 $ svn up
41 At revision 1.
41 At revision 1.
42 $ echo "externals -r1 $SVNREPO/externals" > extdef
42 $ echo "externals -r1 $SVNREPO/externals" > extdef
43 $ svn propset -F extdef svn:externals src
43 $ svn propset -F extdef svn:externals src
44 property 'svn:externals' set on 'src'
44 property 'svn:externals' set on 'src'
45 $ svn ci -m 'Setting externals'
45 $ svn ci -m 'Setting externals'
46 Sending src
46 Sending src
47
47
48 Committed revision 2.
48 Committed revision 2.
49 $ cd ..
49 $ cd ..
50
50
51 create hg repo
51 create hg repo
52
52
53 $ mkdir sub
53 $ mkdir sub
54 $ cd sub
54 $ cd sub
55 $ hg init t
55 $ hg init t
56 $ cd t
56 $ cd t
57
57
58 first revision, no sub
58 first revision, no sub
59
59
60 $ echo a > a
60 $ echo a > a
61 $ hg ci -Am0
61 $ hg ci -Am0
62 adding a
62 adding a
63
63
64 add first svn sub with leading whitespaces
64 add first svn sub with leading whitespaces
65
65
66 $ echo "s = [svn] $SVNREPO/src" >> .hgsub
66 $ echo "s = [svn] $SVNREPO/src" >> .hgsub
67 $ echo "subdir/s = [svn] $SVNREPO/src" >> .hgsub
67 $ echo "subdir/s = [svn] $SVNREPO/src" >> .hgsub
68 $ svn co --quiet "$SVNREPO"/src s
68 $ svn co --quiet "$SVNREPO"/src s
69 $ mkdir subdir
69 $ mkdir subdir
70 $ svn co --quiet "$SVNREPO"/src subdir/s
70 $ svn co --quiet "$SVNREPO"/src subdir/s
71 $ hg add .hgsub
71 $ hg add .hgsub
72 $ hg ci -m1
72 $ hg ci -m1
73 committing subrepository s
73 committing subrepository s
74 committing subrepository subdir/s
74 committing subrepository subdir/s
75
75
76 make sure we avoid empty commits (issue2445)
76 make sure we avoid empty commits (issue2445)
77
77
78 $ hg sum
78 $ hg sum
79 parent: 1:* tip (glob)
79 parent: 1:* tip (glob)
80 1
80 1
81 branch: default
81 branch: default
82 commit: (clean)
82 commit: (clean)
83 update: (current)
83 update: (current)
84 $ hg ci -moops
84 $ hg ci -moops
85 nothing changed
85 nothing changed
86 [1]
86 [1]
87
87
88 debugsub
88 debugsub
89
89
90 $ hg debugsub
90 $ hg debugsub
91 path s
91 path s
92 source file://*/svn-repo/src (glob)
92 source file://*/svn-repo/src (glob)
93 revision 2
93 revision 2
94 path subdir/s
94 path subdir/s
95 source file://*/svn-repo/src (glob)
95 source file://*/svn-repo/src (glob)
96 revision 2
96 revision 2
97
97
98 change file in svn and hg, commit
98 change file in svn and hg, commit
99
99
100 $ echo a >> a
100 $ echo a >> a
101 $ echo alpha >> s/alpha
101 $ echo alpha >> s/alpha
102 $ hg sum
102 $ hg sum
103 parent: 1:* tip (glob)
103 parent: 1:* tip (glob)
104 1
104 1
105 branch: default
105 branch: default
106 commit: 1 modified, 1 subrepos
106 commit: 1 modified, 1 subrepos
107 update: (current)
107 update: (current)
108 $ hg commit --subrepos -m 'Message!'
108 $ hg commit --subrepos -m 'Message!'
109 committing subrepository s
109 committing subrepository s
110 Sending*s/alpha (glob)
110 Sending*s/alpha (glob)
111 Transmitting file data .
111 Transmitting file data .
112 Committed revision 3.
112 Committed revision 3.
113
113
114 Fetching external item into '$TESTTMP/sub/t/s/externals'
114 Fetching external item into '$TESTTMP/sub/t/s/externals'
115 External at revision 1.
115 External at revision 1.
116
116
117 At revision 3.
117 At revision 3.
118 $ hg debugsub
118 $ hg debugsub
119 path s
119 path s
120 source file://*/svn-repo/src (glob)
120 source file://*/svn-repo/src (glob)
121 revision 3
121 revision 3
122 path subdir/s
122 path subdir/s
123 source file://*/svn-repo/src (glob)
123 source file://*/svn-repo/src (glob)
124 revision 2
124 revision 2
125
125
126 add an unrelated revision in svn and update the subrepo to without
126 add an unrelated revision in svn and update the subrepo to without
127 bringing any changes.
127 bringing any changes.
128
128
129 $ svn mkdir "$SVNREPO/unrelated" -m 'create unrelated'
129 $ svn mkdir "$SVNREPO/unrelated" -m 'create unrelated'
130
130
131 Committed revision 4.
131 Committed revision 4.
132 $ svn up s
132 $ svn up s
133
133
134 Fetching external item into 's/externals'
134 Fetching external item into 's/externals'
135 External at revision 1.
135 External at revision 1.
136
136
137 At revision 4.
137 At revision 4.
138 $ hg sum
138 $ hg sum
139 parent: 2:* tip (glob)
139 parent: 2:* tip (glob)
140 Message!
140 Message!
141 branch: default
141 branch: default
142 commit: (clean)
142 commit: (clean)
143 update: (current)
143 update: (current)
144
144
145 $ echo a > s/a
145 $ echo a > s/a
146
146
147 should be empty despite change to s/a
147 should be empty despite change to s/a
148
148
149 $ hg st
149 $ hg st
150
150
151 add a commit from svn
151 add a commit from svn
152
152
153 $ cd "$WCROOT"/src
153 $ cd "$WCROOT"/src
154 $ svn up
154 $ svn up
155 U alpha
155 U alpha
156
156
157 Fetching external item into 'externals'
157 Fetching external item into 'externals'
158 A externals/other
158 A externals/other
159 Updated external to revision 1.
159 Updated external to revision 1.
160
160
161 Updated to revision 4.
161 Updated to revision 4.
162 $ echo xyz >> alpha
162 $ echo xyz >> alpha
163 $ svn propset svn:mime-type 'text/xml' alpha
163 $ svn propset svn:mime-type 'text/xml' alpha
164 property 'svn:mime-type' set on 'alpha'
164 property 'svn:mime-type' set on 'alpha'
165 $ svn ci -m 'amend a from svn'
165 $ svn ci -m 'amend a from svn'
166 Sending src/alpha
166 Sending src/alpha
167 Transmitting file data .
167 Transmitting file data .
168 Committed revision 5.
168 Committed revision 5.
169 $ cd ../../sub/t
169 $ cd ../../sub/t
170
170
171 this commit from hg will fail
171 this commit from hg will fail
172
172
173 $ echo zzz >> s/alpha
173 $ echo zzz >> s/alpha
174 $ hg ci --subrepos -m 'amend alpha from hg'
174 $ hg ci --subrepos -m 'amend alpha from hg'
175 committing subrepository s
175 committing subrepository s
176 abort: svn: Commit failed (details follow):
176 abort: svn: Commit failed (details follow):
177 svn: (Out of date)?.*/src/alpha.*(is out of date)? (re)
177 svn: (Out of date)?.*/src/alpha.*(is out of date)? (re)
178 [255]
178 [255]
179 $ svn revert -q s/alpha
179 $ svn revert -q s/alpha
180
180
181 this commit fails because of meta changes
181 this commit fails because of meta changes
182
182
183 $ svn propset svn:mime-type 'text/html' s/alpha
183 $ svn propset svn:mime-type 'text/html' s/alpha
184 property 'svn:mime-type' set on 's/alpha'
184 property 'svn:mime-type' set on 's/alpha'
185 $ hg ci --subrepos -m 'amend alpha from hg'
185 $ hg ci --subrepos -m 'amend alpha from hg'
186 committing subrepository s
186 committing subrepository s
187 abort: svn: Commit failed (details follow):
187 abort: svn: Commit failed (details follow):
188 svn: (Out of date)?.*/src/alpha.*(is out of date)? (re)
188 svn: (Out of date)?.*/src/alpha.*(is out of date)? (re)
189 [255]
189 [255]
190 $ svn revert -q s/alpha
190 $ svn revert -q s/alpha
191
191
192 this commit fails because of externals changes
192 this commit fails because of externals changes
193
193
194 $ echo zzz > s/externals/other
194 $ echo zzz > s/externals/other
195 $ hg ci --subrepos -m 'amend externals from hg'
195 $ hg ci --subrepos -m 'amend externals from hg'
196 committing subrepository s
196 committing subrepository s
197 abort: cannot commit svn externals
197 abort: cannot commit svn externals
198 [255]
198 [255]
199 $ hg diff --subrepos -r 1:2 | grep -v diff
199 $ hg diff --subrepos -r 1:2 | grep -v diff
200 --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
200 --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
201 +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
201 +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
202 @@ -1,2 +1,2 @@
202 @@ -1,2 +1,2 @@
203 -2 s
203 -2 s
204 +3 s
204 +3 s
205 2 subdir/s
205 2 subdir/s
206 --- a/a Thu Jan 01 00:00:00 1970 +0000
206 --- a/a Thu Jan 01 00:00:00 1970 +0000
207 +++ b/a Thu Jan 01 00:00:00 1970 +0000
207 +++ b/a Thu Jan 01 00:00:00 1970 +0000
208 @@ -1,1 +1,2 @@
208 @@ -1,1 +1,2 @@
209 a
209 a
210 +a
210 +a
211 $ svn revert -q s/externals/other
211 $ svn revert -q s/externals/other
212
212
213 this commit fails because of externals meta changes
213 this commit fails because of externals meta changes
214
214
215 $ svn propset svn:mime-type 'text/html' s/externals/other
215 $ svn propset svn:mime-type 'text/html' s/externals/other
216 property 'svn:mime-type' set on 's/externals/other'
216 property 'svn:mime-type' set on 's/externals/other'
217 $ hg ci --subrepos -m 'amend externals from hg'
217 $ hg ci --subrepos -m 'amend externals from hg'
218 committing subrepository s
218 committing subrepository s
219 abort: cannot commit svn externals
219 abort: cannot commit svn externals
220 [255]
220 [255]
221 $ svn revert -q s/externals/other
221 $ svn revert -q s/externals/other
222
222
223 clone
223 clone
224
224
225 $ cd ..
225 $ cd ..
226 $ hg clone t tc | fix_path
226 $ hg clone t tc | fix_path
227 updating to branch default
227 updating to branch default
228 A tc/s/alpha
228 A tc/s/alpha
229 U tc/s
229 U tc/s
230
230
231 Fetching external item into 'tc/s/externals'
231 Fetching external item into 'tc/s/externals'
232 A tc/s/externals/other
232 A tc/s/externals/other
233 Checked out external at revision 1.
233 Checked out external at revision 1.
234
234
235 Checked out revision 3.
235 Checked out revision 3.
236 A tc/subdir/s/alpha
236 A tc/subdir/s/alpha
237 U tc/subdir/s
237 U tc/subdir/s
238
238
239 Fetching external item into 'tc/subdir/s/externals'
239 Fetching external item into 'tc/subdir/s/externals'
240 A tc/subdir/s/externals/other
240 A tc/subdir/s/externals/other
241 Checked out external at revision 1.
241 Checked out external at revision 1.
242
242
243 Checked out revision 2.
243 Checked out revision 2.
244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 $ cd tc
245 $ cd tc
246
246
247 debugsub in clone
247 debugsub in clone
248
248
249 $ hg debugsub
249 $ hg debugsub
250 path s
250 path s
251 source file://*/svn-repo/src (glob)
251 source file://*/svn-repo/src (glob)
252 revision 3
252 revision 3
253 path subdir/s
253 path subdir/s
254 source file://*/svn-repo/src (glob)
254 source file://*/svn-repo/src (glob)
255 revision 2
255 revision 2
256
256
257 verify subrepo is contained within the repo directory
257 verify subrepo is contained within the repo directory
258
258
259 $ python -c "import os.path; print os.path.exists('s')"
259 $ python -c "import os.path; print os.path.exists('s')"
260 True
260 True
261
261
262 update to nullrev (must delete the subrepo)
262 update to nullrev (must delete the subrepo)
263
263
264 $ hg up null
264 $ hg up null
265 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
265 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
266 $ ls
266 $ ls
267
267
268 Check hg update --clean
268 Check hg update --clean
269 $ cd $TESTTMP/sub/t
269 $ cd $TESTTMP/sub/t
270 $ cd s
270 $ cd s
271 $ echo c0 > alpha
271 $ echo c0 > alpha
272 $ echo c1 > f1
272 $ echo c1 > f1
273 $ echo c1 > f2
273 $ echo c1 > f2
274 $ svn add f1 -q
274 $ svn add f1 -q
275 $ svn status
275 $ svn status
276 ? * a (glob)
276 ? * a (glob)
277 X * externals (glob)
277 X * externals (glob)
278 ? * f2 (glob)
278 ? * f2 (glob)
279 M * alpha (glob)
279 M * alpha (glob)
280 A * f1 (glob)
280 A * f1 (glob)
281
281
282 Performing status on external item at 'externals'
282 Performing status on external item at 'externals'
283 $ cd ../..
283 $ cd ../..
284 $ hg -R t update -C
284 $ hg -R t update -C
285
285
286 Fetching external item into 't/s/externals'
286 Fetching external item into 't/s/externals'
287 Checked out external at revision 1.
287 Checked out external at revision 1.
288
288
289 Checked out revision 3.
289 Checked out revision 3.
290 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 $ cd t/s
291 $ cd t/s
292 $ svn status
292 $ svn status
293 ? * a (glob)
293 ? * a (glob)
294 X * externals (glob)
294 X * externals (glob)
295 ? * f1 (glob)
295 ? * f1 (glob)
296 ? * f2 (glob)
296 ? * f2 (glob)
297
297
298 Performing status on external item at 'externals'
298 Performing status on external item at 'externals'
299
299
300 Sticky subrepositories, no changes
300 Sticky subrepositories, no changes
301 $ cd $TESTTMP/sub/t
301 $ cd $TESTTMP/sub/t
302 $ hg id -n
302 $ hg id -n
303 2
303 2
304 $ cd s
304 $ cd s
305 $ svnversion
305 $ svnversion
306 3
306 3
307 $ cd ..
307 $ cd ..
308 $ hg update 1
308 $ hg update 1
309 U $TESTTMP/sub/t/s/alpha
309 U $TESTTMP/sub/t/s/alpha
310
310
311 Fetching external item into '$TESTTMP/sub/t/s/externals'
311 Fetching external item into '$TESTTMP/sub/t/s/externals'
312 Checked out external at revision 1.
312 Checked out external at revision 1.
313
313
314 Checked out revision 2.
314 Checked out revision 2.
315 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 $ hg id -n
316 $ hg id -n
317 1
317 1
318 $ cd s
318 $ cd s
319 $ svnversion
319 $ svnversion
320 2
320 2
321 $ cd ..
321 $ cd ..
322
322
323 Sticky subrepositorys, file changes
323 Sticky subrepositorys, file changes
324 $ touch s/f1
324 $ touch s/f1
325 $ cd s
325 $ cd s
326 $ svn add f1
326 $ svn add f1
327 A f1
327 A f1
328 $ cd ..
328 $ cd ..
329 $ hg id -n
329 $ hg id -n
330 1
330 1
331 $ cd s
331 $ cd s
332 $ svnversion
332 $ svnversion
333 2M
333 2M
334 $ cd ..
334 $ cd ..
335 $ hg update tip
335 $ hg update tip
336 subrepository sources for s differ
336 subrepository sources for s differ
337 use (l)ocal source (2) or (r)emote source (3)?
337 use (l)ocal source (2) or (r)emote source (3)?
338 l
338 l
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 $ hg id -n
340 $ hg id -n
341 2+
341 2+
342 $ cd s
342 $ cd s
343 $ svnversion
343 $ svnversion
344 2M
344 2M
345 $ cd ..
345 $ cd ..
346 $ hg update --clean tip
346 $ hg update --clean tip
347 U $TESTTMP/sub/t/s/alpha
347 U $TESTTMP/sub/t/s/alpha
348
348
349 Fetching external item into '$TESTTMP/sub/t/s/externals'
349 Fetching external item into '$TESTTMP/sub/t/s/externals'
350 Checked out external at revision 1.
350 Checked out external at revision 1.
351
351
352 Checked out revision 3.
352 Checked out revision 3.
353 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
353 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
354
354
355 Sticky subrepository, revision updates
355 Sticky subrepository, revision updates
356 $ hg id -n
356 $ hg id -n
357 2
357 2
358 $ cd s
358 $ cd s
359 $ svnversion
359 $ svnversion
360 3
360 3
361 $ cd ..
361 $ cd ..
362 $ cd s
362 $ cd s
363 $ svn update -r 1
363 $ svn update -r 1
364 U alpha
364 U alpha
365 U .
365 U .
366
366
367 Fetching external item into 'externals'
367 Fetching external item into 'externals'
368 Updated external to revision 1.
368 Updated external to revision 1.
369
369
370 Updated to revision 1.
370 Updated to revision 1.
371 $ cd ..
371 $ cd ..
372 $ hg update 1
372 $ hg update 1
373 subrepository sources for s differ (in checked out version)
373 subrepository sources for s differ (in checked out version)
374 use (l)ocal source (1) or (r)emote source (2)?
374 use (l)ocal source (1) or (r)emote source (2)?
375 l
375 l
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 $ hg id -n
377 $ hg id -n
378 1+
378 1+
379 $ cd s
379 $ cd s
380 $ svnversion
380 $ svnversion
381 1
381 1
382 $ cd ..
382 $ cd ..
383
383
384 Sticky subrepository, file changes and revision updates
384 Sticky subrepository, file changes and revision updates
385 $ touch s/f1
385 $ touch s/f1
386 $ cd s
386 $ cd s
387 $ svn add f1
387 $ svn add f1
388 A f1
388 A f1
389 $ svnversion
389 $ svnversion
390 1M
390 1M
391 $ cd ..
391 $ cd ..
392 $ hg id -n
392 $ hg id -n
393 1+
393 1+
394 $ hg update tip
394 $ hg update tip
395 subrepository sources for s differ
395 subrepository sources for s differ
396 use (l)ocal source (1) or (r)emote source (3)?
396 use (l)ocal source (1) or (r)emote source (3)?
397 l
397 l
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 $ hg id -n
399 $ hg id -n
400 2
400 2
401 $ cd s
401 $ cd s
402 $ svnversion
402 $ svnversion
403 1M
403 1M
404 $ cd ..
404 $ cd ..
405
405
406 Sticky repository, update --clean
406 Sticky repository, update --clean
407 $ hg update --clean tip
407 $ hg update --clean tip
408 U $TESTTMP/sub/t/s/alpha
408 U $TESTTMP/sub/t/s/alpha
409 U $TESTTMP/sub/t/s
409 U $TESTTMP/sub/t/s
410
410
411 Fetching external item into '$TESTTMP/sub/t/s/externals'
411 Fetching external item into '$TESTTMP/sub/t/s/externals'
412 Checked out external at revision 1.
412 Checked out external at revision 1.
413
413
414 Checked out revision 3.
414 Checked out revision 3.
415 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
415 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
416 $ hg id -n
416 $ hg id -n
417 2
417 2
418 $ cd s
418 $ cd s
419 $ svnversion
419 $ svnversion
420 3
420 3
421 $ cd ..
421 $ cd ..
422
422
423 Test subrepo already at intended revision:
423 Test subrepo already at intended revision:
424 $ cd s
424 $ cd s
425 $ svn update -r 2
425 $ svn update -r 2
426 U alpha
426 U alpha
427
427
428 Fetching external item into 'externals'
428 Fetching external item into 'externals'
429 Updated external to revision 1.
429 Updated external to revision 1.
430
430
431 Updated to revision 2.
431 Updated to revision 2.
432 $ cd ..
432 $ cd ..
433 $ hg update 1
433 $ hg update 1
434 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
434 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 $ hg id -n
435 $ hg id -n
436 1+
436 1+
437 $ cd s
437 $ cd s
438 $ svnversion
438 $ svnversion
439 2
439 2
440 $ cd ..
440 $ cd ..
441
441
442 Test case where subversion would fail to update the subrepo because there
442 Test case where subversion would fail to update the subrepo because there
443 are unknown directories being replaced by tracked ones (happens with rebase).
443 are unknown directories being replaced by tracked ones (happens with rebase).
444
444
445 $ cd $WCROOT/src
445 $ cd $WCROOT/src
446 $ mkdir dir
446 $ mkdir dir
447 $ echo epsilon.py > dir/epsilon.py
447 $ echo epsilon.py > dir/epsilon.py
448 $ svn add dir
448 $ svn add dir
449 A dir
449 A dir
450 A dir/epsilon.py
450 A dir/epsilon.py
451 $ svn ci -m 'Add dir/epsilon.py'
451 $ svn ci -m 'Add dir/epsilon.py'
452 Adding src/dir
452 Adding src/dir
453 Adding src/dir/epsilon.py
453 Adding src/dir/epsilon.py
454 Transmitting file data .
454 Transmitting file data .
455 Committed revision 6.
455 Committed revision 6.
456 $ cd ../..
456 $ cd ../..
457 $ hg init rebaserepo
457 $ hg init rebaserepo
458 $ cd rebaserepo
458 $ cd rebaserepo
459 $ svn co -r5 --quiet "$SVNREPO"/src s
459 $ svn co -r5 --quiet "$SVNREPO"/src s
460 $ echo "s = [svn] $SVNREPO/src" >> .hgsub
460 $ echo "s = [svn] $SVNREPO/src" >> .hgsub
461 $ hg add .hgsub
461 $ hg add .hgsub
462 $ hg ci -m addsub
462 $ hg ci -m addsub
463 committing subrepository s
463 committing subrepository s
464 $ echo a > a
464 $ echo a > a
465 $ hg ci -Am adda
465 $ hg ci -Am adda
466 adding a
466 adding a
467 $ hg up 0
467 $ hg up 0
468 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
468 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
469 $ svn up -r6 s
469 $ svn up -r6 s
470 A s/dir
470 A s/dir
471 A s/dir/epsilon.py
471 A s/dir/epsilon.py
472
472
473 Fetching external item into 's/externals'
473 Fetching external item into 's/externals'
474 Updated external to revision 1.
474 Updated external to revision 1.
475
475
476 Updated to revision 6.
476 Updated to revision 6.
477 $ hg ci -m updatesub
477 $ hg ci -m updatesub
478 committing subrepository s
478 committing subrepository s
479 created new head
479 created new head
480 $ echo pyc > s/dir/epsilon.pyc
480 $ echo pyc > s/dir/epsilon.pyc
481 $ hg up 1
481 $ hg up 1
482 D $TESTTMP/rebaserepo/s/dir
482 D $TESTTMP/rebaserepo/s/dir
483
483
484 Fetching external item into '$TESTTMP/rebaserepo/s/externals'
484 Fetching external item into '$TESTTMP/rebaserepo/s/externals'
485 Checked out external at revision 1.
485 Checked out external at revision 1.
486
486
487 Checked out revision 5.
487 Checked out revision 5.
488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 $ if "$TESTDIR/hghave" -q svn15; then
489 $ if "$TESTDIR/hghave" -q svn15; then
490 > hg up 2 >/dev/null 2>&1 || echo update failed
490 > hg up 2 >/dev/null 2>&1 || echo update failed
491 > fi
491 > fi
492
492
493 Modify one of the externals to point to a different path so we can
493 Modify one of the externals to point to a different path so we can
494 test having obstructions when switching branches on checkout:
494 test having obstructions when switching branches on checkout:
495 $ hg checkout tip
495 $ hg checkout tip
496 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
496 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
497 $ echo "obstruct = [svn] $SVNREPO/externals" >> .hgsub
497 $ echo "obstruct = [svn] $SVNREPO/externals" >> .hgsub
498 $ svn co -r5 --quiet "$SVNREPO"/externals obstruct
498 $ svn co -r5 --quiet "$SVNREPO"/externals obstruct
499 $ hg commit -m 'Start making obstructed wc'
499 $ hg commit -m 'Start making obstructed working copy'
500 committing subrepository obstruct
500 committing subrepository obstruct
501 $ hg book other
501 $ hg book other
502 $ hg co -r 'p1(tip)'
502 $ hg co -r 'p1(tip)'
503 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
503 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 $ echo "obstruct = [svn] $SVNREPO/src" >> .hgsub
504 $ echo "obstruct = [svn] $SVNREPO/src" >> .hgsub
505 $ svn co -r5 --quiet "$SVNREPO"/src obstruct
505 $ svn co -r5 --quiet "$SVNREPO"/src obstruct
506 $ hg commit -m 'Other branch which will be obstructed'
506 $ hg commit -m 'Other branch which will be obstructed'
507 committing subrepository obstruct
507 committing subrepository obstruct
508 created new head
508 created new head
509
509
510 Switching back to the head where we have another path mapped to the
510 Switching back to the head where we have another path mapped to the
511 same subrepo should work if the subrepo is clean.
511 same subrepo should work if the subrepo is clean.
512 $ hg co other
512 $ hg co other
513 A $TESTTMP/rebaserepo/obstruct/other
513 A $TESTTMP/rebaserepo/obstruct/other
514 Checked out revision 1.
514 Checked out revision 1.
515 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
515 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
516
516
517 This is surprising, but is also correct based on the current code:
517 This is surprising, but is also correct based on the current code:
518 $ echo "updating should (maybe) fail" > obstruct/other
518 $ echo "updating should (maybe) fail" > obstruct/other
519 $ hg co tip
519 $ hg co tip
520 abort: crosses branches (merge branches or use --clean to discard changes)
520 abort: crosses branches (merge branches or use --clean to discard changes)
521 [255]
521 [255]
522
522
523 Point to a Subversion branch which has since been deleted and recreated
523 Point to a Subversion branch which has since been deleted and recreated
524 First, create that condition in the repository.
524 First, create that condition in the repository.
525
525
526 $ hg ci --subrepos -m cleanup
526 $ hg ci --subrepos -m cleanup
527 committing subrepository obstruct
527 committing subrepository obstruct
528 Sending obstruct/other
528 Sending obstruct/other
529 Transmitting file data .
529 Transmitting file data .
530 Committed revision 7.
530 Committed revision 7.
531 At revision 7.
531 At revision 7.
532 $ svn mkdir -m "baseline" $SVNREPO/trunk
532 $ svn mkdir -m "baseline" $SVNREPO/trunk
533
533
534 Committed revision 8.
534 Committed revision 8.
535 $ svn copy -m "initial branch" $SVNREPO/trunk $SVNREPO/branch
535 $ svn copy -m "initial branch" $SVNREPO/trunk $SVNREPO/branch
536
536
537 Committed revision 9.
537 Committed revision 9.
538 $ svn co --quiet "$SVNREPO"/branch tempwc
538 $ svn co --quiet "$SVNREPO"/branch tempwc
539 $ cd tempwc
539 $ cd tempwc
540 $ echo "something old" > somethingold
540 $ echo "something old" > somethingold
541 $ svn add somethingold
541 $ svn add somethingold
542 A somethingold
542 A somethingold
543 $ svn ci -m 'Something old'
543 $ svn ci -m 'Something old'
544 Adding somethingold
544 Adding somethingold
545 Transmitting file data .
545 Transmitting file data .
546 Committed revision 10.
546 Committed revision 10.
547 $ svn rm -m "remove branch" $SVNREPO/branch
547 $ svn rm -m "remove branch" $SVNREPO/branch
548
548
549 Committed revision 11.
549 Committed revision 11.
550 $ svn copy -m "recreate branch" $SVNREPO/trunk $SVNREPO/branch
550 $ svn copy -m "recreate branch" $SVNREPO/trunk $SVNREPO/branch
551
551
552 Committed revision 12.
552 Committed revision 12.
553 $ svn up
553 $ svn up
554 D somethingold
554 D somethingold
555 Updated to revision 12.
555 Updated to revision 12.
556 $ echo "something new" > somethingnew
556 $ echo "something new" > somethingnew
557 $ svn add somethingnew
557 $ svn add somethingnew
558 A somethingnew
558 A somethingnew
559 $ svn ci -m 'Something new'
559 $ svn ci -m 'Something new'
560 Adding somethingnew
560 Adding somethingnew
561 Transmitting file data .
561 Transmitting file data .
562 Committed revision 13.
562 Committed revision 13.
563 $ cd ..
563 $ cd ..
564 $ rm -rf tempwc
564 $ rm -rf tempwc
565 $ svn co "$SVNREPO/branch"@10 recreated
565 $ svn co "$SVNREPO/branch"@10 recreated
566 A recreated/somethingold
566 A recreated/somethingold
567 Checked out revision 10.
567 Checked out revision 10.
568 $ echo "recreated = [svn] $SVNREPO/branch" >> .hgsub
568 $ echo "recreated = [svn] $SVNREPO/branch" >> .hgsub
569 $ hg ci -m addsub
569 $ hg ci -m addsub
570 committing subrepository recreated
570 committing subrepository recreated
571 $ cd recreated
571 $ cd recreated
572 $ svn up
572 $ svn up
573 D somethingold
573 D somethingold
574 A somethingnew
574 A somethingnew
575 Updated to revision 13.
575 Updated to revision 13.
576 $ cd ..
576 $ cd ..
577 $ hg ci -m updatesub
577 $ hg ci -m updatesub
578 committing subrepository recreated
578 committing subrepository recreated
579 $ hg up -r-2
579 $ hg up -r-2
580 D $TESTTMP/rebaserepo/recreated/somethingnew
580 D $TESTTMP/rebaserepo/recreated/somethingnew
581 A $TESTTMP/rebaserepo/recreated/somethingold
581 A $TESTTMP/rebaserepo/recreated/somethingold
582 Checked out revision 10.
582 Checked out revision 10.
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 $ test -f recreated/somethingold
584 $ test -f recreated/somethingold
585
585
General Comments 0
You need to be logged in to leave comments. Login now