##// END OF EJS Templates
tests: make timezone in diff output glob-ed for portability...
FUJIWARA Katsunori -
r28034:e7ff258f default
parent child Browse files
Show More
@@ -1,589 +1,591 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 """style and portability checker for Mercurial
10 """style and portability checker for Mercurial
11
11
12 when a rule triggers wrong, do one of the following (prefer one from top):
12 when a rule triggers wrong, do one of the following (prefer one from top):
13 * do the work-around the rule suggests
13 * do the work-around the rule suggests
14 * doublecheck that it is a false match
14 * doublecheck that it is a false match
15 * improve the rule pattern
15 * improve the rule pattern
16 * add an ignore pattern to the rule (3rd arg) which matches your good line
16 * add an ignore pattern to the rule (3rd arg) which matches your good line
17 (you can append a short comment and match this, like: #re-raises, # no-py24)
17 (you can append a short comment and match this, like: #re-raises, # no-py24)
18 * change the pattern to a warning and list the exception in test-check-code-hg
18 * change the pattern to a warning and list the exception in test-check-code-hg
19 * ONLY use no--check-code for skipping entire files from external sources
19 * ONLY use no--check-code for skipping entire files from external sources
20 """
20 """
21
21
22 import re, glob, os, sys
22 import re, glob, os, sys
23 import keyword
23 import keyword
24 import optparse
24 import optparse
25 try:
25 try:
26 import re2
26 import re2
27 except ImportError:
27 except ImportError:
28 re2 = None
28 re2 = None
29
29
30 def compilere(pat, multiline=False):
30 def compilere(pat, multiline=False):
31 if multiline:
31 if multiline:
32 pat = '(?m)' + pat
32 pat = '(?m)' + pat
33 if re2:
33 if re2:
34 try:
34 try:
35 return re2.compile(pat)
35 return re2.compile(pat)
36 except re2.error:
36 except re2.error:
37 pass
37 pass
38 return re.compile(pat)
38 return re.compile(pat)
39
39
40 def repquote(m):
40 def repquote(m):
41 fromc = '.:'
41 fromc = '.:'
42 tochr = 'pq'
42 tochr = 'pq'
43 def encodechr(i):
43 def encodechr(i):
44 if i > 255:
44 if i > 255:
45 return 'u'
45 return 'u'
46 c = chr(i)
46 c = chr(i)
47 if c in ' \n':
47 if c in ' \n':
48 return c
48 return c
49 if c.isalpha():
49 if c.isalpha():
50 return 'x'
50 return 'x'
51 if c.isdigit():
51 if c.isdigit():
52 return 'n'
52 return 'n'
53 try:
53 try:
54 return tochr[fromc.find(c)]
54 return tochr[fromc.find(c)]
55 except (ValueError, IndexError):
55 except (ValueError, IndexError):
56 return 'o'
56 return 'o'
57 t = m.group('text')
57 t = m.group('text')
58 tt = ''.join(encodechr(i) for i in xrange(256))
58 tt = ''.join(encodechr(i) for i in xrange(256))
59 t = t.translate(tt)
59 t = t.translate(tt)
60 return m.group('quote') + t + m.group('quote')
60 return m.group('quote') + t + m.group('quote')
61
61
62 def reppython(m):
62 def reppython(m):
63 comment = m.group('comment')
63 comment = m.group('comment')
64 if comment:
64 if comment:
65 l = len(comment.rstrip())
65 l = len(comment.rstrip())
66 return "#" * l + comment[l:]
66 return "#" * l + comment[l:]
67 return repquote(m)
67 return repquote(m)
68
68
69 def repcomment(m):
69 def repcomment(m):
70 return m.group(1) + "#" * len(m.group(2))
70 return m.group(1) + "#" * len(m.group(2))
71
71
72 def repccomment(m):
72 def repccomment(m):
73 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
73 t = re.sub(r"((?<=\n) )|\S", "x", m.group(2))
74 return m.group(1) + t + "*/"
74 return m.group(1) + t + "*/"
75
75
76 def repcallspaces(m):
76 def repcallspaces(m):
77 t = re.sub(r"\n\s+", "\n", m.group(2))
77 t = re.sub(r"\n\s+", "\n", m.group(2))
78 return m.group(1) + t
78 return m.group(1) + t
79
79
80 def repinclude(m):
80 def repinclude(m):
81 return m.group(1) + "<foo>"
81 return m.group(1) + "<foo>"
82
82
83 def rephere(m):
83 def rephere(m):
84 t = re.sub(r"\S", "x", m.group(2))
84 t = re.sub(r"\S", "x", m.group(2))
85 return m.group(1) + t
85 return m.group(1) + t
86
86
87
87
88 testpats = [
88 testpats = [
89 [
89 [
90 (r'pushd|popd', "don't use 'pushd' or 'popd', use 'cd'"),
90 (r'pushd|popd', "don't use 'pushd' or 'popd', use 'cd'"),
91 (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
91 (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
92 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
92 (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
93 (r'(?<!hg )grep.* -a', "don't use 'grep -a', use in-line python"),
93 (r'(?<!hg )grep.* -a', "don't use 'grep -a', use in-line python"),
94 (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
94 (r'sed.*-i', "don't use 'sed -i', use a temporary file"),
95 (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
95 (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
96 (r'echo -n', "don't use 'echo -n', use printf"),
96 (r'echo -n', "don't use 'echo -n', use printf"),
97 (r'(^|\|\s*)\bwc\b[^|]*$\n(?!.*\(re\))', "filter wc output"),
97 (r'(^|\|\s*)\bwc\b[^|]*$\n(?!.*\(re\))', "filter wc output"),
98 (r'head -c', "don't use 'head -c', use 'dd'"),
98 (r'head -c', "don't use 'head -c', use 'dd'"),
99 (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"),
99 (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"),
100 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
100 (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
101 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
101 (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
102 (r'printf.*[^\\]\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
102 (r'printf.*[^\\]\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
103 (r'printf.*[^\\]\\x', "don't use printf \\x, use Python"),
103 (r'printf.*[^\\]\\x', "don't use printf \\x, use Python"),
104 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
104 (r'\$\(.*\)', "don't use $(expr), use `expr`"),
105 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
105 (r'rm -rf \*', "don't use naked rm -rf, target a directory"),
106 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
106 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
107 "use egrep for extended grep syntax"),
107 "use egrep for extended grep syntax"),
108 (r'/bin/', "don't use explicit paths for tools"),
108 (r'/bin/', "don't use explicit paths for tools"),
109 (r'[^\n]\Z', "no trailing newline"),
109 (r'[^\n]\Z', "no trailing newline"),
110 (r'export .*=', "don't export and assign at once"),
110 (r'export .*=', "don't export and assign at once"),
111 (r'^source\b', "don't use 'source', use '.'"),
111 (r'^source\b', "don't use 'source', use '.'"),
112 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
112 (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
113 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
113 (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"),
114 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
114 (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
115 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
115 (r'^stop\(\)', "don't use 'stop' as a shell function name"),
116 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
116 (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"),
117 (r'\[\[\s+[^\]]*\]\]', "don't use '[[ ]]', use '[ ]'"),
117 (r'\[\[\s+[^\]]*\]\]', "don't use '[[ ]]', use '[ ]'"),
118 (r'^alias\b.*=', "don't use alias, use a function"),
118 (r'^alias\b.*=', "don't use alias, use a function"),
119 (r'if\s*!', "don't use '!' to negate exit status"),
119 (r'if\s*!', "don't use '!' to negate exit status"),
120 (r'/dev/u?random', "don't use entropy, use /dev/zero"),
120 (r'/dev/u?random', "don't use entropy, use /dev/zero"),
121 (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
121 (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"),
122 (r'^( *)\t', "don't use tabs to indent"),
122 (r'^( *)\t', "don't use tabs to indent"),
123 (r'sed (-e )?\'(\d+|/[^/]*/)i(?!\\\n)',
123 (r'sed (-e )?\'(\d+|/[^/]*/)i(?!\\\n)',
124 "put a backslash-escaped newline after sed 'i' command"),
124 "put a backslash-escaped newline after sed 'i' command"),
125 (r'^diff *-\w*[uU].*$\n(^ \$ |^$)', "prefix diff -u/-U with cmp"),
125 (r'^diff *-\w*[uU].*$\n(^ \$ |^$)', "prefix diff -u/-U with cmp"),
126 (r'^\s+(if)? diff *-\w*[uU]', "prefix diff -u/-U with cmp"),
126 (r'^\s+(if)? diff *-\w*[uU]', "prefix diff -u/-U with cmp"),
127 (r'seq ', "don't use 'seq', use $TESTDIR/seq.py"),
127 (r'seq ', "don't use 'seq', use $TESTDIR/seq.py"),
128 (r'\butil\.Abort\b', "directly use error.Abort"),
128 (r'\butil\.Abort\b', "directly use error.Abort"),
129 (r'\|&', "don't use |&, use 2>&1"),
129 (r'\|&', "don't use |&, use 2>&1"),
130 (r'\w = +\w', "only one space after = allowed"),
130 (r'\w = +\w', "only one space after = allowed"),
131 ],
131 ],
132 # warnings
132 # warnings
133 [
133 [
134 (r'^function', "don't use 'function', use old style"),
134 (r'^function', "don't use 'function', use old style"),
135 (r'^diff.*-\w*N', "don't use 'diff -N'"),
135 (r'^diff.*-\w*N', "don't use 'diff -N'"),
136 (r'\$PWD|\${PWD}', "don't use $PWD, use `pwd`"),
136 (r'\$PWD|\${PWD}', "don't use $PWD, use `pwd`"),
137 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
137 (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"),
138 (r'kill (`|\$\()', "don't use kill, use killdaemons.py")
138 (r'kill (`|\$\()', "don't use kill, use killdaemons.py")
139 ]
139 ]
140 ]
140 ]
141
141
142 testfilters = [
142 testfilters = [
143 (r"( *)(#([^\n]*\S)?)", repcomment),
143 (r"( *)(#([^\n]*\S)?)", repcomment),
144 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
144 (r"<<(\S+)((.|\n)*?\n\1)", rephere),
145 ]
145 ]
146
146
147 winglobmsg = "use (glob) to match Windows paths too"
147 winglobmsg = "use (glob) to match Windows paths too"
148 uprefix = r"^ \$ "
148 uprefix = r"^ \$ "
149 utestpats = [
149 utestpats = [
150 [
150 [
151 (r'^(\S.*|| [$>] \S.*)[ \t]\n', "trailing whitespace on non-output"),
151 (r'^(\S.*|| [$>] \S.*)[ \t]\n', "trailing whitespace on non-output"),
152 (uprefix + r'.*\|\s*sed[^|>\n]*\n',
152 (uprefix + r'.*\|\s*sed[^|>\n]*\n',
153 "use regex test output patterns instead of sed"),
153 "use regex test output patterns instead of sed"),
154 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
154 (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
155 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
155 (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"),
156 (uprefix + r'.*\|\| echo.*(fail|error)',
156 (uprefix + r'.*\|\| echo.*(fail|error)',
157 "explicit exit code checks unnecessary"),
157 "explicit exit code checks unnecessary"),
158 (uprefix + r'set -e', "don't use set -e"),
158 (uprefix + r'set -e', "don't use set -e"),
159 (uprefix + r'(\s|fi\b|done\b)', "use > for continued lines"),
159 (uprefix + r'(\s|fi\b|done\b)', "use > for continued lines"),
160 (uprefix + r'.*:\.\S*/', "x:.y in a path does not work on msys, rewrite "
160 (uprefix + r'.*:\.\S*/', "x:.y in a path does not work on msys, rewrite "
161 "as x://.y, or see `hg log -k msys` for alternatives", r'-\S+:\.|' #-Rxxx
161 "as x://.y, or see `hg log -k msys` for alternatives", r'-\S+:\.|' #-Rxxx
162 '# no-msys'), # in test-pull.t which is skipped on windows
162 '# no-msys'), # in test-pull.t which is skipped on windows
163 (r'^ saved backup bundle to \$TESTTMP.*\.hg$', winglobmsg),
163 (r'^ saved backup bundle to \$TESTTMP.*\.hg$', winglobmsg),
164 (r'^ changeset .* references (corrupted|missing) \$TESTTMP/.*[^)]$',
164 (r'^ changeset .* references (corrupted|missing) \$TESTTMP/.*[^)]$',
165 winglobmsg),
165 winglobmsg),
166 (r'^ pulling from \$TESTTMP/.*[^)]$', winglobmsg,
166 (r'^ pulling from \$TESTTMP/.*[^)]$', winglobmsg,
167 '\$TESTTMP/unix-repo$'), # in test-issue1802.t which skipped on windows
167 '\$TESTTMP/unix-repo$'), # in test-issue1802.t which skipped on windows
168 (r'^ reverting (?!subrepo ).*/.*[^)]$', winglobmsg),
168 (r'^ reverting (?!subrepo ).*/.*[^)]$', winglobmsg),
169 (r'^ cloning subrepo \S+/.*[^)]$', winglobmsg),
169 (r'^ cloning subrepo \S+/.*[^)]$', winglobmsg),
170 (r'^ pushing to \$TESTTMP/.*[^)]$', winglobmsg),
170 (r'^ pushing to \$TESTTMP/.*[^)]$', winglobmsg),
171 (r'^ pushing subrepo \S+/\S+ to.*[^)]$', winglobmsg),
171 (r'^ pushing subrepo \S+/\S+ to.*[^)]$', winglobmsg),
172 (r'^ moving \S+/.*[^)]$', winglobmsg),
172 (r'^ moving \S+/.*[^)]$', winglobmsg),
173 (r'^ no changes made to subrepo since.*/.*[^)]$', winglobmsg),
173 (r'^ no changes made to subrepo since.*/.*[^)]$', winglobmsg),
174 (r'^ .*: largefile \S+ not available from file:.*/.*[^)]$', winglobmsg),
174 (r'^ .*: largefile \S+ not available from file:.*/.*[^)]$', winglobmsg),
175 (r'^ .*file://\$TESTTMP',
175 (r'^ .*file://\$TESTTMP',
176 'write "file:/*/$TESTTMP" + (glob) to match on windows too'),
176 'write "file:/*/$TESTTMP" + (glob) to match on windows too'),
177 (r'^ (cat|find): .*: No such file or directory',
177 (r'^ (cat|find): .*: No such file or directory',
178 'use test -f to test for file existence'),
178 'use test -f to test for file existence'),
179 (r'^ diff -[^ -]*p',
179 (r'^ diff -[^ -]*p',
180 "don't use (external) diff with -p for portability"),
180 "don't use (external) diff with -p for portability"),
181 (r'^ [-+][-+][-+] .* [-+]0000 \(glob\)',
182 "glob timezone field in diff output for portability"),
181 ],
183 ],
182 # warnings
184 # warnings
183 [
185 [
184 (r'^ [^*?/\n]* \(glob\)$',
186 (r'^ [^*?/\n]* \(glob\)$',
185 "glob match with no glob character (?*/)"),
187 "glob match with no glob character (?*/)"),
186 ]
188 ]
187 ]
189 ]
188
190
189 for i in [0, 1]:
191 for i in [0, 1]:
190 for tp in testpats[i]:
192 for tp in testpats[i]:
191 p = tp[0]
193 p = tp[0]
192 m = tp[1]
194 m = tp[1]
193 if p.startswith(r'^'):
195 if p.startswith(r'^'):
194 p = r"^ [$>] (%s)" % p[1:]
196 p = r"^ [$>] (%s)" % p[1:]
195 else:
197 else:
196 p = r"^ [$>] .*(%s)" % p
198 p = r"^ [$>] .*(%s)" % p
197 utestpats[i].append((p, m) + tp[2:])
199 utestpats[i].append((p, m) + tp[2:])
198
200
199 utestfilters = [
201 utestfilters = [
200 (r"<<(\S+)((.|\n)*?\n > \1)", rephere),
202 (r"<<(\S+)((.|\n)*?\n > \1)", rephere),
201 (r"( *)(#([^\n]*\S)?)", repcomment),
203 (r"( *)(#([^\n]*\S)?)", repcomment),
202 ]
204 ]
203
205
204 pypats = [
206 pypats = [
205 [
207 [
206 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
208 (r'^\s*def\s*\w+\s*\(.*,\s*\(',
207 "tuple parameter unpacking not available in Python 3+"),
209 "tuple parameter unpacking not available in Python 3+"),
208 (r'lambda\s*\(.*,.*\)',
210 (r'lambda\s*\(.*,.*\)',
209 "tuple parameter unpacking not available in Python 3+"),
211 "tuple parameter unpacking not available in Python 3+"),
210 (r'import (.+,[^.]+\.[^.]+|[^.]+\.[^.]+,)',
212 (r'import (.+,[^.]+\.[^.]+|[^.]+\.[^.]+,)',
211 '2to3 can\'t always rewrite "import qux, foo.bar", '
213 '2to3 can\'t always rewrite "import qux, foo.bar", '
212 'use "import foo.bar" on its own line instead.'),
214 'use "import foo.bar" on its own line instead.'),
213 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
215 (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"),
214 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
216 (r'\breduce\s*\(.*', "reduce is not available in Python 3+"),
215 (r'dict\(.*=', 'dict() is different in Py2 and 3 and is slower than {}',
217 (r'dict\(.*=', 'dict() is different in Py2 and 3 and is slower than {}',
216 'dict-from-generator'),
218 'dict-from-generator'),
217 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
219 (r'\.has_key\b', "dict.has_key is not available in Python 3+"),
218 (r'\s<>\s', '<> operator is not available in Python 3+, use !='),
220 (r'\s<>\s', '<> operator is not available in Python 3+, use !='),
219 (r'^\s*\t', "don't use tabs"),
221 (r'^\s*\t', "don't use tabs"),
220 (r'\S;\s*\n', "semicolon"),
222 (r'\S;\s*\n', "semicolon"),
221 (r'[^_]_\([ \t\n]*(?:"[^"]+"[ \t\n+]*)+%', "don't use % inside _()"),
223 (r'[^_]_\([ \t\n]*(?:"[^"]+"[ \t\n+]*)+%', "don't use % inside _()"),
222 (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"),
224 (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"),
223 (r'(\w|\)),\w', "missing whitespace after ,"),
225 (r'(\w|\)),\w', "missing whitespace after ,"),
224 (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"),
226 (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"),
225 (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"),
227 (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"),
226 (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
228 (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
227 (r'.{81}', "line too long"),
229 (r'.{81}', "line too long"),
228 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
230 (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'),
229 (r'[^\n]\Z', "no trailing newline"),
231 (r'[^\n]\Z', "no trailing newline"),
230 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
232 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
231 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
233 # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=',
232 # "don't use underbars in identifiers"),
234 # "don't use underbars in identifiers"),
233 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
235 (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
234 "don't use camelcase in identifiers"),
236 "don't use camelcase in identifiers"),
235 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
237 (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
236 "linebreak after :"),
238 "linebreak after :"),
237 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
239 (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
238 (r'class\s[^( \n]+\(\):',
240 (r'class\s[^( \n]+\(\):',
239 "class foo() creates old style object, use class foo(object)"),
241 "class foo() creates old style object, use class foo(object)"),
240 (r'\b(%s)\(' % '|'.join(k for k in keyword.kwlist
242 (r'\b(%s)\(' % '|'.join(k for k in keyword.kwlist
241 if k not in ('print', 'exec')),
243 if k not in ('print', 'exec')),
242 "Python keyword is not a function"),
244 "Python keyword is not a function"),
243 (r',]', "unneeded trailing ',' in list"),
245 (r',]', "unneeded trailing ',' in list"),
244 # (r'class\s[A-Z][^\(]*\((?!Exception)',
246 # (r'class\s[A-Z][^\(]*\((?!Exception)',
245 # "don't capitalize non-exception classes"),
247 # "don't capitalize non-exception classes"),
246 # (r'in range\(', "use xrange"),
248 # (r'in range\(', "use xrange"),
247 # (r'^\s*print\s+', "avoid using print in core and extensions"),
249 # (r'^\s*print\s+', "avoid using print in core and extensions"),
248 (r'[\x80-\xff]', "non-ASCII character literal"),
250 (r'[\x80-\xff]', "non-ASCII character literal"),
249 (r'("\')\.format\(', "str.format() has no bytes counterpart, use %"),
251 (r'("\')\.format\(', "str.format() has no bytes counterpart, use %"),
250 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
252 (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
251 "gratuitous whitespace after Python keyword"),
253 "gratuitous whitespace after Python keyword"),
252 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
254 (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"),
253 # (r'\s\s=', "gratuitous whitespace before ="),
255 # (r'\s\s=', "gratuitous whitespace before ="),
254 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
256 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
255 "missing whitespace around operator"),
257 "missing whitespace around operator"),
256 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
258 (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s',
257 "missing whitespace around operator"),
259 "missing whitespace around operator"),
258 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
260 (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S',
259 "missing whitespace around operator"),
261 "missing whitespace around operator"),
260 (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
262 (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]',
261 "wrong whitespace around ="),
263 "wrong whitespace around ="),
262 (r'\([^()]*( =[^=]|[^<>!=]= )',
264 (r'\([^()]*( =[^=]|[^<>!=]= )',
263 "no whitespace around = for named parameters"),
265 "no whitespace around = for named parameters"),
264 (r'raise Exception', "don't raise generic exceptions"),
266 (r'raise Exception', "don't raise generic exceptions"),
265 (r'raise [^,(]+, (\([^\)]+\)|[^,\(\)]+)$',
267 (r'raise [^,(]+, (\([^\)]+\)|[^,\(\)]+)$',
266 "don't use old-style two-argument raise, use Exception(message)"),
268 "don't use old-style two-argument raise, use Exception(message)"),
267 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
269 (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
268 (r' [=!]=\s+(True|False|None)',
270 (r' [=!]=\s+(True|False|None)',
269 "comparison with singleton, use 'is' or 'is not' instead"),
271 "comparison with singleton, use 'is' or 'is not' instead"),
270 (r'^\s*(while|if) [01]:',
272 (r'^\s*(while|if) [01]:',
271 "use True/False for constant Boolean expression"),
273 "use True/False for constant Boolean expression"),
272 (r'(?:(?<!def)\s+|\()hasattr',
274 (r'(?:(?<!def)\s+|\()hasattr',
273 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
275 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
274 (r'opener\([^)]*\).read\(',
276 (r'opener\([^)]*\).read\(',
275 "use opener.read() instead"),
277 "use opener.read() instead"),
276 (r'opener\([^)]*\).write\(',
278 (r'opener\([^)]*\).write\(',
277 "use opener.write() instead"),
279 "use opener.write() instead"),
278 (r'[\s\(](open|file)\([^)]*\)\.read\(',
280 (r'[\s\(](open|file)\([^)]*\)\.read\(',
279 "use util.readfile() instead"),
281 "use util.readfile() instead"),
280 (r'[\s\(](open|file)\([^)]*\)\.write\(',
282 (r'[\s\(](open|file)\([^)]*\)\.write\(',
281 "use util.writefile() instead"),
283 "use util.writefile() instead"),
282 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
284 (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
283 "always assign an opened file to a variable, and close it afterwards"),
285 "always assign an opened file to a variable, and close it afterwards"),
284 (r'[\s\(](open|file)\([^)]*\)\.',
286 (r'[\s\(](open|file)\([^)]*\)\.',
285 "always assign an opened file to a variable, and close it afterwards"),
287 "always assign an opened file to a variable, and close it afterwards"),
286 (r'(?i)descend[e]nt', "the proper spelling is descendAnt"),
288 (r'(?i)descend[e]nt', "the proper spelling is descendAnt"),
287 (r'\.debug\(\_', "don't mark debug messages for translation"),
289 (r'\.debug\(\_', "don't mark debug messages for translation"),
288 (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
290 (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
289 (r'^\s*except\s*:', "naked except clause", r'#.*re-raises'),
291 (r'^\s*except\s*:', "naked except clause", r'#.*re-raises'),
290 (r'^\s*except\s([^\(,]+|\([^\)]+\))\s*,',
292 (r'^\s*except\s([^\(,]+|\([^\)]+\))\s*,',
291 'legacy exception syntax; use "as" instead of ","'),
293 'legacy exception syntax; use "as" instead of ","'),
292 (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"),
294 (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"),
293 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
295 (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
294 "missing _() in ui message (use () to hide false-positives)"),
296 "missing _() in ui message (use () to hide false-positives)"),
295 (r'release\(.*wlock, .*lock\)', "wrong lock release order"),
297 (r'release\(.*wlock, .*lock\)', "wrong lock release order"),
296 (r'\b__bool__\b', "__bool__ should be __nonzero__ in Python 2"),
298 (r'\b__bool__\b', "__bool__ should be __nonzero__ in Python 2"),
297 (r'os\.path\.join\(.*, *(""|\'\')\)',
299 (r'os\.path\.join\(.*, *(""|\'\')\)',
298 "use pathutil.normasprefix(path) instead of os.path.join(path, '')"),
300 "use pathutil.normasprefix(path) instead of os.path.join(path, '')"),
299 (r'\s0[0-7]+\b', 'legacy octal syntax; use "0o" prefix instead of "0"'),
301 (r'\s0[0-7]+\b', 'legacy octal syntax; use "0o" prefix instead of "0"'),
300 # XXX only catch mutable arguments on the first line of the definition
302 # XXX only catch mutable arguments on the first line of the definition
301 (r'def.*[( ]\w+=\{\}', "don't use mutable default arguments"),
303 (r'def.*[( ]\w+=\{\}', "don't use mutable default arguments"),
302 (r'\butil\.Abort\b', "directly use error.Abort"),
304 (r'\butil\.Abort\b', "directly use error.Abort"),
303 ],
305 ],
304 # warnings
306 # warnings
305 [
307 [
306 (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"),
308 (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"),
307 ]
309 ]
308 ]
310 ]
309
311
310 pyfilters = [
312 pyfilters = [
311 (r"""(?msx)(?P<comment>\#.*?$)|
313 (r"""(?msx)(?P<comment>\#.*?$)|
312 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
314 ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
313 (?P<text>(([^\\]|\\.)*?))
315 (?P<text>(([^\\]|\\.)*?))
314 (?P=quote))""", reppython),
316 (?P=quote))""", reppython),
315 ]
317 ]
316
318
317 txtfilters = []
319 txtfilters = []
318
320
319 txtpats = [
321 txtpats = [
320 [
322 [
321 ('\s$', 'trailing whitespace'),
323 ('\s$', 'trailing whitespace'),
322 ('.. note::[ \n][^\n]', 'add two newlines after note::')
324 ('.. note::[ \n][^\n]', 'add two newlines after note::')
323 ],
325 ],
324 []
326 []
325 ]
327 ]
326
328
327 cpats = [
329 cpats = [
328 [
330 [
329 (r'//', "don't use //-style comments"),
331 (r'//', "don't use //-style comments"),
330 (r'^ ', "don't use spaces to indent"),
332 (r'^ ', "don't use spaces to indent"),
331 (r'\S\t', "don't use tabs except for indent"),
333 (r'\S\t', "don't use tabs except for indent"),
332 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
334 (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
333 (r'.{81}', "line too long"),
335 (r'.{81}', "line too long"),
334 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
336 (r'(while|if|do|for)\(', "use space after while/if/do/for"),
335 (r'return\(', "return is not a function"),
337 (r'return\(', "return is not a function"),
336 (r' ;', "no space before ;"),
338 (r' ;', "no space before ;"),
337 (r'[^;] \)', "no space before )"),
339 (r'[^;] \)', "no space before )"),
338 (r'[)][{]', "space between ) and {"),
340 (r'[)][{]', "space between ) and {"),
339 (r'\w+\* \w+', "use int *foo, not int* foo"),
341 (r'\w+\* \w+', "use int *foo, not int* foo"),
340 (r'\W\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
342 (r'\W\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
341 (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
343 (r'\w+ (\+\+|--)', "use foo++, not foo ++"),
342 (r'\w,\w', "missing whitespace after ,"),
344 (r'\w,\w', "missing whitespace after ,"),
343 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
345 (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
344 (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
346 (r'\w\s=\s\s+\w', "gratuitous whitespace after ="),
345 (r'^#\s+\w', "use #foo, not # foo"),
347 (r'^#\s+\w', "use #foo, not # foo"),
346 (r'[^\n]\Z', "no trailing newline"),
348 (r'[^\n]\Z', "no trailing newline"),
347 (r'^\s*#import\b', "use only #include in standard C code"),
349 (r'^\s*#import\b', "use only #include in standard C code"),
348 ],
350 ],
349 # warnings
351 # warnings
350 []
352 []
351 ]
353 ]
352
354
353 cfilters = [
355 cfilters = [
354 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
356 (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
355 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
357 (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
356 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
358 (r'''(#\s*include\s+<)([^>]+)>''', repinclude),
357 (r'(\()([^)]+\))', repcallspaces),
359 (r'(\()([^)]+\))', repcallspaces),
358 ]
360 ]
359
361
360 inutilpats = [
362 inutilpats = [
361 [
363 [
362 (r'\bui\.', "don't use ui in util"),
364 (r'\bui\.', "don't use ui in util"),
363 ],
365 ],
364 # warnings
366 # warnings
365 []
367 []
366 ]
368 ]
367
369
368 inrevlogpats = [
370 inrevlogpats = [
369 [
371 [
370 (r'\brepo\.', "don't use repo in revlog"),
372 (r'\brepo\.', "don't use repo in revlog"),
371 ],
373 ],
372 # warnings
374 # warnings
373 []
375 []
374 ]
376 ]
375
377
376 webtemplatefilters = []
378 webtemplatefilters = []
377
379
378 webtemplatepats = [
380 webtemplatepats = [
379 [],
381 [],
380 [
382 [
381 (r'{desc(\|(?!websub|firstline)[^\|]*)+}',
383 (r'{desc(\|(?!websub|firstline)[^\|]*)+}',
382 'follow desc keyword with either firstline or websub'),
384 'follow desc keyword with either firstline or websub'),
383 ]
385 ]
384 ]
386 ]
385
387
386 checks = [
388 checks = [
387 ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats),
389 ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats),
388 ('test script', r'(.*/)?test-[^.~]*$', '', testfilters, testpats),
390 ('test script', r'(.*/)?test-[^.~]*$', '', testfilters, testpats),
389 ('c', r'.*\.[ch]$', '', cfilters, cpats),
391 ('c', r'.*\.[ch]$', '', cfilters, cpats),
390 ('unified test', r'.*\.t$', '', utestfilters, utestpats),
392 ('unified test', r'.*\.t$', '', utestfilters, utestpats),
391 ('layering violation repo in revlog', r'mercurial/revlog\.py', '',
393 ('layering violation repo in revlog', r'mercurial/revlog\.py', '',
392 pyfilters, inrevlogpats),
394 pyfilters, inrevlogpats),
393 ('layering violation ui in util', r'mercurial/util\.py', '', pyfilters,
395 ('layering violation ui in util', r'mercurial/util\.py', '', pyfilters,
394 inutilpats),
396 inutilpats),
395 ('txt', r'.*\.txt$', '', txtfilters, txtpats),
397 ('txt', r'.*\.txt$', '', txtfilters, txtpats),
396 ('web template', r'mercurial/templates/.*\.tmpl', '',
398 ('web template', r'mercurial/templates/.*\.tmpl', '',
397 webtemplatefilters, webtemplatepats),
399 webtemplatefilters, webtemplatepats),
398 ]
400 ]
399
401
400 def _preparepats():
402 def _preparepats():
401 for c in checks:
403 for c in checks:
402 failandwarn = c[-1]
404 failandwarn = c[-1]
403 for pats in failandwarn:
405 for pats in failandwarn:
404 for i, pseq in enumerate(pats):
406 for i, pseq in enumerate(pats):
405 # fix-up regexes for multi-line searches
407 # fix-up regexes for multi-line searches
406 p = pseq[0]
408 p = pseq[0]
407 # \s doesn't match \n
409 # \s doesn't match \n
408 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
410 p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p)
409 # [^...] doesn't match newline
411 # [^...] doesn't match newline
410 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
412 p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p)
411
413
412 pats[i] = (re.compile(p, re.MULTILINE),) + pseq[1:]
414 pats[i] = (re.compile(p, re.MULTILINE),) + pseq[1:]
413 filters = c[3]
415 filters = c[3]
414 for i, flt in enumerate(filters):
416 for i, flt in enumerate(filters):
415 filters[i] = re.compile(flt[0]), flt[1]
417 filters[i] = re.compile(flt[0]), flt[1]
416 _preparepats()
418 _preparepats()
417
419
418 class norepeatlogger(object):
420 class norepeatlogger(object):
419 def __init__(self):
421 def __init__(self):
420 self._lastseen = None
422 self._lastseen = None
421
423
422 def log(self, fname, lineno, line, msg, blame):
424 def log(self, fname, lineno, line, msg, blame):
423 """print error related a to given line of a given file.
425 """print error related a to given line of a given file.
424
426
425 The faulty line will also be printed but only once in the case
427 The faulty line will also be printed but only once in the case
426 of multiple errors.
428 of multiple errors.
427
429
428 :fname: filename
430 :fname: filename
429 :lineno: line number
431 :lineno: line number
430 :line: actual content of the line
432 :line: actual content of the line
431 :msg: error message
433 :msg: error message
432 """
434 """
433 msgid = fname, lineno, line
435 msgid = fname, lineno, line
434 if msgid != self._lastseen:
436 if msgid != self._lastseen:
435 if blame:
437 if blame:
436 print "%s:%d (%s):" % (fname, lineno, blame)
438 print "%s:%d (%s):" % (fname, lineno, blame)
437 else:
439 else:
438 print "%s:%d:" % (fname, lineno)
440 print "%s:%d:" % (fname, lineno)
439 print " > %s" % line
441 print " > %s" % line
440 self._lastseen = msgid
442 self._lastseen = msgid
441 print " " + msg
443 print " " + msg
442
444
443 _defaultlogger = norepeatlogger()
445 _defaultlogger = norepeatlogger()
444
446
445 def getblame(f):
447 def getblame(f):
446 lines = []
448 lines = []
447 for l in os.popen('hg annotate -un %s' % f):
449 for l in os.popen('hg annotate -un %s' % f):
448 start, line = l.split(':', 1)
450 start, line = l.split(':', 1)
449 user, rev = start.split()
451 user, rev = start.split()
450 lines.append((line[1:-1], user, rev))
452 lines.append((line[1:-1], user, rev))
451 return lines
453 return lines
452
454
453 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
455 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
454 blame=False, debug=False, lineno=True):
456 blame=False, debug=False, lineno=True):
455 """checks style and portability of a given file
457 """checks style and portability of a given file
456
458
457 :f: filepath
459 :f: filepath
458 :logfunc: function used to report error
460 :logfunc: function used to report error
459 logfunc(filename, linenumber, linecontent, errormessage)
461 logfunc(filename, linenumber, linecontent, errormessage)
460 :maxerr: number of error to display before aborting.
462 :maxerr: number of error to display before aborting.
461 Set to false (default) to report all errors
463 Set to false (default) to report all errors
462
464
463 return True if no error is found, False otherwise.
465 return True if no error is found, False otherwise.
464 """
466 """
465 blamecache = None
467 blamecache = None
466 result = True
468 result = True
467
469
468 try:
470 try:
469 fp = open(f)
471 fp = open(f)
470 except IOError as e:
472 except IOError as e:
471 print "Skipping %s, %s" % (f, str(e).split(':', 1)[0])
473 print "Skipping %s, %s" % (f, str(e).split(':', 1)[0])
472 return result
474 return result
473 pre = post = fp.read()
475 pre = post = fp.read()
474 fp.close()
476 fp.close()
475
477
476 for name, match, magic, filters, pats in checks:
478 for name, match, magic, filters, pats in checks:
477 if debug:
479 if debug:
478 print name, f
480 print name, f
479 fc = 0
481 fc = 0
480 if not (re.match(match, f) or (magic and re.search(magic, f))):
482 if not (re.match(match, f) or (magic and re.search(magic, f))):
481 if debug:
483 if debug:
482 print "Skipping %s for %s it doesn't match %s" % (
484 print "Skipping %s for %s it doesn't match %s" % (
483 name, match, f)
485 name, match, f)
484 continue
486 continue
485 if "no-" "check-code" in pre:
487 if "no-" "check-code" in pre:
486 # If you're looking at this line, it's because a file has:
488 # If you're looking at this line, it's because a file has:
487 # no- check- code
489 # no- check- code
488 # but the reason to output skipping is to make life for
490 # but the reason to output skipping is to make life for
489 # tests easier. So, instead of writing it with a normal
491 # tests easier. So, instead of writing it with a normal
490 # spelling, we write it with the expected spelling from
492 # spelling, we write it with the expected spelling from
491 # tests/test-check-code.t
493 # tests/test-check-code.t
492 print "Skipping %s it has no-che?k-code (glob)" % f
494 print "Skipping %s it has no-che?k-code (glob)" % f
493 return "Skip" # skip checking this file
495 return "Skip" # skip checking this file
494 for p, r in filters:
496 for p, r in filters:
495 post = re.sub(p, r, post)
497 post = re.sub(p, r, post)
496 nerrs = len(pats[0]) # nerr elements are errors
498 nerrs = len(pats[0]) # nerr elements are errors
497 if warnings:
499 if warnings:
498 pats = pats[0] + pats[1]
500 pats = pats[0] + pats[1]
499 else:
501 else:
500 pats = pats[0]
502 pats = pats[0]
501 # print post # uncomment to show filtered version
503 # print post # uncomment to show filtered version
502
504
503 if debug:
505 if debug:
504 print "Checking %s for %s" % (name, f)
506 print "Checking %s for %s" % (name, f)
505
507
506 prelines = None
508 prelines = None
507 errors = []
509 errors = []
508 for i, pat in enumerate(pats):
510 for i, pat in enumerate(pats):
509 if len(pat) == 3:
511 if len(pat) == 3:
510 p, msg, ignore = pat
512 p, msg, ignore = pat
511 else:
513 else:
512 p, msg = pat
514 p, msg = pat
513 ignore = None
515 ignore = None
514 if i >= nerrs:
516 if i >= nerrs:
515 msg = "warning: " + msg
517 msg = "warning: " + msg
516
518
517 pos = 0
519 pos = 0
518 n = 0
520 n = 0
519 for m in p.finditer(post):
521 for m in p.finditer(post):
520 if prelines is None:
522 if prelines is None:
521 prelines = pre.splitlines()
523 prelines = pre.splitlines()
522 postlines = post.splitlines(True)
524 postlines = post.splitlines(True)
523
525
524 start = m.start()
526 start = m.start()
525 while n < len(postlines):
527 while n < len(postlines):
526 step = len(postlines[n])
528 step = len(postlines[n])
527 if pos + step > start:
529 if pos + step > start:
528 break
530 break
529 pos += step
531 pos += step
530 n += 1
532 n += 1
531 l = prelines[n]
533 l = prelines[n]
532
534
533 if ignore and re.search(ignore, l, re.MULTILINE):
535 if ignore and re.search(ignore, l, re.MULTILINE):
534 if debug:
536 if debug:
535 print "Skipping %s for %s:%s (ignore pattern)" % (
537 print "Skipping %s for %s:%s (ignore pattern)" % (
536 name, f, n)
538 name, f, n)
537 continue
539 continue
538 bd = ""
540 bd = ""
539 if blame:
541 if blame:
540 bd = 'working directory'
542 bd = 'working directory'
541 if not blamecache:
543 if not blamecache:
542 blamecache = getblame(f)
544 blamecache = getblame(f)
543 if n < len(blamecache):
545 if n < len(blamecache):
544 bl, bu, br = blamecache[n]
546 bl, bu, br = blamecache[n]
545 if bl == l:
547 if bl == l:
546 bd = '%s@%s' % (bu, br)
548 bd = '%s@%s' % (bu, br)
547
549
548 errors.append((f, lineno and n + 1, l, msg, bd))
550 errors.append((f, lineno and n + 1, l, msg, bd))
549 result = False
551 result = False
550
552
551 errors.sort()
553 errors.sort()
552 for e in errors:
554 for e in errors:
553 logfunc(*e)
555 logfunc(*e)
554 fc += 1
556 fc += 1
555 if maxerr and fc >= maxerr:
557 if maxerr and fc >= maxerr:
556 print " (too many errors, giving up)"
558 print " (too many errors, giving up)"
557 break
559 break
558
560
559 return result
561 return result
560
562
561 if __name__ == "__main__":
563 if __name__ == "__main__":
562 parser = optparse.OptionParser("%prog [options] [files]")
564 parser = optparse.OptionParser("%prog [options] [files]")
563 parser.add_option("-w", "--warnings", action="store_true",
565 parser.add_option("-w", "--warnings", action="store_true",
564 help="include warning-level checks")
566 help="include warning-level checks")
565 parser.add_option("-p", "--per-file", type="int",
567 parser.add_option("-p", "--per-file", type="int",
566 help="max warnings per file")
568 help="max warnings per file")
567 parser.add_option("-b", "--blame", action="store_true",
569 parser.add_option("-b", "--blame", action="store_true",
568 help="use annotate to generate blame info")
570 help="use annotate to generate blame info")
569 parser.add_option("", "--debug", action="store_true",
571 parser.add_option("", "--debug", action="store_true",
570 help="show debug information")
572 help="show debug information")
571 parser.add_option("", "--nolineno", action="store_false",
573 parser.add_option("", "--nolineno", action="store_false",
572 dest='lineno', help="don't show line numbers")
574 dest='lineno', help="don't show line numbers")
573
575
574 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
576 parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
575 lineno=True)
577 lineno=True)
576 (options, args) = parser.parse_args()
578 (options, args) = parser.parse_args()
577
579
578 if len(args) == 0:
580 if len(args) == 0:
579 check = glob.glob("*")
581 check = glob.glob("*")
580 else:
582 else:
581 check = args
583 check = args
582
584
583 ret = 0
585 ret = 0
584 for f in check:
586 for f in check:
585 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
587 if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
586 blame=options.blame, debug=options.debug,
588 blame=options.blame, debug=options.debug,
587 lineno=options.lineno):
589 lineno=options.lineno):
588 ret = 1
590 ret = 1
589 sys.exit(ret)
591 sys.exit(ret)
@@ -1,248 +1,248 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add -n
4 $ hg add -n
5 adding a
5 adding a
6 $ hg st
6 $ hg st
7 ? a
7 ? a
8 $ hg add
8 $ hg add
9 adding a
9 adding a
10 $ hg st
10 $ hg st
11 A a
11 A a
12 $ hg forget a
12 $ hg forget a
13 $ hg add
13 $ hg add
14 adding a
14 adding a
15 $ hg st
15 $ hg st
16 A a
16 A a
17
17
18 $ echo b > b
18 $ echo b > b
19 $ hg add -n b
19 $ hg add -n b
20 $ hg st
20 $ hg st
21 A a
21 A a
22 ? b
22 ? b
23 $ hg add b
23 $ hg add b
24 $ hg st
24 $ hg st
25 A a
25 A a
26 A b
26 A b
27
27
28 should fail
28 should fail
29
29
30 $ hg add b
30 $ hg add b
31 b already tracked!
31 b already tracked!
32 $ hg st
32 $ hg st
33 A a
33 A a
34 A b
34 A b
35
35
36 #if no-windows
36 #if no-windows
37 $ echo foo > con.xml
37 $ echo foo > con.xml
38 $ hg --config ui.portablefilenames=jump add con.xml
38 $ hg --config ui.portablefilenames=jump add con.xml
39 abort: ui.portablefilenames value is invalid ('jump')
39 abort: ui.portablefilenames value is invalid ('jump')
40 [255]
40 [255]
41 $ hg --config ui.portablefilenames=abort add con.xml
41 $ hg --config ui.portablefilenames=abort add con.xml
42 abort: filename contains 'con', which is reserved on Windows: 'con.xml'
42 abort: filename contains 'con', which is reserved on Windows: 'con.xml'
43 [255]
43 [255]
44 $ hg st
44 $ hg st
45 A a
45 A a
46 A b
46 A b
47 ? con.xml
47 ? con.xml
48 $ hg add con.xml
48 $ hg add con.xml
49 warning: filename contains 'con', which is reserved on Windows: 'con.xml'
49 warning: filename contains 'con', which is reserved on Windows: 'con.xml'
50 $ hg st
50 $ hg st
51 A a
51 A a
52 A b
52 A b
53 A con.xml
53 A con.xml
54 $ hg forget con.xml
54 $ hg forget con.xml
55 $ rm con.xml
55 $ rm con.xml
56 #endif
56 #endif
57
57
58 #if eol-in-paths
58 #if eol-in-paths
59 $ echo bla > 'hello:world'
59 $ echo bla > 'hello:world'
60 $ hg --config ui.portablefilenames=abort add
60 $ hg --config ui.portablefilenames=abort add
61 adding hello:world
61 adding hello:world
62 abort: filename contains ':', which is reserved on Windows: 'hello:world'
62 abort: filename contains ':', which is reserved on Windows: 'hello:world'
63 [255]
63 [255]
64 $ hg st
64 $ hg st
65 A a
65 A a
66 A b
66 A b
67 ? hello:world
67 ? hello:world
68 $ hg --config ui.portablefilenames=ignore add
68 $ hg --config ui.portablefilenames=ignore add
69 adding hello:world
69 adding hello:world
70 $ hg st
70 $ hg st
71 A a
71 A a
72 A b
72 A b
73 A hello:world
73 A hello:world
74 #endif
74 #endif
75
75
76 $ hg ci -m 0 --traceback
76 $ hg ci -m 0 --traceback
77
77
78 $ hg log -r "heads(. or wdir() & file('**'))"
78 $ hg log -r "heads(. or wdir() & file('**'))"
79 changeset: 0:* (glob)
79 changeset: 0:* (glob)
80 tag: tip
80 tag: tip
81 user: test
81 user: test
82 date: Thu Jan 01 00:00:00 1970 +0000
82 date: Thu Jan 01 00:00:00 1970 +0000
83 summary: 0
83 summary: 0
84
84
85 should fail
85 should fail
86
86
87 $ hg add a
87 $ hg add a
88 a already tracked!
88 a already tracked!
89
89
90 $ echo aa > a
90 $ echo aa > a
91 $ hg ci -m 1
91 $ hg ci -m 1
92 $ hg up 0
92 $ hg up 0
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 $ echo aaa > a
94 $ echo aaa > a
95 $ hg ci -m 2
95 $ hg ci -m 2
96 created new head
96 created new head
97
97
98 $ hg merge
98 $ hg merge
99 merging a
99 merging a
100 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
100 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
101 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
101 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
102 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
102 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
103 [1]
103 [1]
104 $ hg st
104 $ hg st
105 M a
105 M a
106 ? a.orig
106 ? a.orig
107
107
108 wdir doesn't cause a crash, and can be dynamically selected if dirty
108 wdir doesn't cause a crash, and can be dynamically selected if dirty
109
109
110 $ hg log -r "heads(. or wdir() & file('**'))"
110 $ hg log -r "heads(. or wdir() & file('**'))"
111 changeset: 2147483647:ffffffffffff
111 changeset: 2147483647:ffffffffffff
112 parent: 2:* (glob)
112 parent: 2:* (glob)
113 parent: 1:* (glob)
113 parent: 1:* (glob)
114 user: test
114 user: test
115 date: * (glob)
115 date: * (glob)
116
116
117 should fail
117 should fail
118
118
119 $ hg add a
119 $ hg add a
120 a already tracked!
120 a already tracked!
121 $ hg st
121 $ hg st
122 M a
122 M a
123 ? a.orig
123 ? a.orig
124 $ hg resolve -m a
124 $ hg resolve -m a
125 (no more unresolved files)
125 (no more unresolved files)
126 $ hg ci -m merge
126 $ hg ci -m merge
127
127
128 Issue683: peculiarity with hg revert of an removed then added file
128 Issue683: peculiarity with hg revert of an removed then added file
129
129
130 $ hg forget a
130 $ hg forget a
131 $ hg add a
131 $ hg add a
132 $ hg st
132 $ hg st
133 ? a.orig
133 ? a.orig
134 $ hg rm a
134 $ hg rm a
135 $ hg st
135 $ hg st
136 R a
136 R a
137 ? a.orig
137 ? a.orig
138 $ echo a > a
138 $ echo a > a
139 $ hg add a
139 $ hg add a
140 $ hg st
140 $ hg st
141 M a
141 M a
142 ? a.orig
142 ? a.orig
143
143
144 Forgotten file can be added back (as either clean or modified)
144 Forgotten file can be added back (as either clean or modified)
145
145
146 $ hg forget b
146 $ hg forget b
147 $ hg add b
147 $ hg add b
148 $ hg st -A b
148 $ hg st -A b
149 C b
149 C b
150 $ hg forget b
150 $ hg forget b
151 $ echo modified > b
151 $ echo modified > b
152 $ hg add b
152 $ hg add b
153 $ hg st -A b
153 $ hg st -A b
154 M b
154 M b
155 $ hg revert -qC b
155 $ hg revert -qC b
156
156
157 $ hg add c && echo "unexpected addition of missing file"
157 $ hg add c && echo "unexpected addition of missing file"
158 c: * (glob)
158 c: * (glob)
159 [1]
159 [1]
160 $ echo c > c
160 $ echo c > c
161 $ hg add d c && echo "unexpected addition of missing file"
161 $ hg add d c && echo "unexpected addition of missing file"
162 d: * (glob)
162 d: * (glob)
163 [1]
163 [1]
164 $ hg st
164 $ hg st
165 M a
165 M a
166 A c
166 A c
167 ? a.orig
167 ? a.orig
168 $ hg up -C
168 $ hg up -C
169 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
170
170
171 forget and get should have the right order: added but missing dir should be
171 forget and get should have the right order: added but missing dir should be
172 forgotten before file with same name is added
172 forgotten before file with same name is added
173
173
174 $ echo file d > d
174 $ echo file d > d
175 $ hg add d
175 $ hg add d
176 $ hg ci -md
176 $ hg ci -md
177 $ hg rm d
177 $ hg rm d
178 $ mkdir d
178 $ mkdir d
179 $ echo a > d/a
179 $ echo a > d/a
180 $ hg add d/a
180 $ hg add d/a
181 $ rm -r d
181 $ rm -r d
182 $ hg up -C
182 $ hg up -C
183 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
184 $ cat d
184 $ cat d
185 file d
185 file d
186
186
187 Test that adding a directory doesn't require case matching (issue4578)
187 Test that adding a directory doesn't require case matching (issue4578)
188 #if icasefs
188 #if icasefs
189 $ mkdir -p CapsDir1/CapsDir
189 $ mkdir -p CapsDir1/CapsDir
190 $ echo abc > CapsDir1/CapsDir/AbC.txt
190 $ echo abc > CapsDir1/CapsDir/AbC.txt
191 $ mkdir CapsDir1/CapsDir/SubDir
191 $ mkdir CapsDir1/CapsDir/SubDir
192 $ echo def > CapsDir1/CapsDir/SubDir/Def.txt
192 $ echo def > CapsDir1/CapsDir/SubDir/Def.txt
193
193
194 $ hg add capsdir1/capsdir
194 $ hg add capsdir1/capsdir
195 adding CapsDir1/CapsDir/AbC.txt (glob)
195 adding CapsDir1/CapsDir/AbC.txt (glob)
196 adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
196 adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
197
197
198 $ hg forget capsdir1/capsdir/abc.txt
198 $ hg forget capsdir1/capsdir/abc.txt
199 removing CapsDir1/CapsDir/AbC.txt (glob)
199 removing CapsDir1/CapsDir/AbC.txt (glob)
200
200
201 $ hg forget capsdir1/capsdir
201 $ hg forget capsdir1/capsdir
202 removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
202 removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
203
203
204 $ hg add capsdir1
204 $ hg add capsdir1
205 adding CapsDir1/CapsDir/AbC.txt (glob)
205 adding CapsDir1/CapsDir/AbC.txt (glob)
206 adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
206 adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
207
207
208 $ hg ci -m "AbCDef" capsdir1/capsdir
208 $ hg ci -m "AbCDef" capsdir1/capsdir
209
209
210 $ hg status -A capsdir1/capsdir
210 $ hg status -A capsdir1/capsdir
211 C CapsDir1/CapsDir/AbC.txt
211 C CapsDir1/CapsDir/AbC.txt
212 C CapsDir1/CapsDir/SubDir/Def.txt
212 C CapsDir1/CapsDir/SubDir/Def.txt
213
213
214 $ hg files capsdir1/capsdir
214 $ hg files capsdir1/capsdir
215 CapsDir1/CapsDir/AbC.txt (glob)
215 CapsDir1/CapsDir/AbC.txt (glob)
216 CapsDir1/CapsDir/SubDir/Def.txt (glob)
216 CapsDir1/CapsDir/SubDir/Def.txt (glob)
217
217
218 $ echo xyz > CapsDir1/CapsDir/SubDir/Def.txt
218 $ echo xyz > CapsDir1/CapsDir/SubDir/Def.txt
219 $ hg ci -m xyz capsdir1/capsdir/subdir/def.txt
219 $ hg ci -m xyz capsdir1/capsdir/subdir/def.txt
220
220
221 $ hg revert -r '.^' capsdir1/capsdir
221 $ hg revert -r '.^' capsdir1/capsdir
222 reverting CapsDir1/CapsDir/SubDir/Def.txt (glob)
222 reverting CapsDir1/CapsDir/SubDir/Def.txt (glob)
223
223
224 The conditional tests above mean the hash on the diff line differs on Windows
224 The conditional tests above mean the hash on the diff line differs on Windows
225 and OS X
225 and OS X
226 $ hg diff capsdir1/capsdir
226 $ hg diff capsdir1/capsdir
227 diff -r * CapsDir1/CapsDir/SubDir/Def.txt (glob)
227 diff -r * CapsDir1/CapsDir/SubDir/Def.txt (glob)
228 --- a/CapsDir1/CapsDir/SubDir/Def.txt Thu Jan 01 00:00:00 1970 +0000
228 --- a/CapsDir1/CapsDir/SubDir/Def.txt Thu Jan 01 00:00:00 1970 +0000
229 +++ b/CapsDir1/CapsDir/SubDir/Def.txt * +0000 (glob)
229 +++ b/CapsDir1/CapsDir/SubDir/Def.txt * (glob)
230 @@ -1,1 +1,1 @@
230 @@ -1,1 +1,1 @@
231 -xyz
231 -xyz
232 +def
232 +def
233
233
234 $ hg mv CapsDir1/CapsDir/abc.txt CapsDir1/CapsDir/ABC.txt
234 $ hg mv CapsDir1/CapsDir/abc.txt CapsDir1/CapsDir/ABC.txt
235 moving CapsDir1/CapsDir/AbC.txt to CapsDir1/CapsDir/ABC.txt (glob)
235 moving CapsDir1/CapsDir/AbC.txt to CapsDir1/CapsDir/ABC.txt (glob)
236 $ hg ci -m "case changing rename" CapsDir1/CapsDir/AbC.txt CapsDir1/CapsDir/ABC.txt
236 $ hg ci -m "case changing rename" CapsDir1/CapsDir/AbC.txt CapsDir1/CapsDir/ABC.txt
237
237
238 $ hg status -A capsdir1/capsdir
238 $ hg status -A capsdir1/capsdir
239 M CapsDir1/CapsDir/SubDir/Def.txt
239 M CapsDir1/CapsDir/SubDir/Def.txt
240 C CapsDir1/CapsDir/ABC.txt
240 C CapsDir1/CapsDir/ABC.txt
241
241
242 $ hg remove -f 'glob:**.txt' -X capsdir1/capsdir
242 $ hg remove -f 'glob:**.txt' -X capsdir1/capsdir
243 $ hg remove -f 'glob:**.txt' -I capsdir1/capsdir
243 $ hg remove -f 'glob:**.txt' -I capsdir1/capsdir
244 removing CapsDir1/CapsDir/ABC.txt (glob)
244 removing CapsDir1/CapsDir/ABC.txt (glob)
245 removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
245 removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
246 #endif
246 #endif
247
247
248 $ cd ..
248 $ cd ..
@@ -1,836 +1,836 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [defaults]
2 > [defaults]
3 > # for portability
3 > # for portability
4 > extdiff = --option -Nru
4 > extdiff = --option -Nru
5 > EOF
5 > EOF
6
6
7 Create a repo with some stuff in it:
7 Create a repo with some stuff in it:
8
8
9 $ hg init a
9 $ hg init a
10 $ cd a
10 $ cd a
11 $ echo a > a
11 $ echo a > a
12 $ echo a > d
12 $ echo a > d
13 $ echo a > e
13 $ echo a > e
14 $ hg ci -qAm0
14 $ hg ci -qAm0
15 $ echo b > a
15 $ echo b > a
16 $ hg ci -m1 -u bar
16 $ hg ci -m1 -u bar
17 $ hg mv a b
17 $ hg mv a b
18 $ hg ci -m2
18 $ hg ci -m2
19 $ hg cp b c
19 $ hg cp b c
20 $ hg ci -m3 -u baz
20 $ hg ci -m3 -u baz
21 $ echo b > d
21 $ echo b > d
22 $ echo f > e
22 $ echo f > e
23 $ hg ci -m4
23 $ hg ci -m4
24 $ hg up -q 3
24 $ hg up -q 3
25 $ echo b > e
25 $ echo b > e
26 $ hg branch -q stable
26 $ hg branch -q stable
27 $ hg ci -m5
27 $ hg ci -m5
28 $ hg merge -q default --tool internal:local
28 $ hg merge -q default --tool internal:local
29 $ hg branch -q default
29 $ hg branch -q default
30 $ hg ci -m6
30 $ hg ci -m6
31 $ hg phase --public 3
31 $ hg phase --public 3
32 $ hg phase --force --secret 6
32 $ hg phase --force --secret 6
33
33
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
35 @ test@6.secret: 6
35 @ test@6.secret: 6
36 |\
36 |\
37 | o test@5.draft: 5
37 | o test@5.draft: 5
38 | |
38 | |
39 o | test@4.draft: 4
39 o | test@4.draft: 4
40 |/
40 |/
41 o baz@3.public: 3
41 o baz@3.public: 3
42 |
42 |
43 o test@2.public: 2
43 o test@2.public: 2
44 |
44 |
45 o bar@1.public: 1
45 o bar@1.public: 1
46 |
46 |
47 o test@0.public: 0
47 o test@0.public: 0
48
48
49
49
50 Need to specify a rev:
50 Need to specify a rev:
51
51
52 $ hg graft
52 $ hg graft
53 abort: no revisions specified
53 abort: no revisions specified
54 [255]
54 [255]
55
55
56 Can't graft ancestor:
56 Can't graft ancestor:
57
57
58 $ hg graft 1 2
58 $ hg graft 1 2
59 skipping ancestor revision 1:5d205f8b35b6
59 skipping ancestor revision 1:5d205f8b35b6
60 skipping ancestor revision 2:5c095ad7e90f
60 skipping ancestor revision 2:5c095ad7e90f
61 [255]
61 [255]
62
62
63 Specify revisions with -r:
63 Specify revisions with -r:
64
64
65 $ hg graft -r 1 -r 2
65 $ hg graft -r 1 -r 2
66 skipping ancestor revision 1:5d205f8b35b6
66 skipping ancestor revision 1:5d205f8b35b6
67 skipping ancestor revision 2:5c095ad7e90f
67 skipping ancestor revision 2:5c095ad7e90f
68 [255]
68 [255]
69
69
70 $ hg graft -r 1 2
70 $ hg graft -r 1 2
71 warning: inconsistent use of --rev might give unexpected revision ordering!
71 warning: inconsistent use of --rev might give unexpected revision ordering!
72 skipping ancestor revision 2:5c095ad7e90f
72 skipping ancestor revision 2:5c095ad7e90f
73 skipping ancestor revision 1:5d205f8b35b6
73 skipping ancestor revision 1:5d205f8b35b6
74 [255]
74 [255]
75
75
76 Can't graft with dirty wd:
76 Can't graft with dirty wd:
77
77
78 $ hg up -q 0
78 $ hg up -q 0
79 $ echo foo > a
79 $ echo foo > a
80 $ hg graft 1
80 $ hg graft 1
81 abort: uncommitted changes
81 abort: uncommitted changes
82 [255]
82 [255]
83 $ hg revert a
83 $ hg revert a
84
84
85 Graft a rename:
85 Graft a rename:
86 (this also tests that editor is invoked if '--edit' is specified)
86 (this also tests that editor is invoked if '--edit' is specified)
87
87
88 $ hg status --rev "2^1" --rev 2
88 $ hg status --rev "2^1" --rev 2
89 A b
89 A b
90 R a
90 R a
91 $ HGEDITOR=cat hg graft 2 -u foo --edit
91 $ HGEDITOR=cat hg graft 2 -u foo --edit
92 grafting 2:5c095ad7e90f "2"
92 grafting 2:5c095ad7e90f "2"
93 merging a and b to b
93 merging a and b to b
94 2
94 2
95
95
96
96
97 HG: Enter commit message. Lines beginning with 'HG:' are removed.
97 HG: Enter commit message. Lines beginning with 'HG:' are removed.
98 HG: Leave message empty to abort commit.
98 HG: Leave message empty to abort commit.
99 HG: --
99 HG: --
100 HG: user: foo
100 HG: user: foo
101 HG: branch 'default'
101 HG: branch 'default'
102 HG: added b
102 HG: added b
103 HG: removed a
103 HG: removed a
104 $ hg export tip --git
104 $ hg export tip --git
105 # HG changeset patch
105 # HG changeset patch
106 # User foo
106 # User foo
107 # Date 0 0
107 # Date 0 0
108 # Thu Jan 01 00:00:00 1970 +0000
108 # Thu Jan 01 00:00:00 1970 +0000
109 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
109 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
110 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
110 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
111 2
111 2
112
112
113 diff --git a/a b/b
113 diff --git a/a b/b
114 rename from a
114 rename from a
115 rename to b
115 rename to b
116
116
117 Look for extra:source
117 Look for extra:source
118
118
119 $ hg log --debug -r tip
119 $ hg log --debug -r tip
120 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
120 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
121 tag: tip
121 tag: tip
122 phase: draft
122 phase: draft
123 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
123 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
124 parent: -1:0000000000000000000000000000000000000000
124 parent: -1:0000000000000000000000000000000000000000
125 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
125 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
126 user: foo
126 user: foo
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 files+: b
128 files+: b
129 files-: a
129 files-: a
130 extra: branch=default
130 extra: branch=default
131 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
131 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
132 description:
132 description:
133 2
133 2
134
134
135
135
136
136
137 Graft out of order, skipping a merge and a duplicate
137 Graft out of order, skipping a merge and a duplicate
138 (this also tests that editor is not invoked if '--edit' is not specified)
138 (this also tests that editor is not invoked if '--edit' is not specified)
139
139
140 $ hg graft 1 5 4 3 'merge()' 2 -n
140 $ hg graft 1 5 4 3 'merge()' 2 -n
141 skipping ungraftable merge revision 6
141 skipping ungraftable merge revision 6
142 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
142 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
143 grafting 1:5d205f8b35b6 "1"
143 grafting 1:5d205f8b35b6 "1"
144 grafting 5:97f8bfe72746 "5"
144 grafting 5:97f8bfe72746 "5"
145 grafting 4:9c233e8e184d "4"
145 grafting 4:9c233e8e184d "4"
146 grafting 3:4c60f11aa304 "3"
146 grafting 3:4c60f11aa304 "3"
147
147
148 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
148 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
149 skipping ungraftable merge revision 6
149 skipping ungraftable merge revision 6
150 scanning for duplicate grafts
150 scanning for duplicate grafts
151 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
151 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
152 grafting 1:5d205f8b35b6 "1"
152 grafting 1:5d205f8b35b6 "1"
153 searching for copies back to rev 1
153 searching for copies back to rev 1
154 unmatched files in local:
154 unmatched files in local:
155 b
155 b
156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
157 src: 'a' -> dst: 'b' *
157 src: 'a' -> dst: 'b' *
158 checking for directory renames
158 checking for directory renames
159 resolving manifests
159 resolving manifests
160 branchmerge: True, force: True, partial: False
160 branchmerge: True, force: True, partial: False
161 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
161 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
162 preserving b for resolve of b
162 preserving b for resolve of b
163 b: local copied/moved from a -> m (premerge)
163 b: local copied/moved from a -> m (premerge)
164 picked tool ':merge' for b (binary False symlink False changedelete False)
164 picked tool ':merge' for b (binary False symlink False changedelete False)
165 merging b and a to b
165 merging b and a to b
166 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
166 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
167 premerge successful
167 premerge successful
168 committing files:
168 committing files:
169 b
169 b
170 committing manifest
170 committing manifest
171 committing changelog
171 committing changelog
172 grafting 5:97f8bfe72746 "5"
172 grafting 5:97f8bfe72746 "5"
173 searching for copies back to rev 1
173 searching for copies back to rev 1
174 resolving manifests
174 resolving manifests
175 branchmerge: True, force: True, partial: False
175 branchmerge: True, force: True, partial: False
176 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
176 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
177 e: remote is newer -> g
177 e: remote is newer -> g
178 getting e
178 getting e
179 b: remote unchanged -> k
179 b: remote unchanged -> k
180 committing files:
180 committing files:
181 e
181 e
182 committing manifest
182 committing manifest
183 committing changelog
183 committing changelog
184 $ HGEDITOR=cat hg graft 4 3 --log --debug
184 $ HGEDITOR=cat hg graft 4 3 --log --debug
185 scanning for duplicate grafts
185 scanning for duplicate grafts
186 grafting 4:9c233e8e184d "4"
186 grafting 4:9c233e8e184d "4"
187 searching for copies back to rev 1
187 searching for copies back to rev 1
188 resolving manifests
188 resolving manifests
189 branchmerge: True, force: True, partial: False
189 branchmerge: True, force: True, partial: False
190 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
190 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
191 preserving e for resolve of e
191 preserving e for resolve of e
192 d: remote is newer -> g
192 d: remote is newer -> g
193 getting d
193 getting d
194 b: remote unchanged -> k
194 b: remote unchanged -> k
195 e: versions differ -> m (premerge)
195 e: versions differ -> m (premerge)
196 picked tool ':merge' for e (binary False symlink False changedelete False)
196 picked tool ':merge' for e (binary False symlink False changedelete False)
197 merging e
197 merging e
198 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
198 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
199 e: versions differ -> m (merge)
199 e: versions differ -> m (merge)
200 picked tool ':merge' for e (binary False symlink False changedelete False)
200 picked tool ':merge' for e (binary False symlink False changedelete False)
201 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
201 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
202 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
202 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
203 abort: unresolved conflicts, can't continue
203 abort: unresolved conflicts, can't continue
204 (use hg resolve and hg graft --continue --log)
204 (use hg resolve and hg graft --continue --log)
205 [255]
205 [255]
206
206
207 Summary should mention graft:
207 Summary should mention graft:
208
208
209 $ hg summary |grep graft
209 $ hg summary |grep graft
210 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
210 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
211
211
212 Commit while interrupted should fail:
212 Commit while interrupted should fail:
213
213
214 $ hg ci -m 'commit interrupted graft'
214 $ hg ci -m 'commit interrupted graft'
215 abort: graft in progress
215 abort: graft in progress
216 (use 'hg graft --continue' or 'hg update' to abort)
216 (use 'hg graft --continue' or 'hg update' to abort)
217 [255]
217 [255]
218
218
219 Abort the graft and try committing:
219 Abort the graft and try committing:
220
220
221 $ hg up -C .
221 $ hg up -C .
222 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 $ echo c >> e
223 $ echo c >> e
224 $ hg ci -mtest
224 $ hg ci -mtest
225
225
226 $ hg strip . --config extensions.strip=
226 $ hg strip . --config extensions.strip=
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
228 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
229
229
230 Graft again:
230 Graft again:
231
231
232 $ hg graft 1 5 4 3 'merge()' 2
232 $ hg graft 1 5 4 3 'merge()' 2
233 skipping ungraftable merge revision 6
233 skipping ungraftable merge revision 6
234 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
234 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
235 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
235 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
236 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
236 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
237 grafting 4:9c233e8e184d "4"
237 grafting 4:9c233e8e184d "4"
238 merging e
238 merging e
239 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
239 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
240 abort: unresolved conflicts, can't continue
240 abort: unresolved conflicts, can't continue
241 (use hg resolve and hg graft --continue)
241 (use hg resolve and hg graft --continue)
242 [255]
242 [255]
243
243
244 Continue without resolve should fail:
244 Continue without resolve should fail:
245
245
246 $ hg graft -c
246 $ hg graft -c
247 grafting 4:9c233e8e184d "4"
247 grafting 4:9c233e8e184d "4"
248 abort: unresolved merge conflicts (see "hg help resolve")
248 abort: unresolved merge conflicts (see "hg help resolve")
249 [255]
249 [255]
250
250
251 Fix up:
251 Fix up:
252
252
253 $ echo b > e
253 $ echo b > e
254 $ hg resolve -m e
254 $ hg resolve -m e
255 (no more unresolved files)
255 (no more unresolved files)
256 continue: hg graft --continue
256 continue: hg graft --continue
257
257
258 Continue with a revision should fail:
258 Continue with a revision should fail:
259
259
260 $ hg graft -c 6
260 $ hg graft -c 6
261 abort: can't specify --continue and revisions
261 abort: can't specify --continue and revisions
262 [255]
262 [255]
263
263
264 $ hg graft -c -r 6
264 $ hg graft -c -r 6
265 abort: can't specify --continue and revisions
265 abort: can't specify --continue and revisions
266 [255]
266 [255]
267
267
268 Continue for real, clobber usernames
268 Continue for real, clobber usernames
269
269
270 $ hg graft -c -U
270 $ hg graft -c -U
271 grafting 4:9c233e8e184d "4"
271 grafting 4:9c233e8e184d "4"
272 grafting 3:4c60f11aa304 "3"
272 grafting 3:4c60f11aa304 "3"
273
273
274 Compare with original:
274 Compare with original:
275
275
276 $ hg diff -r 6
276 $ hg diff -r 6
277 $ hg status --rev 0:. -C
277 $ hg status --rev 0:. -C
278 M d
278 M d
279 M e
279 M e
280 A b
280 A b
281 a
281 a
282 A c
282 A c
283 a
283 a
284 R a
284 R a
285
285
286 View graph:
286 View graph:
287
287
288 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
288 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
289 @ test@11.draft: 3
289 @ test@11.draft: 3
290 |
290 |
291 o test@10.draft: 4
291 o test@10.draft: 4
292 |
292 |
293 o test@9.draft: 5
293 o test@9.draft: 5
294 |
294 |
295 o bar@8.draft: 1
295 o bar@8.draft: 1
296 |
296 |
297 o foo@7.draft: 2
297 o foo@7.draft: 2
298 |
298 |
299 | o test@6.secret: 6
299 | o test@6.secret: 6
300 | |\
300 | |\
301 | | o test@5.draft: 5
301 | | o test@5.draft: 5
302 | | |
302 | | |
303 | o | test@4.draft: 4
303 | o | test@4.draft: 4
304 | |/
304 | |/
305 | o baz@3.public: 3
305 | o baz@3.public: 3
306 | |
306 | |
307 | o test@2.public: 2
307 | o test@2.public: 2
308 | |
308 | |
309 | o bar@1.public: 1
309 | o bar@1.public: 1
310 |/
310 |/
311 o test@0.public: 0
311 o test@0.public: 0
312
312
313 Graft again onto another branch should preserve the original source
313 Graft again onto another branch should preserve the original source
314 $ hg up -q 0
314 $ hg up -q 0
315 $ echo 'g'>g
315 $ echo 'g'>g
316 $ hg add g
316 $ hg add g
317 $ hg ci -m 7
317 $ hg ci -m 7
318 created new head
318 created new head
319 $ hg graft 7
319 $ hg graft 7
320 grafting 7:ef0ef43d49e7 "2"
320 grafting 7:ef0ef43d49e7 "2"
321
321
322 $ hg log -r 7 --template '{rev}:{node}\n'
322 $ hg log -r 7 --template '{rev}:{node}\n'
323 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
323 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
324 $ hg log -r 2 --template '{rev}:{node}\n'
324 $ hg log -r 2 --template '{rev}:{node}\n'
325 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
325 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
326
326
327 $ hg log --debug -r tip
327 $ hg log --debug -r tip
328 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
328 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
329 tag: tip
329 tag: tip
330 phase: draft
330 phase: draft
331 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
331 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
332 parent: -1:0000000000000000000000000000000000000000
332 parent: -1:0000000000000000000000000000000000000000
333 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
333 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
334 user: foo
334 user: foo
335 date: Thu Jan 01 00:00:00 1970 +0000
335 date: Thu Jan 01 00:00:00 1970 +0000
336 files+: b
336 files+: b
337 files-: a
337 files-: a
338 extra: branch=default
338 extra: branch=default
339 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
339 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
340 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
340 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
341 description:
341 description:
342 2
342 2
343
343
344
344
345 Disallow grafting an already grafted cset onto its original branch
345 Disallow grafting an already grafted cset onto its original branch
346 $ hg up -q 6
346 $ hg up -q 6
347 $ hg graft 7
347 $ hg graft 7
348 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
348 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
349 [255]
349 [255]
350
350
351 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
351 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13
352 --- */hg-5c095ad7e90f.patch * +0000 (glob)
352 --- */hg-5c095ad7e90f.patch * (glob)
353 +++ */hg-7a4785234d87.patch * +0000 (glob)
353 +++ */hg-7a4785234d87.patch * (glob)
354 @@ -1,18 +1,18 @@
354 @@ -1,18 +1,18 @@
355 # HG changeset patch
355 # HG changeset patch
356 -# User test
356 -# User test
357 +# User foo
357 +# User foo
358 # Date 0 0
358 # Date 0 0
359 # Thu Jan 01 00:00:00 1970 +0000
359 # Thu Jan 01 00:00:00 1970 +0000
360 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
360 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
361 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
361 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
362 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
362 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
363 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
363 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
364 2
364 2
365
365
366 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
366 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
367 +diff -r b592ea63bb0c -r 7a4785234d87 a
367 +diff -r b592ea63bb0c -r 7a4785234d87 a
368 --- a/a Thu Jan 01 00:00:00 1970 +0000
368 --- a/a Thu Jan 01 00:00:00 1970 +0000
369 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
369 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
370 @@ -1,1 +0,0 @@
370 @@ -1,1 +0,0 @@
371 --b
371 --b
372 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
372 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
373 +-a
373 +-a
374 +diff -r b592ea63bb0c -r 7a4785234d87 b
374 +diff -r b592ea63bb0c -r 7a4785234d87 b
375 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
375 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
376 +++ b/b Thu Jan 01 00:00:00 1970 +0000
376 +++ b/b Thu Jan 01 00:00:00 1970 +0000
377 @@ -0,0 +1,1 @@
377 @@ -0,0 +1,1 @@
378 -+b
378 -+b
379 ++a
379 ++a
380 [1]
380 [1]
381
381
382 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
382 $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
383 --- */hg-5c095ad7e90f.patch * +0000 (glob)
383 --- */hg-5c095ad7e90f.patch * (glob)
384 +++ */hg-7a4785234d87.patch * +0000 (glob)
384 +++ */hg-7a4785234d87.patch * (glob)
385 @@ -1,8 +1,8 @@
385 @@ -1,8 +1,8 @@
386 # HG changeset patch
386 # HG changeset patch
387 -# User test
387 -# User test
388 +# User foo
388 +# User foo
389 # Date 0 0
389 # Date 0 0
390 # Thu Jan 01 00:00:00 1970 +0000
390 # Thu Jan 01 00:00:00 1970 +0000
391 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
391 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
392 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
392 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
393 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
393 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
394 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
394 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
395 2
395 2
396
396
397 [1]
397 [1]
398
398
399 Disallow grafting already grafted csets with the same origin onto each other
399 Disallow grafting already grafted csets with the same origin onto each other
400 $ hg up -q 13
400 $ hg up -q 13
401 $ hg graft 2
401 $ hg graft 2
402 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
402 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
403 [255]
403 [255]
404 $ hg graft 7
404 $ hg graft 7
405 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
405 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
406 [255]
406 [255]
407
407
408 $ hg up -q 7
408 $ hg up -q 7
409 $ hg graft 2
409 $ hg graft 2
410 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
410 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
411 [255]
411 [255]
412 $ hg graft tip
412 $ hg graft tip
413 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
413 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
414 [255]
414 [255]
415
415
416 Graft with --log
416 Graft with --log
417
417
418 $ hg up -Cq 1
418 $ hg up -Cq 1
419 $ hg graft 3 --log -u foo
419 $ hg graft 3 --log -u foo
420 grafting 3:4c60f11aa304 "3"
420 grafting 3:4c60f11aa304 "3"
421 warning: can't find ancestor for 'c' copied from 'b'!
421 warning: can't find ancestor for 'c' copied from 'b'!
422 $ hg log --template '{rev} {parents} {desc}\n' -r tip
422 $ hg log --template '{rev} {parents} {desc}\n' -r tip
423 14 1:5d205f8b35b6 3
423 14 1:5d205f8b35b6 3
424 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
424 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
425
425
426 Resolve conflicted graft
426 Resolve conflicted graft
427 $ hg up -q 0
427 $ hg up -q 0
428 $ echo b > a
428 $ echo b > a
429 $ hg ci -m 8
429 $ hg ci -m 8
430 created new head
430 created new head
431 $ echo c > a
431 $ echo c > a
432 $ hg ci -m 9
432 $ hg ci -m 9
433 $ hg graft 1 --tool internal:fail
433 $ hg graft 1 --tool internal:fail
434 grafting 1:5d205f8b35b6 "1"
434 grafting 1:5d205f8b35b6 "1"
435 abort: unresolved conflicts, can't continue
435 abort: unresolved conflicts, can't continue
436 (use hg resolve and hg graft --continue)
436 (use hg resolve and hg graft --continue)
437 [255]
437 [255]
438 $ hg resolve --all
438 $ hg resolve --all
439 merging a
439 merging a
440 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
440 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
441 [1]
441 [1]
442 $ cat a
442 $ cat a
443 <<<<<<< local: aaa4406d4f0a - test: 9
443 <<<<<<< local: aaa4406d4f0a - test: 9
444 c
444 c
445 =======
445 =======
446 b
446 b
447 >>>>>>> other: 5d205f8b35b6 - bar: 1
447 >>>>>>> other: 5d205f8b35b6 - bar: 1
448 $ echo b > a
448 $ echo b > a
449 $ hg resolve -m a
449 $ hg resolve -m a
450 (no more unresolved files)
450 (no more unresolved files)
451 continue: hg graft --continue
451 continue: hg graft --continue
452 $ hg graft -c
452 $ hg graft -c
453 grafting 1:5d205f8b35b6 "1"
453 grafting 1:5d205f8b35b6 "1"
454 $ hg export tip --git
454 $ hg export tip --git
455 # HG changeset patch
455 # HG changeset patch
456 # User bar
456 # User bar
457 # Date 0 0
457 # Date 0 0
458 # Thu Jan 01 00:00:00 1970 +0000
458 # Thu Jan 01 00:00:00 1970 +0000
459 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
459 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
460 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
460 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
461 1
461 1
462
462
463 diff --git a/a b/a
463 diff --git a/a b/a
464 --- a/a
464 --- a/a
465 +++ b/a
465 +++ b/a
466 @@ -1,1 +1,1 @@
466 @@ -1,1 +1,1 @@
467 -c
467 -c
468 +b
468 +b
469
469
470 Resolve conflicted graft with rename
470 Resolve conflicted graft with rename
471 $ echo c > a
471 $ echo c > a
472 $ hg ci -m 10
472 $ hg ci -m 10
473 $ hg graft 2 --tool internal:fail
473 $ hg graft 2 --tool internal:fail
474 grafting 2:5c095ad7e90f "2"
474 grafting 2:5c095ad7e90f "2"
475 abort: unresolved conflicts, can't continue
475 abort: unresolved conflicts, can't continue
476 (use hg resolve and hg graft --continue)
476 (use hg resolve and hg graft --continue)
477 [255]
477 [255]
478 $ hg resolve --all
478 $ hg resolve --all
479 merging a and b to b
479 merging a and b to b
480 (no more unresolved files)
480 (no more unresolved files)
481 continue: hg graft --continue
481 continue: hg graft --continue
482 $ hg graft -c
482 $ hg graft -c
483 grafting 2:5c095ad7e90f "2"
483 grafting 2:5c095ad7e90f "2"
484 $ hg export tip --git
484 $ hg export tip --git
485 # HG changeset patch
485 # HG changeset patch
486 # User test
486 # User test
487 # Date 0 0
487 # Date 0 0
488 # Thu Jan 01 00:00:00 1970 +0000
488 # Thu Jan 01 00:00:00 1970 +0000
489 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
489 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
490 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
490 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
491 2
491 2
492
492
493 diff --git a/a b/b
493 diff --git a/a b/b
494 rename from a
494 rename from a
495 rename to b
495 rename to b
496
496
497 Test simple origin(), with and without args
497 Test simple origin(), with and without args
498 $ hg log -r 'origin()'
498 $ hg log -r 'origin()'
499 changeset: 1:5d205f8b35b6
499 changeset: 1:5d205f8b35b6
500 user: bar
500 user: bar
501 date: Thu Jan 01 00:00:00 1970 +0000
501 date: Thu Jan 01 00:00:00 1970 +0000
502 summary: 1
502 summary: 1
503
503
504 changeset: 2:5c095ad7e90f
504 changeset: 2:5c095ad7e90f
505 user: test
505 user: test
506 date: Thu Jan 01 00:00:00 1970 +0000
506 date: Thu Jan 01 00:00:00 1970 +0000
507 summary: 2
507 summary: 2
508
508
509 changeset: 3:4c60f11aa304
509 changeset: 3:4c60f11aa304
510 user: baz
510 user: baz
511 date: Thu Jan 01 00:00:00 1970 +0000
511 date: Thu Jan 01 00:00:00 1970 +0000
512 summary: 3
512 summary: 3
513
513
514 changeset: 4:9c233e8e184d
514 changeset: 4:9c233e8e184d
515 user: test
515 user: test
516 date: Thu Jan 01 00:00:00 1970 +0000
516 date: Thu Jan 01 00:00:00 1970 +0000
517 summary: 4
517 summary: 4
518
518
519 changeset: 5:97f8bfe72746
519 changeset: 5:97f8bfe72746
520 branch: stable
520 branch: stable
521 parent: 3:4c60f11aa304
521 parent: 3:4c60f11aa304
522 user: test
522 user: test
523 date: Thu Jan 01 00:00:00 1970 +0000
523 date: Thu Jan 01 00:00:00 1970 +0000
524 summary: 5
524 summary: 5
525
525
526 $ hg log -r 'origin(7)'
526 $ hg log -r 'origin(7)'
527 changeset: 2:5c095ad7e90f
527 changeset: 2:5c095ad7e90f
528 user: test
528 user: test
529 date: Thu Jan 01 00:00:00 1970 +0000
529 date: Thu Jan 01 00:00:00 1970 +0000
530 summary: 2
530 summary: 2
531
531
532 Now transplant a graft to test following through copies
532 Now transplant a graft to test following through copies
533 $ hg up -q 0
533 $ hg up -q 0
534 $ hg branch -q dev
534 $ hg branch -q dev
535 $ hg ci -qm "dev branch"
535 $ hg ci -qm "dev branch"
536 $ hg --config extensions.transplant= transplant -q 7
536 $ hg --config extensions.transplant= transplant -q 7
537 $ hg log -r 'origin(.)'
537 $ hg log -r 'origin(.)'
538 changeset: 2:5c095ad7e90f
538 changeset: 2:5c095ad7e90f
539 user: test
539 user: test
540 date: Thu Jan 01 00:00:00 1970 +0000
540 date: Thu Jan 01 00:00:00 1970 +0000
541 summary: 2
541 summary: 2
542
542
543 Test that the graft and transplant markers in extra are converted, allowing
543 Test that the graft and transplant markers in extra are converted, allowing
544 origin() to still work. Note that these recheck the immediately preceeding two
544 origin() to still work. Note that these recheck the immediately preceeding two
545 tests.
545 tests.
546 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
546 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
547
547
548 The graft case
548 The graft case
549 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
549 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
550 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
550 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
551 branch=default
551 branch=default
552 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
552 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
553 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
553 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
554 $ hg -R ../converted log -r 'origin(7)'
554 $ hg -R ../converted log -r 'origin(7)'
555 changeset: 2:e0213322b2c1
555 changeset: 2:e0213322b2c1
556 user: test
556 user: test
557 date: Thu Jan 01 00:00:00 1970 +0000
557 date: Thu Jan 01 00:00:00 1970 +0000
558 summary: 2
558 summary: 2
559
559
560 Test that template correctly expands more than one 'extra' (issue4362), and that
560 Test that template correctly expands more than one 'extra' (issue4362), and that
561 'intermediate-source' is converted.
561 'intermediate-source' is converted.
562 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
562 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
563 Extra: branch=default
563 Extra: branch=default
564 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
564 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
565 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
565 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
566 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
566 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
567
567
568 The transplant case
568 The transplant case
569 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
569 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
570 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
570 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
571 branch=dev
571 branch=dev
572 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
572 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
573 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
573 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
574 `h\x9b (esc)
574 `h\x9b (esc)
575 $ hg -R ../converted log -r 'origin(tip)'
575 $ hg -R ../converted log -r 'origin(tip)'
576 changeset: 2:e0213322b2c1
576 changeset: 2:e0213322b2c1
577 user: test
577 user: test
578 date: Thu Jan 01 00:00:00 1970 +0000
578 date: Thu Jan 01 00:00:00 1970 +0000
579 summary: 2
579 summary: 2
580
580
581
581
582 Test simple destination
582 Test simple destination
583 $ hg log -r 'destination()'
583 $ hg log -r 'destination()'
584 changeset: 7:ef0ef43d49e7
584 changeset: 7:ef0ef43d49e7
585 parent: 0:68795b066622
585 parent: 0:68795b066622
586 user: foo
586 user: foo
587 date: Thu Jan 01 00:00:00 1970 +0000
587 date: Thu Jan 01 00:00:00 1970 +0000
588 summary: 2
588 summary: 2
589
589
590 changeset: 8:6b9e5368ca4e
590 changeset: 8:6b9e5368ca4e
591 user: bar
591 user: bar
592 date: Thu Jan 01 00:00:00 1970 +0000
592 date: Thu Jan 01 00:00:00 1970 +0000
593 summary: 1
593 summary: 1
594
594
595 changeset: 9:1905859650ec
595 changeset: 9:1905859650ec
596 user: test
596 user: test
597 date: Thu Jan 01 00:00:00 1970 +0000
597 date: Thu Jan 01 00:00:00 1970 +0000
598 summary: 5
598 summary: 5
599
599
600 changeset: 10:52dc0b4c6907
600 changeset: 10:52dc0b4c6907
601 user: test
601 user: test
602 date: Thu Jan 01 00:00:00 1970 +0000
602 date: Thu Jan 01 00:00:00 1970 +0000
603 summary: 4
603 summary: 4
604
604
605 changeset: 11:882b35362a6b
605 changeset: 11:882b35362a6b
606 user: test
606 user: test
607 date: Thu Jan 01 00:00:00 1970 +0000
607 date: Thu Jan 01 00:00:00 1970 +0000
608 summary: 3
608 summary: 3
609
609
610 changeset: 13:7a4785234d87
610 changeset: 13:7a4785234d87
611 user: foo
611 user: foo
612 date: Thu Jan 01 00:00:00 1970 +0000
612 date: Thu Jan 01 00:00:00 1970 +0000
613 summary: 2
613 summary: 2
614
614
615 changeset: 14:f64defefacee
615 changeset: 14:f64defefacee
616 parent: 1:5d205f8b35b6
616 parent: 1:5d205f8b35b6
617 user: foo
617 user: foo
618 date: Thu Jan 01 00:00:00 1970 +0000
618 date: Thu Jan 01 00:00:00 1970 +0000
619 summary: 3
619 summary: 3
620
620
621 changeset: 17:f67661df0c48
621 changeset: 17:f67661df0c48
622 user: bar
622 user: bar
623 date: Thu Jan 01 00:00:00 1970 +0000
623 date: Thu Jan 01 00:00:00 1970 +0000
624 summary: 1
624 summary: 1
625
625
626 changeset: 19:9627f653b421
626 changeset: 19:9627f653b421
627 user: test
627 user: test
628 date: Thu Jan 01 00:00:00 1970 +0000
628 date: Thu Jan 01 00:00:00 1970 +0000
629 summary: 2
629 summary: 2
630
630
631 changeset: 21:7e61b508e709
631 changeset: 21:7e61b508e709
632 branch: dev
632 branch: dev
633 tag: tip
633 tag: tip
634 user: foo
634 user: foo
635 date: Thu Jan 01 00:00:00 1970 +0000
635 date: Thu Jan 01 00:00:00 1970 +0000
636 summary: 2
636 summary: 2
637
637
638 $ hg log -r 'destination(2)'
638 $ hg log -r 'destination(2)'
639 changeset: 7:ef0ef43d49e7
639 changeset: 7:ef0ef43d49e7
640 parent: 0:68795b066622
640 parent: 0:68795b066622
641 user: foo
641 user: foo
642 date: Thu Jan 01 00:00:00 1970 +0000
642 date: Thu Jan 01 00:00:00 1970 +0000
643 summary: 2
643 summary: 2
644
644
645 changeset: 13:7a4785234d87
645 changeset: 13:7a4785234d87
646 user: foo
646 user: foo
647 date: Thu Jan 01 00:00:00 1970 +0000
647 date: Thu Jan 01 00:00:00 1970 +0000
648 summary: 2
648 summary: 2
649
649
650 changeset: 19:9627f653b421
650 changeset: 19:9627f653b421
651 user: test
651 user: test
652 date: Thu Jan 01 00:00:00 1970 +0000
652 date: Thu Jan 01 00:00:00 1970 +0000
653 summary: 2
653 summary: 2
654
654
655 changeset: 21:7e61b508e709
655 changeset: 21:7e61b508e709
656 branch: dev
656 branch: dev
657 tag: tip
657 tag: tip
658 user: foo
658 user: foo
659 date: Thu Jan 01 00:00:00 1970 +0000
659 date: Thu Jan 01 00:00:00 1970 +0000
660 summary: 2
660 summary: 2
661
661
662 Transplants of grafts can find a destination...
662 Transplants of grafts can find a destination...
663 $ hg log -r 'destination(7)'
663 $ hg log -r 'destination(7)'
664 changeset: 21:7e61b508e709
664 changeset: 21:7e61b508e709
665 branch: dev
665 branch: dev
666 tag: tip
666 tag: tip
667 user: foo
667 user: foo
668 date: Thu Jan 01 00:00:00 1970 +0000
668 date: Thu Jan 01 00:00:00 1970 +0000
669 summary: 2
669 summary: 2
670
670
671 ... grafts of grafts unfortunately can't
671 ... grafts of grafts unfortunately can't
672 $ hg graft -q 13
672 $ hg graft -q 13
673 warning: can't find ancestor for 'b' copied from 'a'!
673 warning: can't find ancestor for 'b' copied from 'a'!
674 $ hg log -r 'destination(13)'
674 $ hg log -r 'destination(13)'
675 All copies of a cset
675 All copies of a cset
676 $ hg log -r 'origin(13) or destination(origin(13))'
676 $ hg log -r 'origin(13) or destination(origin(13))'
677 changeset: 2:5c095ad7e90f
677 changeset: 2:5c095ad7e90f
678 user: test
678 user: test
679 date: Thu Jan 01 00:00:00 1970 +0000
679 date: Thu Jan 01 00:00:00 1970 +0000
680 summary: 2
680 summary: 2
681
681
682 changeset: 7:ef0ef43d49e7
682 changeset: 7:ef0ef43d49e7
683 parent: 0:68795b066622
683 parent: 0:68795b066622
684 user: foo
684 user: foo
685 date: Thu Jan 01 00:00:00 1970 +0000
685 date: Thu Jan 01 00:00:00 1970 +0000
686 summary: 2
686 summary: 2
687
687
688 changeset: 13:7a4785234d87
688 changeset: 13:7a4785234d87
689 user: foo
689 user: foo
690 date: Thu Jan 01 00:00:00 1970 +0000
690 date: Thu Jan 01 00:00:00 1970 +0000
691 summary: 2
691 summary: 2
692
692
693 changeset: 19:9627f653b421
693 changeset: 19:9627f653b421
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:00 1970 +0000
695 date: Thu Jan 01 00:00:00 1970 +0000
696 summary: 2
696 summary: 2
697
697
698 changeset: 21:7e61b508e709
698 changeset: 21:7e61b508e709
699 branch: dev
699 branch: dev
700 user: foo
700 user: foo
701 date: Thu Jan 01 00:00:00 1970 +0000
701 date: Thu Jan 01 00:00:00 1970 +0000
702 summary: 2
702 summary: 2
703
703
704 changeset: 22:d1cb6591fa4b
704 changeset: 22:d1cb6591fa4b
705 branch: dev
705 branch: dev
706 tag: tip
706 tag: tip
707 user: foo
707 user: foo
708 date: Thu Jan 01 00:00:00 1970 +0000
708 date: Thu Jan 01 00:00:00 1970 +0000
709 summary: 2
709 summary: 2
710
710
711
711
712 graft works on complex revset
712 graft works on complex revset
713
713
714 $ hg graft 'origin(13) or destination(origin(13))'
714 $ hg graft 'origin(13) or destination(origin(13))'
715 skipping ancestor revision 21:7e61b508e709
715 skipping ancestor revision 21:7e61b508e709
716 skipping ancestor revision 22:d1cb6591fa4b
716 skipping ancestor revision 22:d1cb6591fa4b
717 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
717 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
718 grafting 7:ef0ef43d49e7 "2"
718 grafting 7:ef0ef43d49e7 "2"
719 warning: can't find ancestor for 'b' copied from 'a'!
719 warning: can't find ancestor for 'b' copied from 'a'!
720 grafting 13:7a4785234d87 "2"
720 grafting 13:7a4785234d87 "2"
721 warning: can't find ancestor for 'b' copied from 'a'!
721 warning: can't find ancestor for 'b' copied from 'a'!
722 grafting 19:9627f653b421 "2"
722 grafting 19:9627f653b421 "2"
723 merging b
723 merging b
724 warning: can't find ancestor for 'b' copied from 'a'!
724 warning: can't find ancestor for 'b' copied from 'a'!
725
725
726 graft with --force (still doesn't graft merges)
726 graft with --force (still doesn't graft merges)
727
727
728 $ hg graft 19 0 6
728 $ hg graft 19 0 6
729 skipping ungraftable merge revision 6
729 skipping ungraftable merge revision 6
730 skipping ancestor revision 0:68795b066622
730 skipping ancestor revision 0:68795b066622
731 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
731 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
732 [255]
732 [255]
733 $ hg graft 19 0 6 --force
733 $ hg graft 19 0 6 --force
734 skipping ungraftable merge revision 6
734 skipping ungraftable merge revision 6
735 grafting 19:9627f653b421 "2"
735 grafting 19:9627f653b421 "2"
736 merging b
736 merging b
737 warning: can't find ancestor for 'b' copied from 'a'!
737 warning: can't find ancestor for 'b' copied from 'a'!
738 grafting 0:68795b066622 "0"
738 grafting 0:68795b066622 "0"
739
739
740 graft --force after backout
740 graft --force after backout
741
741
742 $ echo abc > a
742 $ echo abc > a
743 $ hg ci -m 28
743 $ hg ci -m 28
744 $ hg backout 28
744 $ hg backout 28
745 reverting a
745 reverting a
746 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
746 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
747 $ hg graft 28
747 $ hg graft 28
748 skipping ancestor revision 28:50a516bb8b57
748 skipping ancestor revision 28:50a516bb8b57
749 [255]
749 [255]
750 $ hg graft 28 --force
750 $ hg graft 28 --force
751 grafting 28:50a516bb8b57 "28"
751 grafting 28:50a516bb8b57 "28"
752 merging a
752 merging a
753 $ cat a
753 $ cat a
754 abc
754 abc
755
755
756 graft --continue after --force
756 graft --continue after --force
757
757
758 $ echo def > a
758 $ echo def > a
759 $ hg ci -m 31
759 $ hg ci -m 31
760 $ hg graft 28 --force --tool internal:fail
760 $ hg graft 28 --force --tool internal:fail
761 grafting 28:50a516bb8b57 "28"
761 grafting 28:50a516bb8b57 "28"
762 abort: unresolved conflicts, can't continue
762 abort: unresolved conflicts, can't continue
763 (use hg resolve and hg graft --continue)
763 (use hg resolve and hg graft --continue)
764 [255]
764 [255]
765 $ hg resolve --all
765 $ hg resolve --all
766 merging a
766 merging a
767 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
767 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
768 [1]
768 [1]
769 $ echo abc > a
769 $ echo abc > a
770 $ hg resolve -m a
770 $ hg resolve -m a
771 (no more unresolved files)
771 (no more unresolved files)
772 continue: hg graft --continue
772 continue: hg graft --continue
773 $ hg graft -c
773 $ hg graft -c
774 grafting 28:50a516bb8b57 "28"
774 grafting 28:50a516bb8b57 "28"
775 $ cat a
775 $ cat a
776 abc
776 abc
777
777
778 Continue testing same origin policy, using revision numbers from test above
778 Continue testing same origin policy, using revision numbers from test above
779 but do some destructive editing of the repo:
779 but do some destructive editing of the repo:
780
780
781 $ hg up -qC 7
781 $ hg up -qC 7
782 $ hg tag -l -r 13 tmp
782 $ hg tag -l -r 13 tmp
783 $ hg --config extensions.strip= strip 2
783 $ hg --config extensions.strip= strip 2
784 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
784 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
785 $ hg graft tmp
785 $ hg graft tmp
786 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
786 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
787 [255]
787 [255]
788
788
789 Empty graft
789 Empty graft
790
790
791 $ hg up -qr 26
791 $ hg up -qr 26
792 $ hg tag -f something
792 $ hg tag -f something
793 $ hg graft -qr 27
793 $ hg graft -qr 27
794 $ hg graft -f 27
794 $ hg graft -f 27
795 grafting 27:ed6c7e54e319 "28"
795 grafting 27:ed6c7e54e319 "28"
796 note: graft of 27:ed6c7e54e319 created no changes to commit
796 note: graft of 27:ed6c7e54e319 created no changes to commit
797
797
798 $ cd ..
798 $ cd ..
799
799
800 Graft to duplicate a commit
800 Graft to duplicate a commit
801
801
802 $ hg init graftsibling
802 $ hg init graftsibling
803 $ cd graftsibling
803 $ cd graftsibling
804 $ touch a
804 $ touch a
805 $ hg commit -qAm a
805 $ hg commit -qAm a
806 $ touch b
806 $ touch b
807 $ hg commit -qAm b
807 $ hg commit -qAm b
808 $ hg log -G -T '{rev}\n'
808 $ hg log -G -T '{rev}\n'
809 @ 1
809 @ 1
810 |
810 |
811 o 0
811 o 0
812
812
813 $ hg up -q 0
813 $ hg up -q 0
814 $ hg graft -r 1
814 $ hg graft -r 1
815 grafting 1:0e067c57feba "b" (tip)
815 grafting 1:0e067c57feba "b" (tip)
816 $ hg log -G -T '{rev}\n'
816 $ hg log -G -T '{rev}\n'
817 @ 2
817 @ 2
818 |
818 |
819 | o 1
819 | o 1
820 |/
820 |/
821 o 0
821 o 0
822
822
823 Graft to duplicate a commit twice
823 Graft to duplicate a commit twice
824
824
825 $ hg up -q 0
825 $ hg up -q 0
826 $ hg graft -r 2
826 $ hg graft -r 2
827 grafting 2:044ec77f6389 "b" (tip)
827 grafting 2:044ec77f6389 "b" (tip)
828 $ hg log -G -T '{rev}\n'
828 $ hg log -G -T '{rev}\n'
829 @ 3
829 @ 3
830 |
830 |
831 | o 2
831 | o 2
832 |/
832 |/
833 | o 1
833 | o 1
834 |/
834 |/
835 o 0
835 o 0
836
836
@@ -1,810 +1,810 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [defaults]
2 > [defaults]
3 > # for portability
3 > # for portability
4 > extdiff = --option -Nru
4 > extdiff = --option -Nru
5 > EOF
5 > EOF
6
6
7 Preparing the subrepository 'sub2'
7 Preparing the subrepository 'sub2'
8
8
9 $ hg init sub2
9 $ hg init sub2
10 $ echo sub2 > sub2/sub2
10 $ echo sub2 > sub2/sub2
11 $ hg add -R sub2
11 $ hg add -R sub2
12 adding sub2/sub2 (glob)
12 adding sub2/sub2 (glob)
13 $ hg commit -R sub2 -m "sub2 import"
13 $ hg commit -R sub2 -m "sub2 import"
14
14
15 Preparing the 'sub1' repo which depends on the subrepo 'sub2'
15 Preparing the 'sub1' repo which depends on the subrepo 'sub2'
16
16
17 $ hg init sub1
17 $ hg init sub1
18 $ echo sub1 > sub1/sub1
18 $ echo sub1 > sub1/sub1
19 $ echo "sub2 = ../sub2" > sub1/.hgsub
19 $ echo "sub2 = ../sub2" > sub1/.hgsub
20 $ hg clone sub2 sub1/sub2
20 $ hg clone sub2 sub1/sub2
21 updating to branch default
21 updating to branch default
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 $ hg add -R sub1
23 $ hg add -R sub1
24 adding sub1/.hgsub (glob)
24 adding sub1/.hgsub (glob)
25 adding sub1/sub1 (glob)
25 adding sub1/sub1 (glob)
26 $ hg commit -R sub1 -m "sub1 import"
26 $ hg commit -R sub1 -m "sub1 import"
27
27
28 Preparing the 'main' repo which depends on the subrepo 'sub1'
28 Preparing the 'main' repo which depends on the subrepo 'sub1'
29
29
30 $ hg init main
30 $ hg init main
31 $ echo main > main/main
31 $ echo main > main/main
32 $ echo "sub1 = ../sub1" > main/.hgsub
32 $ echo "sub1 = ../sub1" > main/.hgsub
33 $ hg clone sub1 main/sub1
33 $ hg clone sub1 main/sub1
34 updating to branch default
34 updating to branch default
35 cloning subrepo sub2 from $TESTTMP/sub2
35 cloning subrepo sub2 from $TESTTMP/sub2
36 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 $ hg add -R main
37 $ hg add -R main
38 adding main/.hgsub (glob)
38 adding main/.hgsub (glob)
39 adding main/main (glob)
39 adding main/main (glob)
40 $ hg commit -R main -m "main import"
40 $ hg commit -R main -m "main import"
41
41
42 Cleaning both repositories, just as a clone -U
42 Cleaning both repositories, just as a clone -U
43
43
44 $ hg up -C -R sub2 null
44 $ hg up -C -R sub2 null
45 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
45 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
46 $ hg up -C -R sub1 null
46 $ hg up -C -R sub1 null
47 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
47 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
48 $ hg up -C -R main null
48 $ hg up -C -R main null
49 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
49 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
50 $ rm -rf main/sub1
50 $ rm -rf main/sub1
51 $ rm -rf sub1/sub2
51 $ rm -rf sub1/sub2
52
52
53 Clone main
53 Clone main
54
54
55 $ hg --config extensions.largefiles= clone main cloned
55 $ hg --config extensions.largefiles= clone main cloned
56 updating to branch default
56 updating to branch default
57 cloning subrepo sub1 from $TESTTMP/sub1
57 cloning subrepo sub1 from $TESTTMP/sub1
58 cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob)
58 cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob)
59 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
60
60
61 Largefiles is NOT enabled in the clone if the source repo doesn't require it
61 Largefiles is NOT enabled in the clone if the source repo doesn't require it
62 $ cat cloned/.hg/hgrc
62 $ cat cloned/.hg/hgrc
63 # example repository config (see "hg help config" for more info)
63 # example repository config (see "hg help config" for more info)
64 [paths]
64 [paths]
65 default = $TESTTMP/main (glob)
65 default = $TESTTMP/main (glob)
66
66
67 # path aliases to other clones of this repo in URLs or filesystem paths
67 # path aliases to other clones of this repo in URLs or filesystem paths
68 # (see "hg help config.paths" for more info)
68 # (see "hg help config.paths" for more info)
69 #
69 #
70 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
70 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
71 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
71 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
72 # my-clone = /home/jdoe/jdoes-clone
72 # my-clone = /home/jdoe/jdoes-clone
73
73
74 [ui]
74 [ui]
75 # name and email (local to this repository, optional), e.g.
75 # name and email (local to this repository, optional), e.g.
76 # username = Jane Doe <jdoe@example.com>
76 # username = Jane Doe <jdoe@example.com>
77
77
78 Checking cloned repo ids
78 Checking cloned repo ids
79
79
80 $ printf "cloned " ; hg id -R cloned
80 $ printf "cloned " ; hg id -R cloned
81 cloned 7f491f53a367 tip
81 cloned 7f491f53a367 tip
82 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
82 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
83 cloned/sub1 fc3b4ce2696f tip
83 cloned/sub1 fc3b4ce2696f tip
84 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
84 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
85 cloned/sub1/sub2 c57a0840e3ba tip
85 cloned/sub1/sub2 c57a0840e3ba tip
86
86
87 debugsub output for main and sub1
87 debugsub output for main and sub1
88
88
89 $ hg debugsub -R cloned
89 $ hg debugsub -R cloned
90 path sub1
90 path sub1
91 source ../sub1
91 source ../sub1
92 revision fc3b4ce2696f7741438c79207583768f2ce6b0dd
92 revision fc3b4ce2696f7741438c79207583768f2ce6b0dd
93 $ hg debugsub -R cloned/sub1
93 $ hg debugsub -R cloned/sub1
94 path sub2
94 path sub2
95 source ../sub2
95 source ../sub2
96 revision c57a0840e3badd667ef3c3ef65471609acb2ba3c
96 revision c57a0840e3badd667ef3c3ef65471609acb2ba3c
97
97
98 Modifying deeply nested 'sub2'
98 Modifying deeply nested 'sub2'
99
99
100 $ echo modified > cloned/sub1/sub2/sub2
100 $ echo modified > cloned/sub1/sub2/sub2
101 $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned
101 $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned
102 committing subrepository sub1
102 committing subrepository sub1
103 committing subrepository sub1/sub2 (glob)
103 committing subrepository sub1/sub2 (glob)
104
104
105 Checking modified node ids
105 Checking modified node ids
106
106
107 $ printf "cloned " ; hg id -R cloned
107 $ printf "cloned " ; hg id -R cloned
108 cloned ffe6649062fe tip
108 cloned ffe6649062fe tip
109 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
109 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
110 cloned/sub1 2ecb03bf44a9 tip
110 cloned/sub1 2ecb03bf44a9 tip
111 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
111 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
112 cloned/sub1/sub2 53dd3430bcaf tip
112 cloned/sub1/sub2 53dd3430bcaf tip
113
113
114 debugsub output for main and sub1
114 debugsub output for main and sub1
115
115
116 $ hg debugsub -R cloned
116 $ hg debugsub -R cloned
117 path sub1
117 path sub1
118 source ../sub1
118 source ../sub1
119 revision 2ecb03bf44a94e749e8669481dd9069526ce7cb9
119 revision 2ecb03bf44a94e749e8669481dd9069526ce7cb9
120 $ hg debugsub -R cloned/sub1
120 $ hg debugsub -R cloned/sub1
121 path sub2
121 path sub2
122 source ../sub2
122 source ../sub2
123 revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487
123 revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487
124
124
125 Check that deep archiving works
125 Check that deep archiving works
126
126
127 $ cd cloned
127 $ cd cloned
128 $ echo 'test' > sub1/sub2/test.txt
128 $ echo 'test' > sub1/sub2/test.txt
129 $ hg --config extensions.largefiles=! add sub1/sub2/test.txt
129 $ hg --config extensions.largefiles=! add sub1/sub2/test.txt
130 $ mkdir sub1/sub2/folder
130 $ mkdir sub1/sub2/folder
131 $ echo 'subfolder' > sub1/sub2/folder/test.txt
131 $ echo 'subfolder' > sub1/sub2/folder/test.txt
132 $ hg ci -ASm "add test.txt"
132 $ hg ci -ASm "add test.txt"
133 adding sub1/sub2/folder/test.txt
133 adding sub1/sub2/folder/test.txt
134 committing subrepository sub1
134 committing subrepository sub1
135 committing subrepository sub1/sub2 (glob)
135 committing subrepository sub1/sub2 (glob)
136
136
137 .. but first take a detour through some deep removal testing
137 .. but first take a detour through some deep removal testing
138
138
139 $ hg remove -S -I 're:.*.txt' .
139 $ hg remove -S -I 're:.*.txt' .
140 removing sub1/sub2/folder/test.txt (glob)
140 removing sub1/sub2/folder/test.txt (glob)
141 removing sub1/sub2/test.txt (glob)
141 removing sub1/sub2/test.txt (glob)
142 $ hg status -S
142 $ hg status -S
143 R sub1/sub2/folder/test.txt
143 R sub1/sub2/folder/test.txt
144 R sub1/sub2/test.txt
144 R sub1/sub2/test.txt
145 $ hg update -Cq
145 $ hg update -Cq
146 $ hg remove -I 're:.*.txt' sub1
146 $ hg remove -I 're:.*.txt' sub1
147 $ hg status -S
147 $ hg status -S
148 $ hg remove sub1/sub2/folder/test.txt
148 $ hg remove sub1/sub2/folder/test.txt
149 $ hg remove sub1/.hgsubstate
149 $ hg remove sub1/.hgsubstate
150 $ mv sub1/.hgsub sub1/x.hgsub
150 $ mv sub1/.hgsub sub1/x.hgsub
151 $ hg status -S
151 $ hg status -S
152 warning: subrepo spec file 'sub1/.hgsub' not found
152 warning: subrepo spec file 'sub1/.hgsub' not found
153 R sub1/.hgsubstate
153 R sub1/.hgsubstate
154 R sub1/sub2/folder/test.txt
154 R sub1/sub2/folder/test.txt
155 ! sub1/.hgsub
155 ! sub1/.hgsub
156 ? sub1/x.hgsub
156 ? sub1/x.hgsub
157 $ mv sub1/x.hgsub sub1/.hgsub
157 $ mv sub1/x.hgsub sub1/.hgsub
158 $ hg update -Cq
158 $ hg update -Cq
159 $ touch sub1/foo
159 $ touch sub1/foo
160 $ hg forget sub1/sub2/folder/test.txt
160 $ hg forget sub1/sub2/folder/test.txt
161 $ rm sub1/sub2/test.txt
161 $ rm sub1/sub2/test.txt
162
162
163 Test relative path printing + subrepos
163 Test relative path printing + subrepos
164 $ mkdir -p foo/bar
164 $ mkdir -p foo/bar
165 $ cd foo
165 $ cd foo
166 $ touch bar/abc
166 $ touch bar/abc
167 $ hg addremove -S ..
167 $ hg addremove -S ..
168 adding ../sub1/sub2/folder/test.txt (glob)
168 adding ../sub1/sub2/folder/test.txt (glob)
169 removing ../sub1/sub2/test.txt (glob)
169 removing ../sub1/sub2/test.txt (glob)
170 adding ../sub1/foo (glob)
170 adding ../sub1/foo (glob)
171 adding bar/abc (glob)
171 adding bar/abc (glob)
172 $ cd ..
172 $ cd ..
173 $ hg status -S
173 $ hg status -S
174 A foo/bar/abc
174 A foo/bar/abc
175 A sub1/foo
175 A sub1/foo
176 R sub1/sub2/test.txt
176 R sub1/sub2/test.txt
177
177
178 Archive wdir() with subrepos
178 Archive wdir() with subrepos
179 $ hg rm main
179 $ hg rm main
180 $ hg archive -S -r 'wdir()' ../wdir
180 $ hg archive -S -r 'wdir()' ../wdir
181 $ diff -r . ../wdir | egrep -v '\.hg$|^Common subdirectories:'
181 $ diff -r . ../wdir | egrep -v '\.hg$|^Common subdirectories:'
182 Only in ../wdir: .hg_archival.txt
182 Only in ../wdir: .hg_archival.txt
183
183
184 $ find ../wdir -type f | sort
184 $ find ../wdir -type f | sort
185 ../wdir/.hg_archival.txt
185 ../wdir/.hg_archival.txt
186 ../wdir/.hgsub
186 ../wdir/.hgsub
187 ../wdir/.hgsubstate
187 ../wdir/.hgsubstate
188 ../wdir/foo/bar/abc
188 ../wdir/foo/bar/abc
189 ../wdir/sub1/.hgsub
189 ../wdir/sub1/.hgsub
190 ../wdir/sub1/.hgsubstate
190 ../wdir/sub1/.hgsubstate
191 ../wdir/sub1/foo
191 ../wdir/sub1/foo
192 ../wdir/sub1/sub1
192 ../wdir/sub1/sub1
193 ../wdir/sub1/sub2/folder/test.txt
193 ../wdir/sub1/sub2/folder/test.txt
194 ../wdir/sub1/sub2/sub2
194 ../wdir/sub1/sub2/sub2
195
195
196 $ cat ../wdir/.hg_archival.txt
196 $ cat ../wdir/.hg_archival.txt
197 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
197 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
198 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
198 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
199 branch: default
199 branch: default
200 latesttag: null
200 latesttag: null
201 latesttagdistance: 4
201 latesttagdistance: 4
202 changessincelatesttag: 4
202 changessincelatesttag: 4
203
203
204 Attempting to archive 'wdir()' with a missing file is handled gracefully
204 Attempting to archive 'wdir()' with a missing file is handled gracefully
205 $ rm sub1/sub1
205 $ rm sub1/sub1
206 $ rm -r ../wdir
206 $ rm -r ../wdir
207 $ hg archive -v -S -r 'wdir()' ../wdir
207 $ hg archive -v -S -r 'wdir()' ../wdir
208 $ find ../wdir -type f | sort
208 $ find ../wdir -type f | sort
209 ../wdir/.hg_archival.txt
209 ../wdir/.hg_archival.txt
210 ../wdir/.hgsub
210 ../wdir/.hgsub
211 ../wdir/.hgsubstate
211 ../wdir/.hgsubstate
212 ../wdir/foo/bar/abc
212 ../wdir/foo/bar/abc
213 ../wdir/sub1/.hgsub
213 ../wdir/sub1/.hgsub
214 ../wdir/sub1/.hgsubstate
214 ../wdir/sub1/.hgsubstate
215 ../wdir/sub1/foo
215 ../wdir/sub1/foo
216 ../wdir/sub1/sub2/folder/test.txt
216 ../wdir/sub1/sub2/folder/test.txt
217 ../wdir/sub1/sub2/sub2
217 ../wdir/sub1/sub2/sub2
218
218
219 Continue relative path printing + subrepos
219 Continue relative path printing + subrepos
220 $ hg update -Cq
220 $ hg update -Cq
221 $ rm -r ../wdir
221 $ rm -r ../wdir
222 $ hg archive -S -r 'wdir()' ../wdir
222 $ hg archive -S -r 'wdir()' ../wdir
223 $ cat ../wdir/.hg_archival.txt
223 $ cat ../wdir/.hg_archival.txt
224 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
224 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
225 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd
225 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd
226 branch: default
226 branch: default
227 latesttag: null
227 latesttag: null
228 latesttagdistance: 4
228 latesttagdistance: 4
229 changessincelatesttag: 4
229 changessincelatesttag: 4
230
230
231 $ touch sub1/sub2/folder/bar
231 $ touch sub1/sub2/folder/bar
232 $ hg addremove sub1/sub2
232 $ hg addremove sub1/sub2
233 adding sub1/sub2/folder/bar (glob)
233 adding sub1/sub2/folder/bar (glob)
234 $ hg status -S
234 $ hg status -S
235 A sub1/sub2/folder/bar
235 A sub1/sub2/folder/bar
236 ? foo/bar/abc
236 ? foo/bar/abc
237 ? sub1/foo
237 ? sub1/foo
238 $ hg update -Cq
238 $ hg update -Cq
239 $ hg addremove sub1
239 $ hg addremove sub1
240 adding sub1/sub2/folder/bar (glob)
240 adding sub1/sub2/folder/bar (glob)
241 adding sub1/foo (glob)
241 adding sub1/foo (glob)
242 $ hg update -Cq
242 $ hg update -Cq
243 $ rm sub1/sub2/folder/test.txt
243 $ rm sub1/sub2/folder/test.txt
244 $ rm sub1/sub2/test.txt
244 $ rm sub1/sub2/test.txt
245 $ hg ci -ASm "remove test.txt"
245 $ hg ci -ASm "remove test.txt"
246 adding sub1/sub2/folder/bar
246 adding sub1/sub2/folder/bar
247 removing sub1/sub2/folder/test.txt
247 removing sub1/sub2/folder/test.txt
248 removing sub1/sub2/test.txt
248 removing sub1/sub2/test.txt
249 adding sub1/foo
249 adding sub1/foo
250 adding foo/bar/abc
250 adding foo/bar/abc
251 committing subrepository sub1
251 committing subrepository sub1
252 committing subrepository sub1/sub2 (glob)
252 committing subrepository sub1/sub2 (glob)
253
253
254 $ hg forget sub1/sub2/sub2
254 $ hg forget sub1/sub2/sub2
255 $ echo x > sub1/sub2/x.txt
255 $ echo x > sub1/sub2/x.txt
256 $ hg add sub1/sub2/x.txt
256 $ hg add sub1/sub2/x.txt
257
257
258 Files sees uncommitted adds and removes in subrepos
258 Files sees uncommitted adds and removes in subrepos
259 $ hg files -S
259 $ hg files -S
260 .hgsub
260 .hgsub
261 .hgsubstate
261 .hgsubstate
262 foo/bar/abc (glob)
262 foo/bar/abc (glob)
263 main
263 main
264 sub1/.hgsub (glob)
264 sub1/.hgsub (glob)
265 sub1/.hgsubstate (glob)
265 sub1/.hgsubstate (glob)
266 sub1/foo (glob)
266 sub1/foo (glob)
267 sub1/sub1 (glob)
267 sub1/sub1 (glob)
268 sub1/sub2/folder/bar (glob)
268 sub1/sub2/folder/bar (glob)
269 sub1/sub2/x.txt (glob)
269 sub1/sub2/x.txt (glob)
270
270
271 $ hg files -S "set:eol('dos') or eol('unix') or size('<= 0')"
271 $ hg files -S "set:eol('dos') or eol('unix') or size('<= 0')"
272 .hgsub
272 .hgsub
273 .hgsubstate
273 .hgsubstate
274 foo/bar/abc (glob)
274 foo/bar/abc (glob)
275 main
275 main
276 sub1/.hgsub (glob)
276 sub1/.hgsub (glob)
277 sub1/.hgsubstate (glob)
277 sub1/.hgsubstate (glob)
278 sub1/foo (glob)
278 sub1/foo (glob)
279 sub1/sub1 (glob)
279 sub1/sub1 (glob)
280 sub1/sub2/folder/bar (glob)
280 sub1/sub2/folder/bar (glob)
281 sub1/sub2/x.txt (glob)
281 sub1/sub2/x.txt (glob)
282
282
283 $ hg files -r '.^' -S "set:eol('dos') or eol('unix')"
283 $ hg files -r '.^' -S "set:eol('dos') or eol('unix')"
284 .hgsub
284 .hgsub
285 .hgsubstate
285 .hgsubstate
286 main
286 main
287 sub1/.hgsub (glob)
287 sub1/.hgsub (glob)
288 sub1/.hgsubstate (glob)
288 sub1/.hgsubstate (glob)
289 sub1/sub1 (glob)
289 sub1/sub1 (glob)
290 sub1/sub2/folder/test.txt (glob)
290 sub1/sub2/folder/test.txt (glob)
291 sub1/sub2/sub2 (glob)
291 sub1/sub2/sub2 (glob)
292 sub1/sub2/test.txt (glob)
292 sub1/sub2/test.txt (glob)
293
293
294 $ hg files sub1
294 $ hg files sub1
295 sub1/.hgsub (glob)
295 sub1/.hgsub (glob)
296 sub1/.hgsubstate (glob)
296 sub1/.hgsubstate (glob)
297 sub1/foo (glob)
297 sub1/foo (glob)
298 sub1/sub1 (glob)
298 sub1/sub1 (glob)
299 sub1/sub2/folder/bar (glob)
299 sub1/sub2/folder/bar (glob)
300 sub1/sub2/x.txt (glob)
300 sub1/sub2/x.txt (glob)
301
301
302 $ hg files sub1/sub2
302 $ hg files sub1/sub2
303 sub1/sub2/folder/bar (glob)
303 sub1/sub2/folder/bar (glob)
304 sub1/sub2/x.txt (glob)
304 sub1/sub2/x.txt (glob)
305
305
306 $ hg files -S -r '.^' sub1/sub2/folder
306 $ hg files -S -r '.^' sub1/sub2/folder
307 sub1/sub2/folder/test.txt (glob)
307 sub1/sub2/folder/test.txt (glob)
308
308
309 $ hg files -S -r '.^' sub1/sub2/missing
309 $ hg files -S -r '.^' sub1/sub2/missing
310 sub1/sub2/missing: no such file in rev 78026e779ea6 (glob)
310 sub1/sub2/missing: no such file in rev 78026e779ea6 (glob)
311 [1]
311 [1]
312
312
313 $ hg files -r '.^' sub1/
313 $ hg files -r '.^' sub1/
314 sub1/.hgsub (glob)
314 sub1/.hgsub (glob)
315 sub1/.hgsubstate (glob)
315 sub1/.hgsubstate (glob)
316 sub1/sub1 (glob)
316 sub1/sub1 (glob)
317 sub1/sub2/folder/test.txt (glob)
317 sub1/sub2/folder/test.txt (glob)
318 sub1/sub2/sub2 (glob)
318 sub1/sub2/sub2 (glob)
319 sub1/sub2/test.txt (glob)
319 sub1/sub2/test.txt (glob)
320
320
321 $ hg files -r '.^' sub1/sub2
321 $ hg files -r '.^' sub1/sub2
322 sub1/sub2/folder/test.txt (glob)
322 sub1/sub2/folder/test.txt (glob)
323 sub1/sub2/sub2 (glob)
323 sub1/sub2/sub2 (glob)
324 sub1/sub2/test.txt (glob)
324 sub1/sub2/test.txt (glob)
325
325
326 $ hg rollback -q
326 $ hg rollback -q
327 $ hg up -Cq
327 $ hg up -Cq
328
328
329 $ hg --config extensions.largefiles=! archive -S ../archive_all
329 $ hg --config extensions.largefiles=! archive -S ../archive_all
330 $ find ../archive_all | sort
330 $ find ../archive_all | sort
331 ../archive_all
331 ../archive_all
332 ../archive_all/.hg_archival.txt
332 ../archive_all/.hg_archival.txt
333 ../archive_all/.hgsub
333 ../archive_all/.hgsub
334 ../archive_all/.hgsubstate
334 ../archive_all/.hgsubstate
335 ../archive_all/main
335 ../archive_all/main
336 ../archive_all/sub1
336 ../archive_all/sub1
337 ../archive_all/sub1/.hgsub
337 ../archive_all/sub1/.hgsub
338 ../archive_all/sub1/.hgsubstate
338 ../archive_all/sub1/.hgsubstate
339 ../archive_all/sub1/sub1
339 ../archive_all/sub1/sub1
340 ../archive_all/sub1/sub2
340 ../archive_all/sub1/sub2
341 ../archive_all/sub1/sub2/folder
341 ../archive_all/sub1/sub2/folder
342 ../archive_all/sub1/sub2/folder/test.txt
342 ../archive_all/sub1/sub2/folder/test.txt
343 ../archive_all/sub1/sub2/sub2
343 ../archive_all/sub1/sub2/sub2
344 ../archive_all/sub1/sub2/test.txt
344 ../archive_all/sub1/sub2/test.txt
345
345
346 Check that archive -X works in deep subrepos
346 Check that archive -X works in deep subrepos
347
347
348 $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude
348 $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude
349 $ find ../archive_exclude | sort
349 $ find ../archive_exclude | sort
350 ../archive_exclude
350 ../archive_exclude
351 ../archive_exclude/.hg_archival.txt
351 ../archive_exclude/.hg_archival.txt
352 ../archive_exclude/.hgsub
352 ../archive_exclude/.hgsub
353 ../archive_exclude/.hgsubstate
353 ../archive_exclude/.hgsubstate
354 ../archive_exclude/main
354 ../archive_exclude/main
355 ../archive_exclude/sub1
355 ../archive_exclude/sub1
356 ../archive_exclude/sub1/.hgsub
356 ../archive_exclude/sub1/.hgsub
357 ../archive_exclude/sub1/.hgsubstate
357 ../archive_exclude/sub1/.hgsubstate
358 ../archive_exclude/sub1/sub1
358 ../archive_exclude/sub1/sub1
359 ../archive_exclude/sub1/sub2
359 ../archive_exclude/sub1/sub2
360 ../archive_exclude/sub1/sub2/sub2
360 ../archive_exclude/sub1/sub2/sub2
361
361
362 $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include
362 $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include
363 $ find ../archive_include | sort
363 $ find ../archive_include | sort
364 ../archive_include
364 ../archive_include
365 ../archive_include/sub1
365 ../archive_include/sub1
366 ../archive_include/sub1/sub2
366 ../archive_include/sub1/sub2
367 ../archive_include/sub1/sub2/folder
367 ../archive_include/sub1/sub2/folder
368 ../archive_include/sub1/sub2/folder/test.txt
368 ../archive_include/sub1/sub2/folder/test.txt
369 ../archive_include/sub1/sub2/test.txt
369 ../archive_include/sub1/sub2/test.txt
370
370
371 Check that deep archive works with largefiles (which overrides hgsubrepo impl)
371 Check that deep archive works with largefiles (which overrides hgsubrepo impl)
372 This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo
372 This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo
373 subrepos are archived properly.
373 subrepos are archived properly.
374 Note that add --large through a subrepo currently adds the file as a normal file
374 Note that add --large through a subrepo currently adds the file as a normal file
375
375
376 $ echo "large" > sub1/sub2/large.bin
376 $ echo "large" > sub1/sub2/large.bin
377 $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin
377 $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin
378 $ echo "large" > large.bin
378 $ echo "large" > large.bin
379 $ hg --config extensions.largefiles= add --large large.bin
379 $ hg --config extensions.largefiles= add --large large.bin
380 $ hg --config extensions.largefiles= ci -S -m "add large files"
380 $ hg --config extensions.largefiles= ci -S -m "add large files"
381 committing subrepository sub1
381 committing subrepository sub1
382 committing subrepository sub1/sub2 (glob)
382 committing subrepository sub1/sub2 (glob)
383
383
384 $ hg --config extensions.largefiles= archive -S ../archive_lf
384 $ hg --config extensions.largefiles= archive -S ../archive_lf
385 $ find ../archive_lf | sort
385 $ find ../archive_lf | sort
386 ../archive_lf
386 ../archive_lf
387 ../archive_lf/.hg_archival.txt
387 ../archive_lf/.hg_archival.txt
388 ../archive_lf/.hgsub
388 ../archive_lf/.hgsub
389 ../archive_lf/.hgsubstate
389 ../archive_lf/.hgsubstate
390 ../archive_lf/large.bin
390 ../archive_lf/large.bin
391 ../archive_lf/main
391 ../archive_lf/main
392 ../archive_lf/sub1
392 ../archive_lf/sub1
393 ../archive_lf/sub1/.hgsub
393 ../archive_lf/sub1/.hgsub
394 ../archive_lf/sub1/.hgsubstate
394 ../archive_lf/sub1/.hgsubstate
395 ../archive_lf/sub1/sub1
395 ../archive_lf/sub1/sub1
396 ../archive_lf/sub1/sub2
396 ../archive_lf/sub1/sub2
397 ../archive_lf/sub1/sub2/folder
397 ../archive_lf/sub1/sub2/folder
398 ../archive_lf/sub1/sub2/folder/test.txt
398 ../archive_lf/sub1/sub2/folder/test.txt
399 ../archive_lf/sub1/sub2/large.bin
399 ../archive_lf/sub1/sub2/large.bin
400 ../archive_lf/sub1/sub2/sub2
400 ../archive_lf/sub1/sub2/sub2
401 ../archive_lf/sub1/sub2/test.txt
401 ../archive_lf/sub1/sub2/test.txt
402 $ rm -rf ../archive_lf
402 $ rm -rf ../archive_lf
403
403
404 Exclude large files from main and sub-sub repo
404 Exclude large files from main and sub-sub repo
405
405
406 $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf
406 $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf
407 $ find ../archive_lf | sort
407 $ find ../archive_lf | sort
408 ../archive_lf
408 ../archive_lf
409 ../archive_lf/.hg_archival.txt
409 ../archive_lf/.hg_archival.txt
410 ../archive_lf/.hgsub
410 ../archive_lf/.hgsub
411 ../archive_lf/.hgsubstate
411 ../archive_lf/.hgsubstate
412 ../archive_lf/main
412 ../archive_lf/main
413 ../archive_lf/sub1
413 ../archive_lf/sub1
414 ../archive_lf/sub1/.hgsub
414 ../archive_lf/sub1/.hgsub
415 ../archive_lf/sub1/.hgsubstate
415 ../archive_lf/sub1/.hgsubstate
416 ../archive_lf/sub1/sub1
416 ../archive_lf/sub1/sub1
417 ../archive_lf/sub1/sub2
417 ../archive_lf/sub1/sub2
418 ../archive_lf/sub1/sub2/folder
418 ../archive_lf/sub1/sub2/folder
419 ../archive_lf/sub1/sub2/folder/test.txt
419 ../archive_lf/sub1/sub2/folder/test.txt
420 ../archive_lf/sub1/sub2/sub2
420 ../archive_lf/sub1/sub2/sub2
421 ../archive_lf/sub1/sub2/test.txt
421 ../archive_lf/sub1/sub2/test.txt
422 $ rm -rf ../archive_lf
422 $ rm -rf ../archive_lf
423
423
424 Exclude normal files from main and sub-sub repo
424 Exclude normal files from main and sub-sub repo
425
425
426 $ hg --config extensions.largefiles= archive -S -X '**.txt' -p '.' ../archive_lf.tgz
426 $ hg --config extensions.largefiles= archive -S -X '**.txt' -p '.' ../archive_lf.tgz
427 $ tar -tzf ../archive_lf.tgz | sort
427 $ tar -tzf ../archive_lf.tgz | sort
428 .hgsub
428 .hgsub
429 .hgsubstate
429 .hgsubstate
430 large.bin
430 large.bin
431 main
431 main
432 sub1/.hgsub
432 sub1/.hgsub
433 sub1/.hgsubstate
433 sub1/.hgsubstate
434 sub1/sub1
434 sub1/sub1
435 sub1/sub2/large.bin
435 sub1/sub2/large.bin
436 sub1/sub2/sub2
436 sub1/sub2/sub2
437
437
438 Include normal files from within a largefiles subrepo
438 Include normal files from within a largefiles subrepo
439
439
440 $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf
440 $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf
441 $ find ../archive_lf | sort
441 $ find ../archive_lf | sort
442 ../archive_lf
442 ../archive_lf
443 ../archive_lf/.hg_archival.txt
443 ../archive_lf/.hg_archival.txt
444 ../archive_lf/sub1
444 ../archive_lf/sub1
445 ../archive_lf/sub1/sub2
445 ../archive_lf/sub1/sub2
446 ../archive_lf/sub1/sub2/folder
446 ../archive_lf/sub1/sub2/folder
447 ../archive_lf/sub1/sub2/folder/test.txt
447 ../archive_lf/sub1/sub2/folder/test.txt
448 ../archive_lf/sub1/sub2/test.txt
448 ../archive_lf/sub1/sub2/test.txt
449 $ rm -rf ../archive_lf
449 $ rm -rf ../archive_lf
450
450
451 Include large files from within a largefiles subrepo
451 Include large files from within a largefiles subrepo
452
452
453 $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf
453 $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf
454 $ find ../archive_lf | sort
454 $ find ../archive_lf | sort
455 ../archive_lf
455 ../archive_lf
456 ../archive_lf/large.bin
456 ../archive_lf/large.bin
457 ../archive_lf/sub1
457 ../archive_lf/sub1
458 ../archive_lf/sub1/sub2
458 ../archive_lf/sub1/sub2
459 ../archive_lf/sub1/sub2/large.bin
459 ../archive_lf/sub1/sub2/large.bin
460 $ rm -rf ../archive_lf
460 $ rm -rf ../archive_lf
461
461
462 Find an exact largefile match in a largefiles subrepo
462 Find an exact largefile match in a largefiles subrepo
463
463
464 $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf
464 $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf
465 $ find ../archive_lf | sort
465 $ find ../archive_lf | sort
466 ../archive_lf
466 ../archive_lf
467 ../archive_lf/sub1
467 ../archive_lf/sub1
468 ../archive_lf/sub1/sub2
468 ../archive_lf/sub1/sub2
469 ../archive_lf/sub1/sub2/large.bin
469 ../archive_lf/sub1/sub2/large.bin
470 $ rm -rf ../archive_lf
470 $ rm -rf ../archive_lf
471
471
472 The local repo enables largefiles if a largefiles repo is cloned
472 The local repo enables largefiles if a largefiles repo is cloned
473 $ hg showconfig extensions
473 $ hg showconfig extensions
474 abort: repository requires features unknown to this Mercurial: largefiles!
474 abort: repository requires features unknown to this Mercurial: largefiles!
475 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
475 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
476 [255]
476 [255]
477 $ hg --config extensions.largefiles= clone -qU . ../lfclone
477 $ hg --config extensions.largefiles= clone -qU . ../lfclone
478 $ cat ../lfclone/.hg/hgrc
478 $ cat ../lfclone/.hg/hgrc
479 # example repository config (see "hg help config" for more info)
479 # example repository config (see "hg help config" for more info)
480 [paths]
480 [paths]
481 default = $TESTTMP/cloned (glob)
481 default = $TESTTMP/cloned (glob)
482
482
483 # path aliases to other clones of this repo in URLs or filesystem paths
483 # path aliases to other clones of this repo in URLs or filesystem paths
484 # (see "hg help config.paths" for more info)
484 # (see "hg help config.paths" for more info)
485 #
485 #
486 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
486 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
487 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
487 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
488 # my-clone = /home/jdoe/jdoes-clone
488 # my-clone = /home/jdoe/jdoes-clone
489
489
490 [ui]
490 [ui]
491 # name and email (local to this repository, optional), e.g.
491 # name and email (local to this repository, optional), e.g.
492 # username = Jane Doe <jdoe@example.com>
492 # username = Jane Doe <jdoe@example.com>
493
493
494 [extensions]
494 [extensions]
495 largefiles=
495 largefiles=
496
496
497 Find an exact match to a standin (should archive nothing)
497 Find an exact match to a standin (should archive nothing)
498 $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf
498 $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf
499 $ find ../archive_lf 2> /dev/null | sort
499 $ find ../archive_lf 2> /dev/null | sort
500
500
501 $ cat >> $HGRCPATH <<EOF
501 $ cat >> $HGRCPATH <<EOF
502 > [extensions]
502 > [extensions]
503 > largefiles=
503 > largefiles=
504 > [largefiles]
504 > [largefiles]
505 > patterns=glob:**.dat
505 > patterns=glob:**.dat
506 > EOF
506 > EOF
507
507
508 Test forget through a deep subrepo with the largefiles extension, both a
508 Test forget through a deep subrepo with the largefiles extension, both a
509 largefile and a normal file. Then a largefile that hasn't been committed yet.
509 largefile and a normal file. Then a largefile that hasn't been committed yet.
510 $ touch sub1/sub2/untracked.txt
510 $ touch sub1/sub2/untracked.txt
511 $ touch sub1/sub2/large.dat
511 $ touch sub1/sub2/large.dat
512 $ hg forget sub1/sub2/large.bin sub1/sub2/test.txt sub1/sub2/untracked.txt
512 $ hg forget sub1/sub2/large.bin sub1/sub2/test.txt sub1/sub2/untracked.txt
513 not removing sub1/sub2/untracked.txt: file is already untracked (glob)
513 not removing sub1/sub2/untracked.txt: file is already untracked (glob)
514 [1]
514 [1]
515 $ hg add --large --dry-run -v sub1/sub2/untracked.txt
515 $ hg add --large --dry-run -v sub1/sub2/untracked.txt
516 adding sub1/sub2/untracked.txt as a largefile (glob)
516 adding sub1/sub2/untracked.txt as a largefile (glob)
517 $ hg add --large -v sub1/sub2/untracked.txt
517 $ hg add --large -v sub1/sub2/untracked.txt
518 adding sub1/sub2/untracked.txt as a largefile (glob)
518 adding sub1/sub2/untracked.txt as a largefile (glob)
519 $ hg add --normal -v sub1/sub2/large.dat
519 $ hg add --normal -v sub1/sub2/large.dat
520 adding sub1/sub2/large.dat (glob)
520 adding sub1/sub2/large.dat (glob)
521 $ hg forget -v sub1/sub2/untracked.txt
521 $ hg forget -v sub1/sub2/untracked.txt
522 removing sub1/sub2/untracked.txt (glob)
522 removing sub1/sub2/untracked.txt (glob)
523 $ hg status -S
523 $ hg status -S
524 A sub1/sub2/large.dat
524 A sub1/sub2/large.dat
525 R sub1/sub2/large.bin
525 R sub1/sub2/large.bin
526 R sub1/sub2/test.txt
526 R sub1/sub2/test.txt
527 ? foo/bar/abc
527 ? foo/bar/abc
528 ? sub1/sub2/untracked.txt
528 ? sub1/sub2/untracked.txt
529 ? sub1/sub2/x.txt
529 ? sub1/sub2/x.txt
530 $ hg add sub1/sub2
530 $ hg add sub1/sub2
531
531
532 $ hg archive -S -r 'wdir()' ../wdir2
532 $ hg archive -S -r 'wdir()' ../wdir2
533 $ diff -r . ../wdir2 | egrep -v '\.hg$|^Common subdirectories:'
533 $ diff -r . ../wdir2 | egrep -v '\.hg$|^Common subdirectories:'
534 Only in ../wdir2: .hg_archival.txt
534 Only in ../wdir2: .hg_archival.txt
535 Only in .: .hglf
535 Only in .: .hglf
536 Only in .: foo
536 Only in .: foo
537 Only in ./sub1/sub2: large.bin
537 Only in ./sub1/sub2: large.bin
538 Only in ./sub1/sub2: test.txt
538 Only in ./sub1/sub2: test.txt
539 Only in ./sub1/sub2: untracked.txt
539 Only in ./sub1/sub2: untracked.txt
540 Only in ./sub1/sub2: x.txt
540 Only in ./sub1/sub2: x.txt
541 $ find ../wdir2 -type f | sort
541 $ find ../wdir2 -type f | sort
542 ../wdir2/.hg_archival.txt
542 ../wdir2/.hg_archival.txt
543 ../wdir2/.hgsub
543 ../wdir2/.hgsub
544 ../wdir2/.hgsubstate
544 ../wdir2/.hgsubstate
545 ../wdir2/large.bin
545 ../wdir2/large.bin
546 ../wdir2/main
546 ../wdir2/main
547 ../wdir2/sub1/.hgsub
547 ../wdir2/sub1/.hgsub
548 ../wdir2/sub1/.hgsubstate
548 ../wdir2/sub1/.hgsubstate
549 ../wdir2/sub1/sub1
549 ../wdir2/sub1/sub1
550 ../wdir2/sub1/sub2/folder/test.txt
550 ../wdir2/sub1/sub2/folder/test.txt
551 ../wdir2/sub1/sub2/large.dat
551 ../wdir2/sub1/sub2/large.dat
552 ../wdir2/sub1/sub2/sub2
552 ../wdir2/sub1/sub2/sub2
553 $ hg status -S -mac -n | sort
553 $ hg status -S -mac -n | sort
554 .hgsub
554 .hgsub
555 .hgsubstate
555 .hgsubstate
556 large.bin
556 large.bin
557 main
557 main
558 sub1/.hgsub
558 sub1/.hgsub
559 sub1/.hgsubstate
559 sub1/.hgsubstate
560 sub1/sub1
560 sub1/sub1
561 sub1/sub2/folder/test.txt
561 sub1/sub2/folder/test.txt
562 sub1/sub2/large.dat
562 sub1/sub2/large.dat
563 sub1/sub2/sub2
563 sub1/sub2/sub2
564
564
565 $ hg ci -Sqm 'forget testing'
565 $ hg ci -Sqm 'forget testing'
566
566
567 Test 'wdir()' modified file archiving with largefiles
567 Test 'wdir()' modified file archiving with largefiles
568 $ echo 'mod' > main
568 $ echo 'mod' > main
569 $ echo 'mod' > large.bin
569 $ echo 'mod' > large.bin
570 $ echo 'mod' > sub1/sub2/large.dat
570 $ echo 'mod' > sub1/sub2/large.dat
571 $ hg archive -S -r 'wdir()' ../wdir3
571 $ hg archive -S -r 'wdir()' ../wdir3
572 $ diff -r . ../wdir3 | egrep -v '\.hg$|^Common subdirectories'
572 $ diff -r . ../wdir3 | egrep -v '\.hg$|^Common subdirectories'
573 Only in ../wdir3: .hg_archival.txt
573 Only in ../wdir3: .hg_archival.txt
574 Only in .: .hglf
574 Only in .: .hglf
575 Only in .: foo
575 Only in .: foo
576 Only in ./sub1/sub2: large.bin
576 Only in ./sub1/sub2: large.bin
577 Only in ./sub1/sub2: test.txt
577 Only in ./sub1/sub2: test.txt
578 Only in ./sub1/sub2: untracked.txt
578 Only in ./sub1/sub2: untracked.txt
579 Only in ./sub1/sub2: x.txt
579 Only in ./sub1/sub2: x.txt
580 $ find ../wdir3 -type f | sort
580 $ find ../wdir3 -type f | sort
581 ../wdir3/.hg_archival.txt
581 ../wdir3/.hg_archival.txt
582 ../wdir3/.hgsub
582 ../wdir3/.hgsub
583 ../wdir3/.hgsubstate
583 ../wdir3/.hgsubstate
584 ../wdir3/large.bin
584 ../wdir3/large.bin
585 ../wdir3/main
585 ../wdir3/main
586 ../wdir3/sub1/.hgsub
586 ../wdir3/sub1/.hgsub
587 ../wdir3/sub1/.hgsubstate
587 ../wdir3/sub1/.hgsubstate
588 ../wdir3/sub1/sub1
588 ../wdir3/sub1/sub1
589 ../wdir3/sub1/sub2/folder/test.txt
589 ../wdir3/sub1/sub2/folder/test.txt
590 ../wdir3/sub1/sub2/large.dat
590 ../wdir3/sub1/sub2/large.dat
591 ../wdir3/sub1/sub2/sub2
591 ../wdir3/sub1/sub2/sub2
592 $ hg up -Cq
592 $ hg up -Cq
593
593
594 Test issue4330: commit a directory where only normal files have changed
594 Test issue4330: commit a directory where only normal files have changed
595 $ touch foo/bar/large.dat
595 $ touch foo/bar/large.dat
596 $ hg add --large foo/bar/large.dat
596 $ hg add --large foo/bar/large.dat
597 $ hg ci -m 'add foo/bar/large.dat'
597 $ hg ci -m 'add foo/bar/large.dat'
598 $ touch a.txt
598 $ touch a.txt
599 $ touch a.dat
599 $ touch a.dat
600 $ hg add -v foo/bar/abc a.txt a.dat
600 $ hg add -v foo/bar/abc a.txt a.dat
601 adding a.dat as a largefile
601 adding a.dat as a largefile
602 adding a.txt
602 adding a.txt
603 adding foo/bar/abc (glob)
603 adding foo/bar/abc (glob)
604 $ hg ci -m 'dir commit with only normal file deltas' foo/bar
604 $ hg ci -m 'dir commit with only normal file deltas' foo/bar
605 $ hg status
605 $ hg status
606 A a.dat
606 A a.dat
607 A a.txt
607 A a.txt
608
608
609 Test a directory commit with a changed largefile and a changed normal file
609 Test a directory commit with a changed largefile and a changed normal file
610 $ echo changed > foo/bar/large.dat
610 $ echo changed > foo/bar/large.dat
611 $ echo changed > foo/bar/abc
611 $ echo changed > foo/bar/abc
612 $ hg ci -m 'dir commit with normal and lf file deltas' foo
612 $ hg ci -m 'dir commit with normal and lf file deltas' foo
613 $ hg status
613 $ hg status
614 A a.dat
614 A a.dat
615 A a.txt
615 A a.txt
616
616
617 $ hg ci -m "add a.*"
617 $ hg ci -m "add a.*"
618 $ hg mv a.dat b.dat
618 $ hg mv a.dat b.dat
619 $ hg mv foo/bar/abc foo/bar/def
619 $ hg mv foo/bar/abc foo/bar/def
620 $ hg status -C
620 $ hg status -C
621 A b.dat
621 A b.dat
622 a.dat
622 a.dat
623 A foo/bar/def
623 A foo/bar/def
624 foo/bar/abc
624 foo/bar/abc
625 R a.dat
625 R a.dat
626 R foo/bar/abc
626 R foo/bar/abc
627
627
628 $ hg ci -m "move large and normal"
628 $ hg ci -m "move large and normal"
629 $ hg status -C --rev '.^' --rev .
629 $ hg status -C --rev '.^' --rev .
630 A b.dat
630 A b.dat
631 a.dat
631 a.dat
632 A foo/bar/def
632 A foo/bar/def
633 foo/bar/abc
633 foo/bar/abc
634 R a.dat
634 R a.dat
635 R foo/bar/abc
635 R foo/bar/abc
636
636
637
637
638 $ echo foo > main
638 $ echo foo > main
639 $ hg ci -m "mod parent only"
639 $ hg ci -m "mod parent only"
640 $ hg init sub3
640 $ hg init sub3
641 $ echo "sub3 = sub3" >> .hgsub
641 $ echo "sub3 = sub3" >> .hgsub
642 $ echo xyz > sub3/a.txt
642 $ echo xyz > sub3/a.txt
643 $ hg add sub3/a.txt
643 $ hg add sub3/a.txt
644 $ hg ci -Sm "add sub3"
644 $ hg ci -Sm "add sub3"
645 committing subrepository sub3
645 committing subrepository sub3
646 $ cat .hgsub | grep -v sub3 > .hgsub1
646 $ cat .hgsub | grep -v sub3 > .hgsub1
647 $ mv .hgsub1 .hgsub
647 $ mv .hgsub1 .hgsub
648 $ hg ci -m "remove sub3"
648 $ hg ci -m "remove sub3"
649
649
650 $ hg log -r "subrepo()" --style compact
650 $ hg log -r "subrepo()" --style compact
651 0 7f491f53a367 1970-01-01 00:00 +0000 test
651 0 7f491f53a367 1970-01-01 00:00 +0000 test
652 main import
652 main import
653
653
654 1 ffe6649062fe 1970-01-01 00:00 +0000 test
654 1 ffe6649062fe 1970-01-01 00:00 +0000 test
655 deep nested modif should trigger a commit
655 deep nested modif should trigger a commit
656
656
657 2 9bb10eebee29 1970-01-01 00:00 +0000 test
657 2 9bb10eebee29 1970-01-01 00:00 +0000 test
658 add test.txt
658 add test.txt
659
659
660 3 7c64f035294f 1970-01-01 00:00 +0000 test
660 3 7c64f035294f 1970-01-01 00:00 +0000 test
661 add large files
661 add large files
662
662
663 4 f734a59e2e35 1970-01-01 00:00 +0000 test
663 4 f734a59e2e35 1970-01-01 00:00 +0000 test
664 forget testing
664 forget testing
665
665
666 11 9685a22af5db 1970-01-01 00:00 +0000 test
666 11 9685a22af5db 1970-01-01 00:00 +0000 test
667 add sub3
667 add sub3
668
668
669 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
669 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
670 remove sub3
670 remove sub3
671
671
672 $ hg log -r "subrepo('sub3')" --style compact
672 $ hg log -r "subrepo('sub3')" --style compact
673 11 9685a22af5db 1970-01-01 00:00 +0000 test
673 11 9685a22af5db 1970-01-01 00:00 +0000 test
674 add sub3
674 add sub3
675
675
676 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
676 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
677 remove sub3
677 remove sub3
678
678
679 $ hg log -r "subrepo('bogus')" --style compact
679 $ hg log -r "subrepo('bogus')" --style compact
680
680
681
681
682 Test .hgsubstate in the R state
682 Test .hgsubstate in the R state
683
683
684 $ hg rm .hgsub .hgsubstate
684 $ hg rm .hgsub .hgsubstate
685 $ hg ci -m 'trash subrepo tracking'
685 $ hg ci -m 'trash subrepo tracking'
686
686
687 $ hg log -r "subrepo('re:sub\d+')" --style compact
687 $ hg log -r "subrepo('re:sub\d+')" --style compact
688 0 7f491f53a367 1970-01-01 00:00 +0000 test
688 0 7f491f53a367 1970-01-01 00:00 +0000 test
689 main import
689 main import
690
690
691 1 ffe6649062fe 1970-01-01 00:00 +0000 test
691 1 ffe6649062fe 1970-01-01 00:00 +0000 test
692 deep nested modif should trigger a commit
692 deep nested modif should trigger a commit
693
693
694 2 9bb10eebee29 1970-01-01 00:00 +0000 test
694 2 9bb10eebee29 1970-01-01 00:00 +0000 test
695 add test.txt
695 add test.txt
696
696
697 3 7c64f035294f 1970-01-01 00:00 +0000 test
697 3 7c64f035294f 1970-01-01 00:00 +0000 test
698 add large files
698 add large files
699
699
700 4 f734a59e2e35 1970-01-01 00:00 +0000 test
700 4 f734a59e2e35 1970-01-01 00:00 +0000 test
701 forget testing
701 forget testing
702
702
703 11 9685a22af5db 1970-01-01 00:00 +0000 test
703 11 9685a22af5db 1970-01-01 00:00 +0000 test
704 add sub3
704 add sub3
705
705
706 12 2e0485b475b9 1970-01-01 00:00 +0000 test
706 12 2e0485b475b9 1970-01-01 00:00 +0000 test
707 remove sub3
707 remove sub3
708
708
709 13[tip] a68b2c361653 1970-01-01 00:00 +0000 test
709 13[tip] a68b2c361653 1970-01-01 00:00 +0000 test
710 trash subrepo tracking
710 trash subrepo tracking
711
711
712
712
713 Restore the trashed subrepo tracking
713 Restore the trashed subrepo tracking
714
714
715 $ hg rollback -q
715 $ hg rollback -q
716 $ hg update -Cq .
716 $ hg update -Cq .
717
717
718 Interaction with extdiff, largefiles and subrepos
718 Interaction with extdiff, largefiles and subrepos
719
719
720 $ hg --config extensions.extdiff= extdiff -S
720 $ hg --config extensions.extdiff= extdiff -S
721
721
722 $ hg --config extensions.extdiff= extdiff -r '.^' -S
722 $ hg --config extensions.extdiff= extdiff -r '.^' -S
723 diff -Nru cloned.*/.hgsub cloned/.hgsub (glob)
723 diff -Nru cloned.*/.hgsub cloned/.hgsub (glob)
724 --- cloned.*/.hgsub * +0000 (glob)
724 --- cloned.*/.hgsub * (glob)
725 +++ cloned/.hgsub * +0000 (glob)
725 +++ cloned/.hgsub * (glob)
726 @@ -1,2 +1 @@
726 @@ -1,2 +1 @@
727 sub1 = ../sub1
727 sub1 = ../sub1
728 -sub3 = sub3
728 -sub3 = sub3
729 diff -Nru cloned.*/.hgsubstate cloned/.hgsubstate (glob)
729 diff -Nru cloned.*/.hgsubstate cloned/.hgsubstate (glob)
730 --- cloned.*/.hgsubstate * +0000 (glob)
730 --- cloned.*/.hgsubstate * (glob)
731 +++ cloned/.hgsubstate * +0000 (glob)
731 +++ cloned/.hgsubstate * (glob)
732 @@ -1,2 +1 @@
732 @@ -1,2 +1 @@
733 7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
733 7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
734 -b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
734 -b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
735 [1]
735 [1]
736
736
737 $ hg --config extensions.extdiff= extdiff -r 0 -r '.^' -S
737 $ hg --config extensions.extdiff= extdiff -r 0 -r '.^' -S
738 diff -Nru cloned.*/.hglf/b.dat cloned.*/.hglf/b.dat (glob)
738 diff -Nru cloned.*/.hglf/b.dat cloned.*/.hglf/b.dat (glob)
739 --- cloned.*/.hglf/b.dat * (glob)
739 --- cloned.*/.hglf/b.dat * (glob)
740 +++ cloned.*/.hglf/b.dat * (glob)
740 +++ cloned.*/.hglf/b.dat * (glob)
741 @@ -0,0 +1 @@
741 @@ -0,0 +1 @@
742 +da39a3ee5e6b4b0d3255bfef95601890afd80709
742 +da39a3ee5e6b4b0d3255bfef95601890afd80709
743 diff -Nru cloned.*/.hglf/foo/bar/large.dat cloned.*/.hglf/foo/bar/large.dat (glob)
743 diff -Nru cloned.*/.hglf/foo/bar/large.dat cloned.*/.hglf/foo/bar/large.dat (glob)
744 --- cloned.*/.hglf/foo/bar/large.dat * (glob)
744 --- cloned.*/.hglf/foo/bar/large.dat * (glob)
745 +++ cloned.*/.hglf/foo/bar/large.dat * (glob)
745 +++ cloned.*/.hglf/foo/bar/large.dat * (glob)
746 @@ -0,0 +1 @@
746 @@ -0,0 +1 @@
747 +2f6933b5ee0f5fdd823d9717d8729f3c2523811b
747 +2f6933b5ee0f5fdd823d9717d8729f3c2523811b
748 diff -Nru cloned.*/.hglf/large.bin cloned.*/.hglf/large.bin (glob)
748 diff -Nru cloned.*/.hglf/large.bin cloned.*/.hglf/large.bin (glob)
749 --- cloned.*/.hglf/large.bin * (glob)
749 --- cloned.*/.hglf/large.bin * (glob)
750 +++ cloned.*/.hglf/large.bin * (glob)
750 +++ cloned.*/.hglf/large.bin * (glob)
751 @@ -0,0 +1 @@
751 @@ -0,0 +1 @@
752 +7f7097b041ccf68cc5561e9600da4655d21c6d18
752 +7f7097b041ccf68cc5561e9600da4655d21c6d18
753 diff -Nru cloned.*/.hgsub cloned.*/.hgsub (glob)
753 diff -Nru cloned.*/.hgsub cloned.*/.hgsub (glob)
754 --- cloned.*/.hgsub * (glob)
754 --- cloned.*/.hgsub * (glob)
755 +++ cloned.*/.hgsub * (glob)
755 +++ cloned.*/.hgsub * (glob)
756 @@ -1 +1,2 @@
756 @@ -1 +1,2 @@
757 sub1 = ../sub1
757 sub1 = ../sub1
758 +sub3 = sub3
758 +sub3 = sub3
759 diff -Nru cloned.*/.hgsubstate cloned.*/.hgsubstate (glob)
759 diff -Nru cloned.*/.hgsubstate cloned.*/.hgsubstate (glob)
760 --- cloned.*/.hgsubstate * (glob)
760 --- cloned.*/.hgsubstate * (glob)
761 +++ cloned.*/.hgsubstate * (glob)
761 +++ cloned.*/.hgsubstate * (glob)
762 @@ -1 +1,2 @@
762 @@ -1 +1,2 @@
763 -fc3b4ce2696f7741438c79207583768f2ce6b0dd sub1
763 -fc3b4ce2696f7741438c79207583768f2ce6b0dd sub1
764 +7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
764 +7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
765 +b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
765 +b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
766 diff -Nru cloned.*/foo/bar/def cloned.*/foo/bar/def (glob)
766 diff -Nru cloned.*/foo/bar/def cloned.*/foo/bar/def (glob)
767 --- cloned.*/foo/bar/def * (glob)
767 --- cloned.*/foo/bar/def * (glob)
768 +++ cloned.*/foo/bar/def * (glob)
768 +++ cloned.*/foo/bar/def * (glob)
769 @@ -0,0 +1 @@
769 @@ -0,0 +1 @@
770 +changed
770 +changed
771 diff -Nru cloned.*/main cloned.*/main (glob)
771 diff -Nru cloned.*/main cloned.*/main (glob)
772 --- cloned.*/main * (glob)
772 --- cloned.*/main * (glob)
773 +++ cloned.*/main * (glob)
773 +++ cloned.*/main * (glob)
774 @@ -1 +1 @@
774 @@ -1 +1 @@
775 -main
775 -main
776 +foo
776 +foo
777 diff -Nru cloned.*/sub1/.hgsubstate cloned.*/sub1/.hgsubstate (glob)
777 diff -Nru cloned.*/sub1/.hgsubstate cloned.*/sub1/.hgsubstate (glob)
778 --- cloned.*/sub1/.hgsubstate * (glob)
778 --- cloned.*/sub1/.hgsubstate * (glob)
779 +++ cloned.*/sub1/.hgsubstate * (glob)
779 +++ cloned.*/sub1/.hgsubstate * (glob)
780 @@ -1 +1 @@
780 @@ -1 +1 @@
781 -c57a0840e3badd667ef3c3ef65471609acb2ba3c sub2
781 -c57a0840e3badd667ef3c3ef65471609acb2ba3c sub2
782 +c77908c81ccea3794a896c79e98b0e004aee2e9e sub2
782 +c77908c81ccea3794a896c79e98b0e004aee2e9e sub2
783 diff -Nru cloned.*/sub1/sub2/folder/test.txt cloned.*/sub1/sub2/folder/test.txt (glob)
783 diff -Nru cloned.*/sub1/sub2/folder/test.txt cloned.*/sub1/sub2/folder/test.txt (glob)
784 --- cloned.*/sub1/sub2/folder/test.txt * (glob)
784 --- cloned.*/sub1/sub2/folder/test.txt * (glob)
785 +++ cloned.*/sub1/sub2/folder/test.txt * (glob)
785 +++ cloned.*/sub1/sub2/folder/test.txt * (glob)
786 @@ -0,0 +1 @@
786 @@ -0,0 +1 @@
787 +subfolder
787 +subfolder
788 diff -Nru cloned.*/sub1/sub2/sub2 cloned.*/sub1/sub2/sub2 (glob)
788 diff -Nru cloned.*/sub1/sub2/sub2 cloned.*/sub1/sub2/sub2 (glob)
789 --- cloned.*/sub1/sub2/sub2 * (glob)
789 --- cloned.*/sub1/sub2/sub2 * (glob)
790 +++ cloned.*/sub1/sub2/sub2 * (glob)
790 +++ cloned.*/sub1/sub2/sub2 * (glob)
791 @@ -1 +1 @@
791 @@ -1 +1 @@
792 -sub2
792 -sub2
793 +modified
793 +modified
794 diff -Nru cloned.*/sub3/a.txt cloned.*/sub3/a.txt (glob)
794 diff -Nru cloned.*/sub3/a.txt cloned.*/sub3/a.txt (glob)
795 --- cloned.*/sub3/a.txt * (glob)
795 --- cloned.*/sub3/a.txt * (glob)
796 +++ cloned.*/sub3/a.txt * (glob)
796 +++ cloned.*/sub3/a.txt * (glob)
797 @@ -0,0 +1 @@
797 @@ -0,0 +1 @@
798 +xyz
798 +xyz
799 [1]
799 [1]
800
800
801 $ echo mod > sub1/sub2/sub2
801 $ echo mod > sub1/sub2/sub2
802 $ hg --config extensions.extdiff= extdiff -S
802 $ hg --config extensions.extdiff= extdiff -S
803 --- */cloned.*/sub1/sub2/sub2 * (glob)
803 --- */cloned.*/sub1/sub2/sub2 * (glob)
804 +++ */cloned/sub1/sub2/sub2 * (glob)
804 +++ */cloned/sub1/sub2/sub2 * (glob)
805 @@ -1 +1 @@
805 @@ -1 +1 @@
806 -modified
806 -modified
807 +mod
807 +mod
808 [1]
808 [1]
809
809
810 $ cd ..
810 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now