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