##// END OF EJS Templates
Merge
Bryan O'Sullivan -
r17713:2c638277 merge default
parent child Browse files
Show More
@@ -1,453 +1,454 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'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
48 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
49 (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
49 (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
50 (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
50 (r'\becho\b.*\\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'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"),
52 (r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"),
53 (r'head -c', "don't use 'head -c', use 'dd'"),
53 (r'head -c', "don't use 'head -c', use 'dd'"),
54 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
54 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
55 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
55 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
56 (r'printf.*\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
56 (r'printf.*\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
57 (r'printf.*\\x', "don't use printf \\x, use Python"),
57 (r'printf.*\\x', "don't use printf \\x, use Python"),
58 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
58 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
59 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
59 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
60 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
60 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
61 "use egrep for extended grep syntax"),
61 "use egrep for extended grep syntax"),
62 (r'/bin/', "don't use explicit paths for tools"),
62 (r'/bin/', "don't use explicit paths for tools"),
63 (r'[^\n]\Z', "no trailing newline"),
63 (r'[^\n]\Z', "no trailing newline"),
64 (r'export.*=', "don't export and assign at once"),
64 (r'export.*=', "don't export and assign at once"),
65 (r'^source\b', "don't use 'source', use '.'"),
65 (r'^source\b', "don't use 'source', use '.'"),
66 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
66 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
67 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
67 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
68 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
68 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
69 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
69 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
70 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
70 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
71 (r'^alias\b.*=', "don't use alias, use a function"),
71 (r'^alias\b.*=', "don't use alias, use a function"),
72 (r'if\s*!', "don't use '!' to negate exit status"),
72 (r'if\s*!', "don't use '!' to negate exit status"),
73 (r'/dev/u?random', "don't use entropy, use /dev/zero"),
73 (r'/dev/u?random', "don't use entropy, use /dev/zero"),
74 (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
74 (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
75 (r'^( *)\t', "don't use tabs to indent"),
75 (r'^( *)\t', "don't use tabs to indent"),
76 ],
76 ],
77 # warnings
77 # warnings
78 [
78 [
79 (r'^function', "don't use 'function', use old style"),
79 (r'^function', "don't use 'function', use old style"),
80 (r'^diff.*-\w*N', "don't use 'diff -N'"),
80 (r'^diff.*-\w*N', "don't use 'diff -N'"),
81 (r'\$PWD', "don't use $PWD, use `pwd`"),
81 (r'\$PWD', "don't use $PWD, use `pwd`"),
82 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
82 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
83 ]
83 ]
84 ]
84 ]
85
85
86 testfilters = [
86 testfilters = [
87 (r"( *)(#([^\n]*\S)?)", repcomment),
87 (r"( *)(#([^\n]*\S)?)", repcomment),
88 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
88 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
89 ]
89 ]
90
90
91 uprefix = r"^ \$ "
91 uprefix = r"^ \$ "
92 utestpats = [
92 utestpats = [
93 [
93 [
94 (r'^(\S.*|| [$>] .*)[ \t]\n', "trailing whitespace on non-output"),
94 (r'^(\S.*|| [$>] .*)[ \t]\n', "trailing whitespace on non-output"),
95 (uprefix + r'.*\|\s*sed[^|>\n]*\n',
95 (uprefix + r'.*\|\s*sed[^|>\n]*\n',
96 "use regex test output patterns instead of sed"),
96 "use regex test output patterns instead of sed"),
97 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
97 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
98 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
98 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
99 (uprefix + r'.*\|\| echo.*(fail|error)',
99 (uprefix + r'.*\|\| echo.*(fail|error)',
100 "explicit exit code checks unnecessary"),
100 "explicit exit code checks unnecessary"),
101 (uprefix + r'set -e', "don't use set -e"),
101 (uprefix + r'set -e', "don't use set -e"),
102 (uprefix + r'\s', "don't indent commands, use > for continued lines"),
102 (uprefix + r'\s', "don't indent commands, use > for continued lines"),
103 (r'^ saved backup bundle to \$TESTTMP.*\.hg$',
103 (r'^ saved backup bundle to \$TESTTMP.*\.hg$',
104 "use (glob) to match Windows paths too"),
104 "use (glob) to match Windows paths too"),
105 ],
105 ],
106 # warnings
106 # warnings
107 []
107 []
108 ]
108 ]
109
109
110 for i in [0, 1]:
110 for i in [0, 1]:
111 for p, m in testpats[i]:
111 for p, m in testpats[i]:
112 if p.startswith(r'^'):
112 if p.startswith(r'^'):
113 p = r"^ [$>] (%s)" % p[1:]
113 p = r"^ [$>] (%s)" % p[1:]
114 else:
114 else:
115 p = r"^ [$>] .*(%s)" % p
115 p = r"^ [$>] .*(%s)" % p
116 utestpats[i].append((p, m))
116 utestpats[i].append((p, m))
117
117
118 utestfilters = [
118 utestfilters = [
119 (r"<<(\S+)((.|\n)*?\n > \1)", rephere),
119 (r"( *)(#([^\n]*\S)?)", repcomment),
120 (r"( *)(#([^\n]*\S)?)", repcomment),
120 ]
121 ]
121
122
122 pypats = [
123 pypats = [
123 [
124 [
124 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
125 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
125 "tuple parameter unpacking not available in Python 3+"),
126 "tuple parameter unpacking not available in Python 3+"),
126 (r'lambda\s*\(.*,.*\)',
127 (r'lambda\s*\(.*,.*\)',
127 "tuple parameter unpacking not available in Python 3+"),
128 "tuple parameter unpacking not available in Python 3+"),
128 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
129 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
129 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
130 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
130 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
131 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
131 (r'^\s*\t', "don't use tabs"),
132 (r'^\s*\t', "don't use tabs"),
132 (r'\S;\s*\n', "semicolon"),
133 (r'\S;\s*\n', "semicolon"),
133 (r'[^_]_\("[^"]+"\s*%', "don't use % inside _()"),
134 (r'[^_]_\("[^"]+"\s*%', "don't use % inside _()"),
134 (r"[^_]_\('[^']+'\s*%", "don't use % inside _()"),
135 (r"[^_]_\('[^']+'\s*%", "don't use % inside _()"),
135 (r'\w,\w', "missing whitespace after ,"),
136 (r'\w,\w', "missing whitespace after ,"),
136 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
137 (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
137 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
138 (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"),
138 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
139 (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
139 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Python 2.4'),
140 r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Python 2.4'),
140 (r'(\s+)try:\n((?:\n|\1\s.*\n)*?)\1\s*yield\b.*?'
141 (r'(\s+)try:\n((?:\n|\1\s.*\n)*?)\1\s*yield\b.*?'
141 r'((?:\n|\1\s.*\n)+?)\1finally:',
142 r'((?:\n|\1\s.*\n)+?)\1finally:',
142 'no yield inside try/finally in Python 2.4'),
143 'no yield inside try/finally in Python 2.4'),
143 (r'.{81}', "line too long"),
144 (r'.{81}', "line too long"),
144 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
145 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
145 (r'[^\n]\Z', "no trailing newline"),
146 (r'[^\n]\Z', "no trailing newline"),
146 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
147 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
147 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
148 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
148 # "don't use underbars in identifiers"),
149 # "don't use underbars in identifiers"),
149 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
150 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
150 "don't use camelcase in identifiers"),
151 "don't use camelcase in identifiers"),
151 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
152 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
152 "linebreak after :"),
153 "linebreak after :"),
153 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
154 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
154 (r'class\s[^( \n]+\(\):',
155 (r'class\s[^( \n]+\(\):',
155 "class foo() not available in Python 2.4, use class foo(object)"),
156 "class foo() not available in Python 2.4, use class foo(object)"),
156 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
157 (r'\b(%s)\(' % '|'.join(keyword.kwlist),
157 "Python keyword is not a function"),
158 "Python keyword is not a function"),
158 (r',]', "unneeded trailing ',' in list"),
159 (r',]', "unneeded trailing ',' in list"),
159 # (r'class\s[A-Z][^\(]*\((?!Exception)',
160 # (r'class\s[A-Z][^\(]*\((?!Exception)',
160 # "don't capitalize non-exception classes"),
161 # "don't capitalize non-exception classes"),
161 # (r'in range\(', "use xrange"),
162 # (r'in range\(', "use xrange"),
162 # (r'^\s*print\s+', "avoid using print in core and extensions"),
163 # (r'^\s*print\s+', "avoid using print in core and extensions"),
163 (r'[\x80-\xff]', "non-ASCII character literal"),
164 (r'[\x80-\xff]', "non-ASCII character literal"),
164 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
165 (r'("\')\.format\(', "str.format() not available in Python 2.4"),
165 (r'^\s*with\s+', "with not available in Python 2.4"),
166 (r'^\s*with\s+', "with not available in Python 2.4"),
166 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
167 (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
167 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
168 (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
168 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
169 (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
169 (r'(?<!def)\s+(any|all|format)\(',
170 (r'(?<!def)\s+(any|all|format)\(',
170 "any/all/format not available in Python 2.4"),
171 "any/all/format not available in Python 2.4"),
171 (r'(?<!def)\s+(callable)\(',
172 (r'(?<!def)\s+(callable)\(',
172 "callable not available in Python 3, use getattr(f, '__call__', None)"),
173 "callable not available in Python 3, use getattr(f, '__call__', None)"),
173 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
174 (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
174 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
175 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
175 "gratuitous whitespace after Python keyword"),
176 "gratuitous whitespace after Python keyword"),
176 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
177 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
177 # (r'\s\s=', "gratuitous whitespace before ="),
178 # (r'\s\s=', "gratuitous whitespace before ="),
178 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
179 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
179 "missing whitespace around operator"),
180 "missing whitespace around operator"),
180 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
181 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
181 "missing whitespace around operator"),
182 "missing whitespace around operator"),
182 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
183 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
183 "missing whitespace around operator"),
184 "missing whitespace around operator"),
184 (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
185 (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
185 "wrong whitespace around ="),
186 "wrong whitespace around ="),
186 (r'raise Exception', "don't raise generic exceptions"),
187 (r'raise Exception', "don't raise generic exceptions"),
187 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
188 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
188 (r' [=!]=\s+(True|False|None)',
189 (r' [=!]=\s+(True|False|None)',
189 "comparison with singleton, use 'is' or 'is not' instead"),
190 "comparison with singleton, use 'is' or 'is not' instead"),
190 (r'^\s*(while|if) [01]:',
191 (r'^\s*(while|if) [01]:',
191 "use True/False for constant Boolean expression"),
192 "use True/False for constant Boolean expression"),
192 (r'(?:(?<!def)\s+|\()hasattr',
193 (r'(?:(?<!def)\s+|\()hasattr',
193 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
194 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
194 (r'opener\([^)]*\).read\(',
195 (r'opener\([^)]*\).read\(',
195 "use opener.read() instead"),
196 "use opener.read() instead"),
196 (r'BaseException', 'not in Python 2.4, use Exception'),
197 (r'BaseException', 'not in Python 2.4, use Exception'),
197 (r'os\.path\.relpath', 'os.path.relpath is not in Python 2.5'),
198 (r'os\.path\.relpath', 'os.path.relpath is not in Python 2.5'),
198 (r'opener\([^)]*\).write\(',
199 (r'opener\([^)]*\).write\(',
199 "use opener.write() instead"),
200 "use opener.write() instead"),
200 (r'[\s\(](open|file)\([^)]*\)\.read\(',
201 (r'[\s\(](open|file)\([^)]*\)\.read\(',
201 "use util.readfile() instead"),
202 "use util.readfile() instead"),
202 (r'[\s\(](open|file)\([^)]*\)\.write\(',
203 (r'[\s\(](open|file)\([^)]*\)\.write\(',
203 "use util.readfile() instead"),
204 "use util.readfile() instead"),
204 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
205 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
205 "always assign an opened file to a variable, and close it afterwards"),
206 "always assign an opened file to a variable, and close it afterwards"),
206 (r'[\s\(](open|file)\([^)]*\)\.',
207 (r'[\s\(](open|file)\([^)]*\)\.',
207 "always assign an opened file to a variable, and close it afterwards"),
208 "always assign an opened file to a variable, and close it afterwards"),
208 (r'(?i)descendent', "the proper spelling is descendAnt"),
209 (r'(?i)descendent', "the proper spelling is descendAnt"),
209 (r'\.debug\(\_', "don't mark debug messages for translation"),
210 (r'\.debug\(\_', "don't mark debug messages for translation"),
210 (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
211 (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
211 (r'^\s*except\s*:', "warning: naked except clause", r'#.*re-raises'),
212 (r'^\s*except\s*:', "warning: naked except clause", r'#.*re-raises'),
212 (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"),
213 (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"),
213 ],
214 ],
214 # warnings
215 # warnings
215 [
216 [
216 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
217 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
217 "warning: unwrapped ui message"),
218 "warning: unwrapped ui message"),
218 ]
219 ]
219 ]
220 ]
220
221
221 pyfilters = [
222 pyfilters = [
222 (r"""(?msx)(?P<comment>\#.*?$)|
223 (r"""(?msx)(?P<comment>\#.*?$)|
223 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
224 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
224 (?P<text>(([^\\]|\\.)*?))
225 (?P<text>(([^\\]|\\.)*?))
225 (?P=quote))""", reppython),
226 (?P=quote))""", reppython),
226 ]
227 ]
227
228
228 cpats = [
229 cpats = [
229 [
230 [
230 (r'//', "don't use //-style comments"),
231 (r'//', "don't use //-style comments"),
231 (r'^ ', "don't use spaces to indent"),
232 (r'^ ', "don't use spaces to indent"),
232 (r'\S\t', "don't use tabs except for indent"),
233 (r'\S\t', "don't use tabs except for indent"),
233 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
234 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
234 (r'.{81}', "line too long"),
235 (r'.{81}', "line too long"),
235 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
236 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
236 (r'return\(', "return is not a function"),
237 (r'return\(', "return is not a function"),
237 (r' ;', "no space before ;"),
238 (r' ;', "no space before ;"),
238 (r'\w+\* \w+', "use int *foo, not int* foo"),
239 (r'\w+\* \w+', "use int *foo, not int* foo"),
239 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
240 (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
240 (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
241 (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
241 (r'\w,\w', "missing whitespace after ,"),
242 (r'\w,\w', "missing whitespace after ,"),
242 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
243 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
243 (r'^#\s+\w', "use #foo, not # foo"),
244 (r'^#\s+\w', "use #foo, not # foo"),
244 (r'[^\n]\Z', "no trailing newline"),
245 (r'[^\n]\Z', "no trailing newline"),
245 (r'^\s*#import\b', "use only #include in standard C code"),
246 (r'^\s*#import\b', "use only #include in standard C code"),
246 ],
247 ],
247 # warnings
248 # warnings
248 []
249 []
249 ]
250 ]
250
251
251 cfilters = [
252 cfilters = [
252 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
253 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
253 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
254 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
254 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
255 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
255 (r'(\()([^)]+\))', repcallspaces),
256 (r'(\()([^)]+\))', repcallspaces),
256 ]
257 ]
257
258
258 inutilpats = [
259 inutilpats = [
259 [
260 [
260 (r'\bui\.', "don't use ui in util"),
261 (r'\bui\.', "don't use ui in util"),
261 ],
262 ],
262 # warnings
263 # warnings
263 []
264 []
264 ]
265 ]
265
266
266 inrevlogpats = [
267 inrevlogpats = [
267 [
268 [
268 (r'\brepo\.', "don't use repo in revlog"),
269 (r'\brepo\.', "don't use repo in revlog"),
269 ],
270 ],
270 # warnings
271 # warnings
271 []
272 []
272 ]
273 ]
273
274
274 checks = [
275 checks = [
275 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
276 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
276 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
277 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
277 ('c', r'.*\.c$', cfilters, cpats),
278 ('c', r'.*\.c$', cfilters, cpats),
278 ('unified test', r'.*\.t$', utestfilters, utestpats),
279 ('unified test', r'.*\.t$', utestfilters, utestpats),
279 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
280 ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
280 inrevlogpats),
281 inrevlogpats),
281 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
282 ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
282 inutilpats),
283 inutilpats),
283 ]
284 ]
284
285
285 class norepeatlogger(object):
286 class norepeatlogger(object):
286 def __init__(self):
287 def __init__(self):
287 self._lastseen = None
288 self._lastseen = None
288
289
289 def log(self, fname, lineno, line, msg, blame):
290 def log(self, fname, lineno, line, msg, blame):
290 """print error related a to given line of a given file.
291 """print error related a to given line of a given file.
291
292
292 The faulty line will also be printed but only once in the case
293 The faulty line will also be printed but only once in the case
293 of multiple errors.
294 of multiple errors.
294
295
295 :fname: filename
296 :fname: filename
296 :lineno: line number
297 :lineno: line number
297 :line: actual content of the line
298 :line: actual content of the line
298 :msg: error message
299 :msg: error message
299 """
300 """
300 msgid = fname, lineno, line
301 msgid = fname, lineno, line
301 if msgid != self._lastseen:
302 if msgid != self._lastseen:
302 if blame:
303 if blame:
303 print "%s:%d (%s):" % (fname, lineno, blame)
304 print "%s:%d (%s):" % (fname, lineno, blame)
304 else:
305 else:
305 print "%s:%d:" % (fname, lineno)
306 print "%s:%d:" % (fname, lineno)
306 print " > %s" % line
307 print " > %s" % line
307 self._lastseen = msgid
308 self._lastseen = msgid
308 print " " + msg
309 print " " + msg
309
310
310 _defaultlogger = norepeatlogger()
311 _defaultlogger = norepeatlogger()
311
312
312 def getblame(f):
313 def getblame(f):
313 lines = []
314 lines = []
314 for l in os.popen('hg annotate -un %s' % f):
315 for l in os.popen('hg annotate -un %s' % f):
315 start, line = l.split(':', 1)
316 start, line = l.split(':', 1)
316 user, rev = start.split()
317 user, rev = start.split()
317 lines.append((line[1:-1], user, rev))
318 lines.append((line[1:-1], user, rev))
318 return lines
319 return lines
319
320
320 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
321 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
321 blame=False, debug=False, lineno=True):
322 blame=False, debug=False, lineno=True):
322 """checks style and portability of a given file
323 """checks style and portability of a given file
323
324
324 :f: filepath
325 :f: filepath
325 :logfunc: function used to report error
326 :logfunc: function used to report error
326 logfunc(filename, linenumber, linecontent, errormessage)
327 logfunc(filename, linenumber, linecontent, errormessage)
327 :maxerr: number of error to display before aborting.
328 :maxerr: number of error to display before aborting.
328 Set to false (default) to report all errors
329 Set to false (default) to report all errors
329
330
330 return True if no error is found, False otherwise.
331 return True if no error is found, False otherwise.
331 """
332 """
332 blamecache = None
333 blamecache = None
333 result = True
334 result = True
334 for name, match, filters, pats in checks:
335 for name, match, filters, pats in checks:
335 if debug:
336 if debug:
336 print name, f
337 print name, f
337 fc = 0
338 fc = 0
338 if not re.match(match, f):
339 if not re.match(match, f):
339 if debug:
340 if debug:
340 print "Skipping %s for %s it doesn't match %s" % (
341 print "Skipping %s for %s it doesn't match %s" % (
341 name, match, f)
342 name, match, f)
342 continue
343 continue
343 fp = open(f)
344 fp = open(f)
344 pre = post = fp.read()
345 pre = post = fp.read()
345 fp.close()
346 fp.close()
346 if "no-" + "check-code" in pre:
347 if "no-" + "check-code" in pre:
347 if debug:
348 if debug:
348 print "Skipping %s for %s it has no- and check-code" % (
349 print "Skipping %s for %s it has no- and check-code" % (
349 name, f)
350 name, f)
350 break
351 break
351 for p, r in filters:
352 for p, r in filters:
352 post = re.sub(p, r, post)
353 post = re.sub(p, r, post)
353 if warnings:
354 if warnings:
354 pats = pats[0] + pats[1]
355 pats = pats[0] + pats[1]
355 else:
356 else:
356 pats = pats[0]
357 pats = pats[0]
357 # print post # uncomment to show filtered version
358 # print post # uncomment to show filtered version
358
359
359 if debug:
360 if debug:
360 print "Checking %s for %s" % (name, f)
361 print "Checking %s for %s" % (name, f)
361
362
362 prelines = None
363 prelines = None
363 errors = []
364 errors = []
364 for pat in pats:
365 for pat in pats:
365 if len(pat) == 3:
366 if len(pat) == 3:
366 p, msg, ignore = pat
367 p, msg, ignore = pat
367 else:
368 else:
368 p, msg = pat
369 p, msg = pat
369 ignore = None
370 ignore = None
370
371
371 # fix-up regexes for multi-line searches
372 # fix-up regexes for multi-line searches
372 po = p
373 po = p
373 # \s doesn't match \n
374 # \s doesn't match \n
374 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
375 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
375 # [^...] doesn't match newline
376 # [^...] doesn't match newline
376 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
377 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
377
378
378 #print po, '=>', p
379 #print po, '=>', p
379
380
380 pos = 0
381 pos = 0
381 n = 0
382 n = 0
382 for m in re.finditer(p, post, re.MULTILINE):
383 for m in re.finditer(p, post, re.MULTILINE):
383 if prelines is None:
384 if prelines is None:
384 prelines = pre.splitlines()
385 prelines = pre.splitlines()
385 postlines = post.splitlines(True)
386 postlines = post.splitlines(True)
386
387
387 start = m.start()
388 start = m.start()
388 while n < len(postlines):
389 while n < len(postlines):
389 step = len(postlines[n])
390 step = len(postlines[n])
390 if pos + step > start:
391 if pos + step > start:
391 break
392 break
392 pos += step
393 pos += step
393 n += 1
394 n += 1
394 l = prelines[n]
395 l = prelines[n]
395
396
396 if "check-code" + "-ignore" in l:
397 if "check-code" + "-ignore" in l:
397 if debug:
398 if debug:
398 print "Skipping %s for %s:%s (check-code -ignore)" % (
399 print "Skipping %s for %s:%s (check-code -ignore)" % (
399 name, f, n)
400 name, f, n)
400 continue
401 continue
401 elif ignore and re.search(ignore, l, re.MULTILINE):
402 elif ignore and re.search(ignore, l, re.MULTILINE):
402 continue
403 continue
403 bd = ""
404 bd = ""
404 if blame:
405 if blame:
405 bd = 'working directory'
406 bd = 'working directory'
406 if not blamecache:
407 if not blamecache:
407 blamecache = getblame(f)
408 blamecache = getblame(f)
408 if n < len(blamecache):
409 if n < len(blamecache):
409 bl, bu, br = blamecache[n]
410 bl, bu, br = blamecache[n]
410 if bl == l:
411 if bl == l:
411 bd = '%s@%s' % (bu, br)
412 bd = '%s@%s' % (bu, br)
412 errors.append((f, lineno and n + 1, l, msg, bd))
413 errors.append((f, lineno and n + 1, l, msg, bd))
413 result = False
414 result = False
414
415
415 errors.sort()
416 errors.sort()
416 for e in errors:
417 for e in errors:
417 logfunc(*e)
418 logfunc(*e)
418 fc += 1
419 fc += 1
419 if maxerr and fc >= maxerr:
420 if maxerr and fc >= maxerr:
420 print " (too many errors, giving up)"
421 print " (too many errors, giving up)"
421 break
422 break
422
423
423 return result
424 return result
424
425
425 if __name__ == "__main__":
426 if __name__ == "__main__":
426 parser = optparse.OptionParser("%prog [options] [files]")
427 parser = optparse.OptionParser("%prog [options] [files]")
427 parser.add_option("-w", "--warnings", action="store_true",
428 parser.add_option("-w", "--warnings", action="store_true",
428 help="include warning-level checks")
429 help="include warning-level checks")
429 parser.add_option("-p", "--per-file", type="int",
430 parser.add_option("-p", "--per-file", type="int",
430 help="max warnings per file")
431 help="max warnings per file")
431 parser.add_option("-b", "--blame", action="store_true",
432 parser.add_option("-b", "--blame", action="store_true",
432 help="use annotate to generate blame info")
433 help="use annotate to generate blame info")
433 parser.add_option("", "--debug", action="store_true",
434 parser.add_option("", "--debug", action="store_true",
434 help="show debug information")
435 help="show debug information")
435 parser.add_option("", "--nolineno", action="store_false",
436 parser.add_option("", "--nolineno", action="store_false",
436 dest='lineno', help="don't show line numbers")
437 dest='lineno', help="don't show line numbers")
437
438
438 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
439 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
439 lineno=True)
440 lineno=True)
440 (options, args) = parser.parse_args()
441 (options, args) = parser.parse_args()
441
442
442 if len(args) == 0:
443 if len(args) == 0:
443 check = glob.glob("*")
444 check = glob.glob("*")
444 else:
445 else:
445 check = args
446 check = args
446
447
447 ret = 0
448 ret = 0
448 for f in check:
449 for f in check:
449 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
450 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
450 blame=options.blame, debug=options.debug,
451 blame=options.blame, debug=options.debug,
451 lineno=options.lineno):
452 lineno=options.lineno):
452 ret = 1
453 ret = 1
453 sys.exit(ret)
454 sys.exit(ret)
@@ -1,117 +1,122 b''
1 # fancyopts.py - better command line parsing
1 # fancyopts.py - better command line parsing
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import getopt
8 import getopt, util
9 from i18n import _
9
10
10 def gnugetopt(args, options, longoptions):
11 def gnugetopt(args, options, longoptions):
11 """Parse options mostly like getopt.gnu_getopt.
12 """Parse options mostly like getopt.gnu_getopt.
12
13
13 This is different from getopt.gnu_getopt in that an argument of - will
14 This is different from getopt.gnu_getopt in that an argument of - will
14 become an argument of - instead of vanishing completely.
15 become an argument of - instead of vanishing completely.
15 """
16 """
16 extraargs = []
17 extraargs = []
17 if '--' in args:
18 if '--' in args:
18 stopindex = args.index('--')
19 stopindex = args.index('--')
19 extraargs = args[stopindex + 1:]
20 extraargs = args[stopindex + 1:]
20 args = args[:stopindex]
21 args = args[:stopindex]
21 opts, parseargs = getopt.getopt(args, options, longoptions)
22 opts, parseargs = getopt.getopt(args, options, longoptions)
22 args = []
23 args = []
23 while parseargs:
24 while parseargs:
24 arg = parseargs.pop(0)
25 arg = parseargs.pop(0)
25 if arg and arg[0] == '-' and len(arg) > 1:
26 if arg and arg[0] == '-' and len(arg) > 1:
26 parseargs.insert(0, arg)
27 parseargs.insert(0, arg)
27 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
28 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
28 opts = opts + topts
29 opts = opts + topts
29 parseargs = newparseargs
30 parseargs = newparseargs
30 else:
31 else:
31 args.append(arg)
32 args.append(arg)
32 args.extend(extraargs)
33 args.extend(extraargs)
33 return opts, args
34 return opts, args
34
35
35
36
36 def fancyopts(args, options, state, gnu=False):
37 def fancyopts(args, options, state, gnu=False):
37 """
38 """
38 read args, parse options, and store options in state
39 read args, parse options, and store options in state
39
40
40 each option is a tuple of:
41 each option is a tuple of:
41
42
42 short option or ''
43 short option or ''
43 long option
44 long option
44 default value
45 default value
45 description
46 description
46 option value label(optional)
47 option value label(optional)
47
48
48 option types include:
49 option types include:
49
50
50 boolean or none - option sets variable in state to true
51 boolean or none - option sets variable in state to true
51 string - parameter string is stored in state
52 string - parameter string is stored in state
52 list - parameter string is added to a list
53 list - parameter string is added to a list
53 integer - parameter strings is stored as int
54 integer - parameter strings is stored as int
54 function - call function with parameter
55 function - call function with parameter
55
56
56 non-option args are returned
57 non-option args are returned
57 """
58 """
58 namelist = []
59 namelist = []
59 shortlist = ''
60 shortlist = ''
60 argmap = {}
61 argmap = {}
61 defmap = {}
62 defmap = {}
62
63
63 for option in options:
64 for option in options:
64 if len(option) == 5:
65 if len(option) == 5:
65 short, name, default, comment, dummy = option
66 short, name, default, comment, dummy = option
66 else:
67 else:
67 short, name, default, comment = option
68 short, name, default, comment = option
68 # convert opts to getopt format
69 # convert opts to getopt format
69 oname = name
70 oname = name
70 name = name.replace('-', '_')
71 name = name.replace('-', '_')
71
72
72 argmap['-' + short] = argmap['--' + oname] = name
73 argmap['-' + short] = argmap['--' + oname] = name
73 defmap[name] = default
74 defmap[name] = default
74
75
75 # copy defaults to state
76 # copy defaults to state
76 if isinstance(default, list):
77 if isinstance(default, list):
77 state[name] = default[:]
78 state[name] = default[:]
78 elif getattr(default, '__call__', False):
79 elif getattr(default, '__call__', False):
79 state[name] = None
80 state[name] = None
80 else:
81 else:
81 state[name] = default
82 state[name] = default
82
83
83 # does it take a parameter?
84 # does it take a parameter?
84 if not (default is None or default is True or default is False):
85 if not (default is None or default is True or default is False):
85 if short:
86 if short:
86 short += ':'
87 short += ':'
87 if oname:
88 if oname:
88 oname += '='
89 oname += '='
89 if short:
90 if short:
90 shortlist += short
91 shortlist += short
91 if name:
92 if name:
92 namelist.append(oname)
93 namelist.append(oname)
93
94
94 # parse arguments
95 # parse arguments
95 if gnu:
96 if gnu:
96 parse = gnugetopt
97 parse = gnugetopt
97 else:
98 else:
98 parse = getopt.getopt
99 parse = getopt.getopt
99 opts, args = parse(args, shortlist, namelist)
100 opts, args = parse(args, shortlist, namelist)
100
101
101 # transfer result to state
102 # transfer result to state
102 for opt, val in opts:
103 for opt, val in opts:
103 name = argmap[opt]
104 name = argmap[opt]
104 t = type(defmap[name])
105 t = type(defmap[name])
105 if t is type(fancyopts):
106 if t is type(fancyopts):
106 state[name] = defmap[name](val)
107 state[name] = defmap[name](val)
107 elif t is type(1):
108 elif t is type(1):
108 state[name] = int(val)
109 try:
110 state[name] = int(val)
111 except ValueError:
112 raise util.Abort(_('invalid value %r for option %s, '
113 'expected int') % (val, opt))
109 elif t is type(''):
114 elif t is type(''):
110 state[name] = val
115 state[name] = val
111 elif t is type([]):
116 elif t is type([]):
112 state[name].append(val)
117 state[name].append(val)
113 elif t is type(None) or t is type(False):
118 elif t is type(None) or t is type(False):
114 state[name] = True
119 state[name] = True
115
120
116 # return unparsed args
121 # return unparsed args
117 return args
122 return args
@@ -1,183 +1,170 b''
1 $ check_code="$TESTDIR"/../contrib/check-code.py
1 $ check_code="$TESTDIR"/../contrib/check-code.py
2 $ cd "$TESTDIR"/..
2 $ cd "$TESTDIR"/..
3 $ if hg identify -q > /dev/null; then :
3 $ if hg identify -q > /dev/null; then :
4 > else
4 > else
5 > echo "skipped: not a Mercurial working dir" >&2
5 > echo "skipped: not a Mercurial working dir" >&2
6 > exit 80
6 > exit 80
7 > fi
7 > fi
8 $ hg manifest | xargs "$check_code" || echo 'FAILURE IS NOT AN OPTION!!!'
8 $ hg manifest | xargs "$check_code" || echo 'FAILURE IS NOT AN OPTION!!!'
9
9
10 $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 || true
10 $ hg manifest | xargs "$check_code" --warnings --nolineno --per-file=0 || true
11 hgext/convert/cvsps.py:0:
11 hgext/convert/cvsps.py:0:
12 > ui.write('Ancestors: %s\n' % (','.join(r)))
12 > ui.write('Ancestors: %s\n' % (','.join(r)))
13 warning: unwrapped ui message
13 warning: unwrapped ui message
14 hgext/convert/cvsps.py:0:
14 hgext/convert/cvsps.py:0:
15 > ui.write('Parent: %d\n' % cs.parents[0].id)
15 > ui.write('Parent: %d\n' % cs.parents[0].id)
16 warning: unwrapped ui message
16 warning: unwrapped ui message
17 hgext/convert/cvsps.py:0:
17 hgext/convert/cvsps.py:0:
18 > ui.write('Parents: %s\n' %
18 > ui.write('Parents: %s\n' %
19 warning: unwrapped ui message
19 warning: unwrapped ui message
20 hgext/convert/cvsps.py:0:
20 hgext/convert/cvsps.py:0:
21 > ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
21 > ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
22 warning: unwrapped ui message
22 warning: unwrapped ui message
23 hgext/convert/cvsps.py:0:
23 hgext/convert/cvsps.py:0:
24 > ui.write('Author: %s\n' % cs.author)
24 > ui.write('Author: %s\n' % cs.author)
25 warning: unwrapped ui message
25 warning: unwrapped ui message
26 hgext/convert/cvsps.py:0:
26 hgext/convert/cvsps.py:0:
27 > ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
27 > ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
28 warning: unwrapped ui message
28 warning: unwrapped ui message
29 hgext/convert/cvsps.py:0:
29 hgext/convert/cvsps.py:0:
30 > ui.write('Date: %s\n' % util.datestr(cs.date,
30 > ui.write('Date: %s\n' % util.datestr(cs.date,
31 warning: unwrapped ui message
31 warning: unwrapped ui message
32 hgext/convert/cvsps.py:0:
32 hgext/convert/cvsps.py:0:
33 > ui.write('Log:\n')
33 > ui.write('Log:\n')
34 warning: unwrapped ui message
34 warning: unwrapped ui message
35 hgext/convert/cvsps.py:0:
35 hgext/convert/cvsps.py:0:
36 > ui.write('Members: \n')
36 > ui.write('Members: \n')
37 warning: unwrapped ui message
37 warning: unwrapped ui message
38 hgext/convert/cvsps.py:0:
38 hgext/convert/cvsps.py:0:
39 > ui.write('PatchSet %d \n' % cs.id)
39 > ui.write('PatchSet %d \n' % cs.id)
40 warning: unwrapped ui message
40 warning: unwrapped ui message
41 hgext/convert/cvsps.py:0:
41 hgext/convert/cvsps.py:0:
42 > ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags) > 1],
42 > ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags) > 1],
43 warning: unwrapped ui message
43 warning: unwrapped ui message
44 hgext/hgk.py:0:
44 hgext/hgk.py:0:
45 > ui.write("parent %s\n" % p)
45 > ui.write("parent %s\n" % p)
46 warning: unwrapped ui message
46 warning: unwrapped ui message
47 hgext/hgk.py:0:
47 hgext/hgk.py:0:
48 > ui.write('k=%s\nv=%s\n' % (name, value))
48 > ui.write('k=%s\nv=%s\n' % (name, value))
49 warning: unwrapped ui message
49 warning: unwrapped ui message
50 hgext/hgk.py:0:
50 hgext/hgk.py:0:
51 > ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
51 > ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
52 warning: unwrapped ui message
52 warning: unwrapped ui message
53 hgext/hgk.py:0:
53 hgext/hgk.py:0:
54 > ui.write("branch %s\n\n" % ctx.branch())
54 > ui.write("branch %s\n\n" % ctx.branch())
55 warning: unwrapped ui message
55 warning: unwrapped ui message
56 hgext/hgk.py:0:
56 hgext/hgk.py:0:
57 > ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
57 > ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
58 warning: unwrapped ui message
58 warning: unwrapped ui message
59 hgext/hgk.py:0:
59 hgext/hgk.py:0:
60 > ui.write("revision %d\n" % ctx.rev())
60 > ui.write("revision %d\n" % ctx.rev())
61 warning: unwrapped ui message
61 warning: unwrapped ui message
62 hgext/hgk.py:0:
62 hgext/hgk.py:0:
63 > ui.write("tree %s\n" % short(ctx.changeset()[0]))
63 > ui.write("tree %s\n" % short(ctx.changeset()[0]))
64 warning: unwrapped ui message
64 warning: unwrapped ui message
65 hgext/mq.py:0:
65 hgext/mq.py:0:
66 > ui.write("mq: %s\n" % ', '.join(m))
66 > ui.write("mq: %s\n" % ', '.join(m))
67 warning: unwrapped ui message
67 warning: unwrapped ui message
68 hgext/patchbomb.py:0:
68 hgext/patchbomb.py:0:
69 > ui.write('Subject: %s\n' % subj)
69 > ui.write('Subject: %s\n' % subj)
70 warning: unwrapped ui message
70 warning: unwrapped ui message
71 hgext/patchbomb.py:0:
71 hgext/patchbomb.py:0:
72 > ui.write('From: %s\n' % sender)
72 > ui.write('From: %s\n' % sender)
73 warning: unwrapped ui message
73 warning: unwrapped ui message
74 mercurial/commands.py:0:
74 mercurial/commands.py:0:
75 > ui.note('branch %s\n' % data)
75 > ui.note('branch %s\n' % data)
76 warning: unwrapped ui message
76 warning: unwrapped ui message
77 mercurial/commands.py:0:
77 mercurial/commands.py:0:
78 > ui.note('node %s\n' % str(data))
78 > ui.note('node %s\n' % str(data))
79 warning: unwrapped ui message
79 warning: unwrapped ui message
80 mercurial/commands.py:0:
80 mercurial/commands.py:0:
81 > ui.note('tag %s\n' % name)
81 > ui.note('tag %s\n' % name)
82 warning: unwrapped ui message
82 warning: unwrapped ui message
83 mercurial/commands.py:0:
83 mercurial/commands.py:0:
84 > ui.write("unpruned common: %s\n" % " ".join([short(n)
84 > ui.write("unpruned common: %s\n" % " ".join([short(n)
85 warning: unwrapped ui message
85 warning: unwrapped ui message
86 mercurial/commands.py:0:
86 mercurial/commands.py:0:
87 > ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
87 > ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
88 warning: unwrapped ui message
88 warning: unwrapped ui message
89 mercurial/commands.py:0:
89 mercurial/commands.py:0:
90 > ui.write("local is subset\n")
90 > ui.write("local is subset\n")
91 warning: unwrapped ui message
91 warning: unwrapped ui message
92 mercurial/commands.py:0:
92 mercurial/commands.py:0:
93 > ui.write("remote is subset\n")
93 > ui.write("remote is subset\n")
94 warning: unwrapped ui message
94 warning: unwrapped ui message
95 mercurial/commands.py:0:
95 mercurial/commands.py:0:
96 > ui.write('deltas against other : ' + fmt % pcfmt(numother,
96 > ui.write('deltas against other : ' + fmt % pcfmt(numother,
97 warning: unwrapped ui message
97 warning: unwrapped ui message
98 mercurial/commands.py:0:
98 mercurial/commands.py:0:
99 > ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
99 > ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
100 warning: unwrapped ui message
100 warning: unwrapped ui message
101 mercurial/commands.py:0:
101 mercurial/commands.py:0:
102 > ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
102 > ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
103 warning: unwrapped ui message
103 warning: unwrapped ui message
104 mercurial/commands.py:0:
104 mercurial/commands.py:0:
105 > ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
105 > ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
106 warning: unwrapped ui message
106 warning: unwrapped ui message
107 mercurial/commands.py:0:
107 mercurial/commands.py:0:
108 > ui.write("match: %s\n" % m(d[0]))
108 > ui.write("match: %s\n" % m(d[0]))
109 warning: unwrapped ui message
109 warning: unwrapped ui message
110 mercurial/commands.py:0:
110 mercurial/commands.py:0:
111 > ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
111 > ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
112 warning: unwrapped ui message
112 warning: unwrapped ui message
113 mercurial/commands.py:0:
113 mercurial/commands.py:0:
114 > ui.write('path %s\n' % k)
114 > ui.write('path %s\n' % k)
115 warning: unwrapped ui message
115 warning: unwrapped ui message
116 mercurial/commands.py:0:
116 mercurial/commands.py:0:
117 > ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
117 > ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
118 warning: unwrapped ui message
118 warning: unwrapped ui message
119 mercurial/commands.py:0:
119 mercurial/commands.py:0:
120 > ui.write("digraph G {\n")
120 > ui.write("digraph G {\n")
121 warning: unwrapped ui message
121 warning: unwrapped ui message
122 mercurial/commands.py:0:
122 mercurial/commands.py:0:
123 > ui.write("internal: %s %s\n" % d)
123 > ui.write("internal: %s %s\n" % d)
124 warning: unwrapped ui message
124 warning: unwrapped ui message
125 mercurial/commands.py:0:
125 mercurial/commands.py:0:
126 > ui.write("standard: %s\n" % util.datestr(d))
126 > ui.write("standard: %s\n" % util.datestr(d))
127 warning: unwrapped ui message
127 warning: unwrapped ui message
128 mercurial/commands.py:0:
128 mercurial/commands.py:0:
129 > ui.write('avg chain length : ' + fmt % avgchainlen)
129 > ui.write('avg chain length : ' + fmt % avgchainlen)
130 warning: unwrapped ui message
130 warning: unwrapped ui message
131 mercurial/commands.py:0:
131 mercurial/commands.py:0:
132 > ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
132 > ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
133 warning: unwrapped ui message
133 warning: unwrapped ui message
134 mercurial/commands.py:0:
134 mercurial/commands.py:0:
135 > ui.write('compression ratio : ' + fmt % compratio)
135 > ui.write('compression ratio : ' + fmt % compratio)
136 warning: unwrapped ui message
136 warning: unwrapped ui message
137 mercurial/commands.py:0:
137 mercurial/commands.py:0:
138 > ui.write('delta size (min/max/avg) : %d / %d / %d\n'
138 > ui.write('delta size (min/max/avg) : %d / %d / %d\n'
139 warning: unwrapped ui message
139 warning: unwrapped ui message
140 mercurial/commands.py:0:
140 mercurial/commands.py:0:
141 > ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
141 > ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
142 warning: unwrapped ui message
142 warning: unwrapped ui message
143 mercurial/commands.py:0:
143 mercurial/commands.py:0:
144 > ui.write('flags : %s\n' % ', '.join(flags))
144 > ui.write('flags : %s\n' % ', '.join(flags))
145 warning: unwrapped ui message
145 warning: unwrapped ui message
146 mercurial/commands.py:0:
146 mercurial/commands.py:0:
147 > ui.write('format : %d\n' % format)
147 > ui.write('format : %d\n' % format)
148 warning: unwrapped ui message
148 warning: unwrapped ui message
149 mercurial/commands.py:0:
149 mercurial/commands.py:0:
150 > ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
150 > ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
151 warning: unwrapped ui message
151 warning: unwrapped ui message
152 mercurial/commands.py:0:
152 mercurial/commands.py:0:
153 > ui.write('revision size : ' + fmt2 % totalsize)
153 > ui.write('revision size : ' + fmt2 % totalsize)
154 warning: unwrapped ui message
154 warning: unwrapped ui message
155 mercurial/commands.py:0:
155 mercurial/commands.py:0:
156 > ui.write('revisions : ' + fmt2 % numrevs)
156 > ui.write('revisions : ' + fmt2 % numrevs)
157 warning: unwrapped ui message
157 warning: unwrapped ui message
158 warning: unwrapped ui message
158 warning: unwrapped ui message
159 mercurial/commands.py:0:
159 mercurial/commands.py:0:
160 > ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
160 > ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
161 warning: unwrapped ui message
161 warning: unwrapped ui message
162 tests/autodiff.py:0:
162 tests/autodiff.py:0:
163 > ui.write('data lost for: %s\n' % fn)
163 > ui.write('data lost for: %s\n' % fn)
164 warning: unwrapped ui message
164 warning: unwrapped ui message
165 tests/test-convert-mtn.t:0:
166 > > function get_passphrase(keypair_id)
167 don't use 'function', use old style
168 tests/test-import-git.t:0:
169 > > Mc\${NkU|\`?^000jF3jhEB
170 ^ must be quoted
171 tests/test-import.t:0:
172 > > diff -Naur proj-orig/foo proj-new/foo
173 don't use 'diff -N'
174 don't use 'diff -N'
175 tests/test-schemes.t:0:
176 > > z = file:\$PWD/
177 don't use $PWD, use `pwd`
178 tests/test-ui-color.py:0:
165 tests/test-ui-color.py:0:
179 > testui.warn('warning\n')
166 > testui.warn('warning\n')
180 warning: unwrapped ui message
167 warning: unwrapped ui message
181 tests/test-ui-color.py:0:
168 tests/test-ui-color.py:0:
182 > testui.write('buffered\n')
169 > testui.write('buffered\n')
183 warning: unwrapped ui message
170 warning: unwrapped ui message
@@ -1,119 +1,159 b''
1 Init repo1:
1 Init repo1:
2
2
3 $ hg init repo1
3 $ hg init repo1
4 $ cd repo1
4 $ cd repo1
5 $ echo "some text" > a
5 $ echo "some text" > a
6 $ hg add
6 $ hg add
7 adding a
7 adding a
8 $ hg ci -m first
8 $ hg ci -m first
9 $ cat .hg/store/fncache | sort
9 $ cat .hg/store/fncache | sort
10 data/a.i
10 data/a.i
11
11
12 Testing a.i/b:
12 Testing a.i/b:
13
13
14 $ mkdir a.i
14 $ mkdir a.i
15 $ echo "some other text" > a.i/b
15 $ echo "some other text" > a.i/b
16 $ hg add
16 $ hg add
17 adding a.i/b (glob)
17 adding a.i/b (glob)
18 $ hg ci -m second
18 $ hg ci -m second
19 $ cat .hg/store/fncache | sort
19 $ cat .hg/store/fncache | sort
20 data/a.i
20 data/a.i
21 data/a.i.hg/b.i
21 data/a.i.hg/b.i
22
22
23 Testing a.i.hg/c:
23 Testing a.i.hg/c:
24
24
25 $ mkdir a.i.hg
25 $ mkdir a.i.hg
26 $ echo "yet another text" > a.i.hg/c
26 $ echo "yet another text" > a.i.hg/c
27 $ hg add
27 $ hg add
28 adding a.i.hg/c (glob)
28 adding a.i.hg/c (glob)
29 $ hg ci -m third
29 $ hg ci -m third
30 $ cat .hg/store/fncache | sort
30 $ cat .hg/store/fncache | sort
31 data/a.i
31 data/a.i
32 data/a.i.hg.hg/c.i
32 data/a.i.hg.hg/c.i
33 data/a.i.hg/b.i
33 data/a.i.hg/b.i
34
34
35 Testing verify:
35 Testing verify:
36
36
37 $ hg verify
37 $ hg verify
38 checking changesets
38 checking changesets
39 checking manifests
39 checking manifests
40 crosschecking files in changesets and manifests
40 crosschecking files in changesets and manifests
41 checking files
41 checking files
42 3 files, 3 changesets, 3 total revisions
42 3 files, 3 changesets, 3 total revisions
43
43
44 $ rm .hg/store/fncache
44 $ rm .hg/store/fncache
45
45
46 $ hg verify
46 $ hg verify
47 checking changesets
47 checking changesets
48 checking manifests
48 checking manifests
49 crosschecking files in changesets and manifests
49 crosschecking files in changesets and manifests
50 checking files
50 checking files
51 data/a.i@0: missing revlog!
51 data/a.i@0: missing revlog!
52 data/a.i.hg/c.i@2: missing revlog!
52 data/a.i.hg/c.i@2: missing revlog!
53 data/a.i/b.i@1: missing revlog!
53 data/a.i/b.i@1: missing revlog!
54 3 files, 3 changesets, 3 total revisions
54 3 files, 3 changesets, 3 total revisions
55 3 integrity errors encountered!
55 3 integrity errors encountered!
56 (first damaged changeset appears to be 0)
56 (first damaged changeset appears to be 0)
57 [1]
57 [1]
58 $ cd ..
58 $ cd ..
59
59
60 Non store repo:
60 Non store repo:
61
61
62 $ hg --config format.usestore=False init foo
62 $ hg --config format.usestore=False init foo
63 $ cd foo
63 $ cd foo
64 $ mkdir tst.d
64 $ mkdir tst.d
65 $ echo foo > tst.d/foo
65 $ echo foo > tst.d/foo
66 $ hg ci -Amfoo
66 $ hg ci -Amfoo
67 adding tst.d/foo
67 adding tst.d/foo
68 $ find .hg | sort
68 $ find .hg | sort
69 .hg
69 .hg
70 .hg/00changelog.i
70 .hg/00changelog.i
71 .hg/00manifest.i
71 .hg/00manifest.i
72 .hg/cache
72 .hg/cache
73 .hg/cache/branchheads
73 .hg/cache/branchheads
74 .hg/data
74 .hg/data
75 .hg/data/tst.d.hg
75 .hg/data/tst.d.hg
76 .hg/data/tst.d.hg/foo.i
76 .hg/data/tst.d.hg/foo.i
77 .hg/dirstate
77 .hg/dirstate
78 .hg/last-message.txt
78 .hg/last-message.txt
79 .hg/phaseroots
79 .hg/phaseroots
80 .hg/requires
80 .hg/requires
81 .hg/undo
81 .hg/undo
82 .hg/undo.bookmarks
82 .hg/undo.bookmarks
83 .hg/undo.branch
83 .hg/undo.branch
84 .hg/undo.desc
84 .hg/undo.desc
85 .hg/undo.dirstate
85 .hg/undo.dirstate
86 .hg/undo.phaseroots
86 .hg/undo.phaseroots
87 $ cd ..
87 $ cd ..
88
88
89 Non fncache repo:
89 Non fncache repo:
90
90
91 $ hg --config format.usefncache=False init bar
91 $ hg --config format.usefncache=False init bar
92 $ cd bar
92 $ cd bar
93 $ mkdir tst.d
93 $ mkdir tst.d
94 $ echo foo > tst.d/Foo
94 $ echo foo > tst.d/Foo
95 $ hg ci -Amfoo
95 $ hg ci -Amfoo
96 adding tst.d/Foo
96 adding tst.d/Foo
97 $ find .hg | sort
97 $ find .hg | sort
98 .hg
98 .hg
99 .hg/00changelog.i
99 .hg/00changelog.i
100 .hg/cache
100 .hg/cache
101 .hg/cache/branchheads
101 .hg/cache/branchheads
102 .hg/dirstate
102 .hg/dirstate
103 .hg/last-message.txt
103 .hg/last-message.txt
104 .hg/requires
104 .hg/requires
105 .hg/store
105 .hg/store
106 .hg/store/00changelog.i
106 .hg/store/00changelog.i
107 .hg/store/00manifest.i
107 .hg/store/00manifest.i
108 .hg/store/data
108 .hg/store/data
109 .hg/store/data/tst.d.hg
109 .hg/store/data/tst.d.hg
110 .hg/store/data/tst.d.hg/_foo.i
110 .hg/store/data/tst.d.hg/_foo.i
111 .hg/store/phaseroots
111 .hg/store/phaseroots
112 .hg/store/undo
112 .hg/store/undo
113 .hg/store/undo.phaseroots
113 .hg/store/undo.phaseroots
114 .hg/undo.bookmarks
114 .hg/undo.bookmarks
115 .hg/undo.branch
115 .hg/undo.branch
116 .hg/undo.desc
116 .hg/undo.desc
117 .hg/undo.dirstate
117 .hg/undo.dirstate
118 $ cd ..
118 $ cd ..
119
119
120 #if no-windows
121
122 Encoding of reserved / long paths in the store
123
124 $ hg init r2
125 $ cd r2
126 $ cat <<EOF > .hg/hgrc
127 > [ui]
128 > portablefilenames = ignore
129 > EOF
130
131 $ DIR="bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL"
132 $ mkdir -p "$DIR"
133 $ echo foo > "$DIR/normal.c"
134 $ DIR="AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH"
135 $ mkdir -p "$DIR"
136 $ echo foo > "$DIR/LOREMIPSUM.TXT"
137 $ DIR="enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services"
138 $ mkdir -p "$DIR"
139 $ echo foo > "$DIR/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider"
140 $ DIR="Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother"
141 $ mkdir -p "$DIR"
142 $ echo foo > "$DIR/AndThenAnExtremelyLongFileName.txt"
143 $ DIR="12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345"
144 $ mkdir -p "$DIR"
145 $ echo foo > "$DIR/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz"
146 $ hg ci -qAm1
147 $ find .hg/store -name *.i | sort
148 .hg/store/00changelog.i
149 .hg/store/00manifest.i
150 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
151 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
152 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
153 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
154 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
155
156 $ cd ..
157
158 #endif
159
@@ -1,1155 +1,1158 b''
1 $ hg init a
1 $ hg init a
2 $ mkdir a/d1
2 $ mkdir a/d1
3 $ mkdir a/d1/d2
3 $ mkdir a/d1/d2
4 $ echo line 1 > a/a
4 $ echo line 1 > a/a
5 $ echo line 1 > a/d1/d2/a
5 $ echo line 1 > a/d1/d2/a
6 $ hg --cwd a ci -Ama
6 $ hg --cwd a ci -Ama
7 adding a
7 adding a
8 adding d1/d2/a
8 adding d1/d2/a
9
9
10 $ echo line 2 >> a/a
10 $ echo line 2 >> a/a
11 $ hg --cwd a ci -u someone -d '1 0' -m'second change'
11 $ hg --cwd a ci -u someone -d '1 0' -m'second change'
12
12
13 import with no args:
13 import with no args:
14
14
15 $ hg --cwd a import
15 $ hg --cwd a import
16 abort: need at least one patch to import
16 abort: need at least one patch to import
17 [255]
17 [255]
18
18
19 generate patches for the test
19 generate patches for the test
20
20
21 $ hg --cwd a export tip > exported-tip.patch
21 $ hg --cwd a export tip > exported-tip.patch
22 $ hg --cwd a diff -r0:1 > diffed-tip.patch
22 $ hg --cwd a diff -r0:1 > diffed-tip.patch
23
23
24
24
25 import exported patch
25 import exported patch
26
26
27 $ hg clone -r0 a b
27 $ hg clone -r0 a b
28 adding changesets
28 adding changesets
29 adding manifests
29 adding manifests
30 adding file changes
30 adding file changes
31 added 1 changesets with 2 changes to 2 files
31 added 1 changesets with 2 changes to 2 files
32 updating to branch default
32 updating to branch default
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 $ hg --cwd b import ../exported-tip.patch
34 $ hg --cwd b import ../exported-tip.patch
35 applying ../exported-tip.patch
35 applying ../exported-tip.patch
36
36
37 message and committer should be same
37 message and committer should be same
38
38
39 $ hg --cwd b tip
39 $ hg --cwd b tip
40 changeset: 1:1d4bd90af0e4
40 changeset: 1:1d4bd90af0e4
41 tag: tip
41 tag: tip
42 user: someone
42 user: someone
43 date: Thu Jan 01 00:00:01 1970 +0000
43 date: Thu Jan 01 00:00:01 1970 +0000
44 summary: second change
44 summary: second change
45
45
46 $ rm -r b
46 $ rm -r b
47
47
48
48
49 import exported patch with external patcher
49 import exported patch with external patcher
50
50
51 $ cat > dummypatch.py <<EOF
51 $ cat > dummypatch.py <<EOF
52 > print 'patching file a'
52 > print 'patching file a'
53 > file('a', 'wb').write('line2\n')
53 > file('a', 'wb').write('line2\n')
54 > EOF
54 > EOF
55 $ hg clone -r0 a b
55 $ hg clone -r0 a b
56 adding changesets
56 adding changesets
57 adding manifests
57 adding manifests
58 adding file changes
58 adding file changes
59 added 1 changesets with 2 changes to 2 files
59 added 1 changesets with 2 changes to 2 files
60 updating to branch default
60 updating to branch default
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 $ hg --config ui.patch='python ../dummypatch.py' --cwd b import ../exported-tip.patch
62 $ hg --config ui.patch='python ../dummypatch.py' --cwd b import ../exported-tip.patch
63 applying ../exported-tip.patch
63 applying ../exported-tip.patch
64 $ cat b/a
64 $ cat b/a
65 line2
65 line2
66 $ rm -r b
66 $ rm -r b
67
67
68
68
69 import of plain diff should fail without message
69 import of plain diff should fail without message
70
70
71 $ hg clone -r0 a b
71 $ hg clone -r0 a b
72 adding changesets
72 adding changesets
73 adding manifests
73 adding manifests
74 adding file changes
74 adding file changes
75 added 1 changesets with 2 changes to 2 files
75 added 1 changesets with 2 changes to 2 files
76 updating to branch default
76 updating to branch default
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ hg --cwd b import ../diffed-tip.patch
78 $ hg --cwd b import ../diffed-tip.patch
79 applying ../diffed-tip.patch
79 applying ../diffed-tip.patch
80 abort: empty commit message
80 abort: empty commit message
81 [255]
81 [255]
82 $ rm -r b
82 $ rm -r b
83
83
84
84
85 import of plain diff should be ok with message
85 import of plain diff should be ok with message
86
86
87 $ hg clone -r0 a b
87 $ hg clone -r0 a b
88 adding changesets
88 adding changesets
89 adding manifests
89 adding manifests
90 adding file changes
90 adding file changes
91 added 1 changesets with 2 changes to 2 files
91 added 1 changesets with 2 changes to 2 files
92 updating to branch default
92 updating to branch default
93 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 $ hg --cwd b import -mpatch ../diffed-tip.patch
94 $ hg --cwd b import -mpatch ../diffed-tip.patch
95 applying ../diffed-tip.patch
95 applying ../diffed-tip.patch
96 $ rm -r b
96 $ rm -r b
97
97
98
98
99 import of plain diff with specific date and user
99 import of plain diff with specific date and user
100
100
101 $ hg clone -r0 a b
101 $ hg clone -r0 a b
102 adding changesets
102 adding changesets
103 adding manifests
103 adding manifests
104 adding file changes
104 adding file changes
105 added 1 changesets with 2 changes to 2 files
105 added 1 changesets with 2 changes to 2 files
106 updating to branch default
106 updating to branch default
107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
108 $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
109 applying ../diffed-tip.patch
109 applying ../diffed-tip.patch
110 $ hg -R b tip -pv
110 $ hg -R b tip -pv
111 changeset: 1:ca68f19f3a40
111 changeset: 1:ca68f19f3a40
112 tag: tip
112 tag: tip
113 user: user@nowhere.net
113 user: user@nowhere.net
114 date: Thu Jan 01 00:00:01 1970 +0000
114 date: Thu Jan 01 00:00:01 1970 +0000
115 files: a
115 files: a
116 description:
116 description:
117 patch
117 patch
118
118
119
119
120 diff -r 80971e65b431 -r ca68f19f3a40 a
120 diff -r 80971e65b431 -r ca68f19f3a40 a
121 --- a/a Thu Jan 01 00:00:00 1970 +0000
121 --- a/a Thu Jan 01 00:00:00 1970 +0000
122 +++ b/a Thu Jan 01 00:00:01 1970 +0000
122 +++ b/a Thu Jan 01 00:00:01 1970 +0000
123 @@ -1,1 +1,2 @@
123 @@ -1,1 +1,2 @@
124 line 1
124 line 1
125 +line 2
125 +line 2
126
126
127 $ rm -r b
127 $ rm -r b
128
128
129
129
130 import of plain diff should be ok with --no-commit
130 import of plain diff should be ok with --no-commit
131
131
132 $ hg clone -r0 a b
132 $ hg clone -r0 a b
133 adding changesets
133 adding changesets
134 adding manifests
134 adding manifests
135 adding file changes
135 adding file changes
136 added 1 changesets with 2 changes to 2 files
136 added 1 changesets with 2 changes to 2 files
137 updating to branch default
137 updating to branch default
138 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
138 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
139 $ hg --cwd b import --no-commit ../diffed-tip.patch
139 $ hg --cwd b import --no-commit ../diffed-tip.patch
140 applying ../diffed-tip.patch
140 applying ../diffed-tip.patch
141 $ hg --cwd b diff --nodates
141 $ hg --cwd b diff --nodates
142 diff -r 80971e65b431 a
142 diff -r 80971e65b431 a
143 --- a/a
143 --- a/a
144 +++ b/a
144 +++ b/a
145 @@ -1,1 +1,2 @@
145 @@ -1,1 +1,2 @@
146 line 1
146 line 1
147 +line 2
147 +line 2
148 $ rm -r b
148 $ rm -r b
149
149
150
150
151 import of malformed plain diff should fail
151 import of malformed plain diff should fail
152
152
153 $ hg clone -r0 a b
153 $ hg clone -r0 a b
154 adding changesets
154 adding changesets
155 adding manifests
155 adding manifests
156 adding file changes
156 adding file changes
157 added 1 changesets with 2 changes to 2 files
157 added 1 changesets with 2 changes to 2 files
158 updating to branch default
158 updating to branch default
159 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
160 $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
161 $ hg --cwd b import -mpatch ../broken.patch
161 $ hg --cwd b import -mpatch ../broken.patch
162 applying ../broken.patch
162 applying ../broken.patch
163 abort: bad hunk #1
163 abort: bad hunk #1
164 [255]
164 [255]
165 $ rm -r b
165 $ rm -r b
166
166
167
167
168 hg -R repo import
168 hg -R repo import
169 put the clone in a subdir - having a directory named "a"
169 put the clone in a subdir - having a directory named "a"
170 used to hide a bug.
170 used to hide a bug.
171
171
172 $ mkdir dir
172 $ mkdir dir
173 $ hg clone -r0 a dir/b
173 $ hg clone -r0 a dir/b
174 adding changesets
174 adding changesets
175 adding manifests
175 adding manifests
176 adding file changes
176 adding file changes
177 added 1 changesets with 2 changes to 2 files
177 added 1 changesets with 2 changes to 2 files
178 updating to branch default
178 updating to branch default
179 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 $ cd dir
180 $ cd dir
181 $ hg -R b import ../exported-tip.patch
181 $ hg -R b import ../exported-tip.patch
182 applying ../exported-tip.patch
182 applying ../exported-tip.patch
183 $ cd ..
183 $ cd ..
184 $ rm -r dir
184 $ rm -r dir
185
185
186
186
187 import from stdin
187 import from stdin
188
188
189 $ hg clone -r0 a b
189 $ hg clone -r0 a b
190 adding changesets
190 adding changesets
191 adding manifests
191 adding manifests
192 adding file changes
192 adding file changes
193 added 1 changesets with 2 changes to 2 files
193 added 1 changesets with 2 changes to 2 files
194 updating to branch default
194 updating to branch default
195 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 $ hg --cwd b import - < exported-tip.patch
196 $ hg --cwd b import - < exported-tip.patch
197 applying patch from stdin
197 applying patch from stdin
198 $ rm -r b
198 $ rm -r b
199
199
200
200
201 import two patches in one stream
201 import two patches in one stream
202
202
203 $ hg init b
203 $ hg init b
204 $ hg --cwd a export 0:tip | hg --cwd b import -
204 $ hg --cwd a export 0:tip | hg --cwd b import -
205 applying patch from stdin
205 applying patch from stdin
206 $ hg --cwd a id
206 $ hg --cwd a id
207 1d4bd90af0e4 tip
207 1d4bd90af0e4 tip
208 $ hg --cwd b id
208 $ hg --cwd b id
209 1d4bd90af0e4 tip
209 1d4bd90af0e4 tip
210 $ rm -r b
210 $ rm -r b
211
211
212
212
213 override commit message
213 override commit message
214
214
215 $ hg clone -r0 a b
215 $ hg clone -r0 a b
216 adding changesets
216 adding changesets
217 adding manifests
217 adding manifests
218 adding file changes
218 adding file changes
219 added 1 changesets with 2 changes to 2 files
219 added 1 changesets with 2 changes to 2 files
220 updating to branch default
220 updating to branch default
221 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 $ hg --cwd b import -m 'override' - < exported-tip.patch
222 $ hg --cwd b import -m 'override' - < exported-tip.patch
223 applying patch from stdin
223 applying patch from stdin
224 $ hg --cwd b tip | grep override
224 $ hg --cwd b tip | grep override
225 summary: override
225 summary: override
226 $ rm -r b
226 $ rm -r b
227
227
228 $ cat > mkmsg.py <<EOF
228 $ cat > mkmsg.py <<EOF
229 > import email.Message, sys
229 > import email.Message, sys
230 > msg = email.Message.Message()
230 > msg = email.Message.Message()
231 > patch = open(sys.argv[1], 'rb').read()
231 > patch = open(sys.argv[1], 'rb').read()
232 > msg.set_payload('email commit message\n' + patch)
232 > msg.set_payload('email commit message\n' + patch)
233 > msg['Subject'] = 'email patch'
233 > msg['Subject'] = 'email patch'
234 > msg['From'] = 'email patcher'
234 > msg['From'] = 'email patcher'
235 > file(sys.argv[2], 'wb').write(msg.as_string())
235 > file(sys.argv[2], 'wb').write(msg.as_string())
236 > EOF
236 > EOF
237
237
238
238
239 plain diff in email, subject, message body
239 plain diff in email, subject, message body
240
240
241 $ hg clone -r0 a b
241 $ hg clone -r0 a b
242 adding changesets
242 adding changesets
243 adding manifests
243 adding manifests
244 adding file changes
244 adding file changes
245 added 1 changesets with 2 changes to 2 files
245 added 1 changesets with 2 changes to 2 files
246 updating to branch default
246 updating to branch default
247 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 $ python mkmsg.py diffed-tip.patch msg.patch
248 $ python mkmsg.py diffed-tip.patch msg.patch
249 $ hg --cwd b import ../msg.patch
249 $ hg --cwd b import ../msg.patch
250 applying ../msg.patch
250 applying ../msg.patch
251 $ hg --cwd b tip | grep email
251 $ hg --cwd b tip | grep email
252 user: email patcher
252 user: email patcher
253 summary: email patch
253 summary: email patch
254 $ rm -r b
254 $ rm -r b
255
255
256
256
257 plain diff in email, no subject, message body
257 plain diff in email, no subject, message body
258
258
259 $ hg clone -r0 a b
259 $ hg clone -r0 a b
260 adding changesets
260 adding changesets
261 adding manifests
261 adding manifests
262 adding file changes
262 adding file changes
263 added 1 changesets with 2 changes to 2 files
263 added 1 changesets with 2 changes to 2 files
264 updating to branch default
264 updating to branch default
265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 $ grep -v '^Subject:' msg.patch | hg --cwd b import -
266 $ grep -v '^Subject:' msg.patch | hg --cwd b import -
267 applying patch from stdin
267 applying patch from stdin
268 $ rm -r b
268 $ rm -r b
269
269
270
270
271 plain diff in email, subject, no message body
271 plain diff in email, subject, no message body
272
272
273 $ hg clone -r0 a b
273 $ hg clone -r0 a b
274 adding changesets
274 adding changesets
275 adding manifests
275 adding manifests
276 adding file changes
276 adding file changes
277 added 1 changesets with 2 changes to 2 files
277 added 1 changesets with 2 changes to 2 files
278 updating to branch default
278 updating to branch default
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 $ grep -v '^email ' msg.patch | hg --cwd b import -
280 $ grep -v '^email ' msg.patch | hg --cwd b import -
281 applying patch from stdin
281 applying patch from stdin
282 $ rm -r b
282 $ rm -r b
283
283
284
284
285 plain diff in email, no subject, no message body, should fail
285 plain diff in email, no subject, no message body, should fail
286
286
287 $ hg clone -r0 a b
287 $ hg clone -r0 a b
288 adding changesets
288 adding changesets
289 adding manifests
289 adding manifests
290 adding file changes
290 adding file changes
291 added 1 changesets with 2 changes to 2 files
291 added 1 changesets with 2 changes to 2 files
292 updating to branch default
292 updating to branch default
293 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 $ egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
294 $ egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
295 applying patch from stdin
295 applying patch from stdin
296 abort: empty commit message
296 abort: empty commit message
297 [255]
297 [255]
298 $ rm -r b
298 $ rm -r b
299
299
300
300
301 hg export in email, should use patch header
301 hg export in email, should use patch header
302
302
303 $ hg clone -r0 a b
303 $ hg clone -r0 a b
304 adding changesets
304 adding changesets
305 adding manifests
305 adding manifests
306 adding file changes
306 adding file changes
307 added 1 changesets with 2 changes to 2 files
307 added 1 changesets with 2 changes to 2 files
308 updating to branch default
308 updating to branch default
309 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
309 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 $ python mkmsg.py exported-tip.patch msg.patch
310 $ python mkmsg.py exported-tip.patch msg.patch
311 $ cat msg.patch | hg --cwd b import -
311 $ cat msg.patch | hg --cwd b import -
312 applying patch from stdin
312 applying patch from stdin
313 $ hg --cwd b tip | grep second
313 $ hg --cwd b tip | grep second
314 summary: second change
314 summary: second change
315 $ rm -r b
315 $ rm -r b
316
316
317
317
318 subject: duplicate detection, removal of [PATCH]
318 subject: duplicate detection, removal of [PATCH]
319 The '---' tests the gitsendmail handling without proper mail headers
319 The '---' tests the gitsendmail handling without proper mail headers
320
320
321 $ cat > mkmsg2.py <<EOF
321 $ cat > mkmsg2.py <<EOF
322 > import email.Message, sys
322 > import email.Message, sys
323 > msg = email.Message.Message()
323 > msg = email.Message.Message()
324 > patch = open(sys.argv[1], 'rb').read()
324 > patch = open(sys.argv[1], 'rb').read()
325 > msg.set_payload('email patch\n\nnext line\n---\n' + patch)
325 > msg.set_payload('email patch\n\nnext line\n---\n' + patch)
326 > msg['Subject'] = '[PATCH] email patch'
326 > msg['Subject'] = '[PATCH] email patch'
327 > msg['From'] = 'email patcher'
327 > msg['From'] = 'email patcher'
328 > file(sys.argv[2], 'wb').write(msg.as_string())
328 > file(sys.argv[2], 'wb').write(msg.as_string())
329 > EOF
329 > EOF
330
330
331
331
332 plain diff in email, [PATCH] subject, message body with subject
332 plain diff in email, [PATCH] subject, message body with subject
333
333
334 $ hg clone -r0 a b
334 $ hg clone -r0 a b
335 adding changesets
335 adding changesets
336 adding manifests
336 adding manifests
337 adding file changes
337 adding file changes
338 added 1 changesets with 2 changes to 2 files
338 added 1 changesets with 2 changes to 2 files
339 updating to branch default
339 updating to branch default
340 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 $ python mkmsg2.py diffed-tip.patch msg.patch
341 $ python mkmsg2.py diffed-tip.patch msg.patch
342 $ cat msg.patch | hg --cwd b import -
342 $ cat msg.patch | hg --cwd b import -
343 applying patch from stdin
343 applying patch from stdin
344 $ hg --cwd b tip --template '{desc}\n'
344 $ hg --cwd b tip --template '{desc}\n'
345 email patch
345 email patch
346
346
347 next line
347 next line
348 ---
348 ---
349 $ rm -r b
349 $ rm -r b
350
350
351
351
352 Issue963: Parent of working dir incorrect after import of multiple
352 Issue963: Parent of working dir incorrect after import of multiple
353 patches and rollback
353 patches and rollback
354
354
355 We weren't backing up the correct dirstate file when importing many
355 We weren't backing up the correct dirstate file when importing many
356 patches: import patch1 patch2; rollback
356 patches: import patch1 patch2; rollback
357
357
358 $ echo line 3 >> a/a
358 $ echo line 3 >> a/a
359 $ hg --cwd a ci -m'third change'
359 $ hg --cwd a ci -m'third change'
360 $ hg --cwd a export -o '../patch%R' 1 2
360 $ hg --cwd a export -o '../patch%R' 1 2
361 $ hg clone -qr0 a b
361 $ hg clone -qr0 a b
362 $ hg --cwd b parents --template 'parent: {rev}\n'
362 $ hg --cwd b parents --template 'parent: {rev}\n'
363 parent: 0
363 parent: 0
364 $ hg --cwd b import -v ../patch1 ../patch2
364 $ hg --cwd b import -v ../patch1 ../patch2
365 applying ../patch1
365 applying ../patch1
366 patching file a
366 patching file a
367 a
367 a
368 created 1d4bd90af0e4
368 created 1d4bd90af0e4
369 applying ../patch2
369 applying ../patch2
370 patching file a
370 patching file a
371 a
371 a
372 created 6d019af21222
372 created 6d019af21222
373 $ hg --cwd b rollback
373 $ hg --cwd b rollback
374 repository tip rolled back to revision 0 (undo import)
374 repository tip rolled back to revision 0 (undo import)
375 working directory now based on revision 0
375 working directory now based on revision 0
376 $ hg --cwd b parents --template 'parent: {rev}\n'
376 $ hg --cwd b parents --template 'parent: {rev}\n'
377 parent: 0
377 parent: 0
378 $ rm -r b
378 $ rm -r b
379
379
380
380
381 importing a patch in a subdirectory failed at the commit stage
381 importing a patch in a subdirectory failed at the commit stage
382
382
383 $ echo line 2 >> a/d1/d2/a
383 $ echo line 2 >> a/d1/d2/a
384 $ hg --cwd a ci -u someoneelse -d '1 0' -m'subdir change'
384 $ hg --cwd a ci -u someoneelse -d '1 0' -m'subdir change'
385
385
386 hg import in a subdirectory
386 hg import in a subdirectory
387
387
388 $ hg clone -r0 a b
388 $ hg clone -r0 a b
389 adding changesets
389 adding changesets
390 adding manifests
390 adding manifests
391 adding file changes
391 adding file changes
392 added 1 changesets with 2 changes to 2 files
392 added 1 changesets with 2 changes to 2 files
393 updating to branch default
393 updating to branch default
394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 $ hg --cwd a export tip > tmp
395 $ hg --cwd a export tip > tmp
396 $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
396 $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
397 $ dir=`pwd`
397 $ dir=`pwd`
398 $ cd b/d1/d2 2>&1 > /dev/null
398 $ cd b/d1/d2 2>&1 > /dev/null
399 $ hg import ../../../subdir-tip.patch
399 $ hg import ../../../subdir-tip.patch
400 applying ../../../subdir-tip.patch
400 applying ../../../subdir-tip.patch
401 $ cd "$dir"
401 $ cd "$dir"
402
402
403 message should be 'subdir change'
403 message should be 'subdir change'
404 committer should be 'someoneelse'
404 committer should be 'someoneelse'
405
405
406 $ hg --cwd b tip
406 $ hg --cwd b tip
407 changeset: 1:3577f5aea227
407 changeset: 1:3577f5aea227
408 tag: tip
408 tag: tip
409 user: someoneelse
409 user: someoneelse
410 date: Thu Jan 01 00:00:01 1970 +0000
410 date: Thu Jan 01 00:00:01 1970 +0000
411 summary: subdir change
411 summary: subdir change
412
412
413
413
414 should be empty
414 should be empty
415
415
416 $ hg --cwd b status
416 $ hg --cwd b status
417
417
418
418
419 Test fuzziness (ambiguous patch location, fuzz=2)
419 Test fuzziness (ambiguous patch location, fuzz=2)
420
420
421 $ hg init fuzzy
421 $ hg init fuzzy
422 $ cd fuzzy
422 $ cd fuzzy
423 $ echo line1 > a
423 $ echo line1 > a
424 $ echo line0 >> a
424 $ echo line0 >> a
425 $ echo line3 >> a
425 $ echo line3 >> a
426 $ hg ci -Am adda
426 $ hg ci -Am adda
427 adding a
427 adding a
428 $ echo line1 > a
428 $ echo line1 > a
429 $ echo line2 >> a
429 $ echo line2 >> a
430 $ echo line0 >> a
430 $ echo line0 >> a
431 $ echo line3 >> a
431 $ echo line3 >> a
432 $ hg ci -m change a
432 $ hg ci -m change a
433 $ hg export tip > fuzzy-tip.patch
433 $ hg export tip > fuzzy-tip.patch
434 $ hg up -C 0
434 $ hg up -C 0
435 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 $ echo line1 > a
436 $ echo line1 > a
437 $ echo line0 >> a
437 $ echo line0 >> a
438 $ echo line1 >> a
438 $ echo line1 >> a
439 $ echo line0 >> a
439 $ echo line0 >> a
440 $ hg ci -m brancha
440 $ hg ci -m brancha
441 created new head
441 created new head
442 $ hg import --no-commit -v fuzzy-tip.patch
442 $ hg import --no-commit -v fuzzy-tip.patch
443 applying fuzzy-tip.patch
443 applying fuzzy-tip.patch
444 patching file a
444 patching file a
445 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
445 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
446 applied to working directory
446 applied to working directory
447 $ hg revert -a
447 $ hg revert -a
448 reverting a
448 reverting a
449
449
450
450
451 import with --no-commit should have written .hg/last-message.txt
451 import with --no-commit should have written .hg/last-message.txt
452
452
453 $ cat .hg/last-message.txt
453 $ cat .hg/last-message.txt
454 change (no-eol)
454 change (no-eol)
455
455
456
456
457 test fuzziness with eol=auto
457 test fuzziness with eol=auto
458
458
459 $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
459 $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
460 applying fuzzy-tip.patch
460 applying fuzzy-tip.patch
461 patching file a
461 patching file a
462 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
462 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
463 applied to working directory
463 applied to working directory
464 $ cd ..
464 $ cd ..
465
465
466
466
467 Test hunk touching empty files (issue906)
467 Test hunk touching empty files (issue906)
468
468
469 $ hg init empty
469 $ hg init empty
470 $ cd empty
470 $ cd empty
471 $ touch a
471 $ touch a
472 $ touch b1
472 $ touch b1
473 $ touch c1
473 $ touch c1
474 $ echo d > d
474 $ echo d > d
475 $ hg ci -Am init
475 $ hg ci -Am init
476 adding a
476 adding a
477 adding b1
477 adding b1
478 adding c1
478 adding c1
479 adding d
479 adding d
480 $ echo a > a
480 $ echo a > a
481 $ echo b > b1
481 $ echo b > b1
482 $ hg mv b1 b2
482 $ hg mv b1 b2
483 $ echo c > c1
483 $ echo c > c1
484 $ hg copy c1 c2
484 $ hg copy c1 c2
485 $ rm d
485 $ rm d
486 $ touch d
486 $ touch d
487 $ hg diff --git
487 $ hg diff --git
488 diff --git a/a b/a
488 diff --git a/a b/a
489 --- a/a
489 --- a/a
490 +++ b/a
490 +++ b/a
491 @@ -0,0 +1,1 @@
491 @@ -0,0 +1,1 @@
492 +a
492 +a
493 diff --git a/b1 b/b2
493 diff --git a/b1 b/b2
494 rename from b1
494 rename from b1
495 rename to b2
495 rename to b2
496 --- a/b1
496 --- a/b1
497 +++ b/b2
497 +++ b/b2
498 @@ -0,0 +1,1 @@
498 @@ -0,0 +1,1 @@
499 +b
499 +b
500 diff --git a/c1 b/c1
500 diff --git a/c1 b/c1
501 --- a/c1
501 --- a/c1
502 +++ b/c1
502 +++ b/c1
503 @@ -0,0 +1,1 @@
503 @@ -0,0 +1,1 @@
504 +c
504 +c
505 diff --git a/c1 b/c2
505 diff --git a/c1 b/c2
506 copy from c1
506 copy from c1
507 copy to c2
507 copy to c2
508 --- a/c1
508 --- a/c1
509 +++ b/c2
509 +++ b/c2
510 @@ -0,0 +1,1 @@
510 @@ -0,0 +1,1 @@
511 +c
511 +c
512 diff --git a/d b/d
512 diff --git a/d b/d
513 --- a/d
513 --- a/d
514 +++ b/d
514 +++ b/d
515 @@ -1,1 +0,0 @@
515 @@ -1,1 +0,0 @@
516 -d
516 -d
517 $ hg ci -m empty
517 $ hg ci -m empty
518 $ hg export --git tip > empty.diff
518 $ hg export --git tip > empty.diff
519 $ hg up -C 0
519 $ hg up -C 0
520 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
520 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
521 $ hg import empty.diff
521 $ hg import empty.diff
522 applying empty.diff
522 applying empty.diff
523 $ for name in a b1 b2 c1 c2 d; do
523 $ for name in a b1 b2 c1 c2 d; do
524 > echo % $name file
524 > echo % $name file
525 > test -f $name && cat $name
525 > test -f $name && cat $name
526 > done
526 > done
527 % a file
527 % a file
528 a
528 a
529 % b1 file
529 % b1 file
530 % b2 file
530 % b2 file
531 b
531 b
532 % c1 file
532 % c1 file
533 c
533 c
534 % c2 file
534 % c2 file
535 c
535 c
536 % d file
536 % d file
537 $ cd ..
537 $ cd ..
538
538
539
539
540 Test importing a patch ending with a binary file removal
540 Test importing a patch ending with a binary file removal
541
541
542 $ hg init binaryremoval
542 $ hg init binaryremoval
543 $ cd binaryremoval
543 $ cd binaryremoval
544 $ echo a > a
544 $ echo a > a
545 $ python -c "file('b', 'wb').write('a\x00b')"
545 $ python -c "file('b', 'wb').write('a\x00b')"
546 $ hg ci -Am addall
546 $ hg ci -Am addall
547 adding a
547 adding a
548 adding b
548 adding b
549 $ hg rm a
549 $ hg rm a
550 $ hg rm b
550 $ hg rm b
551 $ hg st
551 $ hg st
552 R a
552 R a
553 R b
553 R b
554 $ hg ci -m remove
554 $ hg ci -m remove
555 $ hg export --git . > remove.diff
555 $ hg export --git . > remove.diff
556 $ cat remove.diff | grep git
556 $ cat remove.diff | grep git
557 diff --git a/a b/a
557 diff --git a/a b/a
558 diff --git a/b b/b
558 diff --git a/b b/b
559 $ hg up -C 0
559 $ hg up -C 0
560 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
560 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 $ hg import remove.diff
561 $ hg import remove.diff
562 applying remove.diff
562 applying remove.diff
563 $ hg manifest
563 $ hg manifest
564 $ cd ..
564 $ cd ..
565
565
566
566
567 Issue927: test update+rename with common name
567 Issue927: test update+rename with common name
568
568
569 $ hg init t
569 $ hg init t
570 $ cd t
570 $ cd t
571 $ touch a
571 $ touch a
572 $ hg ci -Am t
572 $ hg ci -Am t
573 adding a
573 adding a
574 $ echo a > a
574 $ echo a > a
575
575
576 Here, bfile.startswith(afile)
576 Here, bfile.startswith(afile)
577
577
578 $ hg copy a a2
578 $ hg copy a a2
579 $ hg ci -m copya
579 $ hg ci -m copya
580 $ hg export --git tip > copy.diff
580 $ hg export --git tip > copy.diff
581 $ hg up -C 0
581 $ hg up -C 0
582 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
582 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 $ hg import copy.diff
583 $ hg import copy.diff
584 applying copy.diff
584 applying copy.diff
585
585
586 a should contain an 'a'
586 a should contain an 'a'
587
587
588 $ cat a
588 $ cat a
589 a
589 a
590
590
591 and a2 should have duplicated it
591 and a2 should have duplicated it
592
592
593 $ cat a2
593 $ cat a2
594 a
594 a
595 $ cd ..
595 $ cd ..
596
596
597
597
598 test -p0
598 test -p0
599
599
600 $ hg init p0
600 $ hg init p0
601 $ cd p0
601 $ cd p0
602 $ echo a > a
602 $ echo a > a
603 $ hg ci -Am t
603 $ hg ci -Am t
604 adding a
604 adding a
605 $ hg import -p foo
606 abort: invalid value 'foo' for option -p, expected int
607 [255]
605 $ hg import -p0 - << EOF
608 $ hg import -p0 - << EOF
606 > foobar
609 > foobar
607 > --- a Sat Apr 12 22:43:58 2008 -0400
610 > --- a Sat Apr 12 22:43:58 2008 -0400
608 > +++ a Sat Apr 12 22:44:05 2008 -0400
611 > +++ a Sat Apr 12 22:44:05 2008 -0400
609 > @@ -1,1 +1,1 @@
612 > @@ -1,1 +1,1 @@
610 > -a
613 > -a
611 > +bb
614 > +bb
612 > EOF
615 > EOF
613 applying patch from stdin
616 applying patch from stdin
614 $ hg status
617 $ hg status
615 $ cat a
618 $ cat a
616 bb
619 bb
617 $ cd ..
620 $ cd ..
618
621
619
622
620 test paths outside repo root
623 test paths outside repo root
621
624
622 $ mkdir outside
625 $ mkdir outside
623 $ touch outside/foo
626 $ touch outside/foo
624 $ hg init inside
627 $ hg init inside
625 $ cd inside
628 $ cd inside
626 $ hg import - <<EOF
629 $ hg import - <<EOF
627 > diff --git a/a b/b
630 > diff --git a/a b/b
628 > rename from ../outside/foo
631 > rename from ../outside/foo
629 > rename to bar
632 > rename to bar
630 > EOF
633 > EOF
631 applying patch from stdin
634 applying patch from stdin
632 abort: path contains illegal component: ../outside/foo (glob)
635 abort: path contains illegal component: ../outside/foo (glob)
633 [255]
636 [255]
634 $ cd ..
637 $ cd ..
635
638
636
639
637 test import with similarity and git and strip (issue295 et al.)
640 test import with similarity and git and strip (issue295 et al.)
638
641
639 $ hg init sim
642 $ hg init sim
640 $ cd sim
643 $ cd sim
641 $ echo 'this is a test' > a
644 $ echo 'this is a test' > a
642 $ hg ci -Ama
645 $ hg ci -Ama
643 adding a
646 adding a
644 $ cat > ../rename.diff <<EOF
647 $ cat > ../rename.diff <<EOF
645 > diff --git a/foo/a b/foo/a
648 > diff --git a/foo/a b/foo/a
646 > deleted file mode 100644
649 > deleted file mode 100644
647 > --- a/foo/a
650 > --- a/foo/a
648 > +++ /dev/null
651 > +++ /dev/null
649 > @@ -1,1 +0,0 @@
652 > @@ -1,1 +0,0 @@
650 > -this is a test
653 > -this is a test
651 > diff --git a/foo/b b/foo/b
654 > diff --git a/foo/b b/foo/b
652 > new file mode 100644
655 > new file mode 100644
653 > --- /dev/null
656 > --- /dev/null
654 > +++ b/foo/b
657 > +++ b/foo/b
655 > @@ -0,0 +1,2 @@
658 > @@ -0,0 +1,2 @@
656 > +this is a test
659 > +this is a test
657 > +foo
660 > +foo
658 > EOF
661 > EOF
659 $ hg import --no-commit -v -s 1 ../rename.diff -p2
662 $ hg import --no-commit -v -s 1 ../rename.diff -p2
660 applying ../rename.diff
663 applying ../rename.diff
661 patching file a
664 patching file a
662 patching file b
665 patching file b
663 adding b
666 adding b
664 recording removal of a as rename to b (88% similar)
667 recording removal of a as rename to b (88% similar)
665 applied to working directory
668 applied to working directory
666 $ hg st -C
669 $ hg st -C
667 A b
670 A b
668 a
671 a
669 R a
672 R a
670 $ hg revert -a
673 $ hg revert -a
671 undeleting a
674 undeleting a
672 forgetting b
675 forgetting b
673 $ rm b
676 $ rm b
674 $ hg import --no-commit -v -s 100 ../rename.diff -p2
677 $ hg import --no-commit -v -s 100 ../rename.diff -p2
675 applying ../rename.diff
678 applying ../rename.diff
676 patching file a
679 patching file a
677 patching file b
680 patching file b
678 adding b
681 adding b
679 applied to working directory
682 applied to working directory
680 $ hg st -C
683 $ hg st -C
681 A b
684 A b
682 R a
685 R a
683 $ cd ..
686 $ cd ..
684
687
685
688
686 Issue1495: add empty file from the end of patch
689 Issue1495: add empty file from the end of patch
687
690
688 $ hg init addemptyend
691 $ hg init addemptyend
689 $ cd addemptyend
692 $ cd addemptyend
690 $ touch a
693 $ touch a
691 $ hg addremove
694 $ hg addremove
692 adding a
695 adding a
693 $ hg ci -m "commit"
696 $ hg ci -m "commit"
694 $ cat > a.patch <<EOF
697 $ cat > a.patch <<EOF
695 > add a, b
698 > add a, b
696 > diff --git a/a b/a
699 > diff --git a/a b/a
697 > --- a/a
700 > --- a/a
698 > +++ b/a
701 > +++ b/a
699 > @@ -0,0 +1,1 @@
702 > @@ -0,0 +1,1 @@
700 > +a
703 > +a
701 > diff --git a/b b/b
704 > diff --git a/b b/b
702 > new file mode 100644
705 > new file mode 100644
703 > EOF
706 > EOF
704 $ hg import --no-commit a.patch
707 $ hg import --no-commit a.patch
705 applying a.patch
708 applying a.patch
706
709
707 apply a good patch followed by an empty patch (mainly to ensure
710 apply a good patch followed by an empty patch (mainly to ensure
708 that dirstate is *not* updated when import crashes)
711 that dirstate is *not* updated when import crashes)
709 $ hg update -q -C .
712 $ hg update -q -C .
710 $ rm b
713 $ rm b
711 $ touch empty.patch
714 $ touch empty.patch
712 $ hg import a.patch empty.patch
715 $ hg import a.patch empty.patch
713 applying a.patch
716 applying a.patch
714 applying empty.patch
717 applying empty.patch
715 transaction abort!
718 transaction abort!
716 rollback completed
719 rollback completed
717 abort: empty.patch: no diffs found
720 abort: empty.patch: no diffs found
718 [255]
721 [255]
719 $ hg tip --template '{rev} {desc|firstline}\n'
722 $ hg tip --template '{rev} {desc|firstline}\n'
720 0 commit
723 0 commit
721 $ hg -q status
724 $ hg -q status
722 M a
725 M a
723 $ cd ..
726 $ cd ..
724
727
725 create file when source is not /dev/null
728 create file when source is not /dev/null
726
729
727 $ cat > create.patch <<EOF
730 $ cat > create.patch <<EOF
728 > diff -Naur proj-orig/foo proj-new/foo
731 > diff -Naur proj-orig/foo proj-new/foo
729 > --- proj-orig/foo 1969-12-31 16:00:00.000000000 -0800
732 > --- proj-orig/foo 1969-12-31 16:00:00.000000000 -0800
730 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
733 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
731 > @@ -0,0 +1,1 @@
734 > @@ -0,0 +1,1 @@
732 > +a
735 > +a
733 > EOF
736 > EOF
734
737
735 some people have patches like the following too
738 some people have patches like the following too
736
739
737 $ cat > create2.patch <<EOF
740 $ cat > create2.patch <<EOF
738 > diff -Naur proj-orig/foo proj-new/foo
741 > diff -Naur proj-orig/foo proj-new/foo
739 > --- proj-orig/foo.orig 1969-12-31 16:00:00.000000000 -0800
742 > --- proj-orig/foo.orig 1969-12-31 16:00:00.000000000 -0800
740 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
743 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
741 > @@ -0,0 +1,1 @@
744 > @@ -0,0 +1,1 @@
742 > +a
745 > +a
743 > EOF
746 > EOF
744 $ hg init oddcreate
747 $ hg init oddcreate
745 $ cd oddcreate
748 $ cd oddcreate
746 $ hg import --no-commit ../create.patch
749 $ hg import --no-commit ../create.patch
747 applying ../create.patch
750 applying ../create.patch
748 $ cat foo
751 $ cat foo
749 a
752 a
750 $ rm foo
753 $ rm foo
751 $ hg revert foo
754 $ hg revert foo
752 $ hg import --no-commit ../create2.patch
755 $ hg import --no-commit ../create2.patch
753 applying ../create2.patch
756 applying ../create2.patch
754 $ cat foo
757 $ cat foo
755 a
758 a
756
759
757 $ cd ..
760 $ cd ..
758
761
759 Issue1859: first line mistaken for email headers
762 Issue1859: first line mistaken for email headers
760
763
761 $ hg init emailconfusion
764 $ hg init emailconfusion
762 $ cd emailconfusion
765 $ cd emailconfusion
763 $ cat > a.patch <<EOF
766 $ cat > a.patch <<EOF
764 > module: summary
767 > module: summary
765 >
768 >
766 > description
769 > description
767 >
770 >
768 >
771 >
769 > diff -r 000000000000 -r 9b4c1e343b55 test.txt
772 > diff -r 000000000000 -r 9b4c1e343b55 test.txt
770 > --- /dev/null
773 > --- /dev/null
771 > +++ b/a
774 > +++ b/a
772 > @@ -0,0 +1,1 @@
775 > @@ -0,0 +1,1 @@
773 > +a
776 > +a
774 > EOF
777 > EOF
775 $ hg import -d '0 0' a.patch
778 $ hg import -d '0 0' a.patch
776 applying a.patch
779 applying a.patch
777 $ hg parents -v
780 $ hg parents -v
778 changeset: 0:5a681217c0ad
781 changeset: 0:5a681217c0ad
779 tag: tip
782 tag: tip
780 user: test
783 user: test
781 date: Thu Jan 01 00:00:00 1970 +0000
784 date: Thu Jan 01 00:00:00 1970 +0000
782 files: a
785 files: a
783 description:
786 description:
784 module: summary
787 module: summary
785
788
786 description
789 description
787
790
788
791
789 $ cd ..
792 $ cd ..
790
793
791
794
792 in commit message
795 in commit message
793
796
794 $ hg init commitconfusion
797 $ hg init commitconfusion
795 $ cd commitconfusion
798 $ cd commitconfusion
796 $ cat > a.patch <<EOF
799 $ cat > a.patch <<EOF
797 > module: summary
800 > module: summary
798 >
801 >
799 > --- description
802 > --- description
800 >
803 >
801 > diff --git a/a b/a
804 > diff --git a/a b/a
802 > new file mode 100644
805 > new file mode 100644
803 > --- /dev/null
806 > --- /dev/null
804 > +++ b/a
807 > +++ b/a
805 > @@ -0,0 +1,1 @@
808 > @@ -0,0 +1,1 @@
806 > +a
809 > +a
807 > EOF
810 > EOF
808 > hg import -d '0 0' a.patch
811 > hg import -d '0 0' a.patch
809 > hg parents -v
812 > hg parents -v
810 > cd ..
813 > cd ..
811 >
814 >
812 > echo '% tricky header splitting'
815 > echo '% tricky header splitting'
813 > cat > trickyheaders.patch <<EOF
816 > cat > trickyheaders.patch <<EOF
814 > From: User A <user@a>
817 > From: User A <user@a>
815 > Subject: [PATCH] from: tricky!
818 > Subject: [PATCH] from: tricky!
816 >
819 >
817 > # HG changeset patch
820 > # HG changeset patch
818 > # User User B
821 > # User User B
819 > # Date 1266264441 18000
822 > # Date 1266264441 18000
820 > # Branch stable
823 > # Branch stable
821 > # Node ID f2be6a1170ac83bf31cb4ae0bad00d7678115bc0
824 > # Node ID f2be6a1170ac83bf31cb4ae0bad00d7678115bc0
822 > # Parent 0000000000000000000000000000000000000000
825 > # Parent 0000000000000000000000000000000000000000
823 > from: tricky!
826 > from: tricky!
824 >
827 >
825 > That is not a header.
828 > That is not a header.
826 >
829 >
827 > diff -r 000000000000 -r f2be6a1170ac foo
830 > diff -r 000000000000 -r f2be6a1170ac foo
828 > --- /dev/null
831 > --- /dev/null
829 > +++ b/foo
832 > +++ b/foo
830 > @@ -0,0 +1,1 @@
833 > @@ -0,0 +1,1 @@
831 > +foo
834 > +foo
832 > EOF
835 > EOF
833 applying a.patch
836 applying a.patch
834 changeset: 0:f34d9187897d
837 changeset: 0:f34d9187897d
835 tag: tip
838 tag: tip
836 user: test
839 user: test
837 date: Thu Jan 01 00:00:00 1970 +0000
840 date: Thu Jan 01 00:00:00 1970 +0000
838 files: a
841 files: a
839 description:
842 description:
840 module: summary
843 module: summary
841
844
842
845
843 % tricky header splitting
846 % tricky header splitting
844
847
845 $ hg init trickyheaders
848 $ hg init trickyheaders
846 $ cd trickyheaders
849 $ cd trickyheaders
847 $ hg import -d '0 0' ../trickyheaders.patch
850 $ hg import -d '0 0' ../trickyheaders.patch
848 applying ../trickyheaders.patch
851 applying ../trickyheaders.patch
849 $ hg export --git tip
852 $ hg export --git tip
850 # HG changeset patch
853 # HG changeset patch
851 # User User B
854 # User User B
852 # Date 0 0
855 # Date 0 0
853 # Node ID eb56ab91903632294ac504838508cb370c0901d2
856 # Node ID eb56ab91903632294ac504838508cb370c0901d2
854 # Parent 0000000000000000000000000000000000000000
857 # Parent 0000000000000000000000000000000000000000
855 from: tricky!
858 from: tricky!
856
859
857 That is not a header.
860 That is not a header.
858
861
859 diff --git a/foo b/foo
862 diff --git a/foo b/foo
860 new file mode 100644
863 new file mode 100644
861 --- /dev/null
864 --- /dev/null
862 +++ b/foo
865 +++ b/foo
863 @@ -0,0 +1,1 @@
866 @@ -0,0 +1,1 @@
864 +foo
867 +foo
865 $ cd ..
868 $ cd ..
866
869
867
870
868 Issue2102: hg export and hg import speak different languages
871 Issue2102: hg export and hg import speak different languages
869
872
870 $ hg init issue2102
873 $ hg init issue2102
871 $ cd issue2102
874 $ cd issue2102
872 $ mkdir -p src/cmd/gc
875 $ mkdir -p src/cmd/gc
873 $ touch src/cmd/gc/mksys.bash
876 $ touch src/cmd/gc/mksys.bash
874 $ hg ci -Am init
877 $ hg ci -Am init
875 adding src/cmd/gc/mksys.bash
878 adding src/cmd/gc/mksys.bash
876 $ hg import - <<EOF
879 $ hg import - <<EOF
877 > # HG changeset patch
880 > # HG changeset patch
878 > # User Rob Pike
881 > # User Rob Pike
879 > # Date 1216685449 25200
882 > # Date 1216685449 25200
880 > # Node ID 03aa2b206f499ad6eb50e6e207b9e710d6409c98
883 > # Node ID 03aa2b206f499ad6eb50e6e207b9e710d6409c98
881 > # Parent 93d10138ad8df586827ca90b4ddb5033e21a3a84
884 > # Parent 93d10138ad8df586827ca90b4ddb5033e21a3a84
882 > help management of empty pkg and lib directories in perforce
885 > help management of empty pkg and lib directories in perforce
883 >
886 >
884 > R=gri
887 > R=gri
885 > DELTA=4 (4 added, 0 deleted, 0 changed)
888 > DELTA=4 (4 added, 0 deleted, 0 changed)
886 > OCL=13328
889 > OCL=13328
887 > CL=13328
890 > CL=13328
888 >
891 >
889 > diff --git a/lib/place-holder b/lib/place-holder
892 > diff --git a/lib/place-holder b/lib/place-holder
890 > new file mode 100644
893 > new file mode 100644
891 > --- /dev/null
894 > --- /dev/null
892 > +++ b/lib/place-holder
895 > +++ b/lib/place-holder
893 > @@ -0,0 +1,2 @@
896 > @@ -0,0 +1,2 @@
894 > +perforce does not maintain empty directories.
897 > +perforce does not maintain empty directories.
895 > +this file helps.
898 > +this file helps.
896 > diff --git a/pkg/place-holder b/pkg/place-holder
899 > diff --git a/pkg/place-holder b/pkg/place-holder
897 > new file mode 100644
900 > new file mode 100644
898 > --- /dev/null
901 > --- /dev/null
899 > +++ b/pkg/place-holder
902 > +++ b/pkg/place-holder
900 > @@ -0,0 +1,2 @@
903 > @@ -0,0 +1,2 @@
901 > +perforce does not maintain empty directories.
904 > +perforce does not maintain empty directories.
902 > +this file helps.
905 > +this file helps.
903 > diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
906 > diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
904 > old mode 100644
907 > old mode 100644
905 > new mode 100755
908 > new mode 100755
906 > EOF
909 > EOF
907 applying patch from stdin
910 applying patch from stdin
908
911
909 #if execbit
912 #if execbit
910
913
911 $ hg sum
914 $ hg sum
912 parent: 1:d59915696727 tip
915 parent: 1:d59915696727 tip
913 help management of empty pkg and lib directories in perforce
916 help management of empty pkg and lib directories in perforce
914 branch: default
917 branch: default
915 commit: (clean)
918 commit: (clean)
916 update: (current)
919 update: (current)
917
920
918 $ hg diff --git -c tip
921 $ hg diff --git -c tip
919 diff --git a/lib/place-holder b/lib/place-holder
922 diff --git a/lib/place-holder b/lib/place-holder
920 new file mode 100644
923 new file mode 100644
921 --- /dev/null
924 --- /dev/null
922 +++ b/lib/place-holder
925 +++ b/lib/place-holder
923 @@ -0,0 +1,2 @@
926 @@ -0,0 +1,2 @@
924 +perforce does not maintain empty directories.
927 +perforce does not maintain empty directories.
925 +this file helps.
928 +this file helps.
926 diff --git a/pkg/place-holder b/pkg/place-holder
929 diff --git a/pkg/place-holder b/pkg/place-holder
927 new file mode 100644
930 new file mode 100644
928 --- /dev/null
931 --- /dev/null
929 +++ b/pkg/place-holder
932 +++ b/pkg/place-holder
930 @@ -0,0 +1,2 @@
933 @@ -0,0 +1,2 @@
931 +perforce does not maintain empty directories.
934 +perforce does not maintain empty directories.
932 +this file helps.
935 +this file helps.
933 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
936 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
934 old mode 100644
937 old mode 100644
935 new mode 100755
938 new mode 100755
936
939
937 #else
940 #else
938
941
939 $ hg sum
942 $ hg sum
940 parent: 1:28f089cc9ccc tip
943 parent: 1:28f089cc9ccc tip
941 help management of empty pkg and lib directories in perforce
944 help management of empty pkg and lib directories in perforce
942 branch: default
945 branch: default
943 commit: (clean)
946 commit: (clean)
944 update: (current)
947 update: (current)
945
948
946 $ hg diff --git -c tip
949 $ hg diff --git -c tip
947 diff --git a/lib/place-holder b/lib/place-holder
950 diff --git a/lib/place-holder b/lib/place-holder
948 new file mode 100644
951 new file mode 100644
949 --- /dev/null
952 --- /dev/null
950 +++ b/lib/place-holder
953 +++ b/lib/place-holder
951 @@ -0,0 +1,2 @@
954 @@ -0,0 +1,2 @@
952 +perforce does not maintain empty directories.
955 +perforce does not maintain empty directories.
953 +this file helps.
956 +this file helps.
954 diff --git a/pkg/place-holder b/pkg/place-holder
957 diff --git a/pkg/place-holder b/pkg/place-holder
955 new file mode 100644
958 new file mode 100644
956 --- /dev/null
959 --- /dev/null
957 +++ b/pkg/place-holder
960 +++ b/pkg/place-holder
958 @@ -0,0 +1,2 @@
961 @@ -0,0 +1,2 @@
959 +perforce does not maintain empty directories.
962 +perforce does not maintain empty directories.
960 +this file helps.
963 +this file helps.
961
964
962 /* The mode change for mksys.bash is missing here, because on platforms */
965 /* The mode change for mksys.bash is missing here, because on platforms */
963 /* that don't support execbits, mode changes in patches are ignored when */
966 /* that don't support execbits, mode changes in patches are ignored when */
964 /* they are imported. This is obviously also the reason for why the hash */
967 /* they are imported. This is obviously also the reason for why the hash */
965 /* in the created changeset is different to the one you see above the */
968 /* in the created changeset is different to the one you see above the */
966 /* #else clause */
969 /* #else clause */
967
970
968 #endif
971 #endif
969 $ cd ..
972 $ cd ..
970
973
971
974
972 diff lines looking like headers
975 diff lines looking like headers
973
976
974 $ hg init difflineslikeheaders
977 $ hg init difflineslikeheaders
975 $ cd difflineslikeheaders
978 $ cd difflineslikeheaders
976 $ echo a >a
979 $ echo a >a
977 $ echo b >b
980 $ echo b >b
978 $ echo c >c
981 $ echo c >c
979 $ hg ci -Am1
982 $ hg ci -Am1
980 adding a
983 adding a
981 adding b
984 adding b
982 adding c
985 adding c
983
986
984 $ echo "key: value" >>a
987 $ echo "key: value" >>a
985 $ echo "key: value" >>b
988 $ echo "key: value" >>b
986 $ echo "foo" >>c
989 $ echo "foo" >>c
987 $ hg ci -m2
990 $ hg ci -m2
988
991
989 $ hg up -C 0
992 $ hg up -C 0
990 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
993 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
991 $ hg diff --git -c1 >want
994 $ hg diff --git -c1 >want
992 $ hg diff -c1 | hg import --no-commit -
995 $ hg diff -c1 | hg import --no-commit -
993 applying patch from stdin
996 applying patch from stdin
994 $ hg diff --git >have
997 $ hg diff --git >have
995 $ diff want have
998 $ diff want have
996 $ cd ..
999 $ cd ..
997
1000
998 import a unified diff with no lines of context (diff -U0)
1001 import a unified diff with no lines of context (diff -U0)
999
1002
1000 $ hg init diffzero
1003 $ hg init diffzero
1001 $ cd diffzero
1004 $ cd diffzero
1002 $ cat > f << EOF
1005 $ cat > f << EOF
1003 > c2
1006 > c2
1004 > c4
1007 > c4
1005 > c5
1008 > c5
1006 > EOF
1009 > EOF
1007 $ hg commit -Am0
1010 $ hg commit -Am0
1008 adding f
1011 adding f
1009
1012
1010 $ hg import --no-commit - << EOF
1013 $ hg import --no-commit - << EOF
1011 > # HG changeset patch
1014 > # HG changeset patch
1012 > # User test
1015 > # User test
1013 > # Date 0 0
1016 > # Date 0 0
1014 > # Node ID f4974ab632f3dee767567b0576c0ec9a4508575c
1017 > # Node ID f4974ab632f3dee767567b0576c0ec9a4508575c
1015 > # Parent 8679a12a975b819fae5f7ad3853a2886d143d794
1018 > # Parent 8679a12a975b819fae5f7ad3853a2886d143d794
1016 > 1
1019 > 1
1017 > diff -r 8679a12a975b -r f4974ab632f3 f
1020 > diff -r 8679a12a975b -r f4974ab632f3 f
1018 > --- a/f Thu Jan 01 00:00:00 1970 +0000
1021 > --- a/f Thu Jan 01 00:00:00 1970 +0000
1019 > +++ b/f Thu Jan 01 00:00:00 1970 +0000
1022 > +++ b/f Thu Jan 01 00:00:00 1970 +0000
1020 > @@ -0,0 +1,1 @@
1023 > @@ -0,0 +1,1 @@
1021 > +c1
1024 > +c1
1022 > @@ -1,0 +3,1 @@
1025 > @@ -1,0 +3,1 @@
1023 > +c3
1026 > +c3
1024 > @@ -3,1 +4,0 @@
1027 > @@ -3,1 +4,0 @@
1025 > -c5
1028 > -c5
1026 > EOF
1029 > EOF
1027 applying patch from stdin
1030 applying patch from stdin
1028
1031
1029 $ cat f
1032 $ cat f
1030 c1
1033 c1
1031 c2
1034 c2
1032 c3
1035 c3
1033 c4
1036 c4
1034
1037
1035 $ cd ..
1038 $ cd ..
1036
1039
1037 no segfault while importing a unified diff which start line is zero but chunk
1040 no segfault while importing a unified diff which start line is zero but chunk
1038 size is non-zero
1041 size is non-zero
1039
1042
1040 $ hg init startlinezero
1043 $ hg init startlinezero
1041 $ cd startlinezero
1044 $ cd startlinezero
1042 $ echo foo > foo
1045 $ echo foo > foo
1043 $ hg commit -Amfoo
1046 $ hg commit -Amfoo
1044 adding foo
1047 adding foo
1045
1048
1046 $ hg import --no-commit - << EOF
1049 $ hg import --no-commit - << EOF
1047 > diff a/foo b/foo
1050 > diff a/foo b/foo
1048 > --- a/foo
1051 > --- a/foo
1049 > +++ b/foo
1052 > +++ b/foo
1050 > @@ -0,1 +0,1 @@
1053 > @@ -0,1 +0,1 @@
1051 > foo
1054 > foo
1052 > EOF
1055 > EOF
1053 applying patch from stdin
1056 applying patch from stdin
1054
1057
1055 $ cd ..
1058 $ cd ..
1056
1059
1057 Test corner case involving fuzz and skew
1060 Test corner case involving fuzz and skew
1058
1061
1059 $ hg init morecornercases
1062 $ hg init morecornercases
1060 $ cd morecornercases
1063 $ cd morecornercases
1061
1064
1062 $ cat > 01-no-context-beginning-of-file.diff <<EOF
1065 $ cat > 01-no-context-beginning-of-file.diff <<EOF
1063 > diff --git a/a b/a
1066 > diff --git a/a b/a
1064 > --- a/a
1067 > --- a/a
1065 > +++ b/a
1068 > +++ b/a
1066 > @@ -1,0 +1,1 @@
1069 > @@ -1,0 +1,1 @@
1067 > +line
1070 > +line
1068 > EOF
1071 > EOF
1069
1072
1070 $ cat > 02-no-context-middle-of-file.diff <<EOF
1073 $ cat > 02-no-context-middle-of-file.diff <<EOF
1071 > diff --git a/a b/a
1074 > diff --git a/a b/a
1072 > --- a/a
1075 > --- a/a
1073 > +++ b/a
1076 > +++ b/a
1074 > @@ -1,1 +1,1 @@
1077 > @@ -1,1 +1,1 @@
1075 > -2
1078 > -2
1076 > +add some skew
1079 > +add some skew
1077 > @@ -2,0 +2,1 @@
1080 > @@ -2,0 +2,1 @@
1078 > +line
1081 > +line
1079 > EOF
1082 > EOF
1080
1083
1081 $ cat > 03-no-context-end-of-file.diff <<EOF
1084 $ cat > 03-no-context-end-of-file.diff <<EOF
1082 > diff --git a/a b/a
1085 > diff --git a/a b/a
1083 > --- a/a
1086 > --- a/a
1084 > +++ b/a
1087 > +++ b/a
1085 > @@ -10,0 +10,1 @@
1088 > @@ -10,0 +10,1 @@
1086 > +line
1089 > +line
1087 > EOF
1090 > EOF
1088
1091
1089 $ cat > 04-middle-of-file-completely-fuzzed.diff <<EOF
1092 $ cat > 04-middle-of-file-completely-fuzzed.diff <<EOF
1090 > diff --git a/a b/a
1093 > diff --git a/a b/a
1091 > --- a/a
1094 > --- a/a
1092 > +++ b/a
1095 > +++ b/a
1093 > @@ -1,1 +1,1 @@
1096 > @@ -1,1 +1,1 @@
1094 > -2
1097 > -2
1095 > +add some skew
1098 > +add some skew
1096 > @@ -2,2 +2,3 @@
1099 > @@ -2,2 +2,3 @@
1097 > not matching, should fuzz
1100 > not matching, should fuzz
1098 > ... a bit
1101 > ... a bit
1099 > +line
1102 > +line
1100 > EOF
1103 > EOF
1101
1104
1102 $ cat > a <<EOF
1105 $ cat > a <<EOF
1103 > 1
1106 > 1
1104 > 2
1107 > 2
1105 > 3
1108 > 3
1106 > 4
1109 > 4
1107 > EOF
1110 > EOF
1108 $ hg ci -Am adda a
1111 $ hg ci -Am adda a
1109 $ for p in *.diff; do
1112 $ for p in *.diff; do
1110 > hg import -v --no-commit $p
1113 > hg import -v --no-commit $p
1111 > cat a
1114 > cat a
1112 > hg revert -aqC a
1115 > hg revert -aqC a
1113 > # patch -p1 < $p
1116 > # patch -p1 < $p
1114 > # cat a
1117 > # cat a
1115 > # hg revert -aC a
1118 > # hg revert -aC a
1116 > done
1119 > done
1117 applying 01-no-context-beginning-of-file.diff
1120 applying 01-no-context-beginning-of-file.diff
1118 patching file a
1121 patching file a
1119 applied to working directory
1122 applied to working directory
1120 1
1123 1
1121 line
1124 line
1122 2
1125 2
1123 3
1126 3
1124 4
1127 4
1125 applying 02-no-context-middle-of-file.diff
1128 applying 02-no-context-middle-of-file.diff
1126 patching file a
1129 patching file a
1127 Hunk #1 succeeded at 2 (offset 1 lines).
1130 Hunk #1 succeeded at 2 (offset 1 lines).
1128 Hunk #2 succeeded at 4 (offset 1 lines).
1131 Hunk #2 succeeded at 4 (offset 1 lines).
1129 applied to working directory
1132 applied to working directory
1130 1
1133 1
1131 add some skew
1134 add some skew
1132 3
1135 3
1133 line
1136 line
1134 4
1137 4
1135 applying 03-no-context-end-of-file.diff
1138 applying 03-no-context-end-of-file.diff
1136 patching file a
1139 patching file a
1137 Hunk #1 succeeded at 5 (offset -6 lines).
1140 Hunk #1 succeeded at 5 (offset -6 lines).
1138 applied to working directory
1141 applied to working directory
1139 1
1142 1
1140 2
1143 2
1141 3
1144 3
1142 4
1145 4
1143 line
1146 line
1144 applying 04-middle-of-file-completely-fuzzed.diff
1147 applying 04-middle-of-file-completely-fuzzed.diff
1145 patching file a
1148 patching file a
1146 Hunk #1 succeeded at 2 (offset 1 lines).
1149 Hunk #1 succeeded at 2 (offset 1 lines).
1147 Hunk #2 succeeded at 5 with fuzz 2 (offset 1 lines).
1150 Hunk #2 succeeded at 5 with fuzz 2 (offset 1 lines).
1148 applied to working directory
1151 applied to working directory
1149 1
1152 1
1150 add some skew
1153 add some skew
1151 3
1154 3
1152 4
1155 4
1153 line
1156 line
1154
1157
1155 $ cd ..
1158 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now