##// END OF EJS Templates
tests: tighten checks for octal escapes in shell printf....
Jim Hague -
r16098:c6c9b83a stable
parent child Browse files
Show More
@@ -1,430 +1,430 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'^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'^diff.*-\w*N', "don't use 'diff -N'"),
52 (r'^diff.*-\w*N', "don't use 'diff -N'"),
53 (r'(^| )wc[^|]*$\n(?!.*\(re\))', "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'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
55 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
56 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
56 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
57 (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"),
57 (r'printf.*\\\d{1,3}', "don't use 'printf \NNN', use Python"),
58 (r'printf.*\\x', "don't use printf \\x, use Python"),
58 (r'printf.*\\x', "don't use printf \\x, use Python"),
59 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
59 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
60 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
60 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
61 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
61 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
62 "use egrep for extended grep syntax"),
62 "use egrep for extended grep syntax"),
63 (r'/bin/', "don't use explicit paths for tools"),
63 (r'/bin/', "don't use explicit paths for tools"),
64 (r'\$PWD', "don't use $PWD, use `pwd`"),
64 (r'\$PWD', "don't use $PWD, use `pwd`"),
65 (r'[^\n]\Z', "no trailing newline"),
65 (r'[^\n]\Z', "no trailing newline"),
66 (r'export.*=', "don't export and assign at once"),
66 (r'export.*=', "don't export and assign at once"),
67 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\\^', "^ must be quoted"),
67 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\\^', "^ must be quoted"),
68 (r'^source\b', "don't use 'source', use '.'"),
68 (r'^source\b', "don't use 'source', use '.'"),
69 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
69 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
70 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
70 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
71 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
71 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
72 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
72 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
73 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
73 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
74 (r'^alias\b.*=', "don't use alias, use a function"),
74 (r'^alias\b.*=', "don't use alias, use a function"),
75 ],
75 ],
76 # warnings
76 # warnings
77 []
77 []
78 ]
78 ]
79
79
80 testfilters = [
80 testfilters = [
81 (r"( *)(#([^\n]*\S)?)", repcomment),
81 (r"( *)(#([^\n]*\S)?)", repcomment),
82 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
82 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
83 ]
83 ]
84
84
85 uprefix = r"^ \$ "
85 uprefix = r"^ \$ "
86 uprefixc = r"^ > "
86 uprefixc = r"^ > "
87 utestpats = [
87 utestpats = [
88 [
88 [
89 (r'^(\S| $ ).*(\S[ \t]+|^[ \t]+)\n', "trailing whitespace on non-output"),
89 (r'^(\S| $ ).*(\S[ \t]+|^[ \t]+)\n', "trailing whitespace on non-output"),
90 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"),
90 (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"),
91 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
91 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
92 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
92 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
93 (uprefix + r'.*\|\| echo.*(fail|error)',
93 (uprefix + r'.*\|\| echo.*(fail|error)',
94 "explicit exit code checks unnecessary"),
94 "explicit exit code checks unnecessary"),
95 (uprefix + r'set -e', "don't use set -e"),
95 (uprefix + r'set -e', "don't use set -e"),
96 (uprefixc + r'( *)\t', "don't use tabs to indent"),
96 (uprefixc + r'( *)\t', "don't use tabs to indent"),
97 ],
97 ],
98 # warnings
98 # warnings
99 []
99 []
100 ]
100 ]
101
101
102 for i in [0, 1]:
102 for i in [0, 1]:
103 for p, m in testpats[i]:
103 for p, m in testpats[i]:
104 if p.startswith(r'^'):
104 if p.startswith(r'^'):
105 p = uprefix + p[1:]
105 p = uprefix + p[1:]
106 else:
106 else:
107 p = uprefix + ".*" + p
107 p = uprefix + ".*" + p
108 utestpats[i].append((p, m))
108 utestpats[i].append((p, m))
109
109
110 utestfilters = [
110 utestfilters = [
111 (r"( *)(#([^\n]*\S)?)", repcomment),
111 (r"( *)(#([^\n]*\S)?)", repcomment),
112 ]
112 ]
113
113
114 pypats = [
114 pypats = [
115 [
115 [
116 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
116 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
117 "tuple parameter unpacking not available in Python 3+"),
117 "tuple parameter unpacking not available in Python 3+"),
118 (r'lambda\s*\(.*,.*\)',
118 (r'lambda\s*\(.*,.*\)',
119 "tuple parameter unpacking not available in Python 3+"),
119 "tuple parameter unpacking not available in Python 3+"),
120 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
120 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
121 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
121 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
122 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
122 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
123 (r'^\s*\t', "don't use tabs"),
123 (r'^\s*\t', "don't use tabs"),
124 (r'\S;\s*\n', "semicolon"),
124 (r'\S;\s*\n', "semicolon"),
125 (r'\w,\w', "missing whitespace after ,"),
125 (r'\w,\w', "missing whitespace after ,"),
126 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
126 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
127 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
127 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
128 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
128 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
129 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Py2.4'),
129 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Py2.4'),
130 (r'.{85}', "line too long"),
130 (r'.{85}', "line too long"),
131 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
131 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
132 (r'[^\n]\Z', "no trailing newline"),
132 (r'[^\n]\Z', "no trailing newline"),
133 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
133 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
134 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"),
134 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"),
135 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
135 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
136 "don't use camelcase in identifiers"),
136 "don't use camelcase in identifiers"),
137 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
137 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
138 "linebreak after :"),
138 "linebreak after :"),
139 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
139 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
140 (r'class\s[^( \n]+\(\):',
140 (r'class\s[^( \n]+\(\):',
141 "class foo() not available in Python 2.4, use class foo(object)"),
141 "class foo() not available in Python 2.4, use class foo(object)"),
142 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
142 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
143 "Python keyword is not a function"),
143 "Python keyword is not a function"),
144 (r',]', "unneeded trailing ',' in list"),
144 (r',]', "unneeded trailing ',' in list"),
145 # (r'class\s[A-Z][^\(]*\((?!Exception)',
145 # (r'class\s[A-Z][^\(]*\((?!Exception)',
146 # "don't capitalize non-exception classes"),
146 # "don't capitalize non-exception classes"),
147 # (r'in range\(', "use xrange"),
147 # (r'in range\(', "use xrange"),
148 # (r'^\s*print\s+', "avoid using print in core and extensions"),
148 # (r'^\s*print\s+', "avoid using print in core and extensions"),
149 (r'[\x80-\xff]', "non-ASCII character literal"),
149 (r'[\x80-\xff]', "non-ASCII character literal"),
150 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
150 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
151 (r'^\s*with\s+', "with not available in Python 2.4"),
151 (r'^\s*with\s+', "with not available in Python 2.4"),
152 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
152 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
153 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
153 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
154 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
154 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
155 (r'(?<!def)\s+(any|all|format)\(',
155 (r'(?<!def)\s+(any|all|format)\(',
156 "any/all/format not available in Python 2.4"),
156 "any/all/format not available in Python 2.4"),
157 (r'(?<!def)\s+(callable)\(',
157 (r'(?<!def)\s+(callable)\(',
158 "callable not available in Python 3, use getattr(f, '__call__', None)"),
158 "callable not available in Python 3, use getattr(f, '__call__', None)"),
159 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
159 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
160 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
160 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
161 "gratuitous whitespace after Python keyword"),
161 "gratuitous whitespace after Python keyword"),
162 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
162 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
163 # (r'\s\s=', "gratuitous whitespace before ="),
163 # (r'\s\s=', "gratuitous whitespace before ="),
164 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
164 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
165 "missing whitespace around operator"),
165 "missing whitespace around operator"),
166 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s',
166 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\s',
167 "missing whitespace around operator"),
167 "missing whitespace around operator"),
168 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
168 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
169 "missing whitespace around operator"),
169 "missing whitespace around operator"),
170 (r'[^+=*/!<>&| -](\s=|=\s)[^= ]',
170 (r'[^+=*/!<>&| -](\s=|=\s)[^= ]',
171 "wrong whitespace around ="),
171 "wrong whitespace around ="),
172 (r'raise Exception', "don't raise generic exceptions"),
172 (r'raise Exception', "don't raise generic exceptions"),
173 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
173 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
174 (r' [=!]=\s+(True|False|None)',
174 (r' [=!]=\s+(True|False|None)',
175 "comparison with singleton, use 'is' or 'is not' instead"),
175 "comparison with singleton, use 'is' or 'is not' instead"),
176 (r'^\s*(while|if) [01]:',
176 (r'^\s*(while|if) [01]:',
177 "use True/False for constant Boolean expression"),
177 "use True/False for constant Boolean expression"),
178 (r'(?<!def)\s+hasattr',
178 (r'(?<!def)\s+hasattr',
179 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
179 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
180 (r'opener\([^)]*\).read\(',
180 (r'opener\([^)]*\).read\(',
181 "use opener.read() instead"),
181 "use opener.read() instead"),
182 (r'BaseException', 'not in Py2.4, use Exception'),
182 (r'BaseException', 'not in Py2.4, use Exception'),
183 (r'os\.path\.relpath', 'os.path.relpath is not in Py2.5'),
183 (r'os\.path\.relpath', 'os.path.relpath is not in Py2.5'),
184 (r'opener\([^)]*\).write\(',
184 (r'opener\([^)]*\).write\(',
185 "use opener.write() instead"),
185 "use opener.write() instead"),
186 (r'[\s\(](open|file)\([^)]*\)\.read\(',
186 (r'[\s\(](open|file)\([^)]*\)\.read\(',
187 "use util.readfile() instead"),
187 "use util.readfile() instead"),
188 (r'[\s\(](open|file)\([^)]*\)\.write\(',
188 (r'[\s\(](open|file)\([^)]*\)\.write\(',
189 "use util.readfile() instead"),
189 "use util.readfile() instead"),
190 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
190 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
191 "always assign an opened file to a variable, and close it afterwards"),
191 "always assign an opened file to a variable, and close it afterwards"),
192 (r'[\s\(](open|file)\([^)]*\)\.',
192 (r'[\s\(](open|file)\([^)]*\)\.',
193 "always assign an opened file to a variable, and close it afterwards"),
193 "always assign an opened file to a variable, and close it afterwards"),
194 (r'(?i)descendent', "the proper spelling is descendAnt"),
194 (r'(?i)descendent', "the proper spelling is descendAnt"),
195 (r'\.debug\(\_', "don't mark debug messages for translation"),
195 (r'\.debug\(\_', "don't mark debug messages for translation"),
196 ],
196 ],
197 # warnings
197 # warnings
198 [
198 [
199 (r'.{81}', "warning: line over 80 characters"),
199 (r'.{81}', "warning: line over 80 characters"),
200 (r'^\s*except:$', "warning: naked except clause"),
200 (r'^\s*except:$', "warning: naked except clause"),
201 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
201 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
202 "warning: unwrapped ui message"),
202 "warning: unwrapped ui message"),
203 ]
203 ]
204 ]
204 ]
205
205
206 pyfilters = [
206 pyfilters = [
207 (r"""(?msx)(?P<comment>\#.*?$)|
207 (r"""(?msx)(?P<comment>\#.*?$)|
208 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
208 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
209 (?P<text>(([^\\]|\\.)*?))
209 (?P<text>(([^\\]|\\.)*?))
210 (?P=quote))""", reppython),
210 (?P=quote))""", reppython),
211 ]
211 ]
212
212
213 cpats = [
213 cpats = [
214 [
214 [
215 (r'//', "don't use //-style comments"),
215 (r'//', "don't use //-style comments"),
216 (r'^ ', "don't use spaces to indent"),
216 (r'^ ', "don't use spaces to indent"),
217 (r'\S\t', "don't use tabs except for indent"),
217 (r'\S\t', "don't use tabs except for indent"),
218 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
218 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
219 (r'.{85}', "line too long"),
219 (r'.{85}', "line too long"),
220 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
220 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
221 (r'return\(', "return is not a function"),
221 (r'return\(', "return is not a function"),
222 (r' ;', "no space before ;"),
222 (r' ;', "no space before ;"),
223 (r'\w+\* \w+', "use int *foo, not int* foo"),
223 (r'\w+\* \w+', "use int *foo, not int* foo"),
224 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
224 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
225 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
225 (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
226 (r'\w,\w', "missing whitespace after ,"),
226 (r'\w,\w', "missing whitespace after ,"),
227 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
227 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
228 (r'^#\s+\w', "use #foo, not # foo"),
228 (r'^#\s+\w', "use #foo, not # foo"),
229 (r'[^\n]\Z', "no trailing newline"),
229 (r'[^\n]\Z', "no trailing newline"),
230 (r'^\s*#import\b', "use only #include in standard C code"),
230 (r'^\s*#import\b', "use only #include in standard C code"),
231 ],
231 ],
232 # warnings
232 # warnings
233 []
233 []
234 ]
234 ]
235
235
236 cfilters = [
236 cfilters = [
237 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
237 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
238 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
238 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
239 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
239 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
240 (r'(\()([^)]+\))', repcallspaces),
240 (r'(\()([^)]+\))', repcallspaces),
241 ]
241 ]
242
242
243 inutilpats = [
243 inutilpats = [
244 [
244 [
245 (r'\bui\.', "don't use ui in util"),
245 (r'\bui\.', "don't use ui in util"),
246 ],
246 ],
247 # warnings
247 # warnings
248 []
248 []
249 ]
249 ]
250
250
251 inrevlogpats = [
251 inrevlogpats = [
252 [
252 [
253 (r'\brepo\.', "don't use repo in revlog"),
253 (r'\brepo\.', "don't use repo in revlog"),
254 ],
254 ],
255 # warnings
255 # warnings
256 []
256 []
257 ]
257 ]
258
258
259 checks = [
259 checks = [
260 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
260 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
261 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
261 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
262 ('c', r'.*\.c$', cfilters, cpats),
262 ('c', r'.*\.c$', cfilters, cpats),
263 ('unified test', r'.*\.t$', utestfilters, utestpats),
263 ('unified test', r'.*\.t$', utestfilters, utestpats),
264 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
264 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
265 inrevlogpats),
265 inrevlogpats),
266 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
266 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
267 inutilpats),
267 inutilpats),
268 ]
268 ]
269
269
270 class norepeatlogger(object):
270 class norepeatlogger(object):
271 def __init__(self):
271 def __init__(self):
272 self._lastseen = None
272 self._lastseen = None
273
273
274 def log(self, fname, lineno, line, msg, blame):
274 def log(self, fname, lineno, line, msg, blame):
275 """print error related a to given line of a given file.
275 """print error related a to given line of a given file.
276
276
277 The faulty line will also be printed but only once in the case
277 The faulty line will also be printed but only once in the case
278 of multiple errors.
278 of multiple errors.
279
279
280 :fname: filename
280 :fname: filename
281 :lineno: line number
281 :lineno: line number
282 :line: actual content of the line
282 :line: actual content of the line
283 :msg: error message
283 :msg: error message
284 """
284 """
285 msgid = fname, lineno, line
285 msgid = fname, lineno, line
286 if msgid != self._lastseen:
286 if msgid != self._lastseen:
287 if blame:
287 if blame:
288 print "%s:%d (%s):" % (fname, lineno, blame)
288 print "%s:%d (%s):" % (fname, lineno, blame)
289 else:
289 else:
290 print "%s:%d:" % (fname, lineno)
290 print "%s:%d:" % (fname, lineno)
291 print " > %s" % line
291 print " > %s" % line
292 self._lastseen = msgid
292 self._lastseen = msgid
293 print " " + msg
293 print " " + msg
294
294
295 _defaultlogger = norepeatlogger()
295 _defaultlogger = norepeatlogger()
296
296
297 def getblame(f):
297 def getblame(f):
298 lines = []
298 lines = []
299 for l in os.popen('hg annotate -un %s' % f):
299 for l in os.popen('hg annotate -un %s' % f):
300 start, line = l.split(':', 1)
300 start, line = l.split(':', 1)
301 user, rev = start.split()
301 user, rev = start.split()
302 lines.append((line[1:-1], user, rev))
302 lines.append((line[1:-1], user, rev))
303 return lines
303 return lines
304
304
305 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
305 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
306 blame=False, debug=False, lineno=True):
306 blame=False, debug=False, lineno=True):
307 """checks style and portability of a given file
307 """checks style and portability of a given file
308
308
309 :f: filepath
309 :f: filepath
310 :logfunc: function used to report error
310 :logfunc: function used to report error
311 logfunc(filename, linenumber, linecontent, errormessage)
311 logfunc(filename, linenumber, linecontent, errormessage)
312 :maxerr: number of error to display before arborting.
312 :maxerr: number of error to display before arborting.
313 Set to false (default) to report all errors
313 Set to false (default) to report all errors
314
314
315 return True if no error is found, False otherwise.
315 return True if no error is found, False otherwise.
316 """
316 """
317 blamecache = None
317 blamecache = None
318 result = True
318 result = True
319 for name, match, filters, pats in checks:
319 for name, match, filters, pats in checks:
320 if debug:
320 if debug:
321 print name, f
321 print name, f
322 fc = 0
322 fc = 0
323 if not re.match(match, f):
323 if not re.match(match, f):
324 if debug:
324 if debug:
325 print "Skipping %s for %s it doesn't match %s" % (
325 print "Skipping %s for %s it doesn't match %s" % (
326 name, match, f)
326 name, match, f)
327 continue
327 continue
328 fp = open(f)
328 fp = open(f)
329 pre = post = fp.read()
329 pre = post = fp.read()
330 fp.close()
330 fp.close()
331 if "no-" + "check-code" in pre:
331 if "no-" + "check-code" in pre:
332 if debug:
332 if debug:
333 print "Skipping %s for %s it has no- and check-code" % (
333 print "Skipping %s for %s it has no- and check-code" % (
334 name, f)
334 name, f)
335 break
335 break
336 for p, r in filters:
336 for p, r in filters:
337 post = re.sub(p, r, post)
337 post = re.sub(p, r, post)
338 if warnings:
338 if warnings:
339 pats = pats[0] + pats[1]
339 pats = pats[0] + pats[1]
340 else:
340 else:
341 pats = pats[0]
341 pats = pats[0]
342 # print post # uncomment to show filtered version
342 # print post # uncomment to show filtered version
343
343
344 if debug:
344 if debug:
345 print "Checking %s for %s" % (name, f)
345 print "Checking %s for %s" % (name, f)
346
346
347 prelines = None
347 prelines = None
348 errors = []
348 errors = []
349 for p, msg in pats:
349 for p, msg in pats:
350 # fix-up regexes for multiline searches
350 # fix-up regexes for multiline searches
351 po = p
351 po = p
352 # \s doesn't match \n
352 # \s doesn't match \n
353 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
353 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
354 # [^...] doesn't match newline
354 # [^...] doesn't match newline
355 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
355 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
356
356
357 #print po, '=>', p
357 #print po, '=>', p
358
358
359 pos = 0
359 pos = 0
360 n = 0
360 n = 0
361 for m in re.finditer(p, post, re.MULTILINE):
361 for m in re.finditer(p, post, re.MULTILINE):
362 if prelines is None:
362 if prelines is None:
363 prelines = pre.splitlines()
363 prelines = pre.splitlines()
364 postlines = post.splitlines(True)
364 postlines = post.splitlines(True)
365
365
366 start = m.start()
366 start = m.start()
367 while n < len(postlines):
367 while n < len(postlines):
368 step = len(postlines[n])
368 step = len(postlines[n])
369 if pos + step > start:
369 if pos + step > start:
370 break
370 break
371 pos += step
371 pos += step
372 n += 1
372 n += 1
373 l = prelines[n]
373 l = prelines[n]
374
374
375 if "check-code" + "-ignore" in l:
375 if "check-code" + "-ignore" in l:
376 if debug:
376 if debug:
377 print "Skipping %s for %s:%s (check-code -ignore)" % (
377 print "Skipping %s for %s:%s (check-code -ignore)" % (
378 name, f, n)
378 name, f, n)
379 continue
379 continue
380 bd = ""
380 bd = ""
381 if blame:
381 if blame:
382 bd = 'working directory'
382 bd = 'working directory'
383 if not blamecache:
383 if not blamecache:
384 blamecache = getblame(f)
384 blamecache = getblame(f)
385 if n < len(blamecache):
385 if n < len(blamecache):
386 bl, bu, br = blamecache[n]
386 bl, bu, br = blamecache[n]
387 if bl == l:
387 if bl == l:
388 bd = '%s@%s' % (bu, br)
388 bd = '%s@%s' % (bu, br)
389 errors.append((f, lineno and n + 1, l, msg, bd))
389 errors.append((f, lineno and n + 1, l, msg, bd))
390 result = False
390 result = False
391
391
392 errors.sort()
392 errors.sort()
393 for e in errors:
393 for e in errors:
394 logfunc(*e)
394 logfunc(*e)
395 fc += 1
395 fc += 1
396 if maxerr and fc >= maxerr:
396 if maxerr and fc >= maxerr:
397 print " (too many errors, giving up)"
397 print " (too many errors, giving up)"
398 break
398 break
399
399
400 return result
400 return result
401
401
402 if __name__ == "__main__":
402 if __name__ == "__main__":
403 parser = optparse.OptionParser("%prog [options] [files]")
403 parser = optparse.OptionParser("%prog [options] [files]")
404 parser.add_option("-w", "--warnings", action="store_true",
404 parser.add_option("-w", "--warnings", action="store_true",
405 help="include warning-level checks")
405 help="include warning-level checks")
406 parser.add_option("-p", "--per-file", type="int",
406 parser.add_option("-p", "--per-file", type="int",
407 help="max warnings per file")
407 help="max warnings per file")
408 parser.add_option("-b", "--blame", action="store_true",
408 parser.add_option("-b", "--blame", action="store_true",
409 help="use annotate to generate blame info")
409 help="use annotate to generate blame info")
410 parser.add_option("", "--debug", action="store_true",
410 parser.add_option("", "--debug", action="store_true",
411 help="show debug information")
411 help="show debug information")
412 parser.add_option("", "--nolineno", action="store_false",
412 parser.add_option("", "--nolineno", action="store_false",
413 dest='lineno', help="don't show line numbers")
413 dest='lineno', help="don't show line numbers")
414
414
415 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
415 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
416 lineno=True)
416 lineno=True)
417 (options, args) = parser.parse_args()
417 (options, args) = parser.parse_args()
418
418
419 if len(args) == 0:
419 if len(args) == 0:
420 check = glob.glob("*")
420 check = glob.glob("*")
421 else:
421 else:
422 check = args
422 check = args
423
423
424 ret = 0
424 ret = 0
425 for f in check:
425 for f in check:
426 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
426 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
427 blame=options.blame, debug=options.debug,
427 blame=options.blame, debug=options.debug,
428 lineno=options.lineno):
428 lineno=options.lineno):
429 ret = 1
429 ret = 1
430 sys.exit(ret)
430 sys.exit(ret)
@@ -1,71 +1,71 b''
1 $ hg init repo
1 $ hg init repo
2 $ cd repo
2 $ cd repo
3 $ i=0; while [ "$i" -lt 213 ]; do echo a >> a; i=`expr $i + 1`; done
3 $ i=0; while [ "$i" -lt 213 ]; do echo a >> a; i=`expr $i + 1`; done
4 $ hg add a
4 $ hg add a
5 $ cp a b
5 $ cp a b
6 $ hg add b
6 $ hg add b
7
7
8 Wide diffstat:
8 Wide diffstat:
9
9
10 $ hg diff --stat
10 $ hg diff --stat
11 a | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 a | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 b | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 b | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 2 files changed, 426 insertions(+), 0 deletions(-)
13 2 files changed, 426 insertions(+), 0 deletions(-)
14
14
15 diffstat width:
15 diffstat width:
16
16
17 $ COLUMNS=24 hg diff --config ui.interactive=true --stat
17 $ COLUMNS=24 hg diff --config ui.interactive=true --stat
18 a | 213 ++++++++++++++
18 a | 213 ++++++++++++++
19 b | 213 ++++++++++++++
19 b | 213 ++++++++++++++
20 2 files changed, 426 insertions(+), 0 deletions(-)
20 2 files changed, 426 insertions(+), 0 deletions(-)
21
21
22 $ hg ci -m adda
22 $ hg ci -m adda
23
23
24 $ cat >> a <<EOF
24 $ cat >> a <<EOF
25 > a
25 > a
26 > a
26 > a
27 > a
27 > a
28 > EOF
28 > EOF
29
29
30 Narrow diffstat:
30 Narrow diffstat:
31
31
32 $ hg diff --stat
32 $ hg diff --stat
33 a | 3 +++
33 a | 3 +++
34 1 files changed, 3 insertions(+), 0 deletions(-)
34 1 files changed, 3 insertions(+), 0 deletions(-)
35
35
36 $ hg ci -m appenda
36 $ hg ci -m appenda
37
37
38 $ printf '\0' > c
38 >>> open("c", "wb").write("\0")
39 $ touch d
39 $ touch d
40 $ hg add c d
40 $ hg add c d
41
41
42 Binary diffstat:
42 Binary diffstat:
43
43
44 $ hg diff --stat
44 $ hg diff --stat
45 c | Bin
45 c | Bin
46 1 files changed, 0 insertions(+), 0 deletions(-)
46 1 files changed, 0 insertions(+), 0 deletions(-)
47
47
48 Binary git diffstat:
48 Binary git diffstat:
49
49
50 $ hg diff --stat --git
50 $ hg diff --stat --git
51 c | Bin
51 c | Bin
52 d | 0
52 d | 0
53 2 files changed, 0 insertions(+), 0 deletions(-)
53 2 files changed, 0 insertions(+), 0 deletions(-)
54
54
55 $ hg ci -m createb
55 $ hg ci -m createb
56
56
57 $ printf '\0' > "file with spaces"
57 >>> open("file with spaces", "wb").write("\0")
58 $ hg add "file with spaces"
58 $ hg add "file with spaces"
59
59
60 Filename with spaces diffstat:
60 Filename with spaces diffstat:
61
61
62 $ hg diff --stat
62 $ hg diff --stat
63 file with spaces | Bin
63 file with spaces | Bin
64 1 files changed, 0 insertions(+), 0 deletions(-)
64 1 files changed, 0 insertions(+), 0 deletions(-)
65
65
66 Filename with spaces git diffstat:
66 Filename with spaces git diffstat:
67
67
68 $ hg diff --stat --git
68 $ hg diff --stat --git
69 file with spaces | Bin
69 file with spaces | Bin
70 1 files changed, 0 insertions(+), 0 deletions(-)
70 1 files changed, 0 insertions(+), 0 deletions(-)
71
71
@@ -1,1108 +1,1108 b''
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2
2
3 $ cat <<EOF >> $HGRCPATH
3 $ cat <<EOF >> $HGRCPATH
4 > [extensions]
4 > [extensions]
5 > keyword =
5 > keyword =
6 > mq =
6 > mq =
7 > notify =
7 > notify =
8 > record =
8 > record =
9 > transplant =
9 > transplant =
10 > [ui]
10 > [ui]
11 > interactive = true
11 > interactive = true
12 > EOF
12 > EOF
13
13
14 Run kwdemo before [keyword] files are set up
14 Run kwdemo before [keyword] files are set up
15 as it would succeed without uisetup otherwise
15 as it would succeed without uisetup otherwise
16
16
17 $ hg --quiet kwdemo
17 $ hg --quiet kwdemo
18 [extensions]
18 [extensions]
19 keyword =
19 keyword =
20 [keyword]
20 [keyword]
21 demo.txt =
21 demo.txt =
22 [keywordset]
22 [keywordset]
23 svn = False
23 svn = False
24 [keywordmaps]
24 [keywordmaps]
25 Author = {author|user}
25 Author = {author|user}
26 Date = {date|utcdate}
26 Date = {date|utcdate}
27 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
27 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
28 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
28 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
29 RCSFile = {file|basename},v
29 RCSFile = {file|basename},v
30 RCSfile = {file|basename},v
30 RCSfile = {file|basename},v
31 Revision = {node|short}
31 Revision = {node|short}
32 Source = {root}/{file},v
32 Source = {root}/{file},v
33 $Author: test $
33 $Author: test $
34 $Date: ????/??/?? ??:??:?? $ (glob)
34 $Date: ????/??/?? ??:??:?? $ (glob)
35 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
35 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 $RCSFile: demo.txt,v $
37 $RCSFile: demo.txt,v $
38 $RCSfile: demo.txt,v $
38 $RCSfile: demo.txt,v $
39 $Revision: ???????????? $ (glob)
39 $Revision: ???????????? $ (glob)
40 $Source: */demo.txt,v $ (glob)
40 $Source: */demo.txt,v $ (glob)
41
41
42 $ hg --quiet kwdemo "Branch = {branches}"
42 $ hg --quiet kwdemo "Branch = {branches}"
43 [extensions]
43 [extensions]
44 keyword =
44 keyword =
45 [keyword]
45 [keyword]
46 demo.txt =
46 demo.txt =
47 [keywordset]
47 [keywordset]
48 svn = False
48 svn = False
49 [keywordmaps]
49 [keywordmaps]
50 Branch = {branches}
50 Branch = {branches}
51 $Branch: demobranch $
51 $Branch: demobranch $
52
52
53 $ cat <<EOF >> $HGRCPATH
53 $ cat <<EOF >> $HGRCPATH
54 > [keyword]
54 > [keyword]
55 > ** =
55 > ** =
56 > b = ignore
56 > b = ignore
57 > i = ignore
57 > i = ignore
58 > [hooks]
58 > [hooks]
59 > EOF
59 > EOF
60 $ cp $HGRCPATH $HGRCPATH.nohooks
60 $ cp $HGRCPATH $HGRCPATH.nohooks
61 > cat <<EOF >> $HGRCPATH
61 > cat <<EOF >> $HGRCPATH
62 > commit=
62 > commit=
63 > commit.test=cp a hooktest
63 > commit.test=cp a hooktest
64 > EOF
64 > EOF
65
65
66 $ hg init Test-bndl
66 $ hg init Test-bndl
67 $ cd Test-bndl
67 $ cd Test-bndl
68
68
69 kwshrink should exit silently in empty/invalid repo
69 kwshrink should exit silently in empty/invalid repo
70
70
71 $ hg kwshrink
71 $ hg kwshrink
72
72
73 Symlinks cannot be created on Windows.
73 Symlinks cannot be created on Windows.
74 A bundle to test this was made with:
74 A bundle to test this was made with:
75 hg init t
75 hg init t
76 cd t
76 cd t
77 echo a > a
77 echo a > a
78 ln -s a sym
78 ln -s a sym
79 hg add sym
79 hg add sym
80 hg ci -m addsym -u mercurial
80 hg ci -m addsym -u mercurial
81 hg bundle --base null ../test-keyword.hg
81 hg bundle --base null ../test-keyword.hg
82
82
83 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
83 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
84 pulling from *test-keyword.hg (glob)
84 pulling from *test-keyword.hg (glob)
85 requesting all changes
85 requesting all changes
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 1 changesets with 1 changes to 1 files
89 added 1 changesets with 1 changes to 1 files
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91
91
92 $ echo 'expand $Id$' > a
92 $ echo 'expand $Id$' > a
93 $ echo 'do not process $Id:' >> a
93 $ echo 'do not process $Id:' >> a
94 $ echo 'xxx $' >> a
94 $ echo 'xxx $' >> a
95 $ echo 'ignore $Id$' > b
95 $ echo 'ignore $Id$' > b
96
96
97 Output files as they were created
97 Output files as they were created
98
98
99 $ cat a b
99 $ cat a b
100 expand $Id$
100 expand $Id$
101 do not process $Id:
101 do not process $Id:
102 xxx $
102 xxx $
103 ignore $Id$
103 ignore $Id$
104
104
105 no kwfiles
105 no kwfiles
106
106
107 $ hg kwfiles
107 $ hg kwfiles
108
108
109 untracked candidates
109 untracked candidates
110
110
111 $ hg -v kwfiles --unknown
111 $ hg -v kwfiles --unknown
112 k a
112 k a
113
113
114 Add files and check status
114 Add files and check status
115
115
116 $ hg addremove
116 $ hg addremove
117 adding a
117 adding a
118 adding b
118 adding b
119 $ hg status
119 $ hg status
120 A a
120 A a
121 A b
121 A b
122
122
123
123
124 Default keyword expansion including commit hook
124 Default keyword expansion including commit hook
125 Interrupted commit should not change state or run commit hook
125 Interrupted commit should not change state or run commit hook
126
126
127 $ hg --debug commit
127 $ hg --debug commit
128 abort: empty commit message
128 abort: empty commit message
129 [255]
129 [255]
130 $ hg status
130 $ hg status
131 A a
131 A a
132 A b
132 A b
133
133
134 Commit with several checks
134 Commit with several checks
135
135
136 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
136 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
137 a
137 a
138 b
138 b
139 overwriting a expanding keywords
139 overwriting a expanding keywords
140 running hook commit.test: cp a hooktest
140 running hook commit.test: cp a hooktest
141 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
141 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
142 $ hg status
142 $ hg status
143 ? hooktest
143 ? hooktest
144 $ hg debugrebuildstate
144 $ hg debugrebuildstate
145 $ hg --quiet identify
145 $ hg --quiet identify
146 ef63ca68695b
146 ef63ca68695b
147
147
148 cat files in working directory with keywords expanded
148 cat files in working directory with keywords expanded
149
149
150 $ cat a b
150 $ cat a b
151 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
151 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
152 do not process $Id:
152 do not process $Id:
153 xxx $
153 xxx $
154 ignore $Id$
154 ignore $Id$
155
155
156 hg cat files and symlink, no expansion
156 hg cat files and symlink, no expansion
157
157
158 $ hg cat sym a b && echo
158 $ hg cat sym a b && echo
159 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
159 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
160 do not process $Id:
160 do not process $Id:
161 xxx $
161 xxx $
162 ignore $Id$
162 ignore $Id$
163 a
163 a
164
164
165 $ diff a hooktest
165 $ diff a hooktest
166
166
167 $ cp $HGRCPATH.nohooks $HGRCPATH
167 $ cp $HGRCPATH.nohooks $HGRCPATH
168 $ rm hooktest
168 $ rm hooktest
169
169
170 hg status of kw-ignored binary file starting with '\1\n'
170 hg status of kw-ignored binary file starting with '\1\n'
171
171
172 $ printf '\1\nfoo' > i
172 >>> open("i", "wb").write("\1\nfoo")
173 $ hg -q commit -Am metasep i
173 $ hg -q commit -Am metasep i
174 $ hg status
174 $ hg status
175 $ printf '\1\nbar' > i
175 >>> open("i", "wb").write("\1\nbar")
176 $ hg status
176 $ hg status
177 M i
177 M i
178 $ hg -q commit -m "modify metasep" i
178 $ hg -q commit -m "modify metasep" i
179 $ hg status --rev 2:3
179 $ hg status --rev 2:3
180 M i
180 M i
181 $ touch empty
181 $ touch empty
182 $ hg -q commit -A -m "another file"
182 $ hg -q commit -A -m "another file"
183 $ hg status -A --rev 3:4 i
183 $ hg status -A --rev 3:4 i
184 C i
184 C i
185
185
186 $ hg -q strip -n 2
186 $ hg -q strip -n 2
187
187
188 Test hook execution
188 Test hook execution
189
189
190 bundle
190 bundle
191
191
192 $ hg bundle --base null ../kw.hg
192 $ hg bundle --base null ../kw.hg
193 2 changesets found
193 2 changesets found
194 $ cd ..
194 $ cd ..
195 $ hg init Test
195 $ hg init Test
196 $ cd Test
196 $ cd Test
197
197
198 Notify on pull to check whether keywords stay as is in email
198 Notify on pull to check whether keywords stay as is in email
199 ie. if patch.diff wrapper acts as it should
199 ie. if patch.diff wrapper acts as it should
200
200
201 $ cat <<EOF >> $HGRCPATH
201 $ cat <<EOF >> $HGRCPATH
202 > [hooks]
202 > [hooks]
203 > incoming.notify = python:hgext.notify.hook
203 > incoming.notify = python:hgext.notify.hook
204 > [notify]
204 > [notify]
205 > sources = pull
205 > sources = pull
206 > diffstat = False
206 > diffstat = False
207 > maxsubject = 15
207 > maxsubject = 15
208 > [reposubs]
208 > [reposubs]
209 > * = Test
209 > * = Test
210 > EOF
210 > EOF
211
211
212 Pull from bundle and trigger notify
212 Pull from bundle and trigger notify
213
213
214 $ hg pull -u ../kw.hg
214 $ hg pull -u ../kw.hg
215 pulling from ../kw.hg
215 pulling from ../kw.hg
216 requesting all changes
216 requesting all changes
217 adding changesets
217 adding changesets
218 adding manifests
218 adding manifests
219 adding file changes
219 adding file changes
220 added 2 changesets with 3 changes to 3 files
220 added 2 changesets with 3 changes to 3 files
221 Content-Type: text/plain; charset="us-ascii"
221 Content-Type: text/plain; charset="us-ascii"
222 MIME-Version: 1.0
222 MIME-Version: 1.0
223 Content-Transfer-Encoding: 7bit
223 Content-Transfer-Encoding: 7bit
224 Date: * (glob)
224 Date: * (glob)
225 Subject: changeset in...
225 Subject: changeset in...
226 From: mercurial
226 From: mercurial
227 X-Hg-Notification: changeset a2392c293916
227 X-Hg-Notification: changeset a2392c293916
228 Message-Id: <hg.a2392c293916*> (glob)
228 Message-Id: <hg.a2392c293916*> (glob)
229 To: Test
229 To: Test
230
230
231 changeset a2392c293916 in $TESTTMP/Test (glob)
231 changeset a2392c293916 in $TESTTMP/Test (glob)
232 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
232 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
233 description:
233 description:
234 addsym
234 addsym
235
235
236 diffs (6 lines):
236 diffs (6 lines):
237
237
238 diff -r 000000000000 -r a2392c293916 sym
238 diff -r 000000000000 -r a2392c293916 sym
239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
240 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
240 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
241 @@ -0,0 +1,1 @@
241 @@ -0,0 +1,1 @@
242 +a
242 +a
243 \ No newline at end of file
243 \ No newline at end of file
244 Content-Type: text/plain; charset="us-ascii"
244 Content-Type: text/plain; charset="us-ascii"
245 MIME-Version: 1.0
245 MIME-Version: 1.0
246 Content-Transfer-Encoding: 7bit
246 Content-Transfer-Encoding: 7bit
247 Date:* (glob)
247 Date:* (glob)
248 Subject: changeset in...
248 Subject: changeset in...
249 From: User Name <user@example.com>
249 From: User Name <user@example.com>
250 X-Hg-Notification: changeset ef63ca68695b
250 X-Hg-Notification: changeset ef63ca68695b
251 Message-Id: <hg.ef63ca68695b*> (glob)
251 Message-Id: <hg.ef63ca68695b*> (glob)
252 To: Test
252 To: Test
253
253
254 changeset ef63ca68695b in $TESTTMP/Test (glob)
254 changeset ef63ca68695b in $TESTTMP/Test (glob)
255 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
255 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
256 description:
256 description:
257 absym
257 absym
258
258
259 diffs (12 lines):
259 diffs (12 lines):
260
260
261 diff -r a2392c293916 -r ef63ca68695b a
261 diff -r a2392c293916 -r ef63ca68695b a
262 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
262 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
263 +++ b/a Thu Jan 01 00:00:00 1970 +0000
263 +++ b/a Thu Jan 01 00:00:00 1970 +0000
264 @@ -0,0 +1,3 @@
264 @@ -0,0 +1,3 @@
265 +expand $Id$
265 +expand $Id$
266 +do not process $Id:
266 +do not process $Id:
267 +xxx $
267 +xxx $
268 diff -r a2392c293916 -r ef63ca68695b b
268 diff -r a2392c293916 -r ef63ca68695b b
269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 +++ b/b Thu Jan 01 00:00:00 1970 +0000
270 +++ b/b Thu Jan 01 00:00:00 1970 +0000
271 @@ -0,0 +1,1 @@
271 @@ -0,0 +1,1 @@
272 +ignore $Id$
272 +ignore $Id$
273 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
273 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
274
274
275 $ cp $HGRCPATH.nohooks $HGRCPATH
275 $ cp $HGRCPATH.nohooks $HGRCPATH
276
276
277 Touch files and check with status
277 Touch files and check with status
278
278
279 $ touch a b
279 $ touch a b
280 $ hg status
280 $ hg status
281
281
282 Update and expand
282 Update and expand
283
283
284 $ rm sym a b
284 $ rm sym a b
285 $ hg update -C
285 $ hg update -C
286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 $ cat a b
287 $ cat a b
288 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
288 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
289 do not process $Id:
289 do not process $Id:
290 xxx $
290 xxx $
291 ignore $Id$
291 ignore $Id$
292
292
293 Check whether expansion is filewise and file mode is preserved
293 Check whether expansion is filewise and file mode is preserved
294
294
295 $ echo '$Id$' > c
295 $ echo '$Id$' > c
296 $ echo 'tests for different changenodes' >> c
296 $ echo 'tests for different changenodes' >> c
297 $ chmod 600 c
297 $ chmod 600 c
298 $ ls -l c | cut -b 1-10
298 $ ls -l c | cut -b 1-10
299 -rw-------
299 -rw-------
300
300
301 commit file c
301 commit file c
302
302
303 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
303 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
304 adding c
304 adding c
305 $ ls -l c | cut -b 1-10
305 $ ls -l c | cut -b 1-10
306 -rw-------
306 -rw-------
307
307
308 force expansion
308 force expansion
309
309
310 $ hg -v kwexpand
310 $ hg -v kwexpand
311 overwriting a expanding keywords
311 overwriting a expanding keywords
312 overwriting c expanding keywords
312 overwriting c expanding keywords
313
313
314 compare changenodes in a and c
314 compare changenodes in a and c
315
315
316 $ cat a c
316 $ cat a c
317 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
317 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
318 do not process $Id:
318 do not process $Id:
319 xxx $
319 xxx $
320 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
320 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
321 tests for different changenodes
321 tests for different changenodes
322
322
323 record
323 record
324
324
325 $ echo '$Id$' > r
325 $ echo '$Id$' > r
326 $ hg add r
326 $ hg add r
327
327
328 record chunk
328 record chunk
329
329
330 >>> lines = open('a').readlines()
330 >>> lines = open('a').readlines()
331 >>> lines.insert(1, 'foo\n')
331 >>> lines.insert(1, 'foo\n')
332 >>> lines.append('bar\n')
332 >>> lines.append('bar\n')
333 >>> open('a', 'w').writelines(lines)
333 >>> open('a', 'w').writelines(lines)
334 $ hg record -d '1 10' -m rectest a<<EOF
334 $ hg record -d '1 10' -m rectest a<<EOF
335 > y
335 > y
336 > y
336 > y
337 > n
337 > n
338 > EOF
338 > EOF
339 diff --git a/a b/a
339 diff --git a/a b/a
340 2 hunks, 2 lines changed
340 2 hunks, 2 lines changed
341 examine changes to 'a'? [Ynsfdaq?]
341 examine changes to 'a'? [Ynsfdaq?]
342 @@ -1,3 +1,4 @@
342 @@ -1,3 +1,4 @@
343 expand $Id$
343 expand $Id$
344 +foo
344 +foo
345 do not process $Id:
345 do not process $Id:
346 xxx $
346 xxx $
347 record change 1/2 to 'a'? [Ynsfdaq?]
347 record change 1/2 to 'a'? [Ynsfdaq?]
348 @@ -2,2 +3,3 @@
348 @@ -2,2 +3,3 @@
349 do not process $Id:
349 do not process $Id:
350 xxx $
350 xxx $
351 +bar
351 +bar
352 record change 2/2 to 'a'? [Ynsfdaq?]
352 record change 2/2 to 'a'? [Ynsfdaq?]
353
353
354 $ hg identify
354 $ hg identify
355 d17e03c92c97+ tip
355 d17e03c92c97+ tip
356 $ hg status
356 $ hg status
357 M a
357 M a
358 A r
358 A r
359
359
360 Cat modified file a
360 Cat modified file a
361
361
362 $ cat a
362 $ cat a
363 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
363 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
364 foo
364 foo
365 do not process $Id:
365 do not process $Id:
366 xxx $
366 xxx $
367 bar
367 bar
368
368
369 Diff remaining chunk
369 Diff remaining chunk
370
370
371 $ hg diff a
371 $ hg diff a
372 diff -r d17e03c92c97 a
372 diff -r d17e03c92c97 a
373 --- a/a Wed Dec 31 23:59:51 1969 -0000
373 --- a/a Wed Dec 31 23:59:51 1969 -0000
374 +++ b/a * (glob)
374 +++ b/a * (glob)
375 @@ -2,3 +2,4 @@
375 @@ -2,3 +2,4 @@
376 foo
376 foo
377 do not process $Id:
377 do not process $Id:
378 xxx $
378 xxx $
379 +bar
379 +bar
380
380
381 $ hg rollback
381 $ hg rollback
382 repository tip rolled back to revision 2 (undo commit)
382 repository tip rolled back to revision 2 (undo commit)
383 working directory now based on revision 2
383 working directory now based on revision 2
384
384
385 Record all chunks in file a
385 Record all chunks in file a
386
386
387 $ echo foo > msg
387 $ echo foo > msg
388
388
389 - do not use "hg record -m" here!
389 - do not use "hg record -m" here!
390
390
391 $ hg record -l msg -d '1 11' a<<EOF
391 $ hg record -l msg -d '1 11' a<<EOF
392 > y
392 > y
393 > y
393 > y
394 > y
394 > y
395 > EOF
395 > EOF
396 diff --git a/a b/a
396 diff --git a/a b/a
397 2 hunks, 2 lines changed
397 2 hunks, 2 lines changed
398 examine changes to 'a'? [Ynsfdaq?]
398 examine changes to 'a'? [Ynsfdaq?]
399 @@ -1,3 +1,4 @@
399 @@ -1,3 +1,4 @@
400 expand $Id$
400 expand $Id$
401 +foo
401 +foo
402 do not process $Id:
402 do not process $Id:
403 xxx $
403 xxx $
404 record change 1/2 to 'a'? [Ynsfdaq?]
404 record change 1/2 to 'a'? [Ynsfdaq?]
405 @@ -2,2 +3,3 @@
405 @@ -2,2 +3,3 @@
406 do not process $Id:
406 do not process $Id:
407 xxx $
407 xxx $
408 +bar
408 +bar
409 record change 2/2 to 'a'? [Ynsfdaq?]
409 record change 2/2 to 'a'? [Ynsfdaq?]
410
410
411 File a should be clean
411 File a should be clean
412
412
413 $ hg status -A a
413 $ hg status -A a
414 C a
414 C a
415
415
416 rollback and revert expansion
416 rollback and revert expansion
417
417
418 $ cat a
418 $ cat a
419 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
419 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
420 foo
420 foo
421 do not process $Id:
421 do not process $Id:
422 xxx $
422 xxx $
423 bar
423 bar
424 $ hg --verbose rollback
424 $ hg --verbose rollback
425 repository tip rolled back to revision 2 (undo commit)
425 repository tip rolled back to revision 2 (undo commit)
426 working directory now based on revision 2
426 working directory now based on revision 2
427 overwriting a expanding keywords
427 overwriting a expanding keywords
428 $ hg status a
428 $ hg status a
429 M a
429 M a
430 $ cat a
430 $ cat a
431 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
431 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
432 foo
432 foo
433 do not process $Id:
433 do not process $Id:
434 xxx $
434 xxx $
435 bar
435 bar
436 $ echo '$Id$' > y
436 $ echo '$Id$' > y
437 $ echo '$Id$' > z
437 $ echo '$Id$' > z
438 $ hg add y
438 $ hg add y
439 $ hg commit -Am "rollback only" z
439 $ hg commit -Am "rollback only" z
440 $ cat z
440 $ cat z
441 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
441 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
442 $ hg --verbose rollback
442 $ hg --verbose rollback
443 repository tip rolled back to revision 2 (undo commit)
443 repository tip rolled back to revision 2 (undo commit)
444 working directory now based on revision 2
444 working directory now based on revision 2
445 overwriting z shrinking keywords
445 overwriting z shrinking keywords
446
446
447 Only z should be overwritten
447 Only z should be overwritten
448
448
449 $ hg status a y z
449 $ hg status a y z
450 M a
450 M a
451 A y
451 A y
452 A z
452 A z
453 $ cat z
453 $ cat z
454 $Id$
454 $Id$
455 $ hg forget y z
455 $ hg forget y z
456 $ rm y z
456 $ rm y z
457
457
458 record added file alone
458 record added file alone
459
459
460 $ hg -v record -l msg -d '1 12' r<<EOF
460 $ hg -v record -l msg -d '1 12' r<<EOF
461 > y
461 > y
462 > EOF
462 > EOF
463 diff --git a/r b/r
463 diff --git a/r b/r
464 new file mode 100644
464 new file mode 100644
465 examine changes to 'r'? [Ynsfdaq?]
465 examine changes to 'r'? [Ynsfdaq?]
466 r
466 r
467 committed changeset 3:899491280810
467 committed changeset 3:899491280810
468 overwriting r expanding keywords
468 overwriting r expanding keywords
469 - status call required for dirstate.normallookup() check
469 - status call required for dirstate.normallookup() check
470 $ hg status r
470 $ hg status r
471 $ hg --verbose rollback
471 $ hg --verbose rollback
472 repository tip rolled back to revision 2 (undo commit)
472 repository tip rolled back to revision 2 (undo commit)
473 working directory now based on revision 2
473 working directory now based on revision 2
474 overwriting r shrinking keywords
474 overwriting r shrinking keywords
475 $ hg forget r
475 $ hg forget r
476 $ rm msg r
476 $ rm msg r
477 $ hg update -C
477 $ hg update -C
478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
479
479
480 record added keyword ignored file
480 record added keyword ignored file
481
481
482 $ echo '$Id$' > i
482 $ echo '$Id$' > i
483 $ hg add i
483 $ hg add i
484 $ hg --verbose record -d '1 13' -m recignored<<EOF
484 $ hg --verbose record -d '1 13' -m recignored<<EOF
485 > y
485 > y
486 > EOF
486 > EOF
487 diff --git a/i b/i
487 diff --git a/i b/i
488 new file mode 100644
488 new file mode 100644
489 examine changes to 'i'? [Ynsfdaq?]
489 examine changes to 'i'? [Ynsfdaq?]
490 i
490 i
491 committed changeset 3:5f40fe93bbdc
491 committed changeset 3:5f40fe93bbdc
492 $ cat i
492 $ cat i
493 $Id$
493 $Id$
494 $ hg -q rollback
494 $ hg -q rollback
495 $ hg forget i
495 $ hg forget i
496 $ rm i
496 $ rm i
497
497
498 Test patch queue repo
498 Test patch queue repo
499
499
500 $ hg init --mq
500 $ hg init --mq
501 $ hg qimport -r tip -n mqtest.diff
501 $ hg qimport -r tip -n mqtest.diff
502 $ hg commit --mq -m mqtest
502 $ hg commit --mq -m mqtest
503
503
504 Keywords should not be expanded in patch
504 Keywords should not be expanded in patch
505
505
506 $ cat .hg/patches/mqtest.diff
506 $ cat .hg/patches/mqtest.diff
507 # HG changeset patch
507 # HG changeset patch
508 # User User Name <user@example.com>
508 # User User Name <user@example.com>
509 # Date 1 0
509 # Date 1 0
510 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
510 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
511 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
511 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
512 cndiff
512 cndiff
513
513
514 diff -r ef63ca68695b -r 40a904bbbe4c c
514 diff -r ef63ca68695b -r 40a904bbbe4c c
515 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
515 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
516 +++ b/c Thu Jan 01 00:00:01 1970 +0000
516 +++ b/c Thu Jan 01 00:00:01 1970 +0000
517 @@ -0,0 +1,2 @@
517 @@ -0,0 +1,2 @@
518 +$Id$
518 +$Id$
519 +tests for different changenodes
519 +tests for different changenodes
520
520
521 $ hg qpop
521 $ hg qpop
522 popping mqtest.diff
522 popping mqtest.diff
523 patch queue now empty
523 patch queue now empty
524
524
525 qgoto, implying qpush, should expand
525 qgoto, implying qpush, should expand
526
526
527 $ hg qgoto mqtest.diff
527 $ hg qgoto mqtest.diff
528 applying mqtest.diff
528 applying mqtest.diff
529 now at: mqtest.diff
529 now at: mqtest.diff
530 $ cat c
530 $ cat c
531 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
531 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
532 tests for different changenodes
532 tests for different changenodes
533 $ hg cat c
533 $ hg cat c
534 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
534 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
535 tests for different changenodes
535 tests for different changenodes
536
536
537 Keywords should not be expanded in filelog
537 Keywords should not be expanded in filelog
538
538
539 $ hg --config 'extensions.keyword=!' cat c
539 $ hg --config 'extensions.keyword=!' cat c
540 $Id$
540 $Id$
541 tests for different changenodes
541 tests for different changenodes
542
542
543 qpop and move on
543 qpop and move on
544
544
545 $ hg qpop
545 $ hg qpop
546 popping mqtest.diff
546 popping mqtest.diff
547 patch queue now empty
547 patch queue now empty
548
548
549 Copy and show added kwfiles
549 Copy and show added kwfiles
550
550
551 $ hg cp a c
551 $ hg cp a c
552 $ hg kwfiles
552 $ hg kwfiles
553 a
553 a
554 c
554 c
555
555
556 Commit and show expansion in original and copy
556 Commit and show expansion in original and copy
557
557
558 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
558 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
559 invalidating branch cache (tip differs)
559 invalidating branch cache (tip differs)
560 c
560 c
561 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
561 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
562 overwriting c expanding keywords
562 overwriting c expanding keywords
563 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
563 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
564 $ cat a c
564 $ cat a c
565 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
565 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
566 do not process $Id:
566 do not process $Id:
567 xxx $
567 xxx $
568 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
568 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
569 do not process $Id:
569 do not process $Id:
570 xxx $
570 xxx $
571
571
572 Touch copied c and check its status
572 Touch copied c and check its status
573
573
574 $ touch c
574 $ touch c
575 $ hg status
575 $ hg status
576
576
577 Copy kwfile to keyword ignored file unexpanding keywords
577 Copy kwfile to keyword ignored file unexpanding keywords
578
578
579 $ hg --verbose copy a i
579 $ hg --verbose copy a i
580 copying a to i
580 copying a to i
581 overwriting i shrinking keywords
581 overwriting i shrinking keywords
582 $ head -n 1 i
582 $ head -n 1 i
583 expand $Id$
583 expand $Id$
584 $ hg forget i
584 $ hg forget i
585 $ rm i
585 $ rm i
586
586
587 Copy ignored file to ignored file: no overwriting
587 Copy ignored file to ignored file: no overwriting
588
588
589 $ hg --verbose copy b i
589 $ hg --verbose copy b i
590 copying b to i
590 copying b to i
591 $ hg forget i
591 $ hg forget i
592 $ rm i
592 $ rm i
593
593
594 cp symlink file; hg cp -A symlink file (part1)
594 cp symlink file; hg cp -A symlink file (part1)
595 - copied symlink points to kwfile: overwrite
595 - copied symlink points to kwfile: overwrite
596
596
597 $ cp sym i
597 $ cp sym i
598 $ ls -l i
598 $ ls -l i
599 -rw-r--r--* (glob)
599 -rw-r--r--* (glob)
600 $ head -1 i
600 $ head -1 i
601 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
601 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
602 $ hg copy --after --verbose sym i
602 $ hg copy --after --verbose sym i
603 copying sym to i
603 copying sym to i
604 overwriting i shrinking keywords
604 overwriting i shrinking keywords
605 $ head -1 i
605 $ head -1 i
606 expand $Id$
606 expand $Id$
607 $ hg forget i
607 $ hg forget i
608 $ rm i
608 $ rm i
609
609
610 Test different options of hg kwfiles
610 Test different options of hg kwfiles
611
611
612 $ hg kwfiles
612 $ hg kwfiles
613 a
613 a
614 c
614 c
615 $ hg -v kwfiles --ignore
615 $ hg -v kwfiles --ignore
616 I b
616 I b
617 I sym
617 I sym
618 $ hg kwfiles --all
618 $ hg kwfiles --all
619 K a
619 K a
620 K c
620 K c
621 I b
621 I b
622 I sym
622 I sym
623
623
624 Diff specific revision
624 Diff specific revision
625
625
626 $ hg diff --rev 1
626 $ hg diff --rev 1
627 diff -r ef63ca68695b c
627 diff -r ef63ca68695b c
628 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
628 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
629 +++ b/c * (glob)
629 +++ b/c * (glob)
630 @@ -0,0 +1,3 @@
630 @@ -0,0 +1,3 @@
631 +expand $Id$
631 +expand $Id$
632 +do not process $Id:
632 +do not process $Id:
633 +xxx $
633 +xxx $
634
634
635 Status after rollback:
635 Status after rollback:
636
636
637 $ hg rollback
637 $ hg rollback
638 repository tip rolled back to revision 1 (undo commit)
638 repository tip rolled back to revision 1 (undo commit)
639 working directory now based on revision 1
639 working directory now based on revision 1
640 $ hg status
640 $ hg status
641 A c
641 A c
642 $ hg update --clean
642 $ hg update --clean
643 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
644
644
645 cp symlink file; hg cp -A symlink file (part2)
645 cp symlink file; hg cp -A symlink file (part2)
646 - copied symlink points to kw ignored file: do not overwrite
646 - copied symlink points to kw ignored file: do not overwrite
647
647
648 $ cat a > i
648 $ cat a > i
649 $ ln -s i symignored
649 $ ln -s i symignored
650 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
650 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
651 $ cp symignored x
651 $ cp symignored x
652 $ hg copy --after --verbose symignored x
652 $ hg copy --after --verbose symignored x
653 copying symignored to x
653 copying symignored to x
654 $ head -n 1 x
654 $ head -n 1 x
655 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
655 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
656 $ hg forget x
656 $ hg forget x
657 $ rm x
657 $ rm x
658
658
659 $ hg rollback
659 $ hg rollback
660 repository tip rolled back to revision 1 (undo commit)
660 repository tip rolled back to revision 1 (undo commit)
661 working directory now based on revision 1
661 working directory now based on revision 1
662 $ hg update --clean
662 $ hg update --clean
663 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
663 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
664 $ rm i symignored
664 $ rm i symignored
665
665
666 Custom keywordmaps as argument to kwdemo
666 Custom keywordmaps as argument to kwdemo
667
667
668 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
668 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
669 [extensions]
669 [extensions]
670 keyword =
670 keyword =
671 [keyword]
671 [keyword]
672 ** =
672 ** =
673 b = ignore
673 b = ignore
674 demo.txt =
674 demo.txt =
675 i = ignore
675 i = ignore
676 [keywordset]
676 [keywordset]
677 svn = False
677 svn = False
678 [keywordmaps]
678 [keywordmaps]
679 Xinfo = {author}: {desc}
679 Xinfo = {author}: {desc}
680 $Xinfo: test: hg keyword configuration and expansion example $
680 $Xinfo: test: hg keyword configuration and expansion example $
681
681
682 Configure custom keywordmaps
682 Configure custom keywordmaps
683
683
684 $ cat <<EOF >>$HGRCPATH
684 $ cat <<EOF >>$HGRCPATH
685 > [keywordmaps]
685 > [keywordmaps]
686 > Id = {file} {node|short} {date|rfc822date} {author|user}
686 > Id = {file} {node|short} {date|rfc822date} {author|user}
687 > Xinfo = {author}: {desc}
687 > Xinfo = {author}: {desc}
688 > EOF
688 > EOF
689
689
690 Cat and hg cat files before custom expansion
690 Cat and hg cat files before custom expansion
691
691
692 $ cat a b
692 $ cat a b
693 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
693 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
694 do not process $Id:
694 do not process $Id:
695 xxx $
695 xxx $
696 ignore $Id$
696 ignore $Id$
697 $ hg cat sym a b && echo
697 $ hg cat sym a b && echo
698 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
698 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
699 do not process $Id:
699 do not process $Id:
700 xxx $
700 xxx $
701 ignore $Id$
701 ignore $Id$
702 a
702 a
703
703
704 Write custom keyword and prepare multiline commit message
704 Write custom keyword and prepare multiline commit message
705
705
706 $ echo '$Xinfo$' >> a
706 $ echo '$Xinfo$' >> a
707 $ cat <<EOF >> log
707 $ cat <<EOF >> log
708 > firstline
708 > firstline
709 > secondline
709 > secondline
710 > EOF
710 > EOF
711
711
712 Interrupted commit should not change state
712 Interrupted commit should not change state
713
713
714 $ hg commit
714 $ hg commit
715 abort: empty commit message
715 abort: empty commit message
716 [255]
716 [255]
717 $ hg status
717 $ hg status
718 M a
718 M a
719 ? c
719 ? c
720 ? log
720 ? log
721
721
722 Commit with multiline message and custom expansion
722 Commit with multiline message and custom expansion
723
723
724 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
724 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
725 a
725 a
726 overwriting a expanding keywords
726 overwriting a expanding keywords
727 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
727 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
728 $ rm log
728 $ rm log
729
729
730 Stat, verify and show custom expansion (firstline)
730 Stat, verify and show custom expansion (firstline)
731
731
732 $ hg status
732 $ hg status
733 ? c
733 ? c
734 $ hg verify
734 $ hg verify
735 checking changesets
735 checking changesets
736 checking manifests
736 checking manifests
737 crosschecking files in changesets and manifests
737 crosschecking files in changesets and manifests
738 checking files
738 checking files
739 3 files, 3 changesets, 4 total revisions
739 3 files, 3 changesets, 4 total revisions
740 $ cat a b
740 $ cat a b
741 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
741 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
742 do not process $Id:
742 do not process $Id:
743 xxx $
743 xxx $
744 $Xinfo: User Name <user@example.com>: firstline $
744 $Xinfo: User Name <user@example.com>: firstline $
745 ignore $Id$
745 ignore $Id$
746 $ hg cat sym a b && echo
746 $ hg cat sym a b && echo
747 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
747 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
748 do not process $Id:
748 do not process $Id:
749 xxx $
749 xxx $
750 $Xinfo: User Name <user@example.com>: firstline $
750 $Xinfo: User Name <user@example.com>: firstline $
751 ignore $Id$
751 ignore $Id$
752 a
752 a
753
753
754 annotate
754 annotate
755
755
756 $ hg annotate a
756 $ hg annotate a
757 1: expand $Id$
757 1: expand $Id$
758 1: do not process $Id:
758 1: do not process $Id:
759 1: xxx $
759 1: xxx $
760 2: $Xinfo$
760 2: $Xinfo$
761
761
762 remove with status checks
762 remove with status checks
763
763
764 $ hg debugrebuildstate
764 $ hg debugrebuildstate
765 $ hg remove a
765 $ hg remove a
766 $ hg --debug commit -m rma
766 $ hg --debug commit -m rma
767 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
767 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
768 $ hg status
768 $ hg status
769 ? c
769 ? c
770
770
771 Rollback, revert, and check expansion
771 Rollback, revert, and check expansion
772
772
773 $ hg rollback
773 $ hg rollback
774 repository tip rolled back to revision 2 (undo commit)
774 repository tip rolled back to revision 2 (undo commit)
775 working directory now based on revision 2
775 working directory now based on revision 2
776 $ hg status
776 $ hg status
777 R a
777 R a
778 ? c
778 ? c
779 $ hg revert --no-backup --rev tip a
779 $ hg revert --no-backup --rev tip a
780 $ cat a
780 $ cat a
781 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
781 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
782 do not process $Id:
782 do not process $Id:
783 xxx $
783 xxx $
784 $Xinfo: User Name <user@example.com>: firstline $
784 $Xinfo: User Name <user@example.com>: firstline $
785
785
786 Clone to test global and local configurations
786 Clone to test global and local configurations
787
787
788 $ cd ..
788 $ cd ..
789
789
790 Expansion in destinaton with global configuration
790 Expansion in destinaton with global configuration
791
791
792 $ hg --quiet clone Test globalconf
792 $ hg --quiet clone Test globalconf
793 $ cat globalconf/a
793 $ cat globalconf/a
794 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
794 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
795 do not process $Id:
795 do not process $Id:
796 xxx $
796 xxx $
797 $Xinfo: User Name <user@example.com>: firstline $
797 $Xinfo: User Name <user@example.com>: firstline $
798
798
799 No expansion in destination with local configuration in origin only
799 No expansion in destination with local configuration in origin only
800
800
801 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
801 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
802 $ cat localconf/a
802 $ cat localconf/a
803 expand $Id$
803 expand $Id$
804 do not process $Id:
804 do not process $Id:
805 xxx $
805 xxx $
806 $Xinfo$
806 $Xinfo$
807
807
808 Clone to test incoming
808 Clone to test incoming
809
809
810 $ hg clone -r1 Test Test-a
810 $ hg clone -r1 Test Test-a
811 adding changesets
811 adding changesets
812 adding manifests
812 adding manifests
813 adding file changes
813 adding file changes
814 added 2 changesets with 3 changes to 3 files
814 added 2 changesets with 3 changes to 3 files
815 updating to branch default
815 updating to branch default
816 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
816 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
817 $ cd Test-a
817 $ cd Test-a
818 $ cat <<EOF >> .hg/hgrc
818 $ cat <<EOF >> .hg/hgrc
819 > [paths]
819 > [paths]
820 > default = ../Test
820 > default = ../Test
821 > EOF
821 > EOF
822 $ hg incoming
822 $ hg incoming
823 comparing with $TESTTMP/Test (glob)
823 comparing with $TESTTMP/Test (glob)
824 searching for changes
824 searching for changes
825 changeset: 2:bb948857c743
825 changeset: 2:bb948857c743
826 tag: tip
826 tag: tip
827 user: User Name <user@example.com>
827 user: User Name <user@example.com>
828 date: Thu Jan 01 00:00:02 1970 +0000
828 date: Thu Jan 01 00:00:02 1970 +0000
829 summary: firstline
829 summary: firstline
830
830
831 Imported patch should not be rejected
831 Imported patch should not be rejected
832
832
833 >>> import re
833 >>> import re
834 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
834 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
835 >>> open('a', 'wb').write(text)
835 >>> open('a', 'wb').write(text)
836 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
836 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
837 a
837 a
838 overwriting a expanding keywords
838 overwriting a expanding keywords
839 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
839 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
840 $ hg export -o ../rejecttest.diff tip
840 $ hg export -o ../rejecttest.diff tip
841 $ cd ../Test
841 $ cd ../Test
842 $ hg import ../rejecttest.diff
842 $ hg import ../rejecttest.diff
843 applying ../rejecttest.diff
843 applying ../rejecttest.diff
844 $ cat a b
844 $ cat a b
845 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
845 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
846 do not process $Id: rejecttest
846 do not process $Id: rejecttest
847 xxx $
847 xxx $
848 $Xinfo: User Name <user@example.com>: rejects? $
848 $Xinfo: User Name <user@example.com>: rejects? $
849 ignore $Id$
849 ignore $Id$
850
850
851 $ hg rollback
851 $ hg rollback
852 repository tip rolled back to revision 2 (undo import)
852 repository tip rolled back to revision 2 (undo import)
853 working directory now based on revision 2
853 working directory now based on revision 2
854 $ hg update --clean
854 $ hg update --clean
855 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
855 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
856
856
857 kwexpand/kwshrink on selected files
857 kwexpand/kwshrink on selected files
858
858
859 $ mkdir x
859 $ mkdir x
860 $ hg copy a x/a
860 $ hg copy a x/a
861 $ hg --verbose kwshrink a
861 $ hg --verbose kwshrink a
862 overwriting a shrinking keywords
862 overwriting a shrinking keywords
863 - sleep required for dirstate.normal() check
863 - sleep required for dirstate.normal() check
864 $ sleep 1
864 $ sleep 1
865 $ hg status a
865 $ hg status a
866 $ hg --verbose kwexpand a
866 $ hg --verbose kwexpand a
867 overwriting a expanding keywords
867 overwriting a expanding keywords
868 $ hg status a
868 $ hg status a
869
869
870 kwexpand x/a should abort
870 kwexpand x/a should abort
871
871
872 $ hg --verbose kwexpand x/a
872 $ hg --verbose kwexpand x/a
873 abort: outstanding uncommitted changes
873 abort: outstanding uncommitted changes
874 [255]
874 [255]
875 $ cd x
875 $ cd x
876 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
876 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
877 x/a
877 x/a
878 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
878 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
879 overwriting x/a expanding keywords
879 overwriting x/a expanding keywords
880 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
880 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
881 $ cat a
881 $ cat a
882 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
882 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
883 do not process $Id:
883 do not process $Id:
884 xxx $
884 xxx $
885 $Xinfo: User Name <user@example.com>: xa $
885 $Xinfo: User Name <user@example.com>: xa $
886
886
887 kwshrink a inside directory x
887 kwshrink a inside directory x
888
888
889 $ hg --verbose kwshrink a
889 $ hg --verbose kwshrink a
890 overwriting x/a shrinking keywords
890 overwriting x/a shrinking keywords
891 $ cat a
891 $ cat a
892 expand $Id$
892 expand $Id$
893 do not process $Id:
893 do not process $Id:
894 xxx $
894 xxx $
895 $Xinfo$
895 $Xinfo$
896 $ cd ..
896 $ cd ..
897
897
898 kwexpand nonexistent
898 kwexpand nonexistent
899
899
900 $ hg kwexpand nonexistent
900 $ hg kwexpand nonexistent
901 nonexistent:* (glob)
901 nonexistent:* (glob)
902
902
903
903
904 hg serve
904 hg serve
905 - expand with hgweb file
905 - expand with hgweb file
906 - no expansion with hgweb annotate/changeset/filediff
906 - no expansion with hgweb annotate/changeset/filediff
907 - check errors
907 - check errors
908
908
909 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
909 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
910 $ cat hg.pid >> $DAEMON_PIDS
910 $ cat hg.pid >> $DAEMON_PIDS
911 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
911 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
912 200 Script output follows
912 200 Script output follows
913
913
914 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
914 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
915 do not process $Id:
915 do not process $Id:
916 xxx $
916 xxx $
917 $Xinfo: User Name <user@example.com>: firstline $
917 $Xinfo: User Name <user@example.com>: firstline $
918 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
918 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
919 200 Script output follows
919 200 Script output follows
920
920
921
921
922 user@1: expand $Id$
922 user@1: expand $Id$
923 user@1: do not process $Id:
923 user@1: do not process $Id:
924 user@1: xxx $
924 user@1: xxx $
925 user@2: $Xinfo$
925 user@2: $Xinfo$
926
926
927
927
928
928
929
929
930 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
930 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
931 200 Script output follows
931 200 Script output follows
932
932
933
933
934 # HG changeset patch
934 # HG changeset patch
935 # User User Name <user@example.com>
935 # User User Name <user@example.com>
936 # Date 3 0
936 # Date 3 0
937 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
937 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
938 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
938 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
939 xa
939 xa
940
940
941 diff -r bb948857c743 -r b4560182a3f9 x/a
941 diff -r bb948857c743 -r b4560182a3f9 x/a
942 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
942 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
943 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
943 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
944 @@ -0,0 +1,4 @@
944 @@ -0,0 +1,4 @@
945 +expand $Id$
945 +expand $Id$
946 +do not process $Id:
946 +do not process $Id:
947 +xxx $
947 +xxx $
948 +$Xinfo$
948 +$Xinfo$
949
949
950 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
950 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
951 200 Script output follows
951 200 Script output follows
952
952
953
953
954 diff -r ef63ca68695b -r bb948857c743 a
954 diff -r ef63ca68695b -r bb948857c743 a
955 --- a/a Thu Jan 01 00:00:00 1970 +0000
955 --- a/a Thu Jan 01 00:00:00 1970 +0000
956 +++ b/a Thu Jan 01 00:00:02 1970 +0000
956 +++ b/a Thu Jan 01 00:00:02 1970 +0000
957 @@ -1,3 +1,4 @@
957 @@ -1,3 +1,4 @@
958 expand $Id$
958 expand $Id$
959 do not process $Id:
959 do not process $Id:
960 xxx $
960 xxx $
961 +$Xinfo$
961 +$Xinfo$
962
962
963
963
964
964
965
965
966 $ cat errors.log
966 $ cat errors.log
967
967
968 Prepare merge and resolve tests
968 Prepare merge and resolve tests
969
969
970 $ echo '$Id$' > m
970 $ echo '$Id$' > m
971 $ hg add m
971 $ hg add m
972 $ hg commit -m 4kw
972 $ hg commit -m 4kw
973 $ echo foo >> m
973 $ echo foo >> m
974 $ hg commit -m 5foo
974 $ hg commit -m 5foo
975
975
976 simplemerge
976 simplemerge
977
977
978 $ hg update 4
978 $ hg update 4
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
980 $ echo foo >> m
980 $ echo foo >> m
981 $ hg commit -m 6foo
981 $ hg commit -m 6foo
982 created new head
982 created new head
983 $ hg merge
983 $ hg merge
984 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
984 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
985 (branch merge, don't forget to commit)
985 (branch merge, don't forget to commit)
986 $ hg commit -m simplemerge
986 $ hg commit -m simplemerge
987 $ cat m
987 $ cat m
988 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
988 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
989 foo
989 foo
990
990
991 conflict: keyword should stay outside conflict zone
991 conflict: keyword should stay outside conflict zone
992
992
993 $ hg update 4
993 $ hg update 4
994 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
994 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
995 $ echo bar >> m
995 $ echo bar >> m
996 $ hg commit -m 8bar
996 $ hg commit -m 8bar
997 created new head
997 created new head
998 $ hg merge
998 $ hg merge
999 merging m
999 merging m
1000 warning: conflicts during merge.
1000 warning: conflicts during merge.
1001 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
1001 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
1002 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1002 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1003 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1003 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1004 [1]
1004 [1]
1005 $ cat m
1005 $ cat m
1006 $Id$
1006 $Id$
1007 <<<<<<< local
1007 <<<<<<< local
1008 bar
1008 bar
1009 =======
1009 =======
1010 foo
1010 foo
1011 >>>>>>> other
1011 >>>>>>> other
1012
1012
1013 resolve to local
1013 resolve to local
1014
1014
1015 $ HGMERGE=internal:local hg resolve -a
1015 $ HGMERGE=internal:local hg resolve -a
1016 $ hg commit -m localresolve
1016 $ hg commit -m localresolve
1017 $ cat m
1017 $ cat m
1018 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
1018 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
1019 bar
1019 bar
1020
1020
1021 Test restricted mode with transplant -b
1021 Test restricted mode with transplant -b
1022
1022
1023 $ hg update 6
1023 $ hg update 6
1024 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1024 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1025 $ hg branch foo
1025 $ hg branch foo
1026 marked working directory as branch foo
1026 marked working directory as branch foo
1027 (branches are permanent and global, did you want a bookmark?)
1027 (branches are permanent and global, did you want a bookmark?)
1028 $ mv a a.bak
1028 $ mv a a.bak
1029 $ echo foobranch > a
1029 $ echo foobranch > a
1030 $ cat a.bak >> a
1030 $ cat a.bak >> a
1031 $ rm a.bak
1031 $ rm a.bak
1032 $ hg commit -m 9foobranch
1032 $ hg commit -m 9foobranch
1033 $ hg update default
1033 $ hg update default
1034 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1034 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1035 $ hg -y transplant -b foo tip
1035 $ hg -y transplant -b foo tip
1036 applying 4aa30d025d50
1036 applying 4aa30d025d50
1037 4aa30d025d50 transplanted to e00abbf63521
1037 4aa30d025d50 transplanted to e00abbf63521
1038
1038
1039 Expansion in changeset but not in file
1039 Expansion in changeset but not in file
1040
1040
1041 $ hg tip -p
1041 $ hg tip -p
1042 changeset: 11:e00abbf63521
1042 changeset: 11:e00abbf63521
1043 tag: tip
1043 tag: tip
1044 parent: 9:800511b3a22d
1044 parent: 9:800511b3a22d
1045 user: test
1045 user: test
1046 date: Thu Jan 01 00:00:00 1970 +0000
1046 date: Thu Jan 01 00:00:00 1970 +0000
1047 summary: 9foobranch
1047 summary: 9foobranch
1048
1048
1049 diff -r 800511b3a22d -r e00abbf63521 a
1049 diff -r 800511b3a22d -r e00abbf63521 a
1050 --- a/a Thu Jan 01 00:00:00 1970 +0000
1050 --- a/a Thu Jan 01 00:00:00 1970 +0000
1051 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1051 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1052 @@ -1,3 +1,4 @@
1052 @@ -1,3 +1,4 @@
1053 +foobranch
1053 +foobranch
1054 expand $Id$
1054 expand $Id$
1055 do not process $Id:
1055 do not process $Id:
1056 xxx $
1056 xxx $
1057
1057
1058 $ head -n 2 a
1058 $ head -n 2 a
1059 foobranch
1059 foobranch
1060 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1060 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1061
1061
1062 Turn off expansion
1062 Turn off expansion
1063
1063
1064 $ hg -q rollback
1064 $ hg -q rollback
1065 $ hg -q update -C
1065 $ hg -q update -C
1066
1066
1067 kwshrink with unknown file u
1067 kwshrink with unknown file u
1068
1068
1069 $ cp a u
1069 $ cp a u
1070 $ hg --verbose kwshrink
1070 $ hg --verbose kwshrink
1071 overwriting a shrinking keywords
1071 overwriting a shrinking keywords
1072 overwriting m shrinking keywords
1072 overwriting m shrinking keywords
1073 overwriting x/a shrinking keywords
1073 overwriting x/a shrinking keywords
1074
1074
1075 Keywords shrunk in working directory, but not yet disabled
1075 Keywords shrunk in working directory, but not yet disabled
1076 - cat shows unexpanded keywords
1076 - cat shows unexpanded keywords
1077 - hg cat shows expanded keywords
1077 - hg cat shows expanded keywords
1078
1078
1079 $ cat a b
1079 $ cat a b
1080 expand $Id$
1080 expand $Id$
1081 do not process $Id:
1081 do not process $Id:
1082 xxx $
1082 xxx $
1083 $Xinfo$
1083 $Xinfo$
1084 ignore $Id$
1084 ignore $Id$
1085 $ hg cat sym a b && echo
1085 $ hg cat sym a b && echo
1086 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1086 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1087 do not process $Id:
1087 do not process $Id:
1088 xxx $
1088 xxx $
1089 $Xinfo: User Name <user@example.com>: firstline $
1089 $Xinfo: User Name <user@example.com>: firstline $
1090 ignore $Id$
1090 ignore $Id$
1091 a
1091 a
1092
1092
1093 Now disable keyword expansion
1093 Now disable keyword expansion
1094
1094
1095 $ rm "$HGRCPATH"
1095 $ rm "$HGRCPATH"
1096 $ cat a b
1096 $ cat a b
1097 expand $Id$
1097 expand $Id$
1098 do not process $Id:
1098 do not process $Id:
1099 xxx $
1099 xxx $
1100 $Xinfo$
1100 $Xinfo$
1101 ignore $Id$
1101 ignore $Id$
1102 $ hg cat sym a b && echo
1102 $ hg cat sym a b && echo
1103 expand $Id$
1103 expand $Id$
1104 do not process $Id:
1104 do not process $Id:
1105 xxx $
1105 xxx $
1106 $Xinfo$
1106 $Xinfo$
1107 ignore $Id$
1107 ignore $Id$
1108 a
1108 a
@@ -1,297 +1,297 b''
1 $ hg init repo1
1 $ hg init repo1
2 $ cd repo1
2 $ cd repo1
3 $ mkdir a b a/1 b/1 b/2
3 $ mkdir a b a/1 b/1 b/2
4 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
4 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
5
5
6 hg status in repo root:
6 hg status in repo root:
7
7
8 $ hg status
8 $ hg status
9 ? a/1/in_a_1
9 ? a/1/in_a_1
10 ? a/in_a
10 ? a/in_a
11 ? b/1/in_b_1
11 ? b/1/in_b_1
12 ? b/2/in_b_2
12 ? b/2/in_b_2
13 ? b/in_b
13 ? b/in_b
14 ? in_root
14 ? in_root
15
15
16 hg status . in repo root:
16 hg status . in repo root:
17
17
18 $ hg status .
18 $ hg status .
19 ? a/1/in_a_1
19 ? a/1/in_a_1
20 ? a/in_a
20 ? a/in_a
21 ? b/1/in_b_1
21 ? b/1/in_b_1
22 ? b/2/in_b_2
22 ? b/2/in_b_2
23 ? b/in_b
23 ? b/in_b
24 ? in_root
24 ? in_root
25
25
26 $ hg status --cwd a
26 $ hg status --cwd a
27 ? a/1/in_a_1
27 ? a/1/in_a_1
28 ? a/in_a
28 ? a/in_a
29 ? b/1/in_b_1
29 ? b/1/in_b_1
30 ? b/2/in_b_2
30 ? b/2/in_b_2
31 ? b/in_b
31 ? b/in_b
32 ? in_root
32 ? in_root
33 $ hg status --cwd a .
33 $ hg status --cwd a .
34 ? 1/in_a_1
34 ? 1/in_a_1
35 ? in_a
35 ? in_a
36 $ hg status --cwd a ..
36 $ hg status --cwd a ..
37 ? 1/in_a_1
37 ? 1/in_a_1
38 ? in_a
38 ? in_a
39 ? ../b/1/in_b_1
39 ? ../b/1/in_b_1
40 ? ../b/2/in_b_2
40 ? ../b/2/in_b_2
41 ? ../b/in_b
41 ? ../b/in_b
42 ? ../in_root
42 ? ../in_root
43
43
44 $ hg status --cwd b
44 $ hg status --cwd b
45 ? a/1/in_a_1
45 ? a/1/in_a_1
46 ? a/in_a
46 ? a/in_a
47 ? b/1/in_b_1
47 ? b/1/in_b_1
48 ? b/2/in_b_2
48 ? b/2/in_b_2
49 ? b/in_b
49 ? b/in_b
50 ? in_root
50 ? in_root
51 $ hg status --cwd b .
51 $ hg status --cwd b .
52 ? 1/in_b_1
52 ? 1/in_b_1
53 ? 2/in_b_2
53 ? 2/in_b_2
54 ? in_b
54 ? in_b
55 $ hg status --cwd b ..
55 $ hg status --cwd b ..
56 ? ../a/1/in_a_1
56 ? ../a/1/in_a_1
57 ? ../a/in_a
57 ? ../a/in_a
58 ? 1/in_b_1
58 ? 1/in_b_1
59 ? 2/in_b_2
59 ? 2/in_b_2
60 ? in_b
60 ? in_b
61 ? ../in_root
61 ? ../in_root
62
62
63 $ hg status --cwd a/1
63 $ hg status --cwd a/1
64 ? a/1/in_a_1
64 ? a/1/in_a_1
65 ? a/in_a
65 ? a/in_a
66 ? b/1/in_b_1
66 ? b/1/in_b_1
67 ? b/2/in_b_2
67 ? b/2/in_b_2
68 ? b/in_b
68 ? b/in_b
69 ? in_root
69 ? in_root
70 $ hg status --cwd a/1 .
70 $ hg status --cwd a/1 .
71 ? in_a_1
71 ? in_a_1
72 $ hg status --cwd a/1 ..
72 $ hg status --cwd a/1 ..
73 ? in_a_1
73 ? in_a_1
74 ? ../in_a
74 ? ../in_a
75
75
76 $ hg status --cwd b/1
76 $ hg status --cwd b/1
77 ? a/1/in_a_1
77 ? a/1/in_a_1
78 ? a/in_a
78 ? a/in_a
79 ? b/1/in_b_1
79 ? b/1/in_b_1
80 ? b/2/in_b_2
80 ? b/2/in_b_2
81 ? b/in_b
81 ? b/in_b
82 ? in_root
82 ? in_root
83 $ hg status --cwd b/1 .
83 $ hg status --cwd b/1 .
84 ? in_b_1
84 ? in_b_1
85 $ hg status --cwd b/1 ..
85 $ hg status --cwd b/1 ..
86 ? in_b_1
86 ? in_b_1
87 ? ../2/in_b_2
87 ? ../2/in_b_2
88 ? ../in_b
88 ? ../in_b
89
89
90 $ hg status --cwd b/2
90 $ hg status --cwd b/2
91 ? a/1/in_a_1
91 ? a/1/in_a_1
92 ? a/in_a
92 ? a/in_a
93 ? b/1/in_b_1
93 ? b/1/in_b_1
94 ? b/2/in_b_2
94 ? b/2/in_b_2
95 ? b/in_b
95 ? b/in_b
96 ? in_root
96 ? in_root
97 $ hg status --cwd b/2 .
97 $ hg status --cwd b/2 .
98 ? in_b_2
98 ? in_b_2
99 $ hg status --cwd b/2 ..
99 $ hg status --cwd b/2 ..
100 ? ../1/in_b_1
100 ? ../1/in_b_1
101 ? in_b_2
101 ? in_b_2
102 ? ../in_b
102 ? ../in_b
103 $ cd ..
103 $ cd ..
104
104
105 $ hg init repo2
105 $ hg init repo2
106 $ cd repo2
106 $ cd repo2
107 $ touch modified removed deleted ignored
107 $ touch modified removed deleted ignored
108 $ echo "^ignored$" > .hgignore
108 $ echo "^ignored$" > .hgignore
109 $ hg ci -A -m 'initial checkin'
109 $ hg ci -A -m 'initial checkin'
110 adding .hgignore
110 adding .hgignore
111 adding deleted
111 adding deleted
112 adding modified
112 adding modified
113 adding removed
113 adding removed
114 $ touch modified added unknown ignored
114 $ touch modified added unknown ignored
115 $ hg add added
115 $ hg add added
116 $ hg remove removed
116 $ hg remove removed
117 $ rm deleted
117 $ rm deleted
118
118
119 hg status:
119 hg status:
120
120
121 $ hg status
121 $ hg status
122 A added
122 A added
123 R removed
123 R removed
124 ! deleted
124 ! deleted
125 ? unknown
125 ? unknown
126
126
127 hg status modified added removed deleted unknown never-existed ignored:
127 hg status modified added removed deleted unknown never-existed ignored:
128
128
129 $ hg status modified added removed deleted unknown never-existed ignored
129 $ hg status modified added removed deleted unknown never-existed ignored
130 never-existed: * (glob)
130 never-existed: * (glob)
131 A added
131 A added
132 R removed
132 R removed
133 ! deleted
133 ! deleted
134 ? unknown
134 ? unknown
135
135
136 $ hg copy modified copied
136 $ hg copy modified copied
137
137
138 hg status -C:
138 hg status -C:
139
139
140 $ hg status -C
140 $ hg status -C
141 A added
141 A added
142 A copied
142 A copied
143 modified
143 modified
144 R removed
144 R removed
145 ! deleted
145 ! deleted
146 ? unknown
146 ? unknown
147
147
148 hg status -A:
148 hg status -A:
149
149
150 $ hg status -A
150 $ hg status -A
151 A added
151 A added
152 A copied
152 A copied
153 modified
153 modified
154 R removed
154 R removed
155 ! deleted
155 ! deleted
156 ? unknown
156 ? unknown
157 I ignored
157 I ignored
158 C .hgignore
158 C .hgignore
159 C modified
159 C modified
160
160
161
161
162 $ echo "^ignoreddir$" > .hgignore
162 $ echo "^ignoreddir$" > .hgignore
163 $ mkdir ignoreddir
163 $ mkdir ignoreddir
164 $ touch ignoreddir/file
164 $ touch ignoreddir/file
165
165
166 hg status ignoreddir/file:
166 hg status ignoreddir/file:
167
167
168 $ hg status ignoreddir/file
168 $ hg status ignoreddir/file
169
169
170 hg status -i ignoreddir/file:
170 hg status -i ignoreddir/file:
171
171
172 $ hg status -i ignoreddir/file
172 $ hg status -i ignoreddir/file
173 I ignoreddir/file
173 I ignoreddir/file
174 $ cd ..
174 $ cd ..
175
175
176 Check 'status -q' and some combinations
176 Check 'status -q' and some combinations
177
177
178 $ hg init repo3
178 $ hg init repo3
179 $ cd repo3
179 $ cd repo3
180 $ touch modified removed deleted ignored
180 $ touch modified removed deleted ignored
181 $ echo "^ignored$" > .hgignore
181 $ echo "^ignored$" > .hgignore
182 $ hg commit -A -m 'initial checkin'
182 $ hg commit -A -m 'initial checkin'
183 adding .hgignore
183 adding .hgignore
184 adding deleted
184 adding deleted
185 adding modified
185 adding modified
186 adding removed
186 adding removed
187 $ touch added unknown ignored
187 $ touch added unknown ignored
188 $ hg add added
188 $ hg add added
189 $ echo "test" >> modified
189 $ echo "test" >> modified
190 $ hg remove removed
190 $ hg remove removed
191 $ rm deleted
191 $ rm deleted
192 $ hg copy modified copied
192 $ hg copy modified copied
193
193
194 Run status with 2 different flags.
194 Run status with 2 different flags.
195 Check if result is the same or different.
195 Check if result is the same or different.
196 If result is not as expected, raise error
196 If result is not as expected, raise error
197
197
198 $ assert() {
198 $ assert() {
199 > hg status $1 > ../a
199 > hg status $1 > ../a
200 > hg status $2 > ../b
200 > hg status $2 > ../b
201 > if diff ../a ../b > /dev/null; then
201 > if diff ../a ../b > /dev/null; then
202 > out=0
202 > out=0
203 > else
203 > else
204 > out=1
204 > out=1
205 > fi
205 > fi
206 > if [ $3 -eq 0 ]; then
206 > if [ $3 -eq 0 ]; then
207 > df="same"
207 > df="same"
208 > else
208 > else
209 > df="different"
209 > df="different"
210 > fi
210 > fi
211 > if [ $out -ne $3 ]; then
211 > if [ $out -ne $3 ]; then
212 > echo "Error on $1 and $2, should be $df."
212 > echo "Error on $1 and $2, should be $df."
213 > fi
213 > fi
214 > }
214 > }
215
215
216 Assert flag1 flag2 [0-same | 1-different]
216 Assert flag1 flag2 [0-same | 1-different]
217
217
218 $ assert "-q" "-mard" 0
218 $ assert "-q" "-mard" 0
219 $ assert "-A" "-marduicC" 0
219 $ assert "-A" "-marduicC" 0
220 $ assert "-qA" "-mardcC" 0
220 $ assert "-qA" "-mardcC" 0
221 $ assert "-qAui" "-A" 0
221 $ assert "-qAui" "-A" 0
222 $ assert "-qAu" "-marducC" 0
222 $ assert "-qAu" "-marducC" 0
223 $ assert "-qAi" "-mardicC" 0
223 $ assert "-qAi" "-mardicC" 0
224 $ assert "-qu" "-u" 0
224 $ assert "-qu" "-u" 0
225 $ assert "-q" "-u" 1
225 $ assert "-q" "-u" 1
226 $ assert "-m" "-a" 1
226 $ assert "-m" "-a" 1
227 $ assert "-r" "-d" 1
227 $ assert "-r" "-d" 1
228 $ cd ..
228 $ cd ..
229
229
230 $ hg init repo4
230 $ hg init repo4
231 $ cd repo4
231 $ cd repo4
232 $ touch modified removed deleted
232 $ touch modified removed deleted
233 $ hg ci -q -A -m 'initial checkin'
233 $ hg ci -q -A -m 'initial checkin'
234 $ touch added unknown
234 $ touch added unknown
235 $ hg add added
235 $ hg add added
236 $ hg remove removed
236 $ hg remove removed
237 $ rm deleted
237 $ rm deleted
238 $ echo x > modified
238 $ echo x > modified
239 $ hg copy modified copied
239 $ hg copy modified copied
240 $ hg ci -m 'test checkin' -d "1000001 0"
240 $ hg ci -m 'test checkin' -d "1000001 0"
241 $ rm *
241 $ rm *
242 $ touch unrelated
242 $ touch unrelated
243 $ hg ci -q -A -m 'unrelated checkin' -d "1000002 0"
243 $ hg ci -q -A -m 'unrelated checkin' -d "1000002 0"
244
244
245 hg status --change 1:
245 hg status --change 1:
246
246
247 $ hg status --change 1
247 $ hg status --change 1
248 M modified
248 M modified
249 A added
249 A added
250 A copied
250 A copied
251 R removed
251 R removed
252
252
253 hg status --change 1 unrelated:
253 hg status --change 1 unrelated:
254
254
255 $ hg status --change 1 unrelated
255 $ hg status --change 1 unrelated
256
256
257 hg status -C --change 1 added modified copied removed deleted:
257 hg status -C --change 1 added modified copied removed deleted:
258
258
259 $ hg status -C --change 1 added modified copied removed deleted
259 $ hg status -C --change 1 added modified copied removed deleted
260 M modified
260 M modified
261 A added
261 A added
262 A copied
262 A copied
263 modified
263 modified
264 R removed
264 R removed
265
265
266 hg status -A --change 1 and revset:
266 hg status -A --change 1 and revset:
267
267
268 $ hg status -A --change '1|1'
268 $ hg status -A --change '1|1'
269 M modified
269 M modified
270 A added
270 A added
271 A copied
271 A copied
272 modified
272 modified
273 R removed
273 R removed
274 C deleted
274 C deleted
275
275
276 $ cd ..
276 $ cd ..
277
277
278 hg status of binary file starting with '\1\n', a separator for metadata:
278 hg status of binary file starting with '\1\n', a separator for metadata:
279
279
280 $ hg init repo5
280 $ hg init repo5
281 $ cd repo5
281 $ cd repo5
282 $ printf '\1\nfoo' > 010a
282 >>> open("010a", "wb").write("\1\nfoo")
283 $ hg ci -q -A -m 'initial checkin'
283 $ hg ci -q -A -m 'initial checkin'
284 $ hg status -A
284 $ hg status -A
285 C 010a
285 C 010a
286
286
287 $ printf '\1\nbar' > 010a
287 >>> open("010a", "wb").write("\1\nbar")
288 $ hg status -A
288 $ hg status -A
289 M 010a
289 M 010a
290 $ hg ci -q -m 'modify 010a'
290 $ hg ci -q -m 'modify 010a'
291 $ hg status -A --rev 0:1
291 $ hg status -A --rev 0:1
292 M 010a
292 M 010a
293
293
294 $ touch empty
294 $ touch empty
295 $ hg ci -q -A -m 'add another file'
295 $ hg ci -q -A -m 'add another file'
296 $ hg status -A --rev 1:2 010a
296 $ hg status -A --rev 1:2 010a
297 C 010a
297 C 010a
@@ -1,59 +1,59 b''
1 $ hg init outer
1 $ hg init outer
2 $ cd outer
2 $ cd outer
3
3
4 $ echo '[paths]' >> .hg/hgrc
4 $ echo '[paths]' >> .hg/hgrc
5 $ echo 'default = http://example.net/' >> .hg/hgrc
5 $ echo 'default = http://example.net/' >> .hg/hgrc
6
6
7 hg debugsub with no remapping
7 hg debugsub with no remapping
8
8
9 $ echo 'sub = libfoo' > .hgsub
9 $ echo 'sub = libfoo' > .hgsub
10 $ hg add .hgsub
10 $ hg add .hgsub
11
11
12 $ hg debugsub
12 $ hg debugsub
13 path sub
13 path sub
14 source libfoo
14 source libfoo
15 revision
15 revision
16
16
17 hg debugsub with remapping
17 hg debugsub with remapping
18
18
19 $ echo '[subpaths]' >> .hg/hgrc
19 $ echo '[subpaths]' >> .hg/hgrc
20 $ printf 'http://example.net/lib(.*) = C:\\libs\\\\1-lib\\\n' >> .hg/hgrc
20 $ printf 'http://example.net/lib(.*) = C:\\libs\\\\1-lib\\\n' >> .hg/hgrc # no-check-code
21
21
22 $ hg debugsub
22 $ hg debugsub
23 path sub
23 path sub
24 source C:\libs\foo-lib\
24 source C:\libs\foo-lib\
25 revision
25 revision
26
26
27 test cumulative remapping, the $HGRCPATH file is loaded first
27 test cumulative remapping, the $HGRCPATH file is loaded first
28
28
29 $ echo '[subpaths]' >> $HGRCPATH
29 $ echo '[subpaths]' >> $HGRCPATH
30 $ echo 'libfoo = libbar' >> $HGRCPATH
30 $ echo 'libfoo = libbar' >> $HGRCPATH
31 $ hg debugsub
31 $ hg debugsub
32 path sub
32 path sub
33 source C:\libs\bar-lib\
33 source C:\libs\bar-lib\
34 revision
34 revision
35
35
36 test absolute source path -- testing with a URL is important since
36 test absolute source path -- testing with a URL is important since
37 standard os.path.join wont treat that as an absolute path
37 standard os.path.join wont treat that as an absolute path
38
38
39 $ echo 'abs = http://example.net/abs' > .hgsub
39 $ echo 'abs = http://example.net/abs' > .hgsub
40 $ hg debugsub
40 $ hg debugsub
41 path abs
41 path abs
42 source http://example.net/abs
42 source http://example.net/abs
43 revision
43 revision
44
44
45 $ echo 'abs = /abs' > .hgsub
45 $ echo 'abs = /abs' > .hgsub
46 $ hg debugsub
46 $ hg debugsub
47 path abs
47 path abs
48 source /abs
48 source /abs
49 revision
49 revision
50
50
51 test bad subpaths pattern
51 test bad subpaths pattern
52
52
53 $ cat > .hg/hgrc <<EOF
53 $ cat > .hg/hgrc <<EOF
54 > [subpaths]
54 > [subpaths]
55 > .* = \1
55 > .* = \1
56 > EOF
56 > EOF
57 $ hg debugsub
57 $ hg debugsub
58 abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference (glob)
58 abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference (glob)
59 [255]
59 [255]
General Comments 0
You need to be logged in to leave comments. Login now