##// END OF EJS Templates
simplestore: use a custom store for the simple store repo...
Gregory Szorc -
r37433:c2c8962a default
parent child Browse files
Show More
@@ -1,772 +1,777 b''
1 1 from __future__ import absolute_import
2 2
3 3 import errno
4 4 import os
5 5 import re
6 6 import socket
7 7 import stat
8 8 import subprocess
9 9 import sys
10 10 import tempfile
11 11
12 12 tempprefix = 'hg-hghave-'
13 13
14 14 checks = {
15 15 "true": (lambda: True, "yak shaving"),
16 16 "false": (lambda: False, "nail clipper"),
17 17 }
18 18
19 19 def check(name, desc):
20 20 """Registers a check function for a feature."""
21 21 def decorator(func):
22 22 checks[name] = (func, desc)
23 23 return func
24 24 return decorator
25 25
26 26 def checkvers(name, desc, vers):
27 27 """Registers a check function for each of a series of versions.
28 28
29 29 vers can be a list or an iterator"""
30 30 def decorator(func):
31 31 def funcv(v):
32 32 def f():
33 33 return func(v)
34 34 return f
35 35 for v in vers:
36 36 v = str(v)
37 37 f = funcv(v)
38 38 checks['%s%s' % (name, v.replace('.', ''))] = (f, desc % v)
39 39 return func
40 40 return decorator
41 41
42 42 def checkfeatures(features):
43 43 result = {
44 44 'error': [],
45 45 'missing': [],
46 46 'skipped': [],
47 47 }
48 48
49 49 for feature in features:
50 50 negate = feature.startswith('no-')
51 51 if negate:
52 52 feature = feature[3:]
53 53
54 54 if feature not in checks:
55 55 result['missing'].append(feature)
56 56 continue
57 57
58 58 check, desc = checks[feature]
59 59 try:
60 60 available = check()
61 61 except Exception:
62 62 result['error'].append('hghave check failed: %s' % feature)
63 63 continue
64 64
65 65 if not negate and not available:
66 66 result['skipped'].append('missing feature: %s' % desc)
67 67 elif negate and available:
68 68 result['skipped'].append('system supports %s' % desc)
69 69
70 70 return result
71 71
72 72 def require(features):
73 73 """Require that features are available, exiting if not."""
74 74 result = checkfeatures(features)
75 75
76 76 for missing in result['missing']:
77 77 sys.stderr.write('skipped: unknown feature: %s\n' % missing)
78 78 for msg in result['skipped']:
79 79 sys.stderr.write('skipped: %s\n' % msg)
80 80 for msg in result['error']:
81 81 sys.stderr.write('%s\n' % msg)
82 82
83 83 if result['missing']:
84 84 sys.exit(2)
85 85
86 86 if result['skipped'] or result['error']:
87 87 sys.exit(1)
88 88
89 89 def matchoutput(cmd, regexp, ignorestatus=False):
90 90 """Return the match object if cmd executes successfully and its output
91 91 is matched by the supplied regular expression.
92 92 """
93 93 r = re.compile(regexp)
94 94 try:
95 95 p = subprocess.Popen(
96 96 cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
97 97 except OSError as e:
98 98 if e.errno != errno.ENOENT:
99 99 raise
100 100 ret = -1
101 101 ret = p.wait()
102 102 s = p.stdout.read()
103 103 return (ignorestatus or not ret) and r.search(s)
104 104
105 105 @check("baz", "GNU Arch baz client")
106 106 def has_baz():
107 107 return matchoutput('baz --version 2>&1', br'baz Bazaar version')
108 108
109 109 @check("bzr", "Canonical's Bazaar client")
110 110 def has_bzr():
111 111 try:
112 112 import bzrlib
113 113 import bzrlib.bzrdir
114 114 import bzrlib.errors
115 115 import bzrlib.revision
116 116 import bzrlib.revisionspec
117 117 bzrlib.revisionspec.RevisionSpec
118 118 return bzrlib.__doc__ is not None
119 119 except (AttributeError, ImportError):
120 120 return False
121 121
122 122 @checkvers("bzr", "Canonical's Bazaar client >= %s", (1.14,))
123 123 def has_bzr_range(v):
124 124 major, minor = v.split('.')[0:2]
125 125 try:
126 126 import bzrlib
127 127 return (bzrlib.__doc__ is not None
128 128 and bzrlib.version_info[:2] >= (int(major), int(minor)))
129 129 except ImportError:
130 130 return False
131 131
132 132 @check("chg", "running with chg")
133 133 def has_chg():
134 134 return 'CHGHG' in os.environ
135 135
136 136 @check("cvs", "cvs client/server")
137 137 def has_cvs():
138 138 re = br'Concurrent Versions System.*?server'
139 139 return matchoutput('cvs --version 2>&1', re) and not has_msys()
140 140
141 141 @check("cvs112", "cvs client/server 1.12.* (not cvsnt)")
142 142 def has_cvs112():
143 143 re = br'Concurrent Versions System \(CVS\) 1.12.*?server'
144 144 return matchoutput('cvs --version 2>&1', re) and not has_msys()
145 145
146 146 @check("cvsnt", "cvsnt client/server")
147 147 def has_cvsnt():
148 148 re = br'Concurrent Versions System \(CVSNT\) (\d+).(\d+).*\(client/server\)'
149 149 return matchoutput('cvsnt --version 2>&1', re)
150 150
151 151 @check("darcs", "darcs client")
152 152 def has_darcs():
153 153 return matchoutput('darcs --version', br'\b2\.([2-9]|\d{2})', True)
154 154
155 155 @check("mtn", "monotone client (>= 1.0)")
156 156 def has_mtn():
157 157 return matchoutput('mtn --version', br'monotone', True) and not matchoutput(
158 158 'mtn --version', br'monotone 0\.', True)
159 159
160 160 @check("eol-in-paths", "end-of-lines in paths")
161 161 def has_eol_in_paths():
162 162 try:
163 163 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r')
164 164 os.close(fd)
165 165 os.remove(path)
166 166 return True
167 167 except (IOError, OSError):
168 168 return False
169 169
170 170 @check("execbit", "executable bit")
171 171 def has_executablebit():
172 172 try:
173 173 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
174 174 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
175 175 try:
176 176 os.close(fh)
177 177 m = os.stat(fn).st_mode & 0o777
178 178 new_file_has_exec = m & EXECFLAGS
179 179 os.chmod(fn, m ^ EXECFLAGS)
180 180 exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0o777) == m)
181 181 finally:
182 182 os.unlink(fn)
183 183 except (IOError, OSError):
184 184 # we don't care, the user probably won't be able to commit anyway
185 185 return False
186 186 return not (new_file_has_exec or exec_flags_cannot_flip)
187 187
188 188 @check("icasefs", "case insensitive file system")
189 189 def has_icasefs():
190 190 # Stolen from mercurial.util
191 191 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
192 192 os.close(fd)
193 193 try:
194 194 s1 = os.stat(path)
195 195 d, b = os.path.split(path)
196 196 p2 = os.path.join(d, b.upper())
197 197 if path == p2:
198 198 p2 = os.path.join(d, b.lower())
199 199 try:
200 200 s2 = os.stat(p2)
201 201 return s2 == s1
202 202 except OSError:
203 203 return False
204 204 finally:
205 205 os.remove(path)
206 206
207 207 @check("fifo", "named pipes")
208 208 def has_fifo():
209 209 if getattr(os, "mkfifo", None) is None:
210 210 return False
211 211 name = tempfile.mktemp(dir='.', prefix=tempprefix)
212 212 try:
213 213 os.mkfifo(name)
214 214 os.unlink(name)
215 215 return True
216 216 except OSError:
217 217 return False
218 218
219 219 @check("killdaemons", 'killdaemons.py support')
220 220 def has_killdaemons():
221 221 return True
222 222
223 223 @check("cacheable", "cacheable filesystem")
224 224 def has_cacheable_fs():
225 225 from mercurial import util
226 226
227 227 fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix)
228 228 os.close(fd)
229 229 try:
230 230 return util.cachestat(path).cacheable()
231 231 finally:
232 232 os.remove(path)
233 233
234 234 @check("lsprof", "python lsprof module")
235 235 def has_lsprof():
236 236 try:
237 237 import _lsprof
238 238 _lsprof.Profiler # silence unused import warning
239 239 return True
240 240 except ImportError:
241 241 return False
242 242
243 243 def gethgversion():
244 244 m = matchoutput('hg --version --quiet 2>&1', br'(\d+)\.(\d+)')
245 245 if not m:
246 246 return (0, 0)
247 247 return (int(m.group(1)), int(m.group(2)))
248 248
249 249 @checkvers("hg", "Mercurial >= %s",
250 250 list([(1.0 * x) / 10 for x in range(9, 99)]))
251 251 def has_hg_range(v):
252 252 major, minor = v.split('.')[0:2]
253 253 return gethgversion() >= (int(major), int(minor))
254 254
255 255 @check("hg08", "Mercurial >= 0.8")
256 256 def has_hg08():
257 257 if checks["hg09"][0]():
258 258 return True
259 259 return matchoutput('hg help annotate 2>&1', '--date')
260 260
261 261 @check("hg07", "Mercurial >= 0.7")
262 262 def has_hg07():
263 263 if checks["hg08"][0]():
264 264 return True
265 265 return matchoutput('hg --version --quiet 2>&1', 'Mercurial Distributed SCM')
266 266
267 267 @check("hg06", "Mercurial >= 0.6")
268 268 def has_hg06():
269 269 if checks["hg07"][0]():
270 270 return True
271 271 return matchoutput('hg --version --quiet 2>&1', 'Mercurial version')
272 272
273 273 @check("gettext", "GNU Gettext (msgfmt)")
274 274 def has_gettext():
275 275 return matchoutput('msgfmt --version', br'GNU gettext-tools')
276 276
277 277 @check("git", "git command line client")
278 278 def has_git():
279 279 return matchoutput('git --version 2>&1', br'^git version')
280 280
281 281 def getgitversion():
282 282 m = matchoutput('git --version 2>&1', br'git version (\d+)\.(\d+)')
283 283 if not m:
284 284 return (0, 0)
285 285 return (int(m.group(1)), int(m.group(2)))
286 286
287 287 # https://github.com/git-lfs/lfs-test-server
288 288 @check("lfs-test-server", "git-lfs test server")
289 289 def has_lfsserver():
290 290 exe = 'lfs-test-server'
291 291 if has_windows():
292 292 exe = 'lfs-test-server.exe'
293 293 return any(
294 294 os.access(os.path.join(path, exe), os.X_OK)
295 295 for path in os.environ["PATH"].split(os.pathsep)
296 296 )
297 297
298 298 @checkvers("git", "git client (with ext::sh support) version >= %s", (1.9,))
299 299 def has_git_range(v):
300 300 major, minor = v.split('.')[0:2]
301 301 return getgitversion() >= (int(major), int(minor))
302 302
303 303 @check("docutils", "Docutils text processing library")
304 304 def has_docutils():
305 305 try:
306 306 import docutils.core
307 307 docutils.core.publish_cmdline # silence unused import
308 308 return True
309 309 except ImportError:
310 310 return False
311 311
312 312 def getsvnversion():
313 313 m = matchoutput('svn --version --quiet 2>&1', br'^(\d+)\.(\d+)')
314 314 if not m:
315 315 return (0, 0)
316 316 return (int(m.group(1)), int(m.group(2)))
317 317
318 318 @checkvers("svn", "subversion client and admin tools >= %s", (1.3, 1.5))
319 319 def has_svn_range(v):
320 320 major, minor = v.split('.')[0:2]
321 321 return getsvnversion() >= (int(major), int(minor))
322 322
323 323 @check("svn", "subversion client and admin tools")
324 324 def has_svn():
325 325 return matchoutput('svn --version 2>&1', br'^svn, version') and \
326 326 matchoutput('svnadmin --version 2>&1', br'^svnadmin, version')
327 327
328 328 @check("svn-bindings", "subversion python bindings")
329 329 def has_svn_bindings():
330 330 try:
331 331 import svn.core
332 332 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
333 333 if version < (1, 4):
334 334 return False
335 335 return True
336 336 except ImportError:
337 337 return False
338 338
339 339 @check("p4", "Perforce server and client")
340 340 def has_p4():
341 341 return (matchoutput('p4 -V', br'Rev\. P4/') and
342 342 matchoutput('p4d -V', br'Rev\. P4D/'))
343 343
344 344 @check("symlink", "symbolic links")
345 345 def has_symlink():
346 346 if getattr(os, "symlink", None) is None:
347 347 return False
348 348 name = tempfile.mktemp(dir='.', prefix=tempprefix)
349 349 try:
350 350 os.symlink(".", name)
351 351 os.unlink(name)
352 352 return True
353 353 except (OSError, AttributeError):
354 354 return False
355 355
356 356 @check("hardlink", "hardlinks")
357 357 def has_hardlink():
358 358 from mercurial import util
359 359 fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix)
360 360 os.close(fh)
361 361 name = tempfile.mktemp(dir='.', prefix=tempprefix)
362 362 try:
363 363 util.oslink(fn, name)
364 364 os.unlink(name)
365 365 return True
366 366 except OSError:
367 367 return False
368 368 finally:
369 369 os.unlink(fn)
370 370
371 371 @check("hardlink-whitelisted", "hardlinks on whitelisted filesystems")
372 372 def has_hardlink_whitelisted():
373 373 from mercurial import util
374 374 try:
375 375 fstype = util.getfstype(b'.')
376 376 except OSError:
377 377 return False
378 378 return fstype in util._hardlinkfswhitelist
379 379
380 380 @check("rmcwd", "can remove current working directory")
381 381 def has_rmcwd():
382 382 ocwd = os.getcwd()
383 383 temp = tempfile.mkdtemp(dir='.', prefix=tempprefix)
384 384 try:
385 385 os.chdir(temp)
386 386 # On Linux, 'rmdir .' isn't allowed, but the other names are okay.
387 387 # On Solaris and Windows, the cwd can't be removed by any names.
388 388 os.rmdir(os.getcwd())
389 389 return True
390 390 except OSError:
391 391 return False
392 392 finally:
393 393 os.chdir(ocwd)
394 394 # clean up temp dir on platforms where cwd can't be removed
395 395 try:
396 396 os.rmdir(temp)
397 397 except OSError:
398 398 pass
399 399
400 400 @check("tla", "GNU Arch tla client")
401 401 def has_tla():
402 402 return matchoutput('tla --version 2>&1', br'The GNU Arch Revision')
403 403
404 404 @check("gpg", "gpg client")
405 405 def has_gpg():
406 406 return matchoutput('gpg --version 2>&1', br'GnuPG')
407 407
408 408 @check("gpg2", "gpg client v2")
409 409 def has_gpg2():
410 410 return matchoutput('gpg --version 2>&1', br'GnuPG[^0-9]+2\.')
411 411
412 412 @check("gpg21", "gpg client v2.1+")
413 413 def has_gpg21():
414 414 return matchoutput('gpg --version 2>&1', br'GnuPG[^0-9]+2\.(?!0)')
415 415
416 416 @check("unix-permissions", "unix-style permissions")
417 417 def has_unix_permissions():
418 418 d = tempfile.mkdtemp(dir='.', prefix=tempprefix)
419 419 try:
420 420 fname = os.path.join(d, 'foo')
421 421 for umask in (0o77, 0o07, 0o22):
422 422 os.umask(umask)
423 423 f = open(fname, 'w')
424 424 f.close()
425 425 mode = os.stat(fname).st_mode
426 426 os.unlink(fname)
427 427 if mode & 0o777 != ~umask & 0o666:
428 428 return False
429 429 return True
430 430 finally:
431 431 os.rmdir(d)
432 432
433 433 @check("unix-socket", "AF_UNIX socket family")
434 434 def has_unix_socket():
435 435 return getattr(socket, 'AF_UNIX', None) is not None
436 436
437 437 @check("root", "root permissions")
438 438 def has_root():
439 439 return getattr(os, 'geteuid', None) and os.geteuid() == 0
440 440
441 441 @check("pyflakes", "Pyflakes python linter")
442 442 def has_pyflakes():
443 443 return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"",
444 444 br"<stdin>:1: 're' imported but unused",
445 445 True)
446 446
447 447 @check("pylint", "Pylint python linter")
448 448 def has_pylint():
449 449 return matchoutput("pylint --help",
450 450 br"Usage: pylint",
451 451 True)
452 452
453 453 @check("clang-format", "clang-format C code formatter")
454 454 def has_clang_format():
455 455 return matchoutput("clang-format --help",
456 456 br"^OVERVIEW: A tool to format C/C\+\+[^ ]+ code.")
457 457
458 458 @check("jshint", "JSHint static code analysis tool")
459 459 def has_jshint():
460 460 return matchoutput("jshint --version 2>&1", br"jshint v")
461 461
462 462 @check("pygments", "Pygments source highlighting library")
463 463 def has_pygments():
464 464 try:
465 465 import pygments
466 466 pygments.highlight # silence unused import warning
467 467 return True
468 468 except ImportError:
469 469 return False
470 470
471 471 @check("outer-repo", "outer repo")
472 472 def has_outer_repo():
473 473 # failing for other reasons than 'no repo' imply that there is a repo
474 474 return not matchoutput('hg root 2>&1',
475 475 br'abort: no repository found', True)
476 476
477 477 @check("ssl", "ssl module available")
478 478 def has_ssl():
479 479 try:
480 480 import ssl
481 481 ssl.CERT_NONE
482 482 return True
483 483 except ImportError:
484 484 return False
485 485
486 486 @check("sslcontext", "python >= 2.7.9 ssl")
487 487 def has_sslcontext():
488 488 try:
489 489 import ssl
490 490 ssl.SSLContext
491 491 return True
492 492 except (ImportError, AttributeError):
493 493 return False
494 494
495 495 @check("defaultcacerts", "can verify SSL certs by system's CA certs store")
496 496 def has_defaultcacerts():
497 497 from mercurial import sslutil, ui as uimod
498 498 ui = uimod.ui.load()
499 499 return sslutil._defaultcacerts(ui) or sslutil._canloaddefaultcerts
500 500
501 501 @check("defaultcacertsloaded", "detected presence of loaded system CA certs")
502 502 def has_defaultcacertsloaded():
503 503 import ssl
504 504 from mercurial import sslutil, ui as uimod
505 505
506 506 if not has_defaultcacerts():
507 507 return False
508 508 if not has_sslcontext():
509 509 return False
510 510
511 511 ui = uimod.ui.load()
512 512 cafile = sslutil._defaultcacerts(ui)
513 513 ctx = ssl.create_default_context()
514 514 if cafile:
515 515 ctx.load_verify_locations(cafile=cafile)
516 516 else:
517 517 ctx.load_default_certs()
518 518
519 519 return len(ctx.get_ca_certs()) > 0
520 520
521 521 @check("tls1.2", "TLS 1.2 protocol support")
522 522 def has_tls1_2():
523 523 from mercurial import sslutil
524 524 return 'tls1.2' in sslutil.supportedprotocols
525 525
526 526 @check("windows", "Windows")
527 527 def has_windows():
528 528 return os.name == 'nt'
529 529
530 530 @check("system-sh", "system() uses sh")
531 531 def has_system_sh():
532 532 return os.name != 'nt'
533 533
534 534 @check("serve", "platform and python can manage 'hg serve -d'")
535 535 def has_serve():
536 536 return True
537 537
538 538 @check("test-repo", "running tests from repository")
539 539 def has_test_repo():
540 540 t = os.environ["TESTDIR"]
541 541 return os.path.isdir(os.path.join(t, "..", ".hg"))
542 542
543 543 @check("tic", "terminfo compiler and curses module")
544 544 def has_tic():
545 545 try:
546 546 import curses
547 547 curses.COLOR_BLUE
548 548 return matchoutput('test -x "`which tic`"', br'')
549 549 except ImportError:
550 550 return False
551 551
552 552 @check("msys", "Windows with MSYS")
553 553 def has_msys():
554 554 return os.getenv('MSYSTEM')
555 555
556 556 @check("aix", "AIX")
557 557 def has_aix():
558 558 return sys.platform.startswith("aix")
559 559
560 560 @check("osx", "OS X")
561 561 def has_osx():
562 562 return sys.platform == 'darwin'
563 563
564 564 @check("osxpackaging", "OS X packaging tools")
565 565 def has_osxpackaging():
566 566 try:
567 567 return (matchoutput('pkgbuild', br'Usage: pkgbuild ', ignorestatus=1)
568 568 and matchoutput(
569 569 'productbuild', br'Usage: productbuild ',
570 570 ignorestatus=1)
571 571 and matchoutput('lsbom', br'Usage: lsbom', ignorestatus=1)
572 572 and matchoutput(
573 573 'xar --help', br'Usage: xar', ignorestatus=1))
574 574 except ImportError:
575 575 return False
576 576
577 577 @check('linuxormacos', 'Linux or MacOS')
578 578 def has_linuxormacos():
579 579 # This isn't a perfect test for MacOS. But it is sufficient for our needs.
580 580 return sys.platform.startswith(('linux', 'darwin'))
581 581
582 582 @check("docker", "docker support")
583 583 def has_docker():
584 584 pat = br'A self-sufficient runtime for'
585 585 if matchoutput('docker --help', pat):
586 586 if 'linux' not in sys.platform:
587 587 # TODO: in theory we should be able to test docker-based
588 588 # package creation on non-linux using boot2docker, but in
589 589 # practice that requires extra coordination to make sure
590 590 # $TESTTEMP is going to be visible at the same path to the
591 591 # boot2docker VM. If we figure out how to verify that, we
592 592 # can use the following instead of just saying False:
593 593 # return 'DOCKER_HOST' in os.environ
594 594 return False
595 595
596 596 return True
597 597 return False
598 598
599 599 @check("debhelper", "debian packaging tools")
600 600 def has_debhelper():
601 601 # Some versions of dpkg say `dpkg', some say 'dpkg' (` vs ' on the first
602 602 # quote), so just accept anything in that spot.
603 603 dpkg = matchoutput('dpkg --version',
604 604 br"Debian .dpkg' package management program")
605 605 dh = matchoutput('dh --help',
606 606 br'dh is a part of debhelper.', ignorestatus=True)
607 607 dh_py2 = matchoutput('dh_python2 --help',
608 608 br'other supported Python versions')
609 609 # debuild comes from the 'devscripts' package, though you might want
610 610 # the 'build-debs' package instead, which has a dependency on devscripts.
611 611 debuild = matchoutput('debuild --help',
612 612 br'to run debian/rules with given parameter')
613 613 return dpkg and dh and dh_py2 and debuild
614 614
615 615 @check("debdeps",
616 616 "debian build dependencies (run dpkg-checkbuilddeps in contrib/)")
617 617 def has_debdeps():
618 618 # just check exit status (ignoring output)
619 619 path = '%s/../contrib/debian/control' % os.environ['TESTDIR']
620 620 return matchoutput('dpkg-checkbuilddeps %s' % path, br'')
621 621
622 622 @check("demandimport", "demandimport enabled")
623 623 def has_demandimport():
624 624 # chg disables demandimport intentionally for performance wins.
625 625 return ((not has_chg()) and os.environ.get('HGDEMANDIMPORT') != 'disable')
626 626
627 627 @check("py3k", "running with Python 3.x")
628 628 def has_py3k():
629 629 return 3 == sys.version_info[0]
630 630
631 631 @check("py3exe", "a Python 3.x interpreter is available")
632 632 def has_python3exe():
633 633 return 'PYTHON3' in os.environ
634 634
635 635 @check("py3pygments", "Pygments available on Python 3.x")
636 636 def has_py3pygments():
637 637 if has_py3k():
638 638 return has_pygments()
639 639 elif has_python3exe():
640 640 # just check exit status (ignoring output)
641 641 py3 = os.environ['PYTHON3']
642 642 return matchoutput('%s -c "import pygments"' % py3, br'')
643 643 return False
644 644
645 645 @check("pure", "running with pure Python code")
646 646 def has_pure():
647 647 return any([
648 648 os.environ.get("HGMODULEPOLICY") == "py",
649 649 os.environ.get("HGTEST_RUN_TESTS_PURE") == "--pure",
650 650 ])
651 651
652 652 @check("slow", "allow slow tests (use --allow-slow-tests)")
653 653 def has_slow():
654 654 return os.environ.get('HGTEST_SLOW') == 'slow'
655 655
656 656 @check("hypothesis", "Hypothesis automated test generation")
657 657 def has_hypothesis():
658 658 try:
659 659 import hypothesis
660 660 hypothesis.given
661 661 return True
662 662 except ImportError:
663 663 return False
664 664
665 665 @check("unziplinks", "unzip(1) understands and extracts symlinks")
666 666 def unzip_understands_symlinks():
667 667 return matchoutput('unzip --help', br'Info-ZIP')
668 668
669 669 @check("zstd", "zstd Python module available")
670 670 def has_zstd():
671 671 try:
672 672 import mercurial.zstd
673 673 mercurial.zstd.__version__
674 674 return True
675 675 except ImportError:
676 676 return False
677 677
678 678 @check("devfull", "/dev/full special file")
679 679 def has_dev_full():
680 680 return os.path.exists('/dev/full')
681 681
682 682 @check("virtualenv", "Python virtualenv support")
683 683 def has_virtualenv():
684 684 try:
685 685 import virtualenv
686 686 virtualenv.ACTIVATE_SH
687 687 return True
688 688 except ImportError:
689 689 return False
690 690
691 691 @check("fsmonitor", "running tests with fsmonitor")
692 692 def has_fsmonitor():
693 693 return 'HGFSMONITOR_TESTS' in os.environ
694 694
695 695 @check("fuzzywuzzy", "Fuzzy string matching library")
696 696 def has_fuzzywuzzy():
697 697 try:
698 698 import fuzzywuzzy
699 699 fuzzywuzzy.__version__
700 700 return True
701 701 except ImportError:
702 702 return False
703 703
704 704 @check("clang-libfuzzer", "clang new enough to include libfuzzer")
705 705 def has_clang_libfuzzer():
706 706 mat = matchoutput('clang --version', b'clang version (\d)')
707 707 if mat:
708 708 # libfuzzer is new in clang 6
709 709 return int(mat.group(1)) > 5
710 710 return False
711 711
712 712 @check("xdiff", "xdiff algorithm")
713 713 def has_xdiff():
714 714 try:
715 715 from mercurial import policy
716 716 bdiff = policy.importmod('bdiff')
717 717 return bdiff.xdiffblocks(b'', b'') == [(0, 0, 0, 0)]
718 718 except (ImportError, AttributeError):
719 719 return False
720 720
721 721 @check('extraextensions', 'whether tests are running with extra extensions')
722 722 def has_extraextensions():
723 723 return 'HGTESTEXTRAEXTENSIONS' in os.environ
724 724
725 725 def getrepofeatures():
726 726 """Obtain set of repository features in use.
727 727
728 728 HGREPOFEATURES can be used to define or remove features. It contains
729 729 a space-delimited list of feature strings. Strings beginning with ``-``
730 730 mean to remove.
731 731 """
732 732 # Default list provided by core.
733 733 features = {
734 734 'bundlerepo',
735 735 'revlogstore',
736 'fncache',
736 737 }
737 738
738 739 # Features that imply other features.
739 740 implies = {
740 'simplestore': ['-revlogstore', '-bundlerepo'],
741 'simplestore': ['-revlogstore', '-bundlerepo', '-fncache'],
741 742 }
742 743
743 744 for override in os.environ.get('HGREPOFEATURES', '').split(' '):
744 745 if not override:
745 746 continue
746 747
747 748 if override.startswith('-'):
748 749 if override[1:] in features:
749 750 features.remove(override[1:])
750 751 else:
751 752 features.add(override)
752 753
753 754 for imply in implies.get(override, []):
754 755 if imply.startswith('-'):
755 756 if imply[1:] in features:
756 757 features.remove(imply[1:])
757 758 else:
758 759 features.add(imply)
759 760
760 761 return features
761 762
762 763 @check('reporevlogstore', 'repository using the default revlog store')
763 764 def has_reporevlogstore():
764 765 return 'revlogstore' in getrepofeatures()
765 766
766 767 @check('reposimplestore', 'repository using simple storage extension')
767 768 def has_reposimplestore():
768 769 return 'simplestore' in getrepofeatures()
769 770
770 771 @check('repobundlerepo', 'whether we can open bundle files as repos')
771 772 def has_repobundlerepo():
772 773 return 'bundlerepo' in getrepofeatures()
774
775 @check('repofncache', 'repository has an fncache')
776 def has_repofncache():
777 return 'fncache' in getrepofeatures()
@@ -1,595 +1,664 b''
1 1 # simplestorerepo.py - Extension that swaps in alternate repository storage.
2 2 #
3 3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 # To use this with the test suite:
9 9 #
10 10 # $ HGREPOFEATURES="simplestore" ./run-tests.py \
11 11 # --extra-config-opt extensions.simplestore=`pwd`/simplestorerepo.py
12 12
13 13 from __future__ import absolute_import
14 14
15 import stat
16
15 17 from mercurial.i18n import _
16 18 from mercurial.node import (
17 19 bin,
18 20 hex,
19 21 nullid,
20 22 nullrev,
21 23 )
22 24 from mercurial.thirdparty import (
23 25 cbor,
24 26 )
25 27 from mercurial import (
26 28 ancestor,
27 29 bundlerepo,
28 30 error,
31 extensions,
29 32 filelog,
33 localrepo,
30 34 mdiff,
31 35 pycompat,
32 36 revlog,
37 store,
33 38 )
34 39
35 40 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
36 41 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
37 42 # be specifying the version(s) of Mercurial they are tested with, or
38 43 # leave the attribute unspecified.
39 44 testedwith = 'ships-with-hg-core'
40 45
46 REQUIREMENT = 'testonly-simplestore'
47
41 48 def validatenode(node):
42 49 if isinstance(node, int):
43 50 raise ValueError('expected node; got int')
44 51
45 52 if len(node) != 20:
46 53 raise ValueError('expected 20 byte node')
47 54
48 55 def validaterev(rev):
49 56 if not isinstance(rev, int):
50 57 raise ValueError('expected int')
51 58
52 59 class filestorage(object):
53 60 """Implements storage for a tracked path.
54 61
55 62 Data is stored in the VFS in a directory corresponding to the tracked
56 63 path.
57 64
58 65 Index data is stored in an ``index`` file using CBOR.
59 66
60 67 Fulltext data is stored in files having names of the node.
61 68 """
62 69
63 70 def __init__(self, svfs, path):
64 71 self._svfs = svfs
65 72 self._path = path
66 73
67 74 self._storepath = b'/'.join([b'data', path])
68 75 self._indexpath = b'/'.join([self._storepath, b'index'])
69 76
70 77 indexdata = self._svfs.tryread(self._indexpath)
71 78 if indexdata:
72 79 indexdata = cbor.loads(indexdata)
73 80
74 81 self._indexdata = indexdata or []
75 82 self._indexbynode = {}
76 83 self._indexbyrev = {}
77 84 self.index = []
78 85 self._refreshindex()
79 86
80 87 # This is used by changegroup code :/
81 88 self._generaldelta = True
82 89 self.storedeltachains = False
83 90
84 91 self.version = 1
85 92
86 93 def _refreshindex(self):
87 94 self._indexbynode.clear()
88 95 self._indexbyrev.clear()
89 96 self.index = []
90 97
91 98 for i, entry in enumerate(self._indexdata):
92 99 self._indexbynode[entry[b'node']] = entry
93 100 self._indexbyrev[i] = entry
94 101
95 102 self._indexbynode[nullid] = {
96 103 b'node': nullid,
97 104 b'p1': nullid,
98 105 b'p2': nullid,
99 106 b'linkrev': nullrev,
100 107 b'flags': 0,
101 108 }
102 109
103 110 self._indexbyrev[nullrev] = {
104 111 b'node': nullid,
105 112 b'p1': nullid,
106 113 b'p2': nullid,
107 114 b'linkrev': nullrev,
108 115 b'flags': 0,
109 116 }
110 117
111 118 for i, entry in enumerate(self._indexdata):
112 119 p1rev, p2rev = self.parentrevs(self.rev(entry[b'node']))
113 120
114 121 # start, length, rawsize, chainbase, linkrev, p1, p2, node
115 122 self.index.append((0, 0, 0, -1, entry[b'linkrev'], p1rev, p2rev,
116 123 entry[b'node']))
117 124
118 125 self.index.append((0, 0, 0, -1, -1, -1, -1, nullid))
119 126
120 127 def __len__(self):
121 128 return len(self._indexdata)
122 129
123 130 def __iter__(self):
124 131 return iter(range(len(self)))
125 132
126 133 def revs(self, start=0, stop=None):
127 134 step = 1
128 135 if stop is not None:
129 136 if start > stop:
130 137 step = -1
131 138
132 139 stop += step
133 140 else:
134 141 stop = len(self)
135 142
136 143 return range(start, stop, step)
137 144
138 145 def parents(self, node):
139 146 validatenode(node)
140 147
141 148 if node not in self._indexbynode:
142 149 raise KeyError('unknown node')
143 150
144 151 entry = self._indexbynode[node]
145 152
146 153 return entry[b'p1'], entry[b'p2']
147 154
148 155 def parentrevs(self, rev):
149 156 p1, p2 = self.parents(self._indexbyrev[rev][b'node'])
150 157 return self.rev(p1), self.rev(p2)
151 158
152 159 def rev(self, node):
153 160 validatenode(node)
154 161
155 162 try:
156 163 self._indexbynode[node]
157 164 except KeyError:
158 165 raise error.LookupError(node, self._indexpath, _('no node'))
159 166
160 167 for rev, entry in self._indexbyrev.items():
161 168 if entry[b'node'] == node:
162 169 return rev
163 170
164 171 raise error.ProgrammingError('this should not occur')
165 172
166 173 def node(self, rev):
167 174 validaterev(rev)
168 175
169 176 return self._indexbyrev[rev][b'node']
170 177
171 178 def lookup(self, node):
172 179 if isinstance(node, int):
173 180 return self.node(node)
174 181
175 182 if len(node) == 20:
176 183 self.rev(node)
177 184 return node
178 185
179 186 try:
180 187 rev = int(node)
181 188 if '%d' % rev != node:
182 189 raise ValueError
183 190
184 191 if rev < 0:
185 192 rev = len(self) + rev
186 193 if rev < 0 or rev >= len(self):
187 194 raise ValueError
188 195
189 196 return self.node(rev)
190 197 except (ValueError, OverflowError):
191 198 pass
192 199
193 200 if len(node) == 40:
194 201 try:
195 202 rawnode = bin(node)
196 203 self.rev(rawnode)
197 204 return rawnode
198 205 except TypeError:
199 206 pass
200 207
201 208 raise error.LookupError(node, self._path, _('invalid lookup input'))
202 209
203 210 def linkrev(self, rev):
204 211 validaterev(rev)
205 212
206 213 return self._indexbyrev[rev][b'linkrev']
207 214
208 215 def flags(self, rev):
209 216 validaterev(rev)
210 217
211 218 return self._indexbyrev[rev][b'flags']
212 219
213 220 def deltaparent(self, rev):
214 221 validaterev(rev)
215 222
216 223 p1node = self.parents(self.node(rev))[0]
217 224 return self.rev(p1node)
218 225
219 226 def candelta(self, baserev, rev):
220 227 validaterev(baserev)
221 228 validaterev(rev)
222 229
223 230 if ((self.flags(baserev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS)
224 231 or (self.flags(rev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS)):
225 232 return False
226 233
227 234 return True
228 235
229 236 def rawsize(self, rev):
230 237 validaterev(rev)
231 238 node = self.node(rev)
232 239 return len(self.revision(node, raw=True))
233 240
234 241 def _processflags(self, text, flags, operation, raw=False):
235 242 if flags == 0:
236 243 return text, True
237 244
238 245 validatehash = True
239 246 # Depending on the operation (read or write), the order might be
240 247 # reversed due to non-commutative transforms.
241 248 orderedflags = revlog.REVIDX_FLAGS_ORDER
242 249 if operation == 'write':
243 250 orderedflags = reversed(orderedflags)
244 251
245 252 for flag in orderedflags:
246 253 # If a flagprocessor has been registered for a known flag, apply the
247 254 # related operation transform and update result tuple.
248 255 if flag & flags:
249 256 vhash = True
250 257
251 258 if flag not in revlog._flagprocessors:
252 259 message = _("missing processor for flag '%#x'") % (flag)
253 260 raise revlog.RevlogError(message)
254 261
255 262 processor = revlog._flagprocessors[flag]
256 263 if processor is not None:
257 264 readtransform, writetransform, rawtransform = processor
258 265
259 266 if raw:
260 267 vhash = rawtransform(self, text)
261 268 elif operation == 'read':
262 269 text, vhash = readtransform(self, text)
263 270 else: # write operation
264 271 text, vhash = writetransform(self, text)
265 272 validatehash = validatehash and vhash
266 273
267 274 return text, validatehash
268 275
269 276 def checkhash(self, text, node, p1=None, p2=None, rev=None):
270 277 if p1 is None and p2 is None:
271 278 p1, p2 = self.parents(node)
272 279 if node != revlog.hash(text, p1, p2):
273 280 raise error.RevlogError(_("integrity check failed on %s") %
274 281 self._path)
275 282
276 283 def revision(self, node, raw=False):
277 284 validatenode(node)
278 285
279 286 if node == nullid:
280 287 return b''
281 288
282 289 rev = self.rev(node)
283 290 flags = self.flags(rev)
284 291
285 292 path = b'/'.join([self._storepath, hex(node)])
286 293 rawtext = self._svfs.read(path)
287 294
288 295 text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw)
289 296 if validatehash:
290 297 self.checkhash(text, node, rev=rev)
291 298
292 299 return text
293 300
294 301 def read(self, node):
295 302 validatenode(node)
296 303
297 304 revision = self.revision(node)
298 305
299 306 if not revision.startswith(b'\1\n'):
300 307 return revision
301 308
302 309 start = revision.index(b'\1\n', 2)
303 310 return revision[start + 2:]
304 311
305 312 def renamed(self, node):
306 313 validatenode(node)
307 314
308 315 if self.parents(node)[0] != nullid:
309 316 return False
310 317
311 318 fulltext = self.revision(node)
312 319 m = filelog.parsemeta(fulltext)[0]
313 320
314 321 if m and 'copy' in m:
315 322 return m['copy'], bin(m['copyrev'])
316 323
317 324 return False
318 325
319 326 def cmp(self, node, text):
320 327 validatenode(node)
321 328
322 329 t = text
323 330
324 331 if text.startswith(b'\1\n'):
325 332 t = b'\1\n\1\n' + text
326 333
327 334 p1, p2 = self.parents(node)
328 335
329 336 if revlog.hash(t, p1, p2) == node:
330 337 return False
331 338
332 339 if self.iscensored(self.rev(node)):
333 340 return text != b''
334 341
335 342 if self.renamed(node):
336 343 t2 = self.read(node)
337 344 return t2 != text
338 345
339 346 return True
340 347
341 348 def size(self, rev):
342 349 validaterev(rev)
343 350
344 351 node = self._indexbyrev[rev][b'node']
345 352
346 353 if self.renamed(node):
347 354 return len(self.read(node))
348 355
349 356 if self.iscensored(rev):
350 357 return 0
351 358
352 359 return len(self.revision(node))
353 360
354 361 def iscensored(self, rev):
355 362 validaterev(rev)
356 363
357 364 return self.flags(rev) & revlog.REVIDX_ISCENSORED
358 365
359 366 def commonancestorsheads(self, a, b):
360 367 validatenode(a)
361 368 validatenode(b)
362 369
363 370 a = self.rev(a)
364 371 b = self.rev(b)
365 372
366 373 ancestors = ancestor.commonancestorsheads(self.parentrevs, a, b)
367 374 return pycompat.maplist(self.node, ancestors)
368 375
369 376 def descendants(self, revs):
370 377 # This is a copy of revlog.descendants()
371 378 first = min(revs)
372 379 if first == nullrev:
373 380 for i in self:
374 381 yield i
375 382 return
376 383
377 384 seen = set(revs)
378 385 for i in self.revs(start=first + 1):
379 386 for x in self.parentrevs(i):
380 387 if x != nullrev and x in seen:
381 388 seen.add(i)
382 389 yield i
383 390 break
384 391
385 392 # Required by verify.
386 393 def files(self):
387 394 entries = self._svfs.listdir(self._storepath)
388 395
389 396 # Strip out undo.backup.* files created as part of transaction
390 397 # recording.
391 398 entries = [f for f in entries if not f.startswith('undo.backup.')]
392 399
393 400 return [b'/'.join((self._storepath, f)) for f in entries]
394 401
395 402 # Required by verify.
396 403 def checksize(self):
397 404 return 0, 0
398 405
399 406 def add(self, text, meta, transaction, linkrev, p1, p2):
400 407 if meta or text.startswith(b'\1\n'):
401 408 text = filelog.packmeta(meta, text)
402 409
403 410 return self.addrevision(text, transaction, linkrev, p1, p2)
404 411
405 412 def addrevision(self, text, transaction, linkrev, p1, p2, node=None,
406 413 flags=0):
407 414 validatenode(p1)
408 415 validatenode(p2)
409 416
410 417 if flags:
411 418 node = node or revlog.hash(text, p1, p2)
412 419
413 420 rawtext, validatehash = self._processflags(text, flags, 'write')
414 421
415 422 node = node or revlog.hash(text, p1, p2)
416 423
417 424 if node in self._indexbynode:
418 425 return node
419 426
420 427 if validatehash:
421 428 self.checkhash(rawtext, node, p1=p1, p2=p2)
422 429
423 430 path = b'/'.join([self._storepath, hex(node)])
424 431
425 432 self._svfs.write(path, text)
426 433
427 434 self._indexdata.append({
428 435 b'node': node,
429 436 b'p1': p1,
430 437 b'p2': p2,
431 438 b'linkrev': linkrev,
432 439 b'flags': flags,
433 440 })
434 441
435 442 self._reflectindexupdate()
436 443
437 444 return node
438 445
439 446 def _reflectindexupdate(self):
440 447 self._refreshindex()
441 448 self._svfs.write(self._indexpath, cbor.dumps(self._indexdata))
442 449
443 450 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
444 451 nodes = []
445 452
446 453 transaction.addbackup(self._indexpath)
447 454
448 455 for node, p1, p2, linknode, deltabase, delta, flags in deltas:
449 456 linkrev = linkmapper(linknode)
450 457
451 458 nodes.append(node)
452 459
453 460 if node in self._indexbynode:
454 461 continue
455 462
456 463 # Need to resolve the fulltext from the delta base.
457 464 if deltabase == nullid:
458 465 text = mdiff.patch(b'', delta)
459 466 else:
460 467 text = mdiff.patch(self.revision(deltabase), delta)
461 468
462 469 self.addrevision(text, transaction, linkrev, p1, p2, flags)
463 470
464 471 if addrevisioncb:
465 472 addrevisioncb(self, node)
466 473
467 474 return nodes
468 475
469 476 def revdiff(self, rev1, rev2):
470 477 validaterev(rev1)
471 478 validaterev(rev2)
472 479
473 480 node1 = self.node(rev1)
474 481 node2 = self.node(rev2)
475 482
476 483 return mdiff.textdiff(self.revision(node1, raw=True),
477 484 self.revision(node2, raw=True))
478 485
479 486 def headrevs(self):
480 487 # Assume all revisions are heads by default.
481 488 revishead = {rev: True for rev in self._indexbyrev}
482 489
483 490 for rev, entry in self._indexbyrev.items():
484 491 # Unset head flag for all seen parents.
485 492 revishead[self.rev(entry[b'p1'])] = False
486 493 revishead[self.rev(entry[b'p2'])] = False
487 494
488 495 return [rev for rev, ishead in sorted(revishead.items())
489 496 if ishead]
490 497
491 498 def heads(self, start=None, stop=None):
492 499 # This is copied from revlog.py.
493 500 if start is None and stop is None:
494 501 if not len(self):
495 502 return [nullid]
496 503 return [self.node(r) for r in self.headrevs()]
497 504
498 505 if start is None:
499 506 start = nullid
500 507 if stop is None:
501 508 stop = []
502 509 stoprevs = set([self.rev(n) for n in stop])
503 510 startrev = self.rev(start)
504 511 reachable = {startrev}
505 512 heads = {startrev}
506 513
507 514 parentrevs = self.parentrevs
508 515 for r in self.revs(start=startrev + 1):
509 516 for p in parentrevs(r):
510 517 if p in reachable:
511 518 if r not in stoprevs:
512 519 reachable.add(r)
513 520 heads.add(r)
514 521 if p in heads and p not in stoprevs:
515 522 heads.remove(p)
516 523
517 524 return [self.node(r) for r in heads]
518 525
519 526 def children(self, node):
520 527 validatenode(node)
521 528
522 529 # This is a copy of revlog.children().
523 530 c = []
524 531 p = self.rev(node)
525 532 for r in self.revs(start=p + 1):
526 533 prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
527 534 if prevs:
528 535 for pr in prevs:
529 536 if pr == p:
530 537 c.append(self.node(r))
531 538 elif p == nullrev:
532 539 c.append(self.node(r))
533 540 return c
534 541
535 542 def getstrippoint(self, minlink):
536 543
537 544 # This is largely a copy of revlog.getstrippoint().
538 545 brokenrevs = set()
539 546 strippoint = len(self)
540 547
541 548 heads = {}
542 549 futurelargelinkrevs = set()
543 550 for head in self.headrevs():
544 551 headlinkrev = self.linkrev(head)
545 552 heads[head] = headlinkrev
546 553 if headlinkrev >= minlink:
547 554 futurelargelinkrevs.add(headlinkrev)
548 555
549 556 # This algorithm involves walking down the rev graph, starting at the
550 557 # heads. Since the revs are topologically sorted according to linkrev,
551 558 # once all head linkrevs are below the minlink, we know there are
552 559 # no more revs that could have a linkrev greater than minlink.
553 560 # So we can stop walking.
554 561 while futurelargelinkrevs:
555 562 strippoint -= 1
556 563 linkrev = heads.pop(strippoint)
557 564
558 565 if linkrev < minlink:
559 566 brokenrevs.add(strippoint)
560 567 else:
561 568 futurelargelinkrevs.remove(linkrev)
562 569
563 570 for p in self.parentrevs(strippoint):
564 571 if p != nullrev:
565 572 plinkrev = self.linkrev(p)
566 573 heads[p] = plinkrev
567 574 if plinkrev >= minlink:
568 575 futurelargelinkrevs.add(plinkrev)
569 576
570 577 return strippoint, brokenrevs
571 578
572 579 def strip(self, minlink, transaction):
573 580 if not len(self):
574 581 return
575 582
576 583 rev, _ignored = self.getstrippoint(minlink)
577 584 if rev == len(self):
578 585 return
579 586
580 587 # Purge index data starting at the requested revision.
581 588 self._indexdata[rev:] = []
582 589 self._reflectindexupdate()
583 590
591 def issimplestorefile(f, kind, st):
592 if kind != stat.S_IFREG:
593 return False
594
595 if store.isrevlog(f, kind, st):
596 return False
597
598 # Ignore transaction undo files.
599 if f.startswith('undo.'):
600 return False
601
602 # Otherwise assume it belongs to the simple store.
603 return True
604
605 class simplestore(store.encodedstore):
606 def datafiles(self):
607 for x in super(simplestore, self).datafiles():
608 yield x
609
610 # Supplement with non-revlog files.
611 extrafiles = self._walk('data', True, filefilter=issimplestorefile)
612
613 for unencoded, encoded, size in extrafiles:
614 try:
615 unencoded = store.decodefilename(unencoded)
616 except KeyError:
617 unencoded = None
618
619 yield unencoded, encoded, size
620
584 621 def reposetup(ui, repo):
585 622 if not repo.local():
586 623 return
587 624
588 625 if isinstance(repo, bundlerepo.bundlerepository):
589 626 raise error.Abort(_('cannot use simple store with bundlerepo'))
590 627
591 628 class simplestorerepo(repo.__class__):
592 629 def file(self, f):
593 630 return filestorage(self.svfs, f)
594 631
595 632 repo.__class__ = simplestorerepo
633
634 def featuresetup(ui, supported):
635 supported.add(REQUIREMENT)
636
637 def newreporequirements(orig, repo):
638 """Modifies default requirements for new repos to use the simple store."""
639 requirements = orig(repo)
640
641 # These requirements are only used to affect creation of the store
642 # object. We have our own store. So we can remove them.
643 # TODO do this once we feel like taking the test hit.
644 #if 'fncache' in requirements:
645 # requirements.remove('fncache')
646 #if 'dotencode' in requirements:
647 # requirements.remove('dotencode')
648
649 requirements.add(REQUIREMENT)
650
651 return requirements
652
653 def makestore(orig, requirements, path, vfstype):
654 if REQUIREMENT not in requirements:
655 return orig(requirements, path, vfstype)
656
657 return simplestore(path, vfstype)
658
659 def extsetup(ui):
660 localrepo.featuresetupfuncs.add(featuresetup)
661
662 extensions.wrapfunction(localrepo, 'newreporequirements',
663 newreporequirements)
664 extensions.wrapfunction(store, 'store', makestore)
@@ -1,1295 +1,1293 b''
1 1 #testcases sshv1 sshv2
2 2
3 3 #if sshv2
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [experimental]
6 6 > sshpeer.advertise-v2 = true
7 7 > sshserver.support-v2 = true
8 8 > EOF
9 9 #endif
10 10
11 11 Prepare repo a:
12 12
13 13 $ hg init a
14 14 $ cd a
15 15 $ echo a > a
16 16 $ hg add a
17 17 $ hg commit -m test
18 18 $ echo first line > b
19 19 $ hg add b
20 20
21 21 Create a non-inlined filelog:
22 22
23 23 $ $PYTHON -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
24 24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
25 25 > cat data1 >> b
26 26 > hg commit -m test
27 27 > done
28 28
29 29 List files in store/data (should show a 'b.d'):
30 30
31 31 #if reporevlogstore
32 32 $ for i in .hg/store/data/*; do
33 33 > echo $i
34 34 > done
35 35 .hg/store/data/a.i
36 36 .hg/store/data/b.d
37 37 .hg/store/data/b.i
38 38 #endif
39 39
40 40 Trigger branchcache creation:
41 41
42 42 $ hg branches
43 43 default 10:a7949464abda
44 44 $ ls .hg/cache
45 45 branch2-served
46 46 checkisexec (execbit !)
47 47 checklink (symlink !)
48 48 checklink-target (symlink !)
49 49 checknoexec (execbit !)
50 50 rbc-names-v1
51 51 rbc-revs-v1
52 52
53 53 Default operation:
54 54
55 55 $ hg clone . ../b
56 56 updating to branch default
57 57 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 58 $ cd ../b
59 59
60 60 Ensure branchcache got copied over:
61 61
62 62 $ ls .hg/cache
63 63 branch2-served
64 64 checkisexec (execbit !)
65 65 checklink (symlink !)
66 66 checklink-target (symlink !)
67 67 rbc-names-v1
68 68 rbc-revs-v1
69 69
70 70 $ cat a
71 71 a
72 72 $ hg verify
73 73 checking changesets
74 74 checking manifests
75 75 crosschecking files in changesets and manifests
76 76 checking files
77 77 2 files, 11 changesets, 11 total revisions
78 78
79 79 Invalid dest '' must abort:
80 80
81 81 $ hg clone . ''
82 82 abort: empty destination path is not valid
83 83 [255]
84 84
85 85 No update, with debug option:
86 86
87 87 #if hardlink
88 88 $ hg --debug clone -U . ../c --config progress.debug=true
89 89 linking: 1
90 90 linking: 2
91 91 linking: 3
92 92 linking: 4
93 93 linking: 5
94 94 linking: 6
95 95 linking: 7
96 96 linking: 8
97 97 linked 8 files (reporevlogstore !)
98 98 linking: 9 (reposimplestore !)
99 99 linking: 10 (reposimplestore !)
100 100 linking: 11 (reposimplestore !)
101 101 linking: 12 (reposimplestore !)
102 102 linking: 13 (reposimplestore !)
103 103 linking: 14 (reposimplestore !)
104 104 linking: 15 (reposimplestore !)
105 105 linking: 16 (reposimplestore !)
106 106 linking: 17 (reposimplestore !)
107 linking: 18 (reposimplestore !)
108 linked 18 files (reposimplestore !)
107 linked 17 files (reposimplestore !)
109 108 #else
110 109 $ hg --debug clone -U . ../c --config progress.debug=true
111 110 linking: 1
112 111 copying: 2
113 112 copying: 3
114 113 copying: 4
115 114 copying: 5
116 115 copying: 6
117 116 copying: 7
118 117 copying: 8
119 118 copied 8 files (reporevlogstore !)
120 119 copying: 9 (reposimplestore !)
121 120 copying: 10 (reposimplestore !)
122 121 copying: 11 (reposimplestore !)
123 122 copying: 12 (reposimplestore !)
124 123 copying: 13 (reposimplestore !)
125 124 copying: 14 (reposimplestore !)
126 125 copying: 15 (reposimplestore !)
127 126 copying: 16 (reposimplestore !)
128 127 copying: 17 (reposimplestore !)
129 copying: 18 (reposimplestore !)
130 copied 18 files (reposimplestore !)
128 copied 17 files (reposimplestore !)
131 129 #endif
132 130 $ cd ../c
133 131
134 132 Ensure branchcache got copied over:
135 133
136 134 $ ls .hg/cache
137 135 branch2-served
138 136 rbc-names-v1
139 137 rbc-revs-v1
140 138
141 139 $ cat a 2>/dev/null || echo "a not present"
142 140 a not present
143 141 $ hg verify
144 142 checking changesets
145 143 checking manifests
146 144 crosschecking files in changesets and manifests
147 145 checking files
148 146 2 files, 11 changesets, 11 total revisions
149 147
150 148 Default destination:
151 149
152 150 $ mkdir ../d
153 151 $ cd ../d
154 152 $ hg clone ../a
155 153 destination directory: a
156 154 updating to branch default
157 155 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 156 $ cd a
159 157 $ hg cat a
160 158 a
161 159 $ cd ../..
162 160
163 161 Check that we drop the 'file:' from the path before writing the .hgrc:
164 162
165 163 $ hg clone file:a e
166 164 updating to branch default
167 165 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 166 $ grep 'file:' e/.hg/hgrc
169 167 [1]
170 168
171 169 Check that path aliases are expanded:
172 170
173 171 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
174 172 $ hg -R f showconfig paths.default
175 173 $TESTTMP/a#0
176 174
177 175 Use --pull:
178 176
179 177 $ hg clone --pull a g
180 178 requesting all changes
181 179 adding changesets
182 180 adding manifests
183 181 adding file changes
184 182 added 11 changesets with 11 changes to 2 files
185 183 new changesets acb14030fe0a:a7949464abda
186 184 updating to branch default
187 185 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
188 186 $ hg -R g verify
189 187 checking changesets
190 188 checking manifests
191 189 crosschecking files in changesets and manifests
192 190 checking files
193 191 2 files, 11 changesets, 11 total revisions
194 192
195 193 Invalid dest '' with --pull must abort (issue2528):
196 194
197 195 $ hg clone --pull a ''
198 196 abort: empty destination path is not valid
199 197 [255]
200 198
201 199 Clone to '.':
202 200
203 201 $ mkdir h
204 202 $ cd h
205 203 $ hg clone ../a .
206 204 updating to branch default
207 205 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 206 $ cd ..
209 207
210 208
211 209 *** Tests for option -u ***
212 210
213 211 Adding some more history to repo a:
214 212
215 213 $ cd a
216 214 $ hg tag ref1
217 215 $ echo the quick brown fox >a
218 216 $ hg ci -m "hacked default"
219 217 $ hg up ref1
220 218 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
221 219 $ hg branch stable
222 220 marked working directory as branch stable
223 221 (branches are permanent and global, did you want a bookmark?)
224 222 $ echo some text >a
225 223 $ hg ci -m "starting branch stable"
226 224 $ hg tag ref2
227 225 $ echo some more text >a
228 226 $ hg ci -m "another change for branch stable"
229 227 $ hg up ref2
230 228 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
231 229 $ hg parents
232 230 changeset: 13:e8ece76546a6
233 231 branch: stable
234 232 tag: ref2
235 233 parent: 10:a7949464abda
236 234 user: test
237 235 date: Thu Jan 01 00:00:00 1970 +0000
238 236 summary: starting branch stable
239 237
240 238
241 239 Repo a has two heads:
242 240
243 241 $ hg heads
244 242 changeset: 15:0aae7cf88f0d
245 243 branch: stable
246 244 tag: tip
247 245 user: test
248 246 date: Thu Jan 01 00:00:00 1970 +0000
249 247 summary: another change for branch stable
250 248
251 249 changeset: 12:f21241060d6a
252 250 user: test
253 251 date: Thu Jan 01 00:00:00 1970 +0000
254 252 summary: hacked default
255 253
256 254
257 255 $ cd ..
258 256
259 257
260 258 Testing --noupdate with --updaterev (must abort):
261 259
262 260 $ hg clone --noupdate --updaterev 1 a ua
263 261 abort: cannot specify both --noupdate and --updaterev
264 262 [255]
265 263
266 264
267 265 Testing clone -u:
268 266
269 267 $ hg clone -u . a ua
270 268 updating to branch stable
271 269 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 270
273 271 Repo ua has both heads:
274 272
275 273 $ hg -R ua heads
276 274 changeset: 15:0aae7cf88f0d
277 275 branch: stable
278 276 tag: tip
279 277 user: test
280 278 date: Thu Jan 01 00:00:00 1970 +0000
281 279 summary: another change for branch stable
282 280
283 281 changeset: 12:f21241060d6a
284 282 user: test
285 283 date: Thu Jan 01 00:00:00 1970 +0000
286 284 summary: hacked default
287 285
288 286
289 287 Same revision checked out in repo a and ua:
290 288
291 289 $ hg -R a parents --template "{node|short}\n"
292 290 e8ece76546a6
293 291 $ hg -R ua parents --template "{node|short}\n"
294 292 e8ece76546a6
295 293
296 294 $ rm -r ua
297 295
298 296
299 297 Testing clone --pull -u:
300 298
301 299 $ hg clone --pull -u . a ua
302 300 requesting all changes
303 301 adding changesets
304 302 adding manifests
305 303 adding file changes
306 304 added 16 changesets with 16 changes to 3 files (+1 heads)
307 305 new changesets acb14030fe0a:0aae7cf88f0d
308 306 updating to branch stable
309 307 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 308
311 309 Repo ua has both heads:
312 310
313 311 $ hg -R ua heads
314 312 changeset: 15:0aae7cf88f0d
315 313 branch: stable
316 314 tag: tip
317 315 user: test
318 316 date: Thu Jan 01 00:00:00 1970 +0000
319 317 summary: another change for branch stable
320 318
321 319 changeset: 12:f21241060d6a
322 320 user: test
323 321 date: Thu Jan 01 00:00:00 1970 +0000
324 322 summary: hacked default
325 323
326 324
327 325 Same revision checked out in repo a and ua:
328 326
329 327 $ hg -R a parents --template "{node|short}\n"
330 328 e8ece76546a6
331 329 $ hg -R ua parents --template "{node|short}\n"
332 330 e8ece76546a6
333 331
334 332 $ rm -r ua
335 333
336 334
337 335 Testing clone -u <branch>:
338 336
339 337 $ hg clone -u stable a ua
340 338 updating to branch stable
341 339 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 340
343 341 Repo ua has both heads:
344 342
345 343 $ hg -R ua heads
346 344 changeset: 15:0aae7cf88f0d
347 345 branch: stable
348 346 tag: tip
349 347 user: test
350 348 date: Thu Jan 01 00:00:00 1970 +0000
351 349 summary: another change for branch stable
352 350
353 351 changeset: 12:f21241060d6a
354 352 user: test
355 353 date: Thu Jan 01 00:00:00 1970 +0000
356 354 summary: hacked default
357 355
358 356
359 357 Branch 'stable' is checked out:
360 358
361 359 $ hg -R ua parents
362 360 changeset: 15:0aae7cf88f0d
363 361 branch: stable
364 362 tag: tip
365 363 user: test
366 364 date: Thu Jan 01 00:00:00 1970 +0000
367 365 summary: another change for branch stable
368 366
369 367
370 368 $ rm -r ua
371 369
372 370
373 371 Testing default checkout:
374 372
375 373 $ hg clone a ua
376 374 updating to branch default
377 375 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 376
379 377 Repo ua has both heads:
380 378
381 379 $ hg -R ua heads
382 380 changeset: 15:0aae7cf88f0d
383 381 branch: stable
384 382 tag: tip
385 383 user: test
386 384 date: Thu Jan 01 00:00:00 1970 +0000
387 385 summary: another change for branch stable
388 386
389 387 changeset: 12:f21241060d6a
390 388 user: test
391 389 date: Thu Jan 01 00:00:00 1970 +0000
392 390 summary: hacked default
393 391
394 392
395 393 Branch 'default' is checked out:
396 394
397 395 $ hg -R ua parents
398 396 changeset: 12:f21241060d6a
399 397 user: test
400 398 date: Thu Jan 01 00:00:00 1970 +0000
401 399 summary: hacked default
402 400
403 401 Test clone with a branch named "@" (issue3677)
404 402
405 403 $ hg -R ua branch @
406 404 marked working directory as branch @
407 405 $ hg -R ua commit -m 'created branch @'
408 406 $ hg clone ua atbranch
409 407 updating to branch default
410 408 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
411 409 $ hg -R atbranch heads
412 410 changeset: 16:798b6d97153e
413 411 branch: @
414 412 tag: tip
415 413 parent: 12:f21241060d6a
416 414 user: test
417 415 date: Thu Jan 01 00:00:00 1970 +0000
418 416 summary: created branch @
419 417
420 418 changeset: 15:0aae7cf88f0d
421 419 branch: stable
422 420 user: test
423 421 date: Thu Jan 01 00:00:00 1970 +0000
424 422 summary: another change for branch stable
425 423
426 424 changeset: 12:f21241060d6a
427 425 user: test
428 426 date: Thu Jan 01 00:00:00 1970 +0000
429 427 summary: hacked default
430 428
431 429 $ hg -R atbranch parents
432 430 changeset: 12:f21241060d6a
433 431 user: test
434 432 date: Thu Jan 01 00:00:00 1970 +0000
435 433 summary: hacked default
436 434
437 435
438 436 $ rm -r ua atbranch
439 437
440 438
441 439 Testing #<branch>:
442 440
443 441 $ hg clone -u . a#stable ua
444 442 adding changesets
445 443 adding manifests
446 444 adding file changes
447 445 added 14 changesets with 14 changes to 3 files
448 446 new changesets acb14030fe0a:0aae7cf88f0d
449 447 updating to branch stable
450 448 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
451 449
452 450 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
453 451
454 452 $ hg -R ua heads
455 453 changeset: 13:0aae7cf88f0d
456 454 branch: stable
457 455 tag: tip
458 456 user: test
459 457 date: Thu Jan 01 00:00:00 1970 +0000
460 458 summary: another change for branch stable
461 459
462 460 changeset: 10:a7949464abda
463 461 user: test
464 462 date: Thu Jan 01 00:00:00 1970 +0000
465 463 summary: test
466 464
467 465
468 466 Same revision checked out in repo a and ua:
469 467
470 468 $ hg -R a parents --template "{node|short}\n"
471 469 e8ece76546a6
472 470 $ hg -R ua parents --template "{node|short}\n"
473 471 e8ece76546a6
474 472
475 473 $ rm -r ua
476 474
477 475
478 476 Testing -u -r <branch>:
479 477
480 478 $ hg clone -u . -r stable a ua
481 479 adding changesets
482 480 adding manifests
483 481 adding file changes
484 482 added 14 changesets with 14 changes to 3 files
485 483 new changesets acb14030fe0a:0aae7cf88f0d
486 484 updating to branch stable
487 485 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 486
489 487 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
490 488
491 489 $ hg -R ua heads
492 490 changeset: 13:0aae7cf88f0d
493 491 branch: stable
494 492 tag: tip
495 493 user: test
496 494 date: Thu Jan 01 00:00:00 1970 +0000
497 495 summary: another change for branch stable
498 496
499 497 changeset: 10:a7949464abda
500 498 user: test
501 499 date: Thu Jan 01 00:00:00 1970 +0000
502 500 summary: test
503 501
504 502
505 503 Same revision checked out in repo a and ua:
506 504
507 505 $ hg -R a parents --template "{node|short}\n"
508 506 e8ece76546a6
509 507 $ hg -R ua parents --template "{node|short}\n"
510 508 e8ece76546a6
511 509
512 510 $ rm -r ua
513 511
514 512
515 513 Testing -r <branch>:
516 514
517 515 $ hg clone -r stable a ua
518 516 adding changesets
519 517 adding manifests
520 518 adding file changes
521 519 added 14 changesets with 14 changes to 3 files
522 520 new changesets acb14030fe0a:0aae7cf88f0d
523 521 updating to branch stable
524 522 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 523
526 524 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
527 525
528 526 $ hg -R ua heads
529 527 changeset: 13:0aae7cf88f0d
530 528 branch: stable
531 529 tag: tip
532 530 user: test
533 531 date: Thu Jan 01 00:00:00 1970 +0000
534 532 summary: another change for branch stable
535 533
536 534 changeset: 10:a7949464abda
537 535 user: test
538 536 date: Thu Jan 01 00:00:00 1970 +0000
539 537 summary: test
540 538
541 539
542 540 Branch 'stable' is checked out:
543 541
544 542 $ hg -R ua parents
545 543 changeset: 13:0aae7cf88f0d
546 544 branch: stable
547 545 tag: tip
548 546 user: test
549 547 date: Thu Jan 01 00:00:00 1970 +0000
550 548 summary: another change for branch stable
551 549
552 550
553 551 $ rm -r ua
554 552
555 553
556 554 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
557 555 iterable in addbranchrevs()
558 556
559 557 $ cat <<EOF > simpleclone.py
560 558 > from mercurial import ui, hg
561 559 > myui = ui.ui.load()
562 560 > repo = hg.repository(myui, 'a')
563 561 > hg.clone(myui, {}, repo, dest="ua")
564 562 > EOF
565 563
566 564 $ $PYTHON simpleclone.py
567 565 updating to branch default
568 566 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
569 567
570 568 $ rm -r ua
571 569
572 570 $ cat <<EOF > branchclone.py
573 571 > from mercurial import ui, hg, extensions
574 572 > myui = ui.ui.load()
575 573 > extensions.loadall(myui)
576 574 > repo = hg.repository(myui, 'a')
577 575 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
578 576 > EOF
579 577
580 578 $ $PYTHON branchclone.py
581 579 adding changesets
582 580 adding manifests
583 581 adding file changes
584 582 added 14 changesets with 14 changes to 3 files
585 583 new changesets acb14030fe0a:0aae7cf88f0d
586 584 updating to branch stable
587 585 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 586 $ rm -r ua
589 587
590 588
591 589 Test clone with special '@' bookmark:
592 590 $ cd a
593 591 $ hg bookmark -r a7949464abda @ # branch point of stable from default
594 592 $ hg clone . ../i
595 593 updating to bookmark @
596 594 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
597 595 $ hg id -i ../i
598 596 a7949464abda
599 597 $ rm -r ../i
600 598
601 599 $ hg bookmark -f -r stable @
602 600 $ hg bookmarks
603 601 @ 15:0aae7cf88f0d
604 602 $ hg clone . ../i
605 603 updating to bookmark @ on branch stable
606 604 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
607 605 $ hg id -i ../i
608 606 0aae7cf88f0d
609 607 $ cd "$TESTTMP"
610 608
611 609
612 610 Testing failures:
613 611
614 612 $ mkdir fail
615 613 $ cd fail
616 614
617 615 No local source
618 616
619 617 $ hg clone a b
620 618 abort: repository a not found!
621 619 [255]
622 620
623 621 No remote source
624 622
625 623 #if windows
626 624 $ hg clone http://$LOCALIP:3121/a b
627 625 abort: error: * (glob)
628 626 [255]
629 627 #else
630 628 $ hg clone http://$LOCALIP:3121/a b
631 629 abort: error: *refused* (glob)
632 630 [255]
633 631 #endif
634 632 $ rm -rf b # work around bug with http clone
635 633
636 634
637 635 #if unix-permissions no-root
638 636
639 637 Inaccessible source
640 638
641 639 $ mkdir a
642 640 $ chmod 000 a
643 641 $ hg clone a b
644 642 abort: repository a not found!
645 643 [255]
646 644
647 645 Inaccessible destination
648 646
649 647 $ hg init b
650 648 $ cd b
651 649 $ hg clone . ../a
652 650 abort: Permission denied: '../a'
653 651 [255]
654 652 $ cd ..
655 653 $ chmod 700 a
656 654 $ rm -r a b
657 655
658 656 #endif
659 657
660 658
661 659 #if fifo
662 660
663 661 Source of wrong type
664 662
665 663 $ mkfifo a
666 664 $ hg clone a b
667 665 abort: repository a not found!
668 666 [255]
669 667 $ rm a
670 668
671 669 #endif
672 670
673 671 Default destination, same directory
674 672
675 673 $ hg init q
676 674 $ hg clone q
677 675 destination directory: q
678 676 abort: destination 'q' is not empty
679 677 [255]
680 678
681 679 destination directory not empty
682 680
683 681 $ mkdir a
684 682 $ echo stuff > a/a
685 683 $ hg clone q a
686 684 abort: destination 'a' is not empty
687 685 [255]
688 686
689 687
690 688 #if unix-permissions no-root
691 689
692 690 leave existing directory in place after clone failure
693 691
694 692 $ hg init c
695 693 $ cd c
696 694 $ echo c > c
697 695 $ hg commit -A -m test
698 696 adding c
699 697 $ chmod -rx .hg/store/data
700 698 $ cd ..
701 699 $ mkdir d
702 700 $ hg clone c d 2> err
703 701 [255]
704 702 $ test -d d
705 703 $ test -d d/.hg
706 704 [1]
707 705
708 706 re-enable perm to allow deletion
709 707
710 708 $ chmod +rx c/.hg/store/data
711 709
712 710 #endif
713 711
714 712 $ cd ..
715 713
716 714 Test clone from the repository in (emulated) revlog format 0 (issue4203):
717 715
718 716 $ mkdir issue4203
719 717 $ mkdir -p src/.hg
720 718 $ echo foo > src/foo
721 719 $ hg -R src add src/foo
722 720 $ hg -R src commit -m '#0'
723 721 $ hg -R src log -q
724 722 0:e1bab28bca43
725 723 $ hg clone -U -q src dst
726 724 $ hg -R dst log -q
727 725 0:e1bab28bca43
728 726
729 727 Create repositories to test auto sharing functionality
730 728
731 729 $ cat >> $HGRCPATH << EOF
732 730 > [extensions]
733 731 > share=
734 732 > EOF
735 733
736 734 $ hg init empty
737 735 $ hg init source1a
738 736 $ cd source1a
739 737 $ echo initial1 > foo
740 738 $ hg -q commit -A -m initial
741 739 $ echo second > foo
742 740 $ hg commit -m second
743 741 $ cd ..
744 742
745 743 $ hg init filteredrev0
746 744 $ cd filteredrev0
747 745 $ cat >> .hg/hgrc << EOF
748 746 > [experimental]
749 747 > evolution.createmarkers=True
750 748 > EOF
751 749 $ echo initial1 > foo
752 750 $ hg -q commit -A -m initial0
753 751 $ hg -q up -r null
754 752 $ echo initial2 > foo
755 753 $ hg -q commit -A -m initial1
756 754 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
757 755 obsoleted 1 changesets
758 756 $ cd ..
759 757
760 758 $ hg -q clone --pull source1a source1b
761 759 $ cd source1a
762 760 $ hg bookmark bookA
763 761 $ echo 1a > foo
764 762 $ hg commit -m 1a
765 763 $ cd ../source1b
766 764 $ hg -q up -r 0
767 765 $ echo head1 > foo
768 766 $ hg commit -m head1
769 767 created new head
770 768 $ hg bookmark head1
771 769 $ hg -q up -r 0
772 770 $ echo head2 > foo
773 771 $ hg commit -m head2
774 772 created new head
775 773 $ hg bookmark head2
776 774 $ hg -q up -r 0
777 775 $ hg branch branch1
778 776 marked working directory as branch branch1
779 777 (branches are permanent and global, did you want a bookmark?)
780 778 $ echo branch1 > foo
781 779 $ hg commit -m branch1
782 780 $ hg -q up -r 0
783 781 $ hg branch branch2
784 782 marked working directory as branch branch2
785 783 $ echo branch2 > foo
786 784 $ hg commit -m branch2
787 785 $ cd ..
788 786 $ hg init source2
789 787 $ cd source2
790 788 $ echo initial2 > foo
791 789 $ hg -q commit -A -m initial2
792 790 $ echo second > foo
793 791 $ hg commit -m second
794 792 $ cd ..
795 793
796 794 Clone with auto share from an empty repo should not result in share
797 795
798 796 $ mkdir share
799 797 $ hg --config share.pool=share clone empty share-empty
800 798 (not using pooled storage: remote appears to be empty)
801 799 updating to branch default
802 800 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
803 801 $ ls share
804 802 $ test -d share-empty/.hg/store
805 803 $ test -f share-empty/.hg/sharedpath
806 804 [1]
807 805
808 806 Clone with auto share from a repo with filtered revision 0 should not result in share
809 807
810 808 $ hg --config share.pool=share clone filteredrev0 share-filtered
811 809 (not using pooled storage: unable to resolve identity of remote)
812 810 requesting all changes
813 811 adding changesets
814 812 adding manifests
815 813 adding file changes
816 814 added 1 changesets with 1 changes to 1 files
817 815 new changesets e082c1832e09
818 816 updating to branch default
819 817 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
820 818
821 819 Clone from repo with content should result in shared store being created
822 820
823 821 $ hg --config share.pool=share clone source1a share-dest1a
824 822 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
825 823 requesting all changes
826 824 adding changesets
827 825 adding manifests
828 826 adding file changes
829 827 added 3 changesets with 3 changes to 1 files
830 828 new changesets b5f04eac9d8f:e5bfe23c0b47
831 829 searching for changes
832 830 no changes found
833 831 adding remote bookmark bookA
834 832 updating working directory
835 833 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
836 834
837 835 The shared repo should have been created
838 836
839 837 $ ls share
840 838 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
841 839
842 840 The destination should point to it
843 841
844 842 $ cat share-dest1a/.hg/sharedpath; echo
845 843 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
846 844
847 845 The destination should have bookmarks
848 846
849 847 $ hg -R share-dest1a bookmarks
850 848 bookA 2:e5bfe23c0b47
851 849
852 850 The default path should be the remote, not the share
853 851
854 852 $ hg -R share-dest1a config paths.default
855 853 $TESTTMP/source1a
856 854
857 855 Clone with existing share dir should result in pull + share
858 856
859 857 $ hg --config share.pool=share clone source1b share-dest1b
860 858 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
861 859 searching for changes
862 860 adding changesets
863 861 adding manifests
864 862 adding file changes
865 863 added 4 changesets with 4 changes to 1 files (+4 heads)
866 864 adding remote bookmark head1
867 865 adding remote bookmark head2
868 866 new changesets 4a8dc1ab4c13:6bacf4683960
869 867 updating working directory
870 868 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
871 869
872 870 $ ls share
873 871 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
874 872
875 873 $ cat share-dest1b/.hg/sharedpath; echo
876 874 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
877 875
878 876 We only get bookmarks from the remote, not everything in the share
879 877
880 878 $ hg -R share-dest1b bookmarks
881 879 head1 3:4a8dc1ab4c13
882 880 head2 4:99f71071f117
883 881
884 882 Default path should be source, not share.
885 883
886 884 $ hg -R share-dest1b config paths.default
887 885 $TESTTMP/source1b
888 886
889 887 Checked out revision should be head of default branch
890 888
891 889 $ hg -R share-dest1b log -r .
892 890 changeset: 4:99f71071f117
893 891 bookmark: head2
894 892 parent: 0:b5f04eac9d8f
895 893 user: test
896 894 date: Thu Jan 01 00:00:00 1970 +0000
897 895 summary: head2
898 896
899 897
900 898 Clone from unrelated repo should result in new share
901 899
902 900 $ hg --config share.pool=share clone source2 share-dest2
903 901 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
904 902 requesting all changes
905 903 adding changesets
906 904 adding manifests
907 905 adding file changes
908 906 added 2 changesets with 2 changes to 1 files
909 907 new changesets 22aeff664783:63cf6c3dba4a
910 908 searching for changes
911 909 no changes found
912 910 updating working directory
913 911 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
914 912
915 913 $ ls share
916 914 22aeff664783fd44c6d9b435618173c118c3448e
917 915 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
918 916
919 917 remote naming mode works as advertised
920 918
921 919 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
922 920 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
923 921 requesting all changes
924 922 adding changesets
925 923 adding manifests
926 924 adding file changes
927 925 added 3 changesets with 3 changes to 1 files
928 926 new changesets b5f04eac9d8f:e5bfe23c0b47
929 927 searching for changes
930 928 no changes found
931 929 adding remote bookmark bookA
932 930 updating working directory
933 931 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
934 932
935 933 $ ls shareremote
936 934 195bb1fcdb595c14a6c13e0269129ed78f6debde
937 935
938 936 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
939 937 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
940 938 requesting all changes
941 939 adding changesets
942 940 adding manifests
943 941 adding file changes
944 942 added 6 changesets with 6 changes to 1 files (+4 heads)
945 943 new changesets b5f04eac9d8f:6bacf4683960
946 944 searching for changes
947 945 no changes found
948 946 adding remote bookmark head1
949 947 adding remote bookmark head2
950 948 updating working directory
951 949 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
952 950
953 951 $ ls shareremote
954 952 195bb1fcdb595c14a6c13e0269129ed78f6debde
955 953 c0d4f83847ca2a873741feb7048a45085fd47c46
956 954
957 955 request to clone a single revision is respected in sharing mode
958 956
959 957 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
960 958 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
961 959 adding changesets
962 960 adding manifests
963 961 adding file changes
964 962 added 2 changesets with 2 changes to 1 files
965 963 new changesets b5f04eac9d8f:4a8dc1ab4c13
966 964 no changes found
967 965 adding remote bookmark head1
968 966 updating working directory
969 967 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
970 968
971 969 $ hg -R share-1arev log -G
972 970 @ changeset: 1:4a8dc1ab4c13
973 971 | bookmark: head1
974 972 | tag: tip
975 973 | user: test
976 974 | date: Thu Jan 01 00:00:00 1970 +0000
977 975 | summary: head1
978 976 |
979 977 o changeset: 0:b5f04eac9d8f
980 978 user: test
981 979 date: Thu Jan 01 00:00:00 1970 +0000
982 980 summary: initial
983 981
984 982
985 983 making another clone should only pull down requested rev
986 984
987 985 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
988 986 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
989 987 searching for changes
990 988 adding changesets
991 989 adding manifests
992 990 adding file changes
993 991 added 1 changesets with 1 changes to 1 files (+1 heads)
994 992 adding remote bookmark head1
995 993 adding remote bookmark head2
996 994 new changesets 99f71071f117
997 995 updating working directory
998 996 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 997
1000 998 $ hg -R share-1brev log -G
1001 999 @ changeset: 2:99f71071f117
1002 1000 | bookmark: head2
1003 1001 | tag: tip
1004 1002 | parent: 0:b5f04eac9d8f
1005 1003 | user: test
1006 1004 | date: Thu Jan 01 00:00:00 1970 +0000
1007 1005 | summary: head2
1008 1006 |
1009 1007 | o changeset: 1:4a8dc1ab4c13
1010 1008 |/ bookmark: head1
1011 1009 | user: test
1012 1010 | date: Thu Jan 01 00:00:00 1970 +0000
1013 1011 | summary: head1
1014 1012 |
1015 1013 o changeset: 0:b5f04eac9d8f
1016 1014 user: test
1017 1015 date: Thu Jan 01 00:00:00 1970 +0000
1018 1016 summary: initial
1019 1017
1020 1018
1021 1019 Request to clone a single branch is respected in sharing mode
1022 1020
1023 1021 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1024 1022 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1025 1023 adding changesets
1026 1024 adding manifests
1027 1025 adding file changes
1028 1026 added 2 changesets with 2 changes to 1 files
1029 1027 new changesets b5f04eac9d8f:5f92a6c1a1b1
1030 1028 no changes found
1031 1029 updating working directory
1032 1030 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1033 1031
1034 1032 $ hg -R share-1bbranch1 log -G
1035 1033 o changeset: 1:5f92a6c1a1b1
1036 1034 | branch: branch1
1037 1035 | tag: tip
1038 1036 | user: test
1039 1037 | date: Thu Jan 01 00:00:00 1970 +0000
1040 1038 | summary: branch1
1041 1039 |
1042 1040 @ changeset: 0:b5f04eac9d8f
1043 1041 user: test
1044 1042 date: Thu Jan 01 00:00:00 1970 +0000
1045 1043 summary: initial
1046 1044
1047 1045
1048 1046 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1049 1047 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1050 1048 searching for changes
1051 1049 adding changesets
1052 1050 adding manifests
1053 1051 adding file changes
1054 1052 added 1 changesets with 1 changes to 1 files (+1 heads)
1055 1053 new changesets 6bacf4683960
1056 1054 updating working directory
1057 1055 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1058 1056
1059 1057 $ hg -R share-1bbranch2 log -G
1060 1058 o changeset: 2:6bacf4683960
1061 1059 | branch: branch2
1062 1060 | tag: tip
1063 1061 | parent: 0:b5f04eac9d8f
1064 1062 | user: test
1065 1063 | date: Thu Jan 01 00:00:00 1970 +0000
1066 1064 | summary: branch2
1067 1065 |
1068 1066 | o changeset: 1:5f92a6c1a1b1
1069 1067 |/ branch: branch1
1070 1068 | user: test
1071 1069 | date: Thu Jan 01 00:00:00 1970 +0000
1072 1070 | summary: branch1
1073 1071 |
1074 1072 @ changeset: 0:b5f04eac9d8f
1075 1073 user: test
1076 1074 date: Thu Jan 01 00:00:00 1970 +0000
1077 1075 summary: initial
1078 1076
1079 1077
1080 1078 -U is respected in share clone mode
1081 1079
1082 1080 $ hg --config share.pool=share clone -U source1a share-1anowc
1083 1081 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1084 1082 searching for changes
1085 1083 no changes found
1086 1084 adding remote bookmark bookA
1087 1085
1088 1086 $ ls share-1anowc
1089 1087
1090 1088 Test that auto sharing doesn't cause failure of "hg clone local remote"
1091 1089
1092 1090 $ cd $TESTTMP
1093 1091 $ hg -R a id -r 0
1094 1092 acb14030fe0a
1095 1093 $ hg id -R remote -r 0
1096 1094 abort: repository remote not found!
1097 1095 [255]
1098 1096 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1099 1097 $ hg -R remote id -r 0
1100 1098 acb14030fe0a
1101 1099
1102 1100 Cloning into pooled storage doesn't race (issue5104)
1103 1101
1104 1102 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1105 1103 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1106 1104 $ wait
1107 1105
1108 1106 $ hg -R share-destrace1 log -r tip
1109 1107 changeset: 2:e5bfe23c0b47
1110 1108 bookmark: bookA
1111 1109 tag: tip
1112 1110 user: test
1113 1111 date: Thu Jan 01 00:00:00 1970 +0000
1114 1112 summary: 1a
1115 1113
1116 1114
1117 1115 $ hg -R share-destrace2 log -r tip
1118 1116 changeset: 2:e5bfe23c0b47
1119 1117 bookmark: bookA
1120 1118 tag: tip
1121 1119 user: test
1122 1120 date: Thu Jan 01 00:00:00 1970 +0000
1123 1121 summary: 1a
1124 1122
1125 1123 One repo should be new, the other should be shared from the pool. We
1126 1124 don't care which is which, so we just make sure we always print the
1127 1125 one containing "new pooled" first, then one one containing "existing
1128 1126 pooled".
1129 1127
1130 1128 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1131 1129 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1132 1130 requesting all changes
1133 1131 adding changesets
1134 1132 adding manifests
1135 1133 adding file changes
1136 1134 added 3 changesets with 3 changes to 1 files
1137 1135 new changesets b5f04eac9d8f:e5bfe23c0b47
1138 1136 searching for changes
1139 1137 no changes found
1140 1138 adding remote bookmark bookA
1141 1139 updating working directory
1142 1140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1143 1141
1144 1142 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1145 1143 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1146 1144 searching for changes
1147 1145 no changes found
1148 1146 adding remote bookmark bookA
1149 1147 updating working directory
1150 1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1151 1149
1152 1150 SEC: check for unsafe ssh url
1153 1151
1154 1152 $ cat >> $HGRCPATH << EOF
1155 1153 > [ui]
1156 1154 > ssh = sh -c "read l; read l; read l"
1157 1155 > EOF
1158 1156
1159 1157 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1160 1158 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1161 1159 [255]
1162 1160 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1163 1161 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1164 1162 [255]
1165 1163 $ hg clone 'ssh://fakehost|touch%20owned/path'
1166 1164 abort: no suitable response from remote hg!
1167 1165 [255]
1168 1166 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1169 1167 abort: no suitable response from remote hg!
1170 1168 [255]
1171 1169
1172 1170 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1173 1171 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1174 1172 [255]
1175 1173
1176 1174 #if windows
1177 1175 $ hg clone "ssh://%26touch%20owned%20/" --debug
1178 1176 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1179 1177 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1180 1178 sending hello command
1181 1179 sending between command
1182 1180 abort: no suitable response from remote hg!
1183 1181 [255]
1184 1182 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1185 1183 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1186 1184 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1187 1185 sending hello command
1188 1186 sending between command
1189 1187 abort: no suitable response from remote hg!
1190 1188 [255]
1191 1189 #else
1192 1190 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1193 1191 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1194 1192 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1195 1193 sending hello command
1196 1194 sending between command
1197 1195 abort: no suitable response from remote hg!
1198 1196 [255]
1199 1197 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1200 1198 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1201 1199 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1202 1200 sending hello command
1203 1201 sending between command
1204 1202 abort: no suitable response from remote hg!
1205 1203 [255]
1206 1204 #endif
1207 1205
1208 1206 $ hg clone "ssh://v-alid.example.com/" --debug
1209 1207 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1210 1208 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1211 1209 sending hello command
1212 1210 sending between command
1213 1211 abort: no suitable response from remote hg!
1214 1212 [255]
1215 1213
1216 1214 We should not have created a file named owned - if it exists, the
1217 1215 attack succeeded.
1218 1216 $ if test -f owned; then echo 'you got owned'; fi
1219 1217
1220 1218 Cloning without fsmonitor enabled does not print a warning for small repos
1221 1219
1222 1220 $ hg clone a fsmonitor-default
1223 1221 updating to bookmark @ on branch stable
1224 1222 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1225 1223
1226 1224 Lower the warning threshold to simulate a large repo
1227 1225
1228 1226 $ cat >> $HGRCPATH << EOF
1229 1227 > [fsmonitor]
1230 1228 > warn_update_file_count = 2
1231 1229 > EOF
1232 1230
1233 1231 We should see a warning about no fsmonitor on supported platforms
1234 1232
1235 1233 #if linuxormacos no-fsmonitor
1236 1234 $ hg clone a nofsmonitor
1237 1235 updating to bookmark @ on branch stable
1238 1236 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1239 1237 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1240 1238 #else
1241 1239 $ hg clone a nofsmonitor
1242 1240 updating to bookmark @ on branch stable
1243 1241 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1244 1242 #endif
1245 1243
1246 1244 We should not see warning about fsmonitor when it is enabled
1247 1245
1248 1246 #if fsmonitor
1249 1247 $ hg clone a fsmonitor-enabled
1250 1248 updating to bookmark @ on branch stable
1251 1249 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1252 1250 #endif
1253 1251
1254 1252 We can disable the fsmonitor warning
1255 1253
1256 1254 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1257 1255 updating to bookmark @ on branch stable
1258 1256 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1259 1257
1260 1258 Loaded fsmonitor but disabled in config should still print warning
1261 1259
1262 1260 #if linuxormacos fsmonitor
1263 1261 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1264 1262 updating to bookmark @ on branch stable
1265 1263 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1266 1264 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1267 1265 #endif
1268 1266
1269 1267 Warning not printed if working directory isn't empty
1270 1268
1271 1269 $ hg -q clone a fsmonitor-update
1272 1270 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1273 1271 $ cd fsmonitor-update
1274 1272 $ hg up acb14030fe0a
1275 1273 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1276 1274 (leaving bookmark @)
1277 1275 $ hg up cf0fe1914066
1278 1276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1279 1277
1280 1278 `hg update` from null revision also prints
1281 1279
1282 1280 $ hg up null
1283 1281 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1284 1282
1285 1283 #if linuxormacos no-fsmonitor
1286 1284 $ hg up cf0fe1914066
1287 1285 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1288 1286 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1289 1287 #else
1290 1288 $ hg up cf0fe1914066
1291 1289 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1292 1290 #endif
1293 1291
1294 1292 $ cd ..
1295 1293
@@ -1,622 +1,618 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > convert=
4 4 > [convert]
5 5 > hg.saverev=False
6 6 > EOF
7 7 $ hg help convert
8 8 hg convert [OPTION]... SOURCE [DEST [REVMAP]]
9 9
10 10 convert a foreign SCM repository to a Mercurial one.
11 11
12 12 Accepted source formats [identifiers]:
13 13
14 14 - Mercurial [hg]
15 15 - CVS [cvs]
16 16 - Darcs [darcs]
17 17 - git [git]
18 18 - Subversion [svn]
19 19 - Monotone [mtn]
20 20 - GNU Arch [gnuarch]
21 21 - Bazaar [bzr]
22 22 - Perforce [p4]
23 23
24 24 Accepted destination formats [identifiers]:
25 25
26 26 - Mercurial [hg]
27 27 - Subversion [svn] (history on branches is not preserved)
28 28
29 29 If no revision is given, all revisions will be converted. Otherwise,
30 30 convert will only import up to the named revision (given in a format
31 31 understood by the source).
32 32
33 33 If no destination directory name is specified, it defaults to the basename
34 34 of the source with "-hg" appended. If the destination repository doesn't
35 35 exist, it will be created.
36 36
37 37 By default, all sources except Mercurial will use --branchsort. Mercurial
38 38 uses --sourcesort to preserve original revision numbers order. Sort modes
39 39 have the following effects:
40 40
41 41 --branchsort convert from parent to child revision when possible, which
42 42 means branches are usually converted one after the other.
43 43 It generates more compact repositories.
44 44 --datesort sort revisions by date. Converted repositories have good-
45 45 looking changelogs but are often an order of magnitude
46 46 larger than the same ones generated by --branchsort.
47 47 --sourcesort try to preserve source revisions order, only supported by
48 48 Mercurial sources.
49 49 --closesort try to move closed revisions as close as possible to parent
50 50 branches, only supported by Mercurial sources.
51 51
52 52 If "REVMAP" isn't given, it will be put in a default location
53 53 ("<dest>/.hg/shamap" by default). The "REVMAP" is a simple text file that
54 54 maps each source commit ID to the destination ID for that revision, like
55 55 so:
56 56
57 57 <source ID> <destination ID>
58 58
59 59 If the file doesn't exist, it's automatically created. It's updated on
60 60 each commit copied, so 'hg convert' can be interrupted and can be run
61 61 repeatedly to copy new commits.
62 62
63 63 The authormap is a simple text file that maps each source commit author to
64 64 a destination commit author. It is handy for source SCMs that use unix
65 65 logins to identify authors (e.g.: CVS). One line per author mapping and
66 66 the line format is:
67 67
68 68 source author = destination author
69 69
70 70 Empty lines and lines starting with a "#" are ignored.
71 71
72 72 The filemap is a file that allows filtering and remapping of files and
73 73 directories. Each line can contain one of the following directives:
74 74
75 75 include path/to/file-or-dir
76 76
77 77 exclude path/to/file-or-dir
78 78
79 79 rename path/to/source path/to/destination
80 80
81 81 Comment lines start with "#". A specified path matches if it equals the
82 82 full relative name of a file or one of its parent directories. The
83 83 "include" or "exclude" directive with the longest matching path applies,
84 84 so line order does not matter.
85 85
86 86 The "include" directive causes a file, or all files under a directory, to
87 87 be included in the destination repository. The default if there are no
88 88 "include" statements is to include everything. If there are any "include"
89 89 statements, nothing else is included. The "exclude" directive causes files
90 90 or directories to be omitted. The "rename" directive renames a file or
91 91 directory if it is converted. To rename from a subdirectory into the root
92 92 of the repository, use "." as the path to rename to.
93 93
94 94 "--full" will make sure the converted changesets contain exactly the right
95 95 files with the right content. It will make a full conversion of all files,
96 96 not just the ones that have changed. Files that already are correct will
97 97 not be changed. This can be used to apply filemap changes when converting
98 98 incrementally. This is currently only supported for Mercurial and
99 99 Subversion.
100 100
101 101 The splicemap is a file that allows insertion of synthetic history,
102 102 letting you specify the parents of a revision. This is useful if you want
103 103 to e.g. give a Subversion merge two parents, or graft two disconnected
104 104 series of history together. Each entry contains a key, followed by a
105 105 space, followed by one or two comma-separated values:
106 106
107 107 key parent1, parent2
108 108
109 109 The key is the revision ID in the source revision control system whose
110 110 parents should be modified (same format as a key in .hg/shamap). The
111 111 values are the revision IDs (in either the source or destination revision
112 112 control system) that should be used as the new parents for that node. For
113 113 example, if you have merged "release-1.0" into "trunk", then you should
114 114 specify the revision on "trunk" as the first parent and the one on the
115 115 "release-1.0" branch as the second.
116 116
117 117 The branchmap is a file that allows you to rename a branch when it is
118 118 being brought in from whatever external repository. When used in
119 119 conjunction with a splicemap, it allows for a powerful combination to help
120 120 fix even the most badly mismanaged repositories and turn them into nicely
121 121 structured Mercurial repositories. The branchmap contains lines of the
122 122 form:
123 123
124 124 original_branch_name new_branch_name
125 125
126 126 where "original_branch_name" is the name of the branch in the source
127 127 repository, and "new_branch_name" is the name of the branch is the
128 128 destination repository. No whitespace is allowed in the new branch name.
129 129 This can be used to (for instance) move code in one repository from
130 130 "default" to a named branch.
131 131
132 132 Mercurial Source
133 133 ################
134 134
135 135 The Mercurial source recognizes the following configuration options, which
136 136 you can set on the command line with "--config":
137 137
138 138 convert.hg.ignoreerrors
139 139 ignore integrity errors when reading. Use it to fix
140 140 Mercurial repositories with missing revlogs, by converting
141 141 from and to Mercurial. Default is False.
142 142 convert.hg.saverev
143 143 store original revision ID in changeset (forces target IDs
144 144 to change). It takes a boolean argument and defaults to
145 145 False.
146 146 convert.hg.startrev
147 147 specify the initial Mercurial revision. The default is 0.
148 148 convert.hg.revs
149 149 revset specifying the source revisions to convert.
150 150
151 151 CVS Source
152 152 ##########
153 153
154 154 CVS source will use a sandbox (i.e. a checked-out copy) from CVS to
155 155 indicate the starting point of what will be converted. Direct access to
156 156 the repository files is not needed, unless of course the repository is
157 157 ":local:". The conversion uses the top level directory in the sandbox to
158 158 find the CVS repository, and then uses CVS rlog commands to find files to
159 159 convert. This means that unless a filemap is given, all files under the
160 160 starting directory will be converted, and that any directory
161 161 reorganization in the CVS sandbox is ignored.
162 162
163 163 The following options can be used with "--config":
164 164
165 165 convert.cvsps.cache
166 166 Set to False to disable remote log caching, for testing and
167 167 debugging purposes. Default is True.
168 168 convert.cvsps.fuzz
169 169 Specify the maximum time (in seconds) that is allowed
170 170 between commits with identical user and log message in a
171 171 single changeset. When very large files were checked in as
172 172 part of a changeset then the default may not be long enough.
173 173 The default is 60.
174 174 convert.cvsps.logencoding
175 175 Specify encoding name to be used for transcoding CVS log
176 176 messages. Multiple encoding names can be specified as a list
177 177 (see 'hg help config.Syntax'), but only the first acceptable
178 178 encoding in the list is used per CVS log entries. This
179 179 transcoding is executed before cvslog hook below.
180 180 convert.cvsps.mergeto
181 181 Specify a regular expression to which commit log messages
182 182 are matched. If a match occurs, then the conversion process
183 183 will insert a dummy revision merging the branch on which
184 184 this log message occurs to the branch indicated in the
185 185 regex. Default is "{{mergetobranch ([-\w]+)}}"
186 186 convert.cvsps.mergefrom
187 187 Specify a regular expression to which commit log messages
188 188 are matched. If a match occurs, then the conversion process
189 189 will add the most recent revision on the branch indicated in
190 190 the regex as the second parent of the changeset. Default is
191 191 "{{mergefrombranch ([-\w]+)}}"
192 192 convert.localtimezone
193 193 use local time (as determined by the TZ environment
194 194 variable) for changeset date/times. The default is False
195 195 (use UTC).
196 196 hooks.cvslog Specify a Python function to be called at the end of
197 197 gathering the CVS log. The function is passed a list with
198 198 the log entries, and can modify the entries in-place, or add
199 199 or delete them.
200 200 hooks.cvschangesets
201 201 Specify a Python function to be called after the changesets
202 202 are calculated from the CVS log. The function is passed a
203 203 list with the changeset entries, and can modify the
204 204 changesets in-place, or add or delete them.
205 205
206 206 An additional "debugcvsps" Mercurial command allows the builtin changeset
207 207 merging code to be run without doing a conversion. Its parameters and
208 208 output are similar to that of cvsps 2.1. Please see the command help for
209 209 more details.
210 210
211 211 Subversion Source
212 212 #################
213 213
214 214 Subversion source detects classical trunk/branches/tags layouts. By
215 215 default, the supplied "svn://repo/path/" source URL is converted as a
216 216 single branch. If "svn://repo/path/trunk" exists it replaces the default
217 217 branch. If "svn://repo/path/branches" exists, its subdirectories are
218 218 listed as possible branches. If "svn://repo/path/tags" exists, it is
219 219 looked for tags referencing converted branches. Default "trunk",
220 220 "branches" and "tags" values can be overridden with following options. Set
221 221 them to paths relative to the source URL, or leave them blank to disable
222 222 auto detection.
223 223
224 224 The following options can be set with "--config":
225 225
226 226 convert.svn.branches
227 227 specify the directory containing branches. The default is
228 228 "branches".
229 229 convert.svn.tags
230 230 specify the directory containing tags. The default is
231 231 "tags".
232 232 convert.svn.trunk
233 233 specify the name of the trunk branch. The default is
234 234 "trunk".
235 235 convert.localtimezone
236 236 use local time (as determined by the TZ environment
237 237 variable) for changeset date/times. The default is False
238 238 (use UTC).
239 239
240 240 Source history can be retrieved starting at a specific revision, instead
241 241 of being integrally converted. Only single branch conversions are
242 242 supported.
243 243
244 244 convert.svn.startrev
245 245 specify start Subversion revision number. The default is 0.
246 246
247 247 Git Source
248 248 ##########
249 249
250 250 The Git importer converts commits from all reachable branches (refs in
251 251 refs/heads) and remotes (refs in refs/remotes) to Mercurial. Branches are
252 252 converted to bookmarks with the same name, with the leading 'refs/heads'
253 253 stripped. Git submodules are converted to Git subrepos in Mercurial.
254 254
255 255 The following options can be set with "--config":
256 256
257 257 convert.git.similarity
258 258 specify how similar files modified in a commit must be to be
259 259 imported as renames or copies, as a percentage between "0"
260 260 (disabled) and "100" (files must be identical). For example,
261 261 "90" means that a delete/add pair will be imported as a
262 262 rename if more than 90% of the file hasn't changed. The
263 263 default is "50".
264 264 convert.git.findcopiesharder
265 265 while detecting copies, look at all files in the working
266 266 copy instead of just changed ones. This is very expensive
267 267 for large projects, and is only effective when
268 268 "convert.git.similarity" is greater than 0. The default is
269 269 False.
270 270 convert.git.renamelimit
271 271 perform rename and copy detection up to this many changed
272 272 files in a commit. Increasing this will make rename and copy
273 273 detection more accurate but will significantly slow down
274 274 computation on large projects. The option is only relevant
275 275 if "convert.git.similarity" is greater than 0. The default
276 276 is "400".
277 277 convert.git.committeractions
278 278 list of actions to take when processing author and committer
279 279 values.
280 280
281 281 Git commits have separate author (who wrote the commit) and committer
282 282 (who applied the commit) fields. Not all destinations support separate
283 283 author and committer fields (including Mercurial). This config option
284 284 controls what to do with these author and committer fields during
285 285 conversion.
286 286
287 287 A value of "messagedifferent" will append a "committer: ..." line to
288 288 the commit message if the Git committer is different from the author.
289 289 The prefix of that line can be specified using the syntax
290 290 "messagedifferent=<prefix>". e.g. "messagedifferent=git-committer:".
291 291 When a prefix is specified, a space will always be inserted between
292 292 the prefix and the value.
293 293
294 294 "messagealways" behaves like "messagedifferent" except it will always
295 295 result in a "committer: ..." line being appended to the commit
296 296 message. This value is mutually exclusive with "messagedifferent".
297 297
298 298 "dropcommitter" will remove references to the committer. Only
299 299 references to the author will remain. Actions that add references to
300 300 the committer will have no effect when this is set.
301 301
302 302 "replaceauthor" will replace the value of the author field with the
303 303 committer. Other actions that add references to the committer will
304 304 still take effect when this is set.
305 305
306 306 The default is "messagedifferent".
307 307
308 308 convert.git.extrakeys
309 309 list of extra keys from commit metadata to copy to the
310 310 destination. Some Git repositories store extra metadata in
311 311 commits. By default, this non-default metadata will be lost
312 312 during conversion. Setting this config option can retain
313 313 that metadata. Some built-in keys such as "parent" and
314 314 "branch" are not allowed to be copied.
315 315 convert.git.remoteprefix
316 316 remote refs are converted as bookmarks with
317 317 "convert.git.remoteprefix" as a prefix followed by a /. The
318 318 default is 'remote'.
319 319 convert.git.saverev
320 320 whether to store the original Git commit ID in the metadata
321 321 of the destination commit. The default is True.
322 322 convert.git.skipsubmodules
323 323 does not convert root level .gitmodules files or files with
324 324 160000 mode indicating a submodule. Default is False.
325 325
326 326 Perforce Source
327 327 ###############
328 328
329 329 The Perforce (P4) importer can be given a p4 depot path or a client
330 330 specification as source. It will convert all files in the source to a flat
331 331 Mercurial repository, ignoring labels, branches and integrations. Note
332 332 that when a depot path is given you then usually should specify a target
333 333 directory, because otherwise the target may be named "...-hg".
334 334
335 335 The following options can be set with "--config":
336 336
337 337 convert.p4.encoding
338 338 specify the encoding to use when decoding standard output of
339 339 the Perforce command line tool. The default is default
340 340 system encoding.
341 341 convert.p4.startrev
342 342 specify initial Perforce revision (a Perforce changelist
343 343 number).
344 344
345 345 Mercurial Destination
346 346 #####################
347 347
348 348 The Mercurial destination will recognize Mercurial subrepositories in the
349 349 destination directory, and update the .hgsubstate file automatically if
350 350 the destination subrepositories contain the <dest>/<sub>/.hg/shamap file.
351 351 Converting a repository with subrepositories requires converting a single
352 352 repository at a time, from the bottom up.
353 353
354 354 The following options are supported:
355 355
356 356 convert.hg.clonebranches
357 357 dispatch source branches in separate clones. The default is
358 358 False.
359 359 convert.hg.tagsbranch
360 360 branch name for tag revisions, defaults to "default".
361 361 convert.hg.usebranchnames
362 362 preserve branch names. The default is True.
363 363 convert.hg.sourcename
364 364 records the given string as a 'convert_source' extra value
365 365 on each commit made in the target repository. The default is
366 366 None.
367 367
368 368 All Destinations
369 369 ################
370 370
371 371 All destination types accept the following options:
372 372
373 373 convert.skiptags
374 374 does not convert tags from the source repo to the target
375 375 repo. The default is False.
376 376
377 377 options ([+] can be repeated):
378 378
379 379 -s --source-type TYPE source repository type
380 380 -d --dest-type TYPE destination repository type
381 381 -r --rev REV [+] import up to source revision REV
382 382 -A --authormap FILE remap usernames using this file
383 383 --filemap FILE remap file names using contents of file
384 384 --full apply filemap changes by converting all files again
385 385 --splicemap FILE splice synthesized history into place
386 386 --branchmap FILE change branch names while converting
387 387 --branchsort try to sort changesets by branches
388 388 --datesort try to sort changesets by date
389 389 --sourcesort preserve source changesets order
390 390 --closesort try to reorder closed revisions
391 391
392 392 (some details hidden, use --verbose to show complete help)
393 393 $ hg init a
394 394 $ cd a
395 395 $ echo a > a
396 396 $ hg ci -d'0 0' -Ama
397 397 adding a
398 398 $ hg cp a b
399 399 $ hg ci -d'1 0' -mb
400 400 $ hg rm a
401 401 $ hg ci -d'2 0' -mc
402 402 $ hg mv b a
403 403 $ hg ci -d'3 0' -md
404 404 $ echo a >> a
405 405 $ hg ci -d'4 0' -me
406 406 $ cd ..
407 407 $ hg convert a 2>&1 | grep -v 'subversion python bindings could not be loaded'
408 408 assuming destination a-hg
409 409 initializing destination a-hg repository
410 410 scanning source...
411 411 sorting...
412 412 converting...
413 413 4 a
414 414 3 b
415 415 2 c
416 416 1 d
417 417 0 e
418 418 $ hg --cwd a-hg pull ../a
419 419 pulling from ../a
420 420 searching for changes
421 421 no changes found
422 422
423 423 conversion to existing file should fail
424 424
425 425 $ touch bogusfile
426 426 $ hg convert a bogusfile
427 427 initializing destination bogusfile repository
428 428 abort: cannot create new bundle repository
429 429 [255]
430 430
431 431 #if unix-permissions no-root
432 432
433 433 conversion to dir without permissions should fail
434 434
435 435 $ mkdir bogusdir
436 436 $ chmod 000 bogusdir
437 437
438 438 $ hg convert a bogusdir
439 439 abort: Permission denied: 'bogusdir'
440 440 [255]
441 441
442 442 user permissions should succeed
443 443
444 444 $ chmod 700 bogusdir
445 445 $ hg convert a bogusdir
446 446 initializing destination bogusdir repository
447 447 scanning source...
448 448 sorting...
449 449 converting...
450 450 4 a
451 451 3 b
452 452 2 c
453 453 1 d
454 454 0 e
455 455
456 456 #endif
457 457
458 458 test pre and post conversion actions
459 459
460 460 $ echo 'include b' > filemap
461 461 $ hg convert --debug --filemap filemap a partialb | \
462 462 > grep 'run hg'
463 463 run hg source pre-conversion action
464 464 run hg sink pre-conversion action
465 465 run hg sink post-conversion action
466 466 run hg source post-conversion action
467 467
468 468 converting empty dir should fail "nicely
469 469
470 470 $ mkdir emptydir
471 471
472 472 override $PATH to ensure p4 not visible; use $PYTHON in case we're
473 473 running from a devel copy, not a temp installation
474 474
475 475 $ PATH="$BINDIR" $PYTHON "$BINDIR"/hg convert emptydir
476 476 assuming destination emptydir-hg
477 477 initializing destination emptydir-hg repository
478 478 emptydir does not look like a CVS checkout
479 479 $TESTTMP/emptydir does not look like a Git repository
480 480 emptydir does not look like a Subversion repository
481 481 emptydir is not a local Mercurial repository
482 482 emptydir does not look like a darcs repository
483 483 emptydir does not look like a monotone repository
484 484 emptydir does not look like a GNU Arch repository
485 485 emptydir does not look like a Bazaar repository
486 486 cannot find required "p4" tool
487 487 abort: emptydir: missing or unsupported repository
488 488 [255]
489 489
490 490 convert with imaginary source type
491 491
492 492 $ hg convert --source-type foo a a-foo
493 493 initializing destination a-foo repository
494 494 abort: foo: invalid source repository type
495 495 [255]
496 496
497 497 convert with imaginary sink type
498 498
499 499 $ hg convert --dest-type foo a a-foo
500 500 abort: foo: invalid destination repository type
501 501 [255]
502 502
503 503 testing: convert must not produce duplicate entries in fncache
504 504
505 505 $ hg convert a b
506 506 initializing destination b repository
507 507 scanning source...
508 508 sorting...
509 509 converting...
510 510 4 a
511 511 3 b
512 512 2 c
513 513 1 d
514 514 0 e
515 515
516 516 contents of fncache file:
517 517
518 #if repofncache
518 519 $ cat b/.hg/store/fncache | sort
519 520 data/a.i (reporevlogstore !)
520 521 data/b.i (reporevlogstore !)
521 data/a/0f3078c2d7345d887b54f7c9dab0d91bfa57fd07 (reposimplestore !)
522 data/a/4271c3e84237016935a176b6f282fde2128458b0 (reposimplestore !)
523 data/a/b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 (reposimplestore !)
524 data/a/index (reposimplestore !)
525 data/b/37d9b5d994eab34eda9c16b195ace52c7b129980 (reposimplestore !)
526 data/b/index (reposimplestore !)
522 #endif
527 523
528 524 test bogus URL
529 525
530 526 $ hg convert -q bzr+ssh://foobar@selenic.com/baz baz
531 527 abort: bzr+ssh://foobar@selenic.com/baz: missing or unsupported repository
532 528 [255]
533 529
534 530 test revset converted() lookup
535 531
536 532 $ hg --config convert.hg.saverev=True convert a c
537 533 initializing destination c repository
538 534 scanning source...
539 535 sorting...
540 536 converting...
541 537 4 a
542 538 3 b
543 539 2 c
544 540 1 d
545 541 0 e
546 542 $ echo f > c/f
547 543 $ hg -R c ci -d'0 0' -Amf
548 544 adding f
549 545 created new head
550 546 $ hg -R c log -r "converted(09d945a62ce6)"
551 547 changeset: 1:98c3dd46a874
552 548 user: test
553 549 date: Thu Jan 01 00:00:01 1970 +0000
554 550 summary: b
555 551
556 552 $ hg -R c log -r "converted()"
557 553 changeset: 0:31ed57b2037c
558 554 user: test
559 555 date: Thu Jan 01 00:00:00 1970 +0000
560 556 summary: a
561 557
562 558 changeset: 1:98c3dd46a874
563 559 user: test
564 560 date: Thu Jan 01 00:00:01 1970 +0000
565 561 summary: b
566 562
567 563 changeset: 2:3b9ca06ef716
568 564 user: test
569 565 date: Thu Jan 01 00:00:02 1970 +0000
570 566 summary: c
571 567
572 568 changeset: 3:4e0debd37cf2
573 569 user: test
574 570 date: Thu Jan 01 00:00:03 1970 +0000
575 571 summary: d
576 572
577 573 changeset: 4:9de3bc9349c5
578 574 user: test
579 575 date: Thu Jan 01 00:00:04 1970 +0000
580 576 summary: e
581 577
582 578
583 579 test specifying a sourcename
584 580 $ echo g > a/g
585 581 $ hg -R a ci -d'0 0' -Amg
586 582 adding g
587 583 $ hg --config convert.hg.sourcename=mysource --config convert.hg.saverev=True convert a c
588 584 scanning source...
589 585 sorting...
590 586 converting...
591 587 0 g
592 588 $ hg -R c log -r tip --template '{extras % "{extra}\n"}'
593 589 branch=default
594 590 convert_revision=a3bc6100aa8ec03e00aaf271f1f50046fb432072
595 591 convert_source=mysource
596 592
597 593 $ cat > branchmap.txt << EOF
598 594 > old branch new_branch
599 595 > EOF
600 596
601 597 $ hg -R a branch -q 'old branch'
602 598 $ echo gg > a/g
603 599 $ hg -R a ci -m 'branch name with spaces'
604 600 $ hg convert --branchmap branchmap.txt a d
605 601 initializing destination d repository
606 602 scanning source...
607 603 sorting...
608 604 converting...
609 605 6 a
610 606 5 b
611 607 4 c
612 608 3 d
613 609 2 e
614 610 1 g
615 611 0 branch name with spaces
616 612
617 613 $ hg -R a branches
618 614 old branch 6:a24a66ade009
619 615 default 5:a3bc6100aa8e (inactive)
620 616 $ hg -R d branches
621 617 new_branch 6:64ed208b732b
622 618 default 5:a3bc6100aa8e (inactive)
@@ -1,436 +1,438 b''
1 #require repofncache
2
1 3 Init repo1:
2 4
3 5 $ hg init repo1
4 6 $ cd repo1
5 7 $ echo "some text" > a
6 8 $ hg add
7 9 adding a
8 10 $ hg ci -m first
9 11 $ cat .hg/store/fncache | sort
10 12 data/a.i
11 13
12 14 Testing a.i/b:
13 15
14 16 $ mkdir a.i
15 17 $ echo "some other text" > a.i/b
16 18 $ hg add
17 19 adding a.i/b
18 20 $ hg ci -m second
19 21 $ cat .hg/store/fncache | sort
20 22 data/a.i
21 23 data/a.i.hg/b.i
22 24
23 25 Testing a.i.hg/c:
24 26
25 27 $ mkdir a.i.hg
26 28 $ echo "yet another text" > a.i.hg/c
27 29 $ hg add
28 30 adding a.i.hg/c
29 31 $ hg ci -m third
30 32 $ cat .hg/store/fncache | sort
31 33 data/a.i
32 34 data/a.i.hg.hg/c.i
33 35 data/a.i.hg/b.i
34 36
35 37 Testing verify:
36 38
37 39 $ hg verify
38 40 checking changesets
39 41 checking manifests
40 42 crosschecking files in changesets and manifests
41 43 checking files
42 44 3 files, 3 changesets, 3 total revisions
43 45
44 46 $ rm .hg/store/fncache
45 47
46 48 $ hg verify
47 49 checking changesets
48 50 checking manifests
49 51 crosschecking files in changesets and manifests
50 52 checking files
51 53 warning: revlog 'data/a.i' not in fncache!
52 54 warning: revlog 'data/a.i.hg/c.i' not in fncache!
53 55 warning: revlog 'data/a.i/b.i' not in fncache!
54 56 3 files, 3 changesets, 3 total revisions
55 57 3 warnings encountered!
56 58 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
57 59
58 60 Follow the hint to make sure it works
59 61
60 62 $ hg debugrebuildfncache
61 63 adding data/a.i
62 64 adding data/a.i.hg/c.i
63 65 adding data/a.i/b.i
64 66 3 items added, 0 removed from fncache
65 67
66 68 $ hg verify
67 69 checking changesets
68 70 checking manifests
69 71 crosschecking files in changesets and manifests
70 72 checking files
71 73 3 files, 3 changesets, 3 total revisions
72 74
73 75 $ cd ..
74 76
75 77 Non store repo:
76 78
77 79 $ hg --config format.usestore=False init foo
78 80 $ cd foo
79 81 $ mkdir tst.d
80 82 $ echo foo > tst.d/foo
81 83 $ hg ci -Amfoo
82 84 adding tst.d/foo
83 85 $ find .hg | sort
84 86 .hg
85 87 .hg/00changelog.i
86 88 .hg/00manifest.i
87 89 .hg/cache
88 90 .hg/cache/branch2-served
89 91 .hg/cache/rbc-names-v1
90 92 .hg/cache/rbc-revs-v1
91 93 .hg/data
92 94 .hg/data/tst.d.hg
93 95 .hg/data/tst.d.hg/foo.i
94 96 .hg/dirstate
95 97 .hg/fsmonitor.state (fsmonitor !)
96 98 .hg/last-message.txt
97 99 .hg/phaseroots
98 100 .hg/requires
99 101 .hg/undo
100 102 .hg/undo.backup.dirstate
101 103 .hg/undo.backupfiles
102 104 .hg/undo.bookmarks
103 105 .hg/undo.branch
104 106 .hg/undo.desc
105 107 .hg/undo.dirstate
106 108 .hg/undo.phaseroots
107 109 $ cd ..
108 110
109 111 Non fncache repo:
110 112
111 113 $ hg --config format.usefncache=False init bar
112 114 $ cd bar
113 115 $ mkdir tst.d
114 116 $ echo foo > tst.d/Foo
115 117 $ hg ci -Amfoo
116 118 adding tst.d/Foo
117 119 $ find .hg | sort
118 120 .hg
119 121 .hg/00changelog.i
120 122 .hg/cache
121 123 .hg/cache/branch2-served
122 124 .hg/cache/rbc-names-v1
123 125 .hg/cache/rbc-revs-v1
124 126 .hg/dirstate
125 127 .hg/fsmonitor.state (fsmonitor !)
126 128 .hg/last-message.txt
127 129 .hg/requires
128 130 .hg/store
129 131 .hg/store/00changelog.i
130 132 .hg/store/00manifest.i
131 133 .hg/store/data
132 134 .hg/store/data/tst.d.hg
133 135 .hg/store/data/tst.d.hg/_foo.i
134 136 .hg/store/phaseroots
135 137 .hg/store/undo
136 138 .hg/store/undo.backupfiles
137 139 .hg/store/undo.phaseroots
138 140 .hg/undo.backup.dirstate
139 141 .hg/undo.bookmarks
140 142 .hg/undo.branch
141 143 .hg/undo.desc
142 144 .hg/undo.dirstate
143 145 $ cd ..
144 146
145 147 Encoding of reserved / long paths in the store
146 148
147 149 $ hg init r2
148 150 $ cd r2
149 151 $ cat <<EOF > .hg/hgrc
150 152 > [ui]
151 153 > portablefilenames = ignore
152 154 > EOF
153 155
154 156 $ hg import -q --bypass - <<EOF
155 157 > # HG changeset patch
156 158 > # User test
157 159 > # Date 0 0
158 160 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
159 161 > # Parent 0000000000000000000000000000000000000000
160 162 > 1
161 163 >
162 164 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
163 165 > new file mode 100644
164 166 > --- /dev/null
165 167 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
166 168 > @@ -0,0 +1,1 @@
167 169 > +foo
168 170 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
169 171 > new file mode 100644
170 172 > --- /dev/null
171 173 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
172 174 > @@ -0,0 +1,1 @@
173 175 > +foo
174 176 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
175 177 > new file mode 100644
176 178 > --- /dev/null
177 179 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
178 180 > @@ -0,0 +1,1 @@
179 181 > +foo
180 182 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
181 183 > new file mode 100644
182 184 > --- /dev/null
183 185 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
184 186 > @@ -0,0 +1,1 @@
185 187 > +foo
186 188 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
187 189 > new file mode 100644
188 190 > --- /dev/null
189 191 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
190 192 > @@ -0,0 +1,1 @@
191 193 > +foo
192 194 > EOF
193 195
194 196 $ find .hg/store -name *.i | sort
195 197 .hg/store/00changelog.i
196 198 .hg/store/00manifest.i
197 199 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
198 200 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
199 201 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
200 202 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
201 203 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
202 204
203 205 $ cd ..
204 206
205 207 Aborting lock does not prevent fncache writes
206 208
207 209 $ cat > exceptionext.py <<EOF
208 210 > from __future__ import absolute_import
209 211 > import os
210 212 > from mercurial import commands, error, extensions
211 213 >
212 214 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
213 215 > def releasewrap():
214 216 > l.held = False # ensure __del__ is a noop
215 217 > raise error.Abort("forced lock failure")
216 218 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
217 219 > return l
218 220 >
219 221 > def reposetup(ui, repo):
220 222 > extensions.wrapfunction(repo, '_lock', lockexception)
221 223 >
222 224 > cmdtable = {}
223 225 >
224 226 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
225 227 > # at the end of dispatching (for intentional "forced lcok failure")
226 228 > def commitwrap(orig, ui, repo, *pats, **opts):
227 229 > repo = repo.unfiltered() # to use replaced repo._lock certainly
228 230 > wlock = repo.wlock()
229 231 > try:
230 232 > return orig(ui, repo, *pats, **opts)
231 233 > finally:
232 234 > # multiple 'relase()' is needed for complete releasing wlock,
233 235 > # because "forced" abort at last releasing store lock
234 236 > # prevents wlock from being released at same 'lockmod.release()'
235 237 > for i in range(wlock.held):
236 238 > wlock.release()
237 239 >
238 240 > def extsetup(ui):
239 241 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
240 242 > EOF
241 243 $ extpath=`pwd`/exceptionext.py
242 244 $ hg init fncachetxn
243 245 $ cd fncachetxn
244 246 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
245 247 $ touch y
246 248 $ hg ci -qAm y
247 249 abort: forced lock failure
248 250 [255]
249 251 $ cat .hg/store/fncache
250 252 data/y.i
251 253
252 254 Aborting transaction prevents fncache change
253 255
254 256 $ cat > ../exceptionext.py <<EOF
255 257 > from __future__ import absolute_import
256 258 > import os
257 259 > from mercurial import commands, error, extensions, localrepo
258 260 >
259 261 > def wrapper(orig, self, *args, **kwargs):
260 262 > tr = orig(self, *args, **kwargs)
261 263 > def fail(tr):
262 264 > raise error.Abort(b"forced transaction failure")
263 265 > # zzz prefix to ensure it sorted after store.write
264 266 > tr.addfinalize(b'zzz-forcefails', fail)
265 267 > return tr
266 268 >
267 269 > def uisetup(ui):
268 270 > extensions.wrapfunction(
269 271 > localrepo.localrepository, b'transaction', wrapper)
270 272 >
271 273 > cmdtable = {}
272 274 >
273 275 > EOF
274 276
275 277 Clean cached version
276 278 $ rm -f "${extpath}c"
277 279 $ rm -Rf "`dirname $extpath`/__pycache__"
278 280
279 281 $ touch z
280 282 $ hg ci -qAm z
281 283 transaction abort!
282 284 rollback completed
283 285 abort: forced transaction failure
284 286 [255]
285 287 $ cat .hg/store/fncache
286 288 data/y.i
287 289
288 290 Aborted transactions can be recovered later
289 291
290 292 $ cat > ../exceptionext.py <<EOF
291 293 > from __future__ import absolute_import
292 294 > import os
293 295 > from mercurial import (
294 296 > commands,
295 297 > error,
296 298 > extensions,
297 299 > localrepo,
298 300 > transaction,
299 301 > )
300 302 >
301 303 > def trwrapper(orig, self, *args, **kwargs):
302 304 > tr = orig(self, *args, **kwargs)
303 305 > def fail(tr):
304 306 > raise error.Abort("forced transaction failure")
305 307 > # zzz prefix to ensure it sorted after store.write
306 308 > tr.addfinalize('zzz-forcefails', fail)
307 309 > return tr
308 310 >
309 311 > def abortwrapper(orig, self, *args, **kwargs):
310 312 > raise error.Abort("forced transaction failure")
311 313 >
312 314 > def uisetup(ui):
313 315 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
314 316 > trwrapper)
315 317 > extensions.wrapfunction(transaction.transaction, '_abort',
316 318 > abortwrapper)
317 319 >
318 320 > cmdtable = {}
319 321 >
320 322 > EOF
321 323
322 324 Clean cached versions
323 325 $ rm -f "${extpath}c"
324 326 $ rm -Rf "`dirname $extpath`/__pycache__"
325 327
326 328 $ hg up -q 1
327 329 $ touch z
328 330 $ hg ci -qAm z 2>/dev/null
329 331 [255]
330 332 $ cat .hg/store/fncache | sort
331 333 data/y.i
332 334 data/z.i
333 335 $ hg recover
334 336 rolling back interrupted transaction
335 337 checking changesets
336 338 checking manifests
337 339 crosschecking files in changesets and manifests
338 340 checking files
339 341 1 files, 1 changesets, 1 total revisions
340 342 $ cat .hg/store/fncache
341 343 data/y.i
342 344
343 345 $ cd ..
344 346
345 347 debugrebuildfncache does nothing unless repo has fncache requirement
346 348
347 349 $ hg --config format.usefncache=false init nofncache
348 350 $ cd nofncache
349 351 $ hg debugrebuildfncache
350 352 (not rebuilding fncache because repository does not support fncache)
351 353
352 354 $ cd ..
353 355
354 356 debugrebuildfncache works on empty repository
355 357
356 358 $ hg init empty
357 359 $ cd empty
358 360 $ hg debugrebuildfncache
359 361 fncache already up to date
360 362 $ cd ..
361 363
362 364 debugrebuildfncache on an up to date repository no-ops
363 365
364 366 $ hg init repo
365 367 $ cd repo
366 368 $ echo initial > foo
367 369 $ echo initial > .bar
368 370 $ hg commit -A -m initial
369 371 adding .bar
370 372 adding foo
371 373
372 374 $ cat .hg/store/fncache | sort
373 375 data/.bar.i
374 376 data/foo.i
375 377
376 378 $ hg debugrebuildfncache
377 379 fncache already up to date
378 380
379 381 debugrebuildfncache restores deleted fncache file
380 382
381 383 $ rm -f .hg/store/fncache
382 384 $ hg debugrebuildfncache
383 385 adding data/.bar.i
384 386 adding data/foo.i
385 387 2 items added, 0 removed from fncache
386 388
387 389 $ cat .hg/store/fncache | sort
388 390 data/.bar.i
389 391 data/foo.i
390 392
391 393 Rebuild after rebuild should no-op
392 394
393 395 $ hg debugrebuildfncache
394 396 fncache already up to date
395 397
396 398 A single missing file should get restored, an extra file should be removed
397 399
398 400 $ cat > .hg/store/fncache << EOF
399 401 > data/foo.i
400 402 > data/bad-entry.i
401 403 > EOF
402 404
403 405 $ hg debugrebuildfncache
404 406 removing data/bad-entry.i
405 407 adding data/.bar.i
406 408 1 items added, 1 removed from fncache
407 409
408 410 $ cat .hg/store/fncache | sort
409 411 data/.bar.i
410 412 data/foo.i
411 413
412 414 $ cd ..
413 415
414 416 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
415 417
416 418 $ hg --config format.dotencode=false init nodotencode
417 419 $ cd nodotencode
418 420 $ echo initial > foo
419 421 $ echo initial > .bar
420 422 $ hg commit -A -m initial
421 423 adding .bar
422 424 adding foo
423 425
424 426 $ cat .hg/store/fncache | sort
425 427 data/.bar.i
426 428 data/foo.i
427 429
428 430 $ rm .hg/store/fncache
429 431 $ hg debugrebuildfncache
430 432 adding data/.bar.i
431 433 adding data/foo.i
432 434 2 items added, 0 removed from fncache
433 435
434 436 $ cat .hg/store/fncache | sort
435 437 data/.bar.i
436 438 data/foo.i
@@ -1,429 +1,429 b''
1 1 #require hardlink reporevlogstore
2 2
3 3 $ cat > nlinks.py <<EOF
4 4 > from __future__ import print_function
5 5 > import sys
6 6 > from mercurial import util
7 7 > for f in sorted(sys.stdin.readlines()):
8 8 > f = f[:-1]
9 9 > print(util.nlinks(f), f)
10 10 > EOF
11 11
12 12 $ nlinksdir()
13 13 > {
14 14 > find "$@" -type f | $PYTHON $TESTTMP/nlinks.py
15 15 > }
16 16
17 17 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
18 18
19 19 $ cat > linkcp.py <<EOF
20 20 > from __future__ import absolute_import
21 21 > import sys
22 22 > from mercurial import util
23 23 > util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
24 24 > EOF
25 25
26 26 $ linkcp()
27 27 > {
28 28 > $PYTHON $TESTTMP/linkcp.py $1 $2
29 29 > }
30 30
31 31 Prepare repo r1:
32 32
33 33 $ hg init r1
34 34 $ cd r1
35 35
36 36 $ echo c1 > f1
37 37 $ hg add f1
38 38 $ hg ci -m0
39 39
40 40 $ mkdir d1
41 41 $ cd d1
42 42 $ echo c2 > f2
43 43 $ hg add f2
44 44 $ hg ci -m1
45 45 $ cd ../..
46 46
47 47 $ nlinksdir r1/.hg/store
48 48 1 r1/.hg/store/00changelog.i
49 49 1 r1/.hg/store/00manifest.i
50 50 1 r1/.hg/store/data/d1/f2.i
51 51 1 r1/.hg/store/data/f1.i
52 1 r1/.hg/store/fncache
52 1 r1/.hg/store/fncache (repofncache !)
53 53 1 r1/.hg/store/phaseroots
54 54 1 r1/.hg/store/undo
55 1 r1/.hg/store/undo.backup.fncache
55 1 r1/.hg/store/undo.backup.fncache (repofncache !)
56 56 1 r1/.hg/store/undo.backupfiles
57 57 1 r1/.hg/store/undo.phaseroots
58 58
59 59
60 60 Create hardlinked clone r2:
61 61
62 62 $ hg clone -U --debug r1 r2 --config progress.debug=true
63 63 linking: 1
64 64 linking: 2
65 65 linking: 3
66 66 linking: 4
67 67 linking: 5
68 68 linking: 6
69 69 linking: 7
70 70 linked 7 files
71 71
72 72 Create non-hardlinked clone r3:
73 73
74 74 $ hg clone --pull r1 r3
75 75 requesting all changes
76 76 adding changesets
77 77 adding manifests
78 78 adding file changes
79 79 added 2 changesets with 2 changes to 2 files
80 80 new changesets 40d85e9847f2:7069c422939c
81 81 updating to branch default
82 82 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 83
84 84
85 85 Repos r1 and r2 should now contain hardlinked files:
86 86
87 87 $ nlinksdir r1/.hg/store
88 88 2 r1/.hg/store/00changelog.i
89 89 2 r1/.hg/store/00manifest.i
90 90 2 r1/.hg/store/data/d1/f2.i
91 91 2 r1/.hg/store/data/f1.i
92 2 r1/.hg/store/fncache
92 2 r1/.hg/store/fncache (repofncache !)
93 93 1 r1/.hg/store/phaseroots
94 94 1 r1/.hg/store/undo
95 1 r1/.hg/store/undo.backup.fncache
95 1 r1/.hg/store/undo.backup.fncache (repofncache !)
96 96 1 r1/.hg/store/undo.backupfiles
97 97 1 r1/.hg/store/undo.phaseroots
98 98
99 99 $ nlinksdir r2/.hg/store
100 100 2 r2/.hg/store/00changelog.i
101 101 2 r2/.hg/store/00manifest.i
102 102 2 r2/.hg/store/data/d1/f2.i
103 103 2 r2/.hg/store/data/f1.i
104 2 r2/.hg/store/fncache
104 2 r2/.hg/store/fncache (repofncache !)
105 105
106 106 Repo r3 should not be hardlinked:
107 107
108 108 $ nlinksdir r3/.hg/store
109 109 1 r3/.hg/store/00changelog.i
110 110 1 r3/.hg/store/00manifest.i
111 111 1 r3/.hg/store/data/d1/f2.i
112 112 1 r3/.hg/store/data/f1.i
113 1 r3/.hg/store/fncache
113 1 r3/.hg/store/fncache (repofncache !)
114 114 1 r3/.hg/store/phaseroots
115 115 1 r3/.hg/store/undo
116 116 1 r3/.hg/store/undo.backupfiles
117 117 1 r3/.hg/store/undo.phaseroots
118 118
119 119
120 120 Create a non-inlined filelog in r3:
121 121
122 122 $ cd r3/d1
123 123 >>> f = open('data1', 'wb')
124 124 >>> for x in range(10000):
125 125 ... f.write("%s\n" % str(x))
126 126 >>> f.close()
127 127 $ for j in 0 1 2 3 4 5 6 7 8 9; do
128 128 > cat data1 >> f2
129 129 > hg commit -m$j
130 130 > done
131 131 $ cd ../..
132 132
133 133 $ nlinksdir r3/.hg/store
134 134 1 r3/.hg/store/00changelog.i
135 135 1 r3/.hg/store/00manifest.i
136 136 1 r3/.hg/store/data/d1/f2.d
137 137 1 r3/.hg/store/data/d1/f2.i
138 138 1 r3/.hg/store/data/f1.i
139 1 r3/.hg/store/fncache
139 1 r3/.hg/store/fncache (repofncache !)
140 140 1 r3/.hg/store/phaseroots
141 141 1 r3/.hg/store/undo
142 1 r3/.hg/store/undo.backup.fncache
142 1 r3/.hg/store/undo.backup.fncache (repofncache !)
143 143 1 r3/.hg/store/undo.backup.phaseroots
144 144 1 r3/.hg/store/undo.backupfiles
145 145 1 r3/.hg/store/undo.phaseroots
146 146
147 147 Push to repo r1 should break up most hardlinks in r2:
148 148
149 149 $ hg -R r2 verify
150 150 checking changesets
151 151 checking manifests
152 152 crosschecking files in changesets and manifests
153 153 checking files
154 154 2 files, 2 changesets, 2 total revisions
155 155
156 156 $ cd r3
157 157 $ hg push
158 158 pushing to $TESTTMP/r1
159 159 searching for changes
160 160 adding changesets
161 161 adding manifests
162 162 adding file changes
163 163 added 10 changesets with 10 changes to 1 files
164 164
165 165 $ cd ..
166 166
167 167 $ nlinksdir r2/.hg/store
168 168 1 r2/.hg/store/00changelog.i
169 169 1 r2/.hg/store/00manifest.i
170 170 1 r2/.hg/store/data/d1/f2.i
171 171 2 r2/.hg/store/data/f1.i
172 [12] r2/\.hg/store/fncache (re)
172 [12] r2/\.hg/store/fncache (re) (repofncache !)
173 173
174 #if hardlink-whitelisted
174 #if hardlink-whitelisted repofncache
175 175 $ nlinksdir r2/.hg/store/fncache
176 176 2 r2/.hg/store/fncache
177 177 #endif
178 178
179 179 $ hg -R r2 verify
180 180 checking changesets
181 181 checking manifests
182 182 crosschecking files in changesets and manifests
183 183 checking files
184 184 2 files, 2 changesets, 2 total revisions
185 185
186 186
187 187 $ cd r1
188 188 $ hg up
189 189 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 190
191 191 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
192 192
193 193 $ echo c1c1 >> f1
194 194 $ hg ci -m00
195 195 $ cd ..
196 196
197 197 $ nlinksdir r2/.hg/store
198 198 1 r2/.hg/store/00changelog.i
199 199 1 r2/.hg/store/00manifest.i
200 200 1 r2/.hg/store/data/d1/f2.i
201 201 1 r2/.hg/store/data/f1.i
202 [12] r2/\.hg/store/fncache (re)
202 [12] r2/\.hg/store/fncache (re) (repofncache !)
203 203
204 #if hardlink-whitelisted
204 #if hardlink-whitelisted repofncache
205 205 $ nlinksdir r2/.hg/store/fncache
206 206 2 r2/.hg/store/fncache
207 207 #endif
208 208
209 209 Create a file which exec permissions we will change
210 210 $ cd r3
211 211 $ echo "echo hello world" > f3
212 212 $ hg add f3
213 213 $ hg ci -mf3
214 214 $ cd ..
215 215
216 216 $ cd r3
217 217 $ hg tip --template '{rev}:{node|short}\n'
218 218 12:d3b77733a28a
219 219 $ echo bla > f1
220 220 $ chmod +x f3
221 221 $ hg ci -m1
222 222 $ cd ..
223 223
224 224 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
225 225
226 226 $ linkcp r3 r4
227 227
228 228 'checklink' is produced by hardlinking a symlink, which is undefined whether
229 229 the symlink should be followed or not. It does behave differently on Linux and
230 230 BSD. Just remove it so the test pass on both platforms.
231 231
232 232 $ rm -f r4/.hg/cache/checklink
233 233
234 234 r4 has hardlinks in the working dir (not just inside .hg):
235 235
236 236 $ nlinksdir r4
237 237 2 r4/.hg/00changelog.i
238 238 2 r4/.hg/branch
239 239 2 r4/.hg/cache/branch2-base
240 240 2 r4/.hg/cache/branch2-served
241 241 2 r4/.hg/cache/checkisexec (execbit !)
242 242 ? r4/.hg/cache/checklink-target (glob) (symlink !)
243 243 2 r4/.hg/cache/checknoexec (execbit !)
244 244 2 r4/.hg/cache/rbc-names-v1
245 245 2 r4/.hg/cache/rbc-revs-v1
246 246 2 r4/.hg/dirstate
247 247 2 r4/.hg/fsmonitor.state (fsmonitor !)
248 248 2 r4/.hg/hgrc
249 249 2 r4/.hg/last-message.txt
250 250 2 r4/.hg/requires
251 251 2 r4/.hg/store/00changelog.i
252 252 2 r4/.hg/store/00manifest.i
253 253 2 r4/.hg/store/data/d1/f2.d
254 254 2 r4/.hg/store/data/d1/f2.i
255 255 2 r4/.hg/store/data/f1.i
256 256 2 r4/.hg/store/data/f3.i
257 2 r4/.hg/store/fncache
257 2 r4/.hg/store/fncache (repofncache !)
258 258 2 r4/.hg/store/phaseroots
259 259 2 r4/.hg/store/undo
260 2 r4/.hg/store/undo.backup.fncache
260 2 r4/.hg/store/undo.backup.fncache (repofncache !)
261 261 2 r4/.hg/store/undo.backup.phaseroots
262 262 2 r4/.hg/store/undo.backupfiles
263 263 2 r4/.hg/store/undo.phaseroots
264 264 [24] r4/\.hg/undo\.backup\.dirstate (re)
265 265 2 r4/.hg/undo.bookmarks
266 266 2 r4/.hg/undo.branch
267 267 2 r4/.hg/undo.desc
268 268 [24] r4/\.hg/undo\.dirstate (re)
269 269 2 r4/d1/data1
270 270 2 r4/d1/f2
271 271 2 r4/f1
272 272 2 r4/f3
273 273
274 274 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
275 275 #if hardlink-whitelisted
276 276 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
277 277 4 r4/.hg/undo.backup.dirstate
278 278 4 r4/.hg/undo.dirstate
279 279 #endif
280 280
281 281
282 282 $ hg -R r4 up 12
283 283 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
284 284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
285 285
286 286 $ nlinksdir r4
287 287 2 r4/.hg/00changelog.i
288 288 1 r4/.hg/branch
289 289 2 r4/.hg/cache/branch2-base
290 290 2 r4/.hg/cache/branch2-served
291 291 2 r4/.hg/cache/checkisexec (execbit !)
292 292 2 r4/.hg/cache/checklink-target (symlink !)
293 293 2 r4/.hg/cache/checknoexec (execbit !)
294 294 2 r4/.hg/cache/rbc-names-v1
295 295 2 r4/.hg/cache/rbc-revs-v1
296 296 1 r4/.hg/dirstate
297 297 1 r4/.hg/fsmonitor.state (fsmonitor !)
298 298 2 r4/.hg/hgrc
299 299 2 r4/.hg/last-message.txt
300 300 2 r4/.hg/requires
301 301 2 r4/.hg/store/00changelog.i
302 302 2 r4/.hg/store/00manifest.i
303 303 2 r4/.hg/store/data/d1/f2.d
304 304 2 r4/.hg/store/data/d1/f2.i
305 305 2 r4/.hg/store/data/f1.i
306 306 2 r4/.hg/store/data/f3.i
307 307 2 r4/.hg/store/fncache
308 308 2 r4/.hg/store/phaseroots
309 309 2 r4/.hg/store/undo
310 2 r4/.hg/store/undo.backup.fncache
310 2 r4/.hg/store/undo.backup.fncache (repofncache !)
311 311 2 r4/.hg/store/undo.backup.phaseroots
312 312 2 r4/.hg/store/undo.backupfiles
313 313 2 r4/.hg/store/undo.phaseroots
314 314 [24] r4/\.hg/undo\.backup\.dirstate (re)
315 315 2 r4/.hg/undo.bookmarks
316 316 2 r4/.hg/undo.branch
317 317 2 r4/.hg/undo.desc
318 318 [24] r4/\.hg/undo\.dirstate (re)
319 319 2 r4/d1/data1
320 320 2 r4/d1/f2
321 321 1 r4/f1
322 322 1 r4/f3 (execbit !)
323 323 2 r4/f3 (no-execbit !)
324 324
325 325 #if hardlink-whitelisted
326 326 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
327 327 4 r4/.hg/undo.backup.dirstate
328 328 4 r4/.hg/undo.dirstate
329 329 #endif
330 330
331 331 Test hardlinking outside hg:
332 332
333 333 $ mkdir x
334 334 $ echo foo > x/a
335 335
336 336 $ linkcp x y
337 337 $ echo bar >> y/a
338 338
339 339 No diff if hardlink:
340 340
341 341 $ diff x/a y/a
342 342
343 343 Test mq hardlinking:
344 344
345 345 $ echo "[extensions]" >> $HGRCPATH
346 346 $ echo "mq=" >> $HGRCPATH
347 347
348 348 $ hg init a
349 349 $ cd a
350 350
351 351 $ hg qimport -n foo - << EOF
352 352 > # HG changeset patch
353 353 > # Date 1 0
354 354 > diff -r 2588a8b53d66 a
355 355 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
356 356 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
357 357 > @@ -0,0 +1,1 @@
358 358 > +a
359 359 > EOF
360 360 adding foo to series file
361 361
362 362 $ hg qpush
363 363 applying foo
364 364 now at: foo
365 365
366 366 $ cd ..
367 367 $ linkcp a b
368 368 $ cd b
369 369
370 370 $ hg qimport -n bar - << EOF
371 371 > # HG changeset patch
372 372 > # Date 2 0
373 373 > diff -r 2588a8b53d66 a
374 374 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
375 375 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
376 376 > @@ -0,0 +1,1 @@
377 377 > +b
378 378 > EOF
379 379 adding bar to series file
380 380
381 381 $ hg qpush
382 382 applying bar
383 383 now at: bar
384 384
385 385 $ cat .hg/patches/status
386 386 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
387 387 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
388 388
389 389 $ cat .hg/patches/series
390 390 foo
391 391 bar
392 392
393 393 $ cat ../a/.hg/patches/status
394 394 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
395 395
396 396 $ cat ../a/.hg/patches/series
397 397 foo
398 398
399 399 Test tags hardlinking:
400 400
401 401 $ hg qdel -r qbase:qtip
402 402 patch foo finalized without changeset message
403 403 patch bar finalized without changeset message
404 404
405 405 $ hg tag -l lfoo
406 406 $ hg tag foo
407 407
408 408 $ cd ..
409 409 $ linkcp b c
410 410 $ cd c
411 411
412 412 $ hg tag -l -r 0 lbar
413 413 $ hg tag -r 0 bar
414 414
415 415 $ cat .hgtags
416 416 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
417 417 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
418 418
419 419 $ cat .hg/localtags
420 420 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
421 421 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
422 422
423 423 $ cat ../b/.hgtags
424 424 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
425 425
426 426 $ cat ../b/.hg/localtags
427 427 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
428 428
429 429 $ cd ..
@@ -1,937 +1,937 b''
1 1 commit hooks can see env vars
2 2 (and post-transaction one are run unlocked)
3 3
4 4
5 5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
6 6 > def showargs(ui, repo, hooktype, **kwargs):
7 7 > ui.write('%s Python hook: %s\n' % (hooktype, ','.join(sorted(kwargs))))
8 8 > EOF
9 9
10 10 $ hg init a
11 11 $ cd a
12 12 $ cat > .hg/hgrc <<EOF
13 13 > [hooks]
14 14 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py commit"
15 15 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py commit.b"
16 16 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py precommit"
17 17 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxncommit"
18 18 > pretxncommit.tip = hg -q tip
19 19 > pre-identify = sh -c "printenv.py pre-identify 1"
20 20 > pre-cat = sh -c "printenv.py pre-cat"
21 21 > post-cat = sh -c "printenv.py post-cat"
22 22 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnopen"
23 23 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnclose"
24 24 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py txnclose"
25 25 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
26 26 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py txnabort"
27 27 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
28 28 > EOF
29 29 $ echo a > a
30 30 $ hg add a
31 31 $ hg commit -m a
32 32 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=0000000000000000000000000000000000000000
33 33 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
34 34 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
35 35 0:cb9a9f314b8b
36 36 pretxnclose hook: HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
37 37 txnclose hook: HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
38 38 commit hook: HG_HOOKNAME=commit HG_HOOKTYPE=commit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
39 39 commit.b hook: HG_HOOKNAME=commit.b HG_HOOKTYPE=commit HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
40 40
41 41 $ hg clone . ../b
42 42 updating to branch default
43 43 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 44 $ cd ../b
45 45
46 46 changegroup hooks can see env vars
47 47
48 48 $ cat > .hg/hgrc <<EOF
49 49 > [hooks]
50 50 > prechangegroup = sh -c "printenv.py prechangegroup"
51 51 > changegroup = sh -c "printenv.py changegroup"
52 52 > incoming = sh -c "printenv.py incoming"
53 53 > EOF
54 54
55 55 pretxncommit and commit hooks can see both parents of merge
56 56
57 57 $ cd ../a
58 58 $ echo b >> a
59 59 $ hg commit -m a1 -d "1 0"
60 60 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
61 61 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
62 62 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
63 63 1:ab228980c14d
64 64 pretxnclose hook: HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
65 65 txnclose hook: HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
66 66 commit hook: HG_HOOKNAME=commit HG_HOOKTYPE=commit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 67 commit.b hook: HG_HOOKNAME=commit.b HG_HOOKTYPE=commit HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
68 68 $ hg update -C 0
69 69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 $ echo b > b
71 71 $ hg add b
72 72 $ hg commit -m b -d '1 0'
73 73 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
74 74 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
75 75 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
76 76 2:ee9deb46ab31
77 77 pretxnclose hook: HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
78 78 created new head
79 79 txnclose hook: HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
80 80 commit hook: HG_HOOKNAME=commit HG_HOOKTYPE=commit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
81 81 commit.b hook: HG_HOOKNAME=commit.b HG_HOOKTYPE=commit HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
82 82 $ hg merge 1
83 83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 84 (branch merge, don't forget to commit)
85 85 $ hg commit -m merge -d '2 0'
86 86 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
87 87 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
88 88 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
89 89 3:07f3376c1e65
90 90 pretxnclose hook: HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
91 91 txnclose hook: HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
92 92 commit hook: HG_HOOKNAME=commit HG_HOOKTYPE=commit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
93 93 commit.b hook: HG_HOOKNAME=commit.b HG_HOOKTYPE=commit HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
94 94
95 95 test generic hooks
96 96
97 97 $ hg id
98 98 pre-identify hook: HG_ARGS=id HG_HOOKNAME=pre-identify HG_HOOKTYPE=pre-identify HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None, 'template': ''} HG_PATS=[]
99 99 abort: pre-identify hook exited with status 1
100 100 [255]
101 101 $ hg cat b
102 102 pre-cat hook: HG_ARGS=cat b HG_HOOKNAME=pre-cat HG_HOOKTYPE=pre-cat HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''} HG_PATS=['b']
103 103 b
104 104 post-cat hook: HG_ARGS=cat b HG_HOOKNAME=post-cat HG_HOOKTYPE=post-cat HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''} HG_PATS=['b'] HG_RESULT=0
105 105
106 106 $ cd ../b
107 107 $ hg pull ../a
108 108 pulling from ../a
109 109 searching for changes
110 110 prechangegroup hook: HG_HOOKNAME=prechangegroup HG_HOOKTYPE=prechangegroup HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
111 111 adding changesets
112 112 adding manifests
113 113 adding file changes
114 114 added 3 changesets with 2 changes to 2 files
115 115 new changesets ab228980c14d:07f3376c1e65
116 116 changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
117 117 incoming hook: HG_HOOKNAME=incoming HG_HOOKTYPE=incoming HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
118 118 incoming hook: HG_HOOKNAME=incoming HG_HOOKTYPE=incoming HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
119 119 incoming hook: HG_HOOKNAME=incoming HG_HOOKTYPE=incoming HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
120 120 (run 'hg update' to get a working copy)
121 121
122 122 tag hooks can see env vars
123 123
124 124 $ cd ../a
125 125 $ cat >> .hg/hgrc <<EOF
126 126 > pretag = sh -c "printenv.py pretag"
127 127 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py tag"
128 128 > EOF
129 129 $ hg tag -d '3 0' a
130 130 pretag hook: HG_HOOKNAME=pretag HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
131 131 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
132 132 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
133 133 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
134 134 4:539e4b31b6dc
135 135 pretxnclose hook: HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
136 136 tag hook: HG_HOOKNAME=tag HG_HOOKTYPE=tag HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
137 137 txnclose hook: HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
138 138 commit hook: HG_HOOKNAME=commit HG_HOOKTYPE=commit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
139 139 commit.b hook: HG_HOOKNAME=commit.b HG_HOOKTYPE=commit HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
140 140 $ hg tag -l la
141 141 pretag hook: HG_HOOKNAME=pretag HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
142 142 tag hook: HG_HOOKNAME=tag HG_HOOKTYPE=tag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
143 143
144 144 pretag hook can forbid tagging
145 145
146 146 $ cat >> .hg/hgrc <<EOF
147 147 > pretag.forbid = sh -c "printenv.py pretag.forbid 1"
148 148 > EOF
149 149 $ hg tag -d '4 0' fa
150 150 pretag hook: HG_HOOKNAME=pretag HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
151 151 pretag.forbid hook: HG_HOOKNAME=pretag.forbid HG_HOOKTYPE=pretag HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
152 152 abort: pretag.forbid hook exited with status 1
153 153 [255]
154 154 $ hg tag -l fla
155 155 pretag hook: HG_HOOKNAME=pretag HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
156 156 pretag.forbid hook: HG_HOOKNAME=pretag.forbid HG_HOOKTYPE=pretag HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
157 157 abort: pretag.forbid hook exited with status 1
158 158 [255]
159 159
160 160 pretxncommit hook can see changeset, can roll back txn, changeset no
161 161 more there after
162 162
163 163 $ cat >> .hg/hgrc <<EOF
164 164 > pretxncommit.forbid0 = sh -c "hg tip -q"
165 165 > pretxncommit.forbid1 = sh -c "printenv.py pretxncommit.forbid 1"
166 166 > EOF
167 167 $ echo z > z
168 168 $ hg add z
169 169 $ hg -q tip
170 170 4:539e4b31b6dc
171 171 $ hg commit -m 'fail' -d '4 0'
172 172 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
173 173 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
174 174 pretxncommit hook: HG_HOOKNAME=pretxncommit HG_HOOKTYPE=pretxncommit HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
175 175 5:6f611f8018c1
176 176 5:6f611f8018c1
177 177 pretxncommit.forbid hook: HG_HOOKNAME=pretxncommit.forbid1 HG_HOOKTYPE=pretxncommit HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
178 178 transaction abort!
179 179 txnabort Python hook: txnid,txnname
180 180 txnabort hook: HG_HOOKNAME=txnabort.1 HG_HOOKTYPE=txnabort HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
181 181 rollback completed
182 182 abort: pretxncommit.forbid1 hook exited with status 1
183 183 [255]
184 184 $ hg -q tip
185 185 4:539e4b31b6dc
186 186
187 187 (Check that no 'changelog.i.a' file were left behind)
188 188
189 189 $ ls -1 .hg/store/
190 190 00changelog.i
191 191 00manifest.i
192 192 data
193 fncache
193 fncache (repofncache !)
194 194 journal.phaseroots
195 195 phaseroots
196 196 undo
197 undo.backup.fncache
197 undo.backup.fncache (repofncache !)
198 198 undo.backupfiles
199 199 undo.phaseroots
200 200
201 201
202 202 precommit hook can prevent commit
203 203
204 204 $ cat >> .hg/hgrc <<EOF
205 205 > precommit.forbid = sh -c "printenv.py precommit.forbid 1"
206 206 > EOF
207 207 $ hg commit -m 'fail' -d '4 0'
208 208 precommit hook: HG_HOOKNAME=precommit HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
209 209 precommit.forbid hook: HG_HOOKNAME=precommit.forbid HG_HOOKTYPE=precommit HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
210 210 abort: precommit.forbid hook exited with status 1
211 211 [255]
212 212 $ hg -q tip
213 213 4:539e4b31b6dc
214 214
215 215 preupdate hook can prevent update
216 216
217 217 $ cat >> .hg/hgrc <<EOF
218 218 > preupdate = sh -c "printenv.py preupdate"
219 219 > EOF
220 220 $ hg update 1
221 221 preupdate hook: HG_HOOKNAME=preupdate HG_HOOKTYPE=preupdate HG_PARENT1=ab228980c14d
222 222 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
223 223
224 224 update hook
225 225
226 226 $ cat >> .hg/hgrc <<EOF
227 227 > update = sh -c "printenv.py update"
228 228 > EOF
229 229 $ hg update
230 230 preupdate hook: HG_HOOKNAME=preupdate HG_HOOKTYPE=preupdate HG_PARENT1=539e4b31b6dc
231 231 update hook: HG_ERROR=0 HG_HOOKNAME=update HG_HOOKTYPE=update HG_PARENT1=539e4b31b6dc
232 232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 233
234 234 pushkey hook
235 235
236 236 $ cat >> .hg/hgrc <<EOF
237 237 > pushkey = sh -c "printenv.py pushkey"
238 238 > EOF
239 239 $ cd ../b
240 240 $ hg bookmark -r null foo
241 241 $ hg push -B foo ../a
242 242 pushing to ../a
243 243 searching for changes
244 244 no changes found
245 245 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=push
246 246 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
247 247 pushkey hook: HG_BUNDLE2=1 HG_HOOKNAME=pushkey HG_HOOKTYPE=pushkey HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_PUSHKEYCOMPAT=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
248 248 txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/a
249 249 exporting bookmark foo
250 250 [1]
251 251 $ cd ../a
252 252
253 253 listkeys hook
254 254
255 255 $ cat >> .hg/hgrc <<EOF
256 256 > listkeys = sh -c "printenv.py listkeys"
257 257 > EOF
258 258 $ hg bookmark -r null bar
259 259 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
260 260 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
261 261 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
262 262 $ cd ../b
263 263 $ hg pull -B bar ../a
264 264 pulling from ../a
265 265 listkeys hook: HG_HOOKNAME=listkeys HG_HOOKTYPE=listkeys HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
266 266 no changes found
267 267 adding remote bookmark bar
268 268 $ cd ../a
269 269
270 270 test that prepushkey can prevent incoming keys
271 271
272 272 $ cat >> .hg/hgrc <<EOF
273 273 > prepushkey = sh -c "printenv.py prepushkey.forbid 1"
274 274 > EOF
275 275 $ cd ../b
276 276 $ hg bookmark -r null baz
277 277 $ hg push -B baz ../a
278 278 pushing to ../a
279 279 searching for changes
280 280 listkeys hook: HG_HOOKNAME=listkeys HG_HOOKTYPE=listkeys HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
281 281 listkeys hook: HG_HOOKNAME=listkeys HG_HOOKTYPE=listkeys HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
282 282 no changes found
283 283 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=push
284 284 prepushkey.forbid hook: HG_BUNDLE2=1 HG_HOOKNAME=prepushkey HG_HOOKTYPE=prepushkey HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_PUSHKEYCOMPAT=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
285 285 abort: prepushkey hook exited with status 1
286 286 [255]
287 287 $ cd ../a
288 288
289 289 test that prelistkeys can prevent listing keys
290 290
291 291 $ cat >> .hg/hgrc <<EOF
292 292 > prelistkeys = sh -c "printenv.py prelistkeys.forbid 1"
293 293 > EOF
294 294 $ hg bookmark -r null quux
295 295 pretxnopen hook: HG_HOOKNAME=pretxnopen HG_HOOKTYPE=pretxnopen HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
296 296 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=pretxnclose HG_HOOKTYPE=pretxnclose HG_PENDING=$TESTTMP/a HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
297 297 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
298 298 $ cd ../b
299 299 $ hg pull -B quux ../a
300 300 pulling from ../a
301 301 prelistkeys.forbid hook: HG_HOOKNAME=prelistkeys HG_HOOKTYPE=prelistkeys HG_NAMESPACE=bookmarks
302 302 abort: prelistkeys hook exited with status 1
303 303 [255]
304 304 $ cd ../a
305 305 $ rm .hg/hgrc
306 306
307 307 prechangegroup hook can prevent incoming changes
308 308
309 309 $ cd ../b
310 310 $ hg -q tip
311 311 3:07f3376c1e65
312 312 $ cat > .hg/hgrc <<EOF
313 313 > [hooks]
314 314 > prechangegroup.forbid = sh -c "printenv.py prechangegroup.forbid 1"
315 315 > EOF
316 316 $ hg pull ../a
317 317 pulling from ../a
318 318 searching for changes
319 319 prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid HG_HOOKTYPE=prechangegroup HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
320 320 abort: prechangegroup.forbid hook exited with status 1
321 321 [255]
322 322
323 323 pretxnchangegroup hook can see incoming changes, can roll back txn,
324 324 incoming changes no longer there after
325 325
326 326 $ cat > .hg/hgrc <<EOF
327 327 > [hooks]
328 328 > pretxnchangegroup.forbid0 = hg tip -q
329 329 > pretxnchangegroup.forbid1 = sh -c "printenv.py pretxnchangegroup.forbid 1"
330 330 > EOF
331 331 $ hg pull ../a
332 332 pulling from ../a
333 333 searching for changes
334 334 adding changesets
335 335 adding manifests
336 336 adding file changes
337 337 added 1 changesets with 1 changes to 1 files
338 338 4:539e4b31b6dc
339 339 pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1 HG_HOOKTYPE=pretxnchangegroup HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=file:$TESTTMP/a
340 340 transaction abort!
341 341 rollback completed
342 342 abort: pretxnchangegroup.forbid1 hook exited with status 1
343 343 [255]
344 344 $ hg -q tip
345 345 3:07f3376c1e65
346 346
347 347 outgoing hooks can see env vars
348 348
349 349 $ rm .hg/hgrc
350 350 $ cat > ../a/.hg/hgrc <<EOF
351 351 > [hooks]
352 352 > preoutgoing = sh -c "printenv.py preoutgoing"
353 353 > outgoing = sh -c "printenv.py outgoing"
354 354 > EOF
355 355 $ hg pull ../a
356 356 pulling from ../a
357 357 searching for changes
358 358 preoutgoing hook: HG_HOOKNAME=preoutgoing HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
359 359 outgoing hook: HG_HOOKNAME=outgoing HG_HOOKTYPE=outgoing HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
360 360 adding changesets
361 361 adding manifests
362 362 adding file changes
363 363 added 1 changesets with 1 changes to 1 files
364 364 adding remote bookmark quux
365 365 new changesets 539e4b31b6dc
366 366 (run 'hg update' to get a working copy)
367 367 $ hg rollback
368 368 repository tip rolled back to revision 3 (undo pull)
369 369
370 370 preoutgoing hook can prevent outgoing changes
371 371
372 372 $ cat >> ../a/.hg/hgrc <<EOF
373 373 > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
374 374 > EOF
375 375 $ hg pull ../a
376 376 pulling from ../a
377 377 searching for changes
378 378 preoutgoing hook: HG_HOOKNAME=preoutgoing HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
379 379 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid HG_HOOKTYPE=preoutgoing HG_SOURCE=pull
380 380 abort: preoutgoing.forbid hook exited with status 1
381 381 [255]
382 382
383 383 outgoing hooks work for local clones
384 384
385 385 $ cd ..
386 386 $ cat > a/.hg/hgrc <<EOF
387 387 > [hooks]
388 388 > preoutgoing = sh -c "printenv.py preoutgoing"
389 389 > outgoing = sh -c "printenv.py outgoing"
390 390 > EOF
391 391 $ hg clone a c
392 392 preoutgoing hook: HG_HOOKNAME=preoutgoing HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
393 393 outgoing hook: HG_HOOKNAME=outgoing HG_HOOKTYPE=outgoing HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
394 394 updating to branch default
395 395 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 396 $ rm -rf c
397 397
398 398 preoutgoing hook can prevent outgoing changes for local clones
399 399
400 400 $ cat >> a/.hg/hgrc <<EOF
401 401 > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
402 402 > EOF
403 403 $ hg clone a zzz
404 404 preoutgoing hook: HG_HOOKNAME=preoutgoing HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
405 405 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid HG_HOOKTYPE=preoutgoing HG_SOURCE=clone
406 406 abort: preoutgoing.forbid hook exited with status 1
407 407 [255]
408 408
409 409 $ cd "$TESTTMP/b"
410 410
411 411 $ cat > hooktests.py <<EOF
412 412 > from __future__ import print_function
413 413 > from mercurial import error
414 414 >
415 415 > uncallable = 0
416 416 >
417 417 > def printargs(ui, args):
418 418 > a = list(args.items())
419 419 > a.sort()
420 420 > ui.write(b'hook args:\n')
421 421 > for k, v in a:
422 422 > ui.write(b' %s %s\n' % (k, v))
423 423 >
424 424 > def passhook(ui, repo, **args):
425 425 > printargs(ui, args)
426 426 >
427 427 > def failhook(ui, repo, **args):
428 428 > printargs(ui, args)
429 429 > return True
430 430 >
431 431 > class LocalException(Exception):
432 432 > pass
433 433 >
434 434 > def raisehook(**args):
435 435 > raise LocalException(b'exception from hook')
436 436 >
437 437 > def aborthook(**args):
438 438 > raise error.Abort(b'raise abort from hook')
439 439 >
440 440 > def brokenhook(**args):
441 441 > return 1 + {}
442 442 >
443 443 > def verbosehook(ui, **args):
444 444 > ui.note(b'verbose output from hook\n')
445 445 >
446 446 > def printtags(ui, repo, **args):
447 447 > ui.write(b'%s\n' % sorted(repo.tags()))
448 448 >
449 449 > class container:
450 450 > unreachable = 1
451 451 > EOF
452 452
453 453 $ cat > syntaxerror.py << EOF
454 454 > (foo
455 455 > EOF
456 456
457 457 test python hooks
458 458
459 459 #if windows
460 460 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
461 461 #else
462 462 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
463 463 #endif
464 464 $ export PYTHONPATH
465 465
466 466 $ echo '[hooks]' > ../a/.hg/hgrc
467 467 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
468 468 $ hg pull ../a 2>&1 | grep 'raised an exception'
469 469 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
470 470
471 471 $ echo '[hooks]' > ../a/.hg/hgrc
472 472 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
473 473 $ hg pull ../a 2>&1 | grep 'raised an exception'
474 474 error: preoutgoing.raise hook raised an exception: exception from hook
475 475
476 476 $ echo '[hooks]' > ../a/.hg/hgrc
477 477 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
478 478 $ hg pull ../a
479 479 pulling from ../a
480 480 searching for changes
481 481 error: preoutgoing.abort hook failed: raise abort from hook
482 482 abort: raise abort from hook
483 483 [255]
484 484
485 485 $ echo '[hooks]' > ../a/.hg/hgrc
486 486 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
487 487 $ hg pull ../a
488 488 pulling from ../a
489 489 searching for changes
490 490 hook args:
491 491 hooktype preoutgoing
492 492 source pull
493 493 abort: preoutgoing.fail hook failed
494 494 [255]
495 495
496 496 $ echo '[hooks]' > ../a/.hg/hgrc
497 497 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
498 498 $ hg pull ../a
499 499 pulling from ../a
500 500 searching for changes
501 501 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
502 502 [255]
503 503
504 504 $ echo '[hooks]' > ../a/.hg/hgrc
505 505 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
506 506 $ hg pull ../a
507 507 pulling from ../a
508 508 searching for changes
509 509 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
510 510 [255]
511 511
512 512 $ echo '[hooks]' > ../a/.hg/hgrc
513 513 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
514 514 $ hg pull ../a
515 515 pulling from ../a
516 516 searching for changes
517 517 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
518 518 [255]
519 519
520 520 $ echo '[hooks]' > ../a/.hg/hgrc
521 521 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
522 522 $ hg pull ../a
523 523 pulling from ../a
524 524 searching for changes
525 525 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
526 526 (run with --traceback for stack trace)
527 527 [255]
528 528
529 529 $ echo '[hooks]' > ../a/.hg/hgrc
530 530 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
531 531 $ hg pull ../a
532 532 pulling from ../a
533 533 searching for changes
534 534 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
535 535 (run with --traceback for stack trace)
536 536 [255]
537 537
538 538 $ echo '[hooks]' > ../a/.hg/hgrc
539 539 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
540 540 $ hg pull ../a
541 541 pulling from ../a
542 542 searching for changes
543 543 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
544 544 (run with --traceback for stack trace)
545 545 [255]
546 546
547 547 The second egrep is to filter out lines like ' ^', which are slightly
548 548 different between Python 2.6 and Python 2.7.
549 549 $ hg pull ../a --traceback 2>&1 | egrep -v '^( +File| [_a-zA-Z*(])' | egrep -v '^( )+(\^)?$'
550 550 pulling from ../a
551 551 searching for changes
552 552 exception from first failed import attempt:
553 553 Traceback (most recent call last):
554 554 SyntaxError: * (glob)
555 555 exception from second failed import attempt:
556 556 Traceback (most recent call last):
557 557 ImportError: No module named hgext_syntaxerror
558 558 Traceback (most recent call last):
559 559 HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
560 560 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
561 561
562 562 $ echo '[hooks]' > ../a/.hg/hgrc
563 563 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
564 564 $ hg pull ../a
565 565 pulling from ../a
566 566 searching for changes
567 567 hook args:
568 568 hooktype preoutgoing
569 569 source pull
570 570 adding changesets
571 571 adding manifests
572 572 adding file changes
573 573 added 1 changesets with 1 changes to 1 files
574 574 adding remote bookmark quux
575 575 new changesets 539e4b31b6dc
576 576 (run 'hg update' to get a working copy)
577 577
578 578 post- python hooks that fail to *run* don't cause an abort
579 579 $ rm ../a/.hg/hgrc
580 580 $ echo '[hooks]' > .hg/hgrc
581 581 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
582 582 $ hg pull ../a
583 583 pulling from ../a
584 584 searching for changes
585 585 no changes found
586 586 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
587 587 (run with --traceback for stack trace)
588 588
589 589 but post- python hooks that fail to *load* do
590 590 $ echo '[hooks]' > .hg/hgrc
591 591 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
592 592 $ hg pull ../a
593 593 pulling from ../a
594 594 searching for changes
595 595 no changes found
596 596 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
597 597 [255]
598 598
599 599 $ echo '[hooks]' > .hg/hgrc
600 600 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
601 601 $ hg pull ../a
602 602 pulling from ../a
603 603 searching for changes
604 604 no changes found
605 605 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
606 606 (run with --traceback for stack trace)
607 607 [255]
608 608
609 609 $ echo '[hooks]' > .hg/hgrc
610 610 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
611 611 $ hg pull ../a
612 612 pulling from ../a
613 613 searching for changes
614 614 no changes found
615 615 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
616 616 [255]
617 617
618 618 make sure --traceback works
619 619
620 620 $ echo '[hooks]' > .hg/hgrc
621 621 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
622 622
623 623 $ echo aa > a
624 624 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
625 625 Traceback (most recent call last):
626 626
627 627 $ cd ..
628 628 $ hg init c
629 629 $ cd c
630 630
631 631 $ cat > hookext.py <<EOF
632 632 > def autohook(ui, **args):
633 633 > ui.write('Automatically installed hook\n')
634 634 >
635 635 > def reposetup(ui, repo):
636 636 > repo.ui.setconfig("hooks", "commit.auto", autohook)
637 637 > EOF
638 638 $ echo '[extensions]' >> .hg/hgrc
639 639 $ echo 'hookext = hookext.py' >> .hg/hgrc
640 640
641 641 $ touch foo
642 642 $ hg add foo
643 643 $ hg ci -d '0 0' -m 'add foo'
644 644 Automatically installed hook
645 645 $ echo >> foo
646 646 $ hg ci --debug -d '0 0' -m 'change foo'
647 647 committing files:
648 648 foo
649 649 committing manifest
650 650 committing changelog
651 651 updating the branch cache
652 652 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
653 653 calling hook commit.auto: hgext_hookext.autohook
654 654 Automatically installed hook
655 655
656 656 $ hg showconfig hooks
657 657 hooks.commit.auto=<function autohook at *> (glob)
658 658
659 659 test python hook configured with python:[file]:[hook] syntax
660 660
661 661 $ cd ..
662 662 $ mkdir d
663 663 $ cd d
664 664 $ hg init repo
665 665 $ mkdir hooks
666 666
667 667 $ cd hooks
668 668 $ cat > testhooks.py <<EOF
669 669 > def testhook(ui, **args):
670 670 > ui.write(b'hook works\n')
671 671 > EOF
672 672 $ echo '[hooks]' > ../repo/.hg/hgrc
673 673 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
674 674
675 675 $ cd ../repo
676 676 $ hg commit -d '0 0'
677 677 hook works
678 678 nothing changed
679 679 [1]
680 680
681 681 $ echo '[hooks]' > .hg/hgrc
682 682 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
683 683 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
684 684
685 685 $ hg up null
686 686 loading update.ne hook failed:
687 687 abort: $ENOENT$: $TESTTMP/d/repo/nonexistent.py
688 688 [255]
689 689
690 690 $ hg id
691 691 loading pre-identify.npmd hook failed:
692 692 abort: No module named repo!
693 693 [255]
694 694
695 695 $ cd ../../b
696 696
697 697 make sure --traceback works on hook import failure
698 698
699 699 $ cat > importfail.py <<EOF
700 700 > import somebogusmodule
701 701 > # dereference something in the module to force demandimport to load it
702 702 > somebogusmodule.whatever
703 703 > EOF
704 704
705 705 $ echo '[hooks]' > .hg/hgrc
706 706 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
707 707
708 708 $ echo a >> a
709 709 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
710 710 exception from first failed import attempt:
711 711 Traceback (most recent call last):
712 712 ImportError: No module named somebogusmodule
713 713 exception from second failed import attempt:
714 714 Traceback (most recent call last):
715 715 ImportError: No module named hgext_importfail
716 716 Traceback (most recent call last):
717 717 HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed
718 718 abort: precommit.importfail hook is invalid: import of "importfail" failed
719 719
720 720 Issue1827: Hooks Update & Commit not completely post operation
721 721
722 722 commit and update hooks should run after command completion. The largefiles
723 723 use demonstrates a recursive wlock, showing the hook doesn't run until the
724 724 final release (and dirstate flush).
725 725
726 726 $ echo '[hooks]' > .hg/hgrc
727 727 $ echo 'commit = hg id' >> .hg/hgrc
728 728 $ echo 'update = hg id' >> .hg/hgrc
729 729 $ echo bb > a
730 730 $ hg ci -ma
731 731 223eafe2750c tip
732 732 $ hg up 0 --config extensions.largefiles=
733 733 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
734 734 cb9a9f314b8b
735 735 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
736 736
737 737 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
738 738 that is passed to pre/post hooks
739 739
740 740 $ echo '[hooks]' > .hg/hgrc
741 741 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
742 742 $ hg id
743 743 cb9a9f314b8b
744 744 $ hg id --verbose
745 745 calling hook pre-identify: hooktests.verbosehook
746 746 verbose output from hook
747 747 cb9a9f314b8b
748 748
749 749 Ensure hooks can be prioritized
750 750
751 751 $ echo '[hooks]' > .hg/hgrc
752 752 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
753 753 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
754 754 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
755 755 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
756 756 $ hg id --verbose
757 757 calling hook pre-identify.b: hooktests.verbosehook
758 758 verbose output from hook
759 759 calling hook pre-identify.a: hooktests.verbosehook
760 760 verbose output from hook
761 761 calling hook pre-identify.c: hooktests.verbosehook
762 762 verbose output from hook
763 763 cb9a9f314b8b
764 764
765 765 new tags must be visible in pretxncommit (issue3210)
766 766
767 767 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
768 768 $ hg tag -f foo
769 769 ['a', 'foo', 'tip']
770 770
771 771 post-init hooks must not crash (issue4983)
772 772 This also creates the `to` repo for the next test block.
773 773
774 774 $ cd ..
775 775 $ cat << EOF >> hgrc-with-post-init-hook
776 776 > [hooks]
777 777 > post-init = sh -c "printenv.py post-init"
778 778 > EOF
779 779 $ HGRCPATH=hgrc-with-post-init-hook hg init to
780 780 post-init hook: HG_ARGS=init to HG_HOOKNAME=post-init HG_HOOKTYPE=post-init HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''} HG_PATS=['to'] HG_RESULT=0
781 781
782 782 new commits must be visible in pretxnchangegroup (issue3428)
783 783
784 784 $ echo '[hooks]' >> to/.hg/hgrc
785 785 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
786 786 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
787 787 $ echo a >> to/a
788 788 $ hg --cwd to ci -Ama
789 789 adding a
790 790 $ hg clone to from
791 791 updating to branch default
792 792 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
793 793 $ echo aa >> from/a
794 794 $ hg --cwd from ci -mb
795 795 $ hg --cwd from push
796 796 pushing to $TESTTMP/to
797 797 searching for changes
798 798 changeset: 0:cb9a9f314b8b
799 799 tag: tip
800 800 user: test
801 801 date: Thu Jan 01 00:00:00 1970 +0000
802 802 summary: a
803 803
804 804 adding changesets
805 805 adding manifests
806 806 adding file changes
807 807 added 1 changesets with 1 changes to 1 files
808 808 changeset: 1:9836a07b9b9d
809 809 tag: tip
810 810 user: test
811 811 date: Thu Jan 01 00:00:00 1970 +0000
812 812 summary: b
813 813
814 814
815 815 pretxnclose hook failure should abort the transaction
816 816
817 817 $ hg init txnfailure
818 818 $ cd txnfailure
819 819 $ touch a && hg commit -Aqm a
820 820 $ cat >> .hg/hgrc <<EOF
821 821 > [hooks]
822 822 > pretxnclose.error = exit 1
823 823 > EOF
824 824 $ hg strip -r 0 --config extensions.strip=
825 825 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
826 826 saved backup bundle to * (glob)
827 827 transaction abort!
828 828 rollback completed
829 829 strip failed, backup bundle stored in * (glob)
830 830 abort: pretxnclose.error hook exited with status 1
831 831 [255]
832 832 $ hg recover
833 833 no interrupted transaction available
834 834 [1]
835 835 $ cd ..
836 836
837 837 check whether HG_PENDING makes pending changes only in related
838 838 repositories visible to an external hook.
839 839
840 840 (emulate a transaction running concurrently by copied
841 841 .hg/store/00changelog.i.a in subsequent test)
842 842
843 843 $ cat > $TESTTMP/savepending.sh <<EOF
844 844 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
845 845 > exit 1 # to avoid adding new revision for subsequent tests
846 846 > EOF
847 847 $ cd a
848 848 $ hg tip -q
849 849 4:539e4b31b6dc
850 850 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
851 851 transaction abort!
852 852 rollback completed
853 853 abort: pretxnclose hook exited with status 1
854 854 [255]
855 855 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
856 856
857 857 (check (in)visibility of new changeset while transaction running in
858 858 repo)
859 859
860 860 $ cat > $TESTTMP/checkpending.sh <<EOF
861 861 > echo '@a'
862 862 > hg -R "$TESTTMP/a" tip -q
863 863 > echo '@a/nested'
864 864 > hg -R "$TESTTMP/a/nested" tip -q
865 865 > exit 1 # to avoid adding new revision for subsequent tests
866 866 > EOF
867 867 $ hg init nested
868 868 $ cd nested
869 869 $ echo a > a
870 870 $ hg add a
871 871 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
872 872 @a
873 873 4:539e4b31b6dc
874 874 @a/nested
875 875 0:bf5e395ced2c
876 876 transaction abort!
877 877 rollback completed
878 878 abort: pretxnclose hook exited with status 1
879 879 [255]
880 880
881 881 Hook from untrusted hgrc are reported as failure
882 882 ================================================
883 883
884 884 $ cat << EOF > $TESTTMP/untrusted.py
885 885 > from mercurial import scmutil, util
886 886 > def uisetup(ui):
887 887 > class untrustedui(ui.__class__):
888 888 > def _trusted(self, fp, f):
889 889 > if util.normpath(fp.name).endswith(b'untrusted/.hg/hgrc'):
890 890 > return False
891 891 > return super(untrustedui, self)._trusted(fp, f)
892 892 > ui.__class__ = untrustedui
893 893 > EOF
894 894 $ cat << EOF >> $HGRCPATH
895 895 > [extensions]
896 896 > untrusted=$TESTTMP/untrusted.py
897 897 > EOF
898 898 $ hg init untrusted
899 899 $ cd untrusted
900 900
901 901 Non-blocking hook
902 902 -----------------
903 903
904 904 $ cat << EOF >> .hg/hgrc
905 905 > [hooks]
906 906 > txnclose.testing=echo txnclose hook called
907 907 > EOF
908 908 $ touch a && hg commit -Aqm a
909 909 warning: untrusted hook txnclose.testing not executed
910 910 $ hg log
911 911 changeset: 0:3903775176ed
912 912 tag: tip
913 913 user: test
914 914 date: Thu Jan 01 00:00:00 1970 +0000
915 915 summary: a
916 916
917 917
918 918 Non-blocking hook
919 919 -----------------
920 920
921 921 $ cat << EOF >> .hg/hgrc
922 922 > [hooks]
923 923 > pretxnclose.testing=echo pre-txnclose hook called
924 924 > EOF
925 925 $ touch b && hg commit -Aqm a
926 926 transaction abort!
927 927 rollback completed
928 928 abort: untrusted hook pretxnclose.testing not executed
929 929 (see 'hg help config.trusted')
930 930 [255]
931 931 $ hg log
932 932 changeset: 0:3903775176ed
933 933 tag: tip
934 934 user: test
935 935 date: Thu Jan 01 00:00:00 1970 +0000
936 936 summary: a
937 937
@@ -1,160 +1,160 b''
1 1 #require unix-permissions
2 2
3 3 test that new files created in .hg inherit the permissions from .hg/store
4 4
5 5 $ mkdir dir
6 6
7 7 just in case somebody has a strange $TMPDIR
8 8
9 9 $ chmod g-s dir
10 10 $ cd dir
11 11
12 12 $ cat >printmodes.py <<EOF
13 13 > from __future__ import absolute_import, print_function
14 14 > import os
15 15 > import sys
16 16 >
17 17 > allnames = []
18 18 > isdir = {}
19 19 > for root, dirs, files in os.walk(sys.argv[1]):
20 20 > for d in dirs:
21 21 > name = os.path.join(root, d)
22 22 > isdir[name] = 1
23 23 > allnames.append(name)
24 24 > for f in files:
25 25 > name = os.path.join(root, f)
26 26 > allnames.append(name)
27 27 > allnames.sort()
28 28 > for name in allnames:
29 29 > suffix = name in isdir and '/' or ''
30 30 > print('%05o %s%s' % (os.lstat(name).st_mode & 0o7777, name, suffix))
31 31 > EOF
32 32
33 33 $ cat >mode.py <<EOF
34 34 > from __future__ import absolute_import, print_function
35 35 > import os
36 36 > import sys
37 37 > print('%05o' % os.lstat(sys.argv[1]).st_mode)
38 38 > EOF
39 39
40 40 $ umask 077
41 41
42 42 $ hg init repo
43 43 $ cd repo
44 44
45 45 $ chmod 0770 .hg/store
46 46
47 47 before commit
48 48 store can be written by the group, other files cannot
49 49 store is setgid
50 50
51 51 $ $PYTHON ../printmodes.py .
52 52 00700 ./.hg/
53 53 00600 ./.hg/00changelog.i
54 54 00600 ./.hg/requires
55 55 00770 ./.hg/store/
56 56
57 57 $ mkdir dir
58 58 $ touch foo dir/bar
59 59 $ hg ci -qAm 'add files'
60 60
61 61 after commit
62 62 working dir files can only be written by the owner
63 63 files created in .hg can be written by the group
64 64 (in particular, store/**, dirstate, branch cache file, undo files)
65 65 new directories are setgid
66 66
67 67 $ $PYTHON ../printmodes.py .
68 68 00700 ./.hg/
69 69 00600 ./.hg/00changelog.i
70 70 00770 ./.hg/cache/
71 71 00660 ./.hg/cache/branch2-served
72 72 00660 ./.hg/cache/rbc-names-v1
73 73 00660 ./.hg/cache/rbc-revs-v1
74 74 00660 ./.hg/dirstate
75 75 00660 ./.hg/fsmonitor.state (fsmonitor !)
76 76 00660 ./.hg/last-message.txt
77 77 00600 ./.hg/requires
78 78 00770 ./.hg/store/
79 79 00660 ./.hg/store/00changelog.i
80 80 00660 ./.hg/store/00manifest.i
81 81 00770 ./.hg/store/data/
82 82 00770 ./.hg/store/data/dir/
83 83 00660 ./.hg/store/data/dir/bar.i
84 84 00660 ./.hg/store/data/foo.i
85 00660 ./.hg/store/fncache
85 00660 ./.hg/store/fncache (repofncache !)
86 86 00660 ./.hg/store/phaseroots
87 87 00660 ./.hg/store/undo
88 88 00660 ./.hg/store/undo.backupfiles
89 89 00660 ./.hg/store/undo.phaseroots
90 90 00660 ./.hg/undo.backup.dirstate
91 91 00660 ./.hg/undo.bookmarks
92 92 00660 ./.hg/undo.branch
93 93 00660 ./.hg/undo.desc
94 94 00660 ./.hg/undo.dirstate
95 95 00700 ./dir/
96 96 00600 ./dir/bar
97 97 00600 ./foo
98 98
99 99 $ umask 007
100 100 $ hg init ../push
101 101
102 102 before push
103 103 group can write everything
104 104
105 105 $ $PYTHON ../printmodes.py ../push
106 106 00770 ../push/.hg/
107 107 00660 ../push/.hg/00changelog.i
108 108 00660 ../push/.hg/requires
109 109 00770 ../push/.hg/store/
110 110
111 111 $ umask 077
112 112 $ hg -q push ../push
113 113
114 114 after push
115 115 group can still write everything
116 116
117 117 $ $PYTHON ../printmodes.py ../push
118 118 00770 ../push/.hg/
119 119 00660 ../push/.hg/00changelog.i
120 120 00770 ../push/.hg/cache/
121 121 00660 ../push/.hg/cache/branch2-base
122 122 00660 ../push/.hg/dirstate
123 123 00660 ../push/.hg/requires
124 124 00770 ../push/.hg/store/
125 125 00660 ../push/.hg/store/00changelog.i
126 126 00660 ../push/.hg/store/00manifest.i
127 127 00770 ../push/.hg/store/data/
128 128 00770 ../push/.hg/store/data/dir/
129 129 00660 ../push/.hg/store/data/dir/bar.i
130 130 00660 ../push/.hg/store/data/foo.i
131 00660 ../push/.hg/store/fncache
131 00660 ../push/.hg/store/fncache (repofncache !)
132 132 00660 ../push/.hg/store/undo
133 133 00660 ../push/.hg/store/undo.backupfiles
134 134 00660 ../push/.hg/store/undo.phaseroots
135 135 00660 ../push/.hg/undo.bookmarks
136 136 00660 ../push/.hg/undo.branch
137 137 00660 ../push/.hg/undo.desc
138 138 00660 ../push/.hg/undo.dirstate
139 139
140 140
141 141 Test that we don't lose the setgid bit when we call chmod.
142 142 Not all systems support setgid directories (e.g. HFS+), so
143 143 just check that directories have the same mode.
144 144
145 145 $ cd ..
146 146 $ hg init setgid
147 147 $ cd setgid
148 148 $ chmod g+rwx .hg/store
149 149 $ chmod g+s .hg/store 2> /dev/null || true
150 150 $ mkdir dir
151 151 $ touch dir/file
152 152 $ hg ci -qAm 'add dir/file'
153 153 $ storemode=`$PYTHON ../mode.py .hg/store`
154 154 $ dirmode=`$PYTHON ../mode.py .hg/store/data/dir`
155 155 $ if [ "$storemode" != "$dirmode" ]; then
156 156 > echo "$storemode != $dirmode"
157 157 > fi
158 158 $ cd ..
159 159
160 160 $ cd .. # g-s dir
@@ -1,255 +1,263 b''
1 1 This test tries to exercise the ssh functionality with a dummy script
2 2
3 3 $ checknewrepo()
4 4 > {
5 5 > name=$1
6 6 > if [ -d "$name"/.hg/store ]; then
7 7 > echo store created
8 8 > fi
9 9 > if [ -f "$name"/.hg/00changelog.i ]; then
10 10 > echo 00changelog.i created
11 11 > fi
12 12 > cat "$name"/.hg/requires
13 13 > }
14 14
15 15 creating 'local'
16 16
17 17 $ hg init local
18 18 $ checknewrepo local
19 19 store created
20 20 00changelog.i created
21 21 dotencode
22 22 fncache
23 23 generaldelta
24 24 revlogv1
25 25 store
26 testonly-simplestore (reposimplestore !)
26 27 $ echo this > local/foo
27 28 $ hg ci --cwd local -A -m "init"
28 29 adding foo
29 30
30 31 test custom revlog chunk cache sizes
31 32
32 33 $ hg --config format.chunkcachesize=0 log -R local -pv
33 34 abort: revlog chunk cache size 0 is not greater than 0!
34 35 [255]
35 36 $ hg --config format.chunkcachesize=1023 log -R local -pv
36 37 abort: revlog chunk cache size 1023 is not a power of 2!
37 38 [255]
38 39 $ hg --config format.chunkcachesize=1024 log -R local -pv
39 40 changeset: 0:08b9e9f63b32
40 41 tag: tip
41 42 user: test
42 43 date: Thu Jan 01 00:00:00 1970 +0000
43 44 files: foo
44 45 description:
45 46 init
46 47
47 48
48 49 diff -r 000000000000 -r 08b9e9f63b32 foo
49 50 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50 51 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
51 52 @@ -0,0 +1,1 @@
52 53 +this
53 54
54 55
55 56 creating repo with format.usestore=false
56 57
57 58 $ hg --config format.usestore=false init old
58 59 $ checknewrepo old
59 60 generaldelta
60 61 revlogv1
62 testonly-simplestore (reposimplestore !)
61 63
62 64 creating repo with format.usefncache=false
63 65
64 66 $ hg --config format.usefncache=false init old2
65 67 $ checknewrepo old2
66 68 store created
67 69 00changelog.i created
68 70 generaldelta
69 71 revlogv1
70 72 store
73 testonly-simplestore (reposimplestore !)
71 74
72 75 creating repo with format.dotencode=false
73 76
74 77 $ hg --config format.dotencode=false init old3
75 78 $ checknewrepo old3
76 79 store created
77 80 00changelog.i created
78 81 fncache
79 82 generaldelta
80 83 revlogv1
81 84 store
85 testonly-simplestore (reposimplestore !)
82 86
83 87 creating repo with format.dotencode=false
84 88
85 89 $ hg --config format.generaldelta=false --config format.usegeneraldelta=false init old4
86 90 $ checknewrepo old4
87 91 store created
88 92 00changelog.i created
89 93 dotencode
90 94 fncache
91 95 revlogv1
92 96 store
97 testonly-simplestore (reposimplestore !)
93 98
94 99 test failure
95 100
96 101 $ hg init local
97 102 abort: repository local already exists!
98 103 [255]
99 104
100 105 init+push to remote2
101 106
102 107 $ hg init -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
103 108 $ hg incoming -R remote2 local
104 109 comparing with local
105 110 changeset: 0:08b9e9f63b32
106 111 tag: tip
107 112 user: test
108 113 date: Thu Jan 01 00:00:00 1970 +0000
109 114 summary: init
110 115
111 116
112 117 $ hg push -R local -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote2
113 118 pushing to ssh://user@dummy/remote2
114 119 searching for changes
115 120 remote: adding changesets
116 121 remote: adding manifests
117 122 remote: adding file changes
118 123 remote: added 1 changesets with 1 changes to 1 files
119 124
120 125 clone to remote1
121 126
122 127 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
123 128 searching for changes
124 129 remote: adding changesets
125 130 remote: adding manifests
126 131 remote: adding file changes
127 132 remote: added 1 changesets with 1 changes to 1 files
128 133
129 134 The largefiles extension doesn't crash
130 135 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remotelf --config extensions.largefiles=
131 136 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
132 137 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
133 138 searching for changes
134 139 remote: adding changesets
135 140 remote: adding manifests
136 141 remote: adding file changes
137 142 remote: added 1 changesets with 1 changes to 1 files
138 143
139 144 init to existing repo
140 145
141 146 $ hg init -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote1
142 147 abort: repository remote1 already exists!
143 148 abort: could not create remote repo!
144 149 [255]
145 150
146 151 clone to existing repo
147 152
148 153 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote1
149 154 abort: repository remote1 already exists!
150 155 abort: could not create remote repo!
151 156 [255]
152 157
153 158 output of dummyssh
154 159
155 160 $ cat dummylog
156 161 Got arguments 1:user@dummy 2:hg init remote2
157 162 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
158 163 Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio
159 164 Got arguments 1:user@dummy 2:hg init remote1
160 165 Got arguments 1:user@dummy 2:hg -R remote1 serve --stdio
161 166 Got arguments 1:user@dummy 2:hg init remotelf
162 167 Got arguments 1:user@dummy 2:hg -R remotelf serve --stdio
163 168 Got arguments 1:user@dummy 2:hg init remote1
164 169 Got arguments 1:user@dummy 2:hg init remote1
165 170
166 171 comparing repositories
167 172
168 173 $ hg tip -q -R local
169 174 0:08b9e9f63b32
170 175 $ hg tip -q -R remote1
171 176 0:08b9e9f63b32
172 177 $ hg tip -q -R remote2
173 178 0:08b9e9f63b32
174 179
175 180 check names for repositories (clashes with URL schemes, special chars)
176 181
177 182 $ for i in bundle file hg http https old-http ssh static-http "with space"; do
178 183 > printf "hg init \"$i\"... "
179 184 > hg init "$i"
180 185 > test -d "$i" -a -d "$i/.hg" && echo "ok" || echo "failed"
181 186 > done
182 187 hg init "bundle"... ok
183 188 hg init "file"... ok
184 189 hg init "hg"... ok
185 190 hg init "http"... ok
186 191 hg init "https"... ok
187 192 hg init "old-http"... ok
188 193 hg init "ssh"... ok
189 194 hg init "static-http"... ok
190 195 hg init "with space"... ok
191 196 #if eol-in-paths
192 197 /* " " is not a valid name for a directory on Windows */
193 198 $ hg init " "
194 199 $ test -d " "
195 200 $ test -d " /.hg"
196 201 #endif
197 202
198 203 creating 'local/sub/repo'
199 204
200 205 $ hg init local/sub/repo
201 206 $ checknewrepo local/sub/repo
202 207 store created
203 208 00changelog.i created
204 209 dotencode
205 210 fncache
206 211 generaldelta
207 212 revlogv1
208 213 store
214 testonly-simplestore (reposimplestore !)
209 215
210 216 prepare test of init of url configured from paths
211 217
212 218 $ echo '[paths]' >> $HGRCPATH
213 219 $ echo "somewhere = `pwd`/url from paths" >> $HGRCPATH
214 220 $ echo "elsewhere = `pwd`/another paths url" >> $HGRCPATH
215 221
216 222 init should (for consistency with clone) expand the url
217 223
218 224 $ hg init somewhere
219 225 $ checknewrepo "url from paths"
220 226 store created
221 227 00changelog.i created
222 228 dotencode
223 229 fncache
224 230 generaldelta
225 231 revlogv1
226 232 store
233 testonly-simplestore (reposimplestore !)
227 234
228 235 verify that clone also expand urls
229 236
230 237 $ hg clone somewhere elsewhere
231 238 updating to branch default
232 239 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 240 $ checknewrepo "another paths url"
234 241 store created
235 242 00changelog.i created
236 243 dotencode
237 244 fncache
238 245 generaldelta
239 246 revlogv1
240 247 store
248 testonly-simplestore (reposimplestore !)
241 249
242 250 clone bookmarks
243 251
244 252 $ hg -R local bookmark test
245 253 $ hg -R local bookmarks
246 254 * test 0:08b9e9f63b32
247 255 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" local ssh://user@dummy/remote-bookmarks
248 256 searching for changes
249 257 remote: adding changesets
250 258 remote: adding manifests
251 259 remote: adding file changes
252 260 remote: added 1 changesets with 1 changes to 1 files
253 261 exporting bookmark test
254 262 $ hg -R remote-bookmarks bookmarks
255 263 test 0:08b9e9f63b32
@@ -1,130 +1,131 b''
1 1 $ . "$TESTDIR/narrow-library.sh"
2 2
3 3 $ hg init master
4 4 $ cd master
5 5 $ mkdir dir
6 6 $ mkdir dir/src
7 7 $ cd dir/src
8 8 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "f$x"; hg add "f$x"; hg commit -m "Commit src $x"; done
9 9 $ cd ..
10 10 $ mkdir tests
11 11 $ cd tests
12 12 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "t$x"; hg add "t$x"; hg commit -m "Commit test $x"; done
13 13 $ cd ../../..
14 14
15 15 narrow clone a file, f10
16 16
17 17 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10"
18 18 requesting all changes
19 19 adding changesets
20 20 adding manifests
21 21 adding file changes
22 22 added 40 changesets with 1 changes to 1 files
23 23 new changesets *:* (glob)
24 24 $ cd narrow
25 25 $ cat .hg/requires | grep -v generaldelta
26 26 dotencode
27 27 fncache
28 28 narrowhg-experimental
29 29 revlogv1
30 30 store
31 testonly-simplestore (reposimplestore !)
31 32
32 33 $ cat .hg/narrowspec
33 34 [includes]
34 35 path:dir/src/f10
35 36 [excludes]
36 37 $ hg update
37 38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 39 $ find * | sort
39 40 dir
40 41 dir/src
41 42 dir/src/f10
42 43 $ cat dir/src/f10
43 44 10
44 45
45 46 $ cd ..
46 47
47 48 narrow clone a directory, tests/, except tests/t19
48 49
49 50 $ hg clone --narrow ssh://user@dummy/master narrowdir --noupdate --include "dir/tests/" --exclude "dir/tests/t19"
50 51 requesting all changes
51 52 adding changesets
52 53 adding manifests
53 54 adding file changes
54 55 added 40 changesets with 19 changes to 19 files
55 56 new changesets *:* (glob)
56 57 $ cd narrowdir
57 58 $ cat .hg/narrowspec
58 59 [includes]
59 60 path:dir/tests
60 61 [excludes]
61 62 path:dir/tests/t19
62 63 $ hg update
63 64 19 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 65 $ find * | sort
65 66 dir
66 67 dir/tests
67 68 dir/tests/t1
68 69 dir/tests/t10
69 70 dir/tests/t11
70 71 dir/tests/t12
71 72 dir/tests/t13
72 73 dir/tests/t14
73 74 dir/tests/t15
74 75 dir/tests/t16
75 76 dir/tests/t17
76 77 dir/tests/t18
77 78 dir/tests/t2
78 79 dir/tests/t20
79 80 dir/tests/t3
80 81 dir/tests/t4
81 82 dir/tests/t5
82 83 dir/tests/t6
83 84 dir/tests/t7
84 85 dir/tests/t8
85 86 dir/tests/t9
86 87
87 88 $ cd ..
88 89
89 90 narrow clone everything but a directory (tests/)
90 91
91 92 $ hg clone --narrow ssh://user@dummy/master narrowroot --noupdate --exclude "dir/tests"
92 93 requesting all changes
93 94 adding changesets
94 95 adding manifests
95 96 adding file changes
96 97 added 40 changesets with 20 changes to 20 files
97 98 new changesets *:* (glob)
98 99 $ cd narrowroot
99 100 $ cat .hg/narrowspec
100 101 [includes]
101 102 path:.
102 103 [excludes]
103 104 path:dir/tests
104 105 $ hg update
105 106 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 107 $ find * | sort
107 108 dir
108 109 dir/src
109 110 dir/src/f1
110 111 dir/src/f10
111 112 dir/src/f11
112 113 dir/src/f12
113 114 dir/src/f13
114 115 dir/src/f14
115 116 dir/src/f15
116 117 dir/src/f16
117 118 dir/src/f17
118 119 dir/src/f18
119 120 dir/src/f19
120 121 dir/src/f2
121 122 dir/src/f20
122 123 dir/src/f3
123 124 dir/src/f4
124 125 dir/src/f5
125 126 dir/src/f6
126 127 dir/src/f7
127 128 dir/src/f8
128 129 dir/src/f9
129 130
130 131 $ cd ..
@@ -1,225 +1,226 b''
1 1 $ . "$TESTDIR/narrow-library.sh"
2 2
3 3 $ hg init master
4 4 $ cd master
5 5 $ cat >> .hg/hgrc <<EOF
6 6 > [narrow]
7 7 > serveellipses=True
8 8 > EOF
9 9 $ mkdir dir
10 10 $ mkdir dir/src
11 11 $ cd dir/src
12 12 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "f$x"; hg add "f$x"; hg commit -m "Commit src $x"; done
13 13 $ cd ..
14 14 $ mkdir tests
15 15 $ cd tests
16 16 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "t$x"; hg add "t$x"; hg commit -m "Commit test $x"; done
17 17 $ cd ../../..
18 18
19 19 narrow clone a file, f10
20 20
21 21 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10"
22 22 requesting all changes
23 23 adding changesets
24 24 adding manifests
25 25 adding file changes
26 26 added 3 changesets with 1 changes to 1 files
27 27 new changesets *:* (glob)
28 28 $ cd narrow
29 29 $ cat .hg/requires | grep -v generaldelta
30 30 dotencode
31 31 fncache
32 32 narrowhg-experimental
33 33 revlogv1
34 34 store
35 testonly-simplestore (reposimplestore !)
35 36
36 37 $ cat .hg/narrowspec
37 38 [includes]
38 39 path:dir/src/f10
39 40 [excludes]
40 41 $ hg tracked
41 42 I path:dir/src/f10
42 43 $ hg update
43 44 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 45 $ find * | sort
45 46 dir
46 47 dir/src
47 48 dir/src/f10
48 49 $ cat dir/src/f10
49 50 10
50 51
51 52 $ cd ..
52 53
53 54 narrow clone with a newline should fail
54 55
55 56 $ hg clone --narrow ssh://user@dummy/master narrow_fail --noupdate --include 'dir/src/f10
56 57 > '
57 58 requesting all changes
58 59 abort: newlines are not allowed in narrowspec paths
59 60 [255]
60 61
61 62 narrow clone a directory, tests/, except tests/t19
62 63
63 64 $ hg clone --narrow ssh://user@dummy/master narrowdir --noupdate --include "dir/tests/" --exclude "dir/tests/t19"
64 65 requesting all changes
65 66 adding changesets
66 67 adding manifests
67 68 adding file changes
68 69 added 21 changesets with 19 changes to 19 files
69 70 new changesets *:* (glob)
70 71 $ cd narrowdir
71 72 $ cat .hg/narrowspec
72 73 [includes]
73 74 path:dir/tests
74 75 [excludes]
75 76 path:dir/tests/t19
76 77 $ hg tracked
77 78 I path:dir/tests
78 79 X path:dir/tests/t19
79 80 $ hg update
80 81 19 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 82 $ find * | sort
82 83 dir
83 84 dir/tests
84 85 dir/tests/t1
85 86 dir/tests/t10
86 87 dir/tests/t11
87 88 dir/tests/t12
88 89 dir/tests/t13
89 90 dir/tests/t14
90 91 dir/tests/t15
91 92 dir/tests/t16
92 93 dir/tests/t17
93 94 dir/tests/t18
94 95 dir/tests/t2
95 96 dir/tests/t20
96 97 dir/tests/t3
97 98 dir/tests/t4
98 99 dir/tests/t5
99 100 dir/tests/t6
100 101 dir/tests/t7
101 102 dir/tests/t8
102 103 dir/tests/t9
103 104
104 105 $ cd ..
105 106
106 107 narrow clone everything but a directory (tests/)
107 108
108 109 $ hg clone --narrow ssh://user@dummy/master narrowroot --noupdate --exclude "dir/tests"
109 110 requesting all changes
110 111 adding changesets
111 112 adding manifests
112 113 adding file changes
113 114 added 21 changesets with 20 changes to 20 files
114 115 new changesets *:* (glob)
115 116 $ cd narrowroot
116 117 $ cat .hg/narrowspec
117 118 [includes]
118 119 path:.
119 120 [excludes]
120 121 path:dir/tests
121 122 $ hg tracked
122 123 I path:.
123 124 X path:dir/tests
124 125 $ hg update
125 126 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 127 $ find * | sort
127 128 dir
128 129 dir/src
129 130 dir/src/f1
130 131 dir/src/f10
131 132 dir/src/f11
132 133 dir/src/f12
133 134 dir/src/f13
134 135 dir/src/f14
135 136 dir/src/f15
136 137 dir/src/f16
137 138 dir/src/f17
138 139 dir/src/f18
139 140 dir/src/f19
140 141 dir/src/f2
141 142 dir/src/f20
142 143 dir/src/f3
143 144 dir/src/f4
144 145 dir/src/f5
145 146 dir/src/f6
146 147 dir/src/f7
147 148 dir/src/f8
148 149 dir/src/f9
149 150
150 151 $ cd ..
151 152
152 153 narrow clone no paths at all
153 154
154 155 $ hg clone --narrow ssh://user@dummy/master narrowempty --noupdate
155 156 requesting all changes
156 157 adding changesets
157 158 adding manifests
158 159 adding file changes
159 160 added 1 changesets with 0 changes to 0 files
160 161 new changesets * (glob)
161 162 $ cd narrowempty
162 163 $ hg tracked
163 164 $ hg update
164 165 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 166 $ ls
166 167
167 168 $ cd ..
168 169
169 170 simple clone
170 171 $ hg clone ssh://user@dummy/master simpleclone
171 172 requesting all changes
172 173 adding changesets
173 174 adding manifests
174 175 adding file changes
175 176 added 40 changesets with 40 changes to 40 files
176 177 new changesets * (glob)
177 178 updating to branch default
178 179 40 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 180 $ cd simpleclone
180 181 $ find * | sort
181 182 dir
182 183 dir/src
183 184 dir/src/f1
184 185 dir/src/f10
185 186 dir/src/f11
186 187 dir/src/f12
187 188 dir/src/f13
188 189 dir/src/f14
189 190 dir/src/f15
190 191 dir/src/f16
191 192 dir/src/f17
192 193 dir/src/f18
193 194 dir/src/f19
194 195 dir/src/f2
195 196 dir/src/f20
196 197 dir/src/f3
197 198 dir/src/f4
198 199 dir/src/f5
199 200 dir/src/f6
200 201 dir/src/f7
201 202 dir/src/f8
202 203 dir/src/f9
203 204 dir/tests
204 205 dir/tests/t1
205 206 dir/tests/t10
206 207 dir/tests/t11
207 208 dir/tests/t12
208 209 dir/tests/t13
209 210 dir/tests/t14
210 211 dir/tests/t15
211 212 dir/tests/t16
212 213 dir/tests/t17
213 214 dir/tests/t18
214 215 dir/tests/t19
215 216 dir/tests/t2
216 217 dir/tests/t20
217 218 dir/tests/t3
218 219 dir/tests/t4
219 220 dir/tests/t5
220 221 dir/tests/t6
221 222 dir/tests/t7
222 223 dir/tests/t8
223 224 dir/tests/t9
224 225
225 226 $ cd ..
@@ -1,392 +1,402 b''
1 1 #testcases flat tree
2 2
3 3 $ . "$TESTDIR/narrow-library.sh"
4 4
5 5 #if tree
6 6 $ cat << EOF >> $HGRCPATH
7 7 > [experimental]
8 8 > treemanifest = 1
9 9 > EOF
10 10 #endif
11 11
12 12 $ hg init master
13 13 $ cd master
14 14 $ cat >> .hg/hgrc <<EOF
15 15 > [narrow]
16 16 > serveellipses=True
17 17 > EOF
18 18 $ for x in `$TESTDIR/seq.py 0 10`
19 19 > do
20 20 > mkdir d$x
21 21 > echo $x > d$x/f
22 22 > hg add d$x/f
23 23 > hg commit -m "add d$x/f"
24 24 > done
25 25 $ hg log -T "{node|short}: {desc}\n"
26 26 *: add d10/f (glob)
27 27 *: add d9/f (glob)
28 28 *: add d8/f (glob)
29 29 *: add d7/f (glob)
30 30 *: add d6/f (glob)
31 31 *: add d5/f (glob)
32 32 *: add d4/f (glob)
33 33 *: add d3/f (glob)
34 34 *: add d2/f (glob)
35 35 *: add d1/f (glob)
36 36 *: add d0/f (glob)
37 37 $ cd ..
38 38
39 39 Error if '.' or '..' are in the directory to track.
40 40 $ hg clone --narrow ssh://user@dummy/master foo --include ./asdf
41 41 requesting all changes
42 42 abort: "." and ".." are not allowed in narrowspec paths
43 43 [255]
44 44 $ hg clone --narrow ssh://user@dummy/master foo --include asdf/..
45 45 requesting all changes
46 46 abort: "." and ".." are not allowed in narrowspec paths
47 47 [255]
48 48 $ hg clone --narrow ssh://user@dummy/master foo --include a/./c
49 49 requesting all changes
50 50 abort: "." and ".." are not allowed in narrowspec paths
51 51 [255]
52 52
53 53 Names with '.' in them are OK.
54 54 $ hg clone --narrow ssh://user@dummy/master should-work --include a/.b/c
55 55 requesting all changes
56 56 adding changesets
57 57 adding manifests
58 58 adding file changes
59 59 added 1 changesets with 0 changes to 0 files
60 60 new changesets * (glob)
61 61 updating to branch default
62 62 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 63
64 64 Test repo with local changes
65 65 $ hg clone --narrow ssh://user@dummy/master narrow-local-changes --include d0 --include d3 --include d6
66 66 requesting all changes
67 67 adding changesets
68 68 adding manifests
69 69 adding file changes
70 70 added 6 changesets with 3 changes to 3 files
71 71 new changesets *:* (glob)
72 72 updating to branch default
73 73 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 74 $ cd narrow-local-changes
75 75 $ cat >> $HGRCPATH << EOF
76 76 > [experimental]
77 77 > evolution=createmarkers
78 78 > EOF
79 79 $ echo local change >> d0/f
80 80 $ hg ci -m 'local change to d0'
81 81 $ hg co '.^'
82 82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 83 $ echo local change >> d3/f
84 84 $ hg ci -m 'local hidden change to d3'
85 85 created new head
86 86 $ hg ci --amend -m 'local change to d3'
87 87 $ hg tracked --removeinclude d0
88 88 comparing with ssh://user@dummy/master
89 89 searching for changes
90 90 looking for local changes to affected paths
91 91 The following changeset(s) or their ancestors have local changes not on the remote:
92 92 * (glob)
93 93 abort: local changes found
94 94 (use --force-delete-local-changes to ignore)
95 95 [255]
96 96 Check that nothing was removed by the failed attempts
97 97 $ hg tracked
98 98 I path:d0
99 99 I path:d3
100 100 I path:d6
101 101 $ hg files
102 102 d0/f
103 103 d3/f
104 104 d6/f
105 105 $ find *
106 106 d0
107 107 d0/f
108 108 d3
109 109 d3/f
110 110 d6
111 111 d6/f
112 112 $ hg verify -q
113 113 Force deletion of local changes
114 114 $ hg log -T "{node|short}: {desc} {outsidenarrow}\n"
115 115 *: local change to d3 (glob)
116 116 *: local change to d0 (glob)
117 117 *: add d10/f outsidenarrow (glob)
118 118 *: add d6/f (glob)
119 119 *: add d5/f outsidenarrow (glob)
120 120 *: add d3/f (glob)
121 121 *: add d2/f outsidenarrow (glob)
122 122 *: add d0/f (glob)
123 123 $ hg tracked --removeinclude d0 --force-delete-local-changes
124 124 comparing with ssh://user@dummy/master
125 125 searching for changes
126 126 looking for local changes to affected paths
127 127 The following changeset(s) or their ancestors have local changes not on the remote:
128 128 * (glob)
129 129 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
130 130 deleting data/d0/f.i (reporevlogstore !)
131 deleting meta/d0/00manifest.i (tree !)
131 132 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
132 133 deleting data/d0/f/4374b5650fc5ae54ac857c0f0381971fdde376f7 (reposimplestore !)
133 134 deleting data/d0/f/index (reposimplestore !)
134 deleting meta/d0/00manifest.i (tree !)
135 135
136 136 $ hg log -T "{node|short}: {desc} {outsidenarrow}\n"
137 137 *: local change to d3 (glob)
138 138 *: add d10/f outsidenarrow (glob)
139 139 *: add d6/f (glob)
140 140 *: add d5/f outsidenarrow (glob)
141 141 *: add d3/f (glob)
142 142 *: add d2/f outsidenarrow (glob)
143 143 *: add d0/f outsidenarrow (glob)
144 144 Can restore stripped local changes after widening
145 145 $ hg tracked --addinclude d0 -q
146 146 $ hg unbundle .hg/strip-backup/*-narrow.hg -q
147 147 $ hg --hidden co -r 'desc("local change to d0")' -q
148 148 $ cat d0/f
149 149 0
150 150 local change
151 151 Pruned commits affecting removed paths should not prevent narrowing
152 152 $ hg co '.^'
153 153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 154 $ hg debugobsolete `hg log -T '{node}' -r 'desc("local change to d0")'`
155 155 obsoleted 1 changesets
156 156 $ hg tracked --removeinclude d0
157 157 comparing with ssh://user@dummy/master
158 158 searching for changes
159 159 looking for local changes to affected paths
160 160 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
161 161 deleting data/d0/f.i (reporevlogstore !)
162 deleting meta/d0/00manifest.i (tree !)
162 163 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
163 164 deleting data/d0/f/4374b5650fc5ae54ac857c0f0381971fdde376f7 (reposimplestore !)
164 165 deleting data/d0/f/index (reposimplestore !)
165 deleting meta/d0/00manifest.i (tree !)
166 166
167 167 Updates off of stripped commit if necessary
168 168 $ hg co -r 'desc("local change to d3")' -q
169 169 $ echo local change >> d6/f
170 170 $ hg ci -m 'local change to d6'
171 171 $ hg tracked --removeinclude d3 --force-delete-local-changes
172 172 comparing with ssh://user@dummy/master
173 173 searching for changes
174 174 looking for local changes to affected paths
175 175 The following changeset(s) or their ancestors have local changes not on the remote:
176 176 * (glob)
177 177 * (glob)
178 178 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 179 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
180 180 deleting data/d3/f.i (reporevlogstore !)
181 deleting meta/d3/00manifest.i (tree !)
181 182 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
182 183 deleting data/d3/f/99fa7136105a15e2045ce3d9152e4837c5349e4d (reposimplestore !)
183 184 deleting data/d3/f/index (reposimplestore !)
184 deleting meta/d3/00manifest.i (tree !)
185 185 $ hg log -T '{desc}\n' -r .
186 186 add d10/f
187 187 Updates to nullid if necessary
188 188 $ hg tracked --addinclude d3 -q
189 189 $ hg co null -q
190 190 $ mkdir d3
191 191 $ echo local change > d3/f
192 192 $ hg add d3/f
193 193 $ hg ci -m 'local change to d3'
194 194 created new head
195 195 $ hg tracked --removeinclude d3 --force-delete-local-changes
196 196 comparing with ssh://user@dummy/master
197 197 searching for changes
198 198 looking for local changes to affected paths
199 199 The following changeset(s) or their ancestors have local changes not on the remote:
200 200 * (glob)
201 201 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
202 202 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
203 203 deleting data/d3/f.i (reporevlogstore !)
204 deleting meta/d3/00manifest.i (tree !)
204 205 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
205 206 deleting data/d3/f/5ce0767945cbdbca3b924bb9fbf5143f72ab40ac (reposimplestore !)
206 207 deleting data/d3/f/index (reposimplestore !)
207 deleting meta/d3/00manifest.i (tree !)
208 208 $ hg id
209 209 000000000000
210 210 $ cd ..
211 211
212 212 Can remove last include, making repo empty
213 213 $ hg clone --narrow ssh://user@dummy/master narrow-empty --include d0 -r 5
214 214 adding changesets
215 215 adding manifests
216 216 adding file changes
217 217 added 2 changesets with 1 changes to 1 files
218 218 new changesets *:* (glob)
219 219 updating to branch default
220 220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 221 $ cd narrow-empty
222 222 $ hg tracked --removeinclude d0
223 223 comparing with ssh://user@dummy/master
224 224 searching for changes
225 225 looking for local changes to affected paths
226 226 deleting data/d0/f.i (reporevlogstore !)
227 deleting meta/d0/00manifest.i (tree !)
227 228 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
228 229 deleting data/d0/f/index (reposimplestore !)
229 deleting meta/d0/00manifest.i (tree !)
230 230 $ hg tracked
231 231 $ hg files
232 232 [1]
233 233 $ test -d d0
234 234 [1]
235 235 Do some work in the empty clone
236 236 $ hg diff --change .
237 237 $ hg branch foo
238 238 marked working directory as branch foo
239 239 (branches are permanent and global, did you want a bookmark?)
240 240 $ hg ci -m empty
241 241 $ hg pull -q
242 242 Can widen the empty clone
243 243 $ hg tracked --addinclude d0
244 244 comparing with ssh://user@dummy/master
245 245 searching for changes
246 246 no changes found
247 247 saved backup bundle to $TESTTMP/narrow-empty/.hg/strip-backup/*-widen.hg (glob)
248 248 adding changesets
249 249 adding manifests
250 250 adding file changes
251 251 added 3 changesets with 1 changes to 1 files
252 252 new changesets *:* (glob)
253 253 $ hg tracked
254 254 I path:d0
255 255 $ hg files
256 256 d0/f
257 257 $ find *
258 258 d0
259 259 d0/f
260 260 $ cd ..
261 261
262 262 TODO(martinvonz): test including e.g. d3/g and then removing it once
263 263 https://bitbucket.org/Google/narrowhg/issues/6 is fixed
264 264
265 265 $ hg clone --narrow ssh://user@dummy/master narrow --include d0 --include d3 --include d6 --include d9
266 266 requesting all changes
267 267 adding changesets
268 268 adding manifests
269 269 adding file changes
270 270 added 8 changesets with 4 changes to 4 files
271 271 new changesets *:* (glob)
272 272 updating to branch default
273 273 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 274 $ cd narrow
275 275 $ hg tracked
276 276 I path:d0
277 277 I path:d3
278 278 I path:d6
279 279 I path:d9
280 280 $ hg tracked --removeinclude d6
281 281 comparing with ssh://user@dummy/master
282 282 searching for changes
283 283 looking for local changes to affected paths
284 284 deleting data/d6/f.i (reporevlogstore !)
285 deleting meta/d6/00manifest.i (tree !)
285 286 deleting data/d6/f/7339d30678f451ac8c3f38753beeb4cf2e1655c7 (reposimplestore !)
286 287 deleting data/d6/f/index (reposimplestore !)
287 deleting meta/d6/00manifest.i (tree !)
288 288 $ hg tracked
289 289 I path:d0
290 290 I path:d3
291 291 I path:d9
292 #if repofncache
292 293 $ hg debugrebuildfncache
293 294 fncache already up to date
295 #endif
294 296 $ find *
295 297 d0
296 298 d0/f
297 299 d3
298 300 d3/f
299 301 d9
300 302 d9/f
301 303 $ hg verify -q
302 304 $ hg tracked --addexclude d3/f
303 305 comparing with ssh://user@dummy/master
304 306 searching for changes
305 307 looking for local changes to affected paths
306 308 deleting data/d3/f.i (reporevlogstore !)
309 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
310 deleting data/d3/f/index (reposimplestore !)
307 311 $ hg tracked
308 312 I path:d0
309 313 I path:d3
310 314 I path:d9
311 315 X path:d3/f
316 #if repofncache
312 317 $ hg debugrebuildfncache
313 318 fncache already up to date
319 #endif
314 320 $ find *
315 321 d0
316 322 d0/f
317 323 d9
318 324 d9/f
319 325 $ hg verify -q
320 326 $ hg tracked --addexclude d0
321 327 comparing with ssh://user@dummy/master
322 328 searching for changes
323 329 looking for local changes to affected paths
324 330 deleting data/d0/f.i (reporevlogstore !)
325 331 deleting meta/d0/00manifest.i (tree !)
332 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
333 deleting data/d0/f/index (reposimplestore !)
326 334 $ hg tracked
327 335 I path:d3
328 336 I path:d9
329 337 X path:d0
330 338 X path:d3/f
339 #if repofncache
331 340 $ hg debugrebuildfncache
332 341 fncache already up to date
342 #endif
333 343 $ find *
334 344 d9
335 345 d9/f
336 346
337 347 Make a 15 of changes to d9 to test the path without --verbose
338 348 (Note: using regexes instead of "* (glob)" because if the test fails, it
339 349 produces more sensible diffs)
340 350 $ hg tracked
341 351 I path:d3
342 352 I path:d9
343 353 X path:d0
344 354 X path:d3/f
345 355 $ for x in `$TESTDIR/seq.py 1 15`
346 356 > do
347 357 > echo local change >> d9/f
348 358 > hg commit -m "change $x to d9/f"
349 359 > done
350 360 $ hg tracked --removeinclude d9
351 361 comparing with ssh://user@dummy/master
352 362 searching for changes
353 363 looking for local changes to affected paths
354 364 The following changeset(s) or their ancestors have local changes not on the remote:
355 365 ^[0-9a-f]{12}$ (re)
356 366 ^[0-9a-f]{12}$ (re)
357 367 ^[0-9a-f]{12}$ (re)
358 368 ^[0-9a-f]{12}$ (re)
359 369 ^[0-9a-f]{12}$ (re)
360 370 ^[0-9a-f]{12}$ (re)
361 371 ^[0-9a-f]{12}$ (re)
362 372 ^[0-9a-f]{12}$ (re)
363 373 ^[0-9a-f]{12}$ (re)
364 374 ^[0-9a-f]{12}$ (re)
365 375 ...and 5 more, use --verbose to list all
366 376 abort: local changes found
367 377 (use --force-delete-local-changes to ignore)
368 378 [255]
369 379 Now test it *with* verbose.
370 380 $ hg tracked --removeinclude d9 --verbose
371 381 comparing with ssh://user@dummy/master
372 382 searching for changes
373 383 looking for local changes to affected paths
374 384 The following changeset(s) or their ancestors have local changes not on the remote:
375 385 ^[0-9a-f]{12}$ (re)
376 386 ^[0-9a-f]{12}$ (re)
377 387 ^[0-9a-f]{12}$ (re)
378 388 ^[0-9a-f]{12}$ (re)
379 389 ^[0-9a-f]{12}$ (re)
380 390 ^[0-9a-f]{12}$ (re)
381 391 ^[0-9a-f]{12}$ (re)
382 392 ^[0-9a-f]{12}$ (re)
383 393 ^[0-9a-f]{12}$ (re)
384 394 ^[0-9a-f]{12}$ (re)
385 395 ^[0-9a-f]{12}$ (re)
386 396 ^[0-9a-f]{12}$ (re)
387 397 ^[0-9a-f]{12}$ (re)
388 398 ^[0-9a-f]{12}$ (re)
389 399 ^[0-9a-f]{12}$ (re)
390 400 abort: local changes found
391 401 (use --force-delete-local-changes to ignore)
392 402 [255]
@@ -1,78 +1,81 b''
1 1 A new repository uses zlib storage, which doesn't need a requirement
2 2
3 3 $ hg init default
4 4 $ cd default
5 5 $ cat .hg/requires
6 6 dotencode
7 7 fncache
8 8 generaldelta
9 9 revlogv1
10 10 store
11 testonly-simplestore (reposimplestore !)
11 12
12 13 $ touch foo
13 14 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text to trigger compression'
14 15 $ hg debugrevlog -c | grep 0x78
15 16 0x78 (x) : 1 (100.00%)
16 17 0x78 (x) : 110 (100.00%)
17 18
18 19 $ cd ..
19 20
20 21 Unknown compression engine to format.compression aborts
21 22
22 23 $ hg --config experimental.format.compression=unknown init unknown
23 24 abort: compression engine unknown defined by experimental.format.compression not available
24 25 (run "hg debuginstall" to list available compression engines)
25 26 [255]
26 27
27 28 A requirement specifying an unknown compression engine results in bail
28 29
29 30 $ hg init unknownrequirement
30 31 $ cd unknownrequirement
31 32 $ echo exp-compression-unknown >> .hg/requires
32 33 $ hg log
33 34 abort: repository requires features unknown to this Mercurial: exp-compression-unknown!
34 35 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
35 36 [255]
36 37
37 38 $ cd ..
38 39
39 40 #if zstd
40 41
41 42 $ hg --config experimental.format.compression=zstd init zstd
42 43 $ cd zstd
43 44 $ cat .hg/requires
44 45 dotencode
45 46 exp-compression-zstd
46 47 fncache
47 48 generaldelta
48 49 revlogv1
49 50 store
51 testonly-simplestore (reposimplestore !)
50 52
51 53 $ touch foo
52 54 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text'
53 55
54 56 $ hg debugrevlog -c | grep 0x28
55 57 0x28 : 1 (100.00%)
56 58 0x28 : 98 (100.00%)
57 59
58 60 $ cd ..
59 61
60 62 Specifying a new format.compression on an existing repo won't introduce data
61 63 with that engine or a requirement
62 64
63 65 $ cd default
64 66 $ touch bar
65 67 $ hg --config experimental.format.compression=zstd -q commit -A -m 'add bar with a lot of repeated repeated repeated text'
66 68
67 69 $ cat .hg/requires
68 70 dotencode
69 71 fncache
70 72 generaldelta
71 73 revlogv1
72 74 store
75 testonly-simplestore (reposimplestore !)
73 76
74 77 $ hg debugrevlog -c | grep 0x78
75 78 0x78 (x) : 2 (100.00%)
76 79 0x78 (x) : 199 (100.00%)
77 80
78 81 #endif
@@ -1,65 +1,68 b''
1 1 $ hg init repo
2 2 $ cd repo
3 3
4 4 $ touch a.html b.html c.py d.py
5 5
6 6 $ cat > frontend.sparse << EOF
7 7 > [include]
8 8 > *.html
9 9 > EOF
10 10
11 11 $ hg -q commit -A -m initial
12 12
13 13 $ echo 1 > a.html
14 14 $ echo 1 > c.py
15 15 $ hg commit -m 'commit 1'
16 16
17 17 Enable sparse profile
18 18
19 19 $ cat .hg/requires
20 20 dotencode
21 21 fncache
22 22 generaldelta
23 23 revlogv1
24 24 store
25 testonly-simplestore (reposimplestore !)
25 26
26 27 $ hg debugsparse --config extensions.sparse= --enable-profile frontend.sparse
27 28 $ ls
28 29 a.html
29 30 b.html
30 31
31 32 Requirement for sparse added when sparse is enabled
32 33
33 34 $ cat .hg/requires
34 35 dotencode
35 36 exp-sparse
36 37 fncache
37 38 generaldelta
38 39 revlogv1
39 40 store
41 testonly-simplestore (reposimplestore !)
40 42
41 43 Client without sparse enabled reacts properly
42 44
43 45 $ hg files
44 46 abort: repository is using sparse feature but sparse is not enabled; enable the "sparse" extensions to access!
45 47 [255]
46 48
47 49 Requirement for sparse is removed when sparse is disabled
48 50
49 51 $ hg debugsparse --reset --config extensions.sparse=
50 52
51 53 $ cat .hg/requires
52 54 dotencode
53 55 fncache
54 56 generaldelta
55 57 revlogv1
56 58 store
59 testonly-simplestore (reposimplestore !)
57 60
58 61 And client without sparse can access
59 62
60 63 $ hg files
61 64 a.html
62 65 b.html
63 66 c.py
64 67 d.py
65 68 frontend.sparse
@@ -1,1336 +1,1340 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "strip=" >> $HGRCPATH
3 3 $ echo "drawdag=$TESTDIR/drawdag.py" >> $HGRCPATH
4 4
5 5 $ restore() {
6 6 > hg unbundle -q .hg/strip-backup/*
7 7 > rm .hg/strip-backup/*
8 8 > }
9 9 $ teststrip() {
10 10 > hg up -C $1
11 11 > echo % before update $1, strip $2
12 12 > hg parents
13 13 > hg --traceback strip $2
14 14 > echo % after update $1, strip $2
15 15 > hg parents
16 16 > restore
17 17 > }
18 18
19 19 $ hg init test
20 20 $ cd test
21 21
22 22 $ echo foo > bar
23 23 $ hg ci -Ama
24 24 adding bar
25 25
26 26 $ echo more >> bar
27 27 $ hg ci -Amb
28 28
29 29 $ echo blah >> bar
30 30 $ hg ci -Amc
31 31
32 32 $ hg up 1
33 33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ echo blah >> bar
35 35 $ hg ci -Amd
36 36 created new head
37 37
38 38 $ echo final >> bar
39 39 $ hg ci -Ame
40 40
41 41 $ hg log
42 42 changeset: 4:443431ffac4f
43 43 tag: tip
44 44 user: test
45 45 date: Thu Jan 01 00:00:00 1970 +0000
46 46 summary: e
47 47
48 48 changeset: 3:65bd5f99a4a3
49 49 parent: 1:ef3a871183d7
50 50 user: test
51 51 date: Thu Jan 01 00:00:00 1970 +0000
52 52 summary: d
53 53
54 54 changeset: 2:264128213d29
55 55 user: test
56 56 date: Thu Jan 01 00:00:00 1970 +0000
57 57 summary: c
58 58
59 59 changeset: 1:ef3a871183d7
60 60 user: test
61 61 date: Thu Jan 01 00:00:00 1970 +0000
62 62 summary: b
63 63
64 64 changeset: 0:9ab35a2d17cb
65 65 user: test
66 66 date: Thu Jan 01 00:00:00 1970 +0000
67 67 summary: a
68 68
69 69
70 70 $ teststrip 4 4
71 71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 72 % before update 4, strip 4
73 73 changeset: 4:443431ffac4f
74 74 tag: tip
75 75 user: test
76 76 date: Thu Jan 01 00:00:00 1970 +0000
77 77 summary: e
78 78
79 79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 80 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
81 81 % after update 4, strip 4
82 82 changeset: 3:65bd5f99a4a3
83 83 tag: tip
84 84 parent: 1:ef3a871183d7
85 85 user: test
86 86 date: Thu Jan 01 00:00:00 1970 +0000
87 87 summary: d
88 88
89 89 $ teststrip 4 3
90 90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 % before update 4, strip 3
92 92 changeset: 4:443431ffac4f
93 93 tag: tip
94 94 user: test
95 95 date: Thu Jan 01 00:00:00 1970 +0000
96 96 summary: e
97 97
98 98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 99 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
100 100 % after update 4, strip 3
101 101 changeset: 1:ef3a871183d7
102 102 user: test
103 103 date: Thu Jan 01 00:00:00 1970 +0000
104 104 summary: b
105 105
106 106 $ teststrip 1 4
107 107 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 108 % before update 1, strip 4
109 109 changeset: 1:ef3a871183d7
110 110 user: test
111 111 date: Thu Jan 01 00:00:00 1970 +0000
112 112 summary: b
113 113
114 114 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
115 115 % after update 1, strip 4
116 116 changeset: 1:ef3a871183d7
117 117 user: test
118 118 date: Thu Jan 01 00:00:00 1970 +0000
119 119 summary: b
120 120
121 121 $ teststrip 4 2
122 122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 123 % before update 4, strip 2
124 124 changeset: 4:443431ffac4f
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: e
129 129
130 130 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
131 131 % after update 4, strip 2
132 132 changeset: 3:443431ffac4f
133 133 tag: tip
134 134 user: test
135 135 date: Thu Jan 01 00:00:00 1970 +0000
136 136 summary: e
137 137
138 138 $ teststrip 4 1
139 139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 140 % before update 4, strip 1
141 141 changeset: 4:264128213d29
142 142 tag: tip
143 143 parent: 1:ef3a871183d7
144 144 user: test
145 145 date: Thu Jan 01 00:00:00 1970 +0000
146 146 summary: c
147 147
148 148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 149 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
150 150 % after update 4, strip 1
151 151 changeset: 0:9ab35a2d17cb
152 152 tag: tip
153 153 user: test
154 154 date: Thu Jan 01 00:00:00 1970 +0000
155 155 summary: a
156 156
157 157 $ teststrip null 4
158 158 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
159 159 % before update null, strip 4
160 160 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
161 161 % after update null, strip 4
162 162
163 163 $ hg log
164 164 changeset: 4:264128213d29
165 165 tag: tip
166 166 parent: 1:ef3a871183d7
167 167 user: test
168 168 date: Thu Jan 01 00:00:00 1970 +0000
169 169 summary: c
170 170
171 171 changeset: 3:443431ffac4f
172 172 user: test
173 173 date: Thu Jan 01 00:00:00 1970 +0000
174 174 summary: e
175 175
176 176 changeset: 2:65bd5f99a4a3
177 177 user: test
178 178 date: Thu Jan 01 00:00:00 1970 +0000
179 179 summary: d
180 180
181 181 changeset: 1:ef3a871183d7
182 182 user: test
183 183 date: Thu Jan 01 00:00:00 1970 +0000
184 184 summary: b
185 185
186 186 changeset: 0:9ab35a2d17cb
187 187 user: test
188 188 date: Thu Jan 01 00:00:00 1970 +0000
189 189 summary: a
190 190
191 191 $ hg up -C 4
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 $ hg parents
194 194 changeset: 4:264128213d29
195 195 tag: tip
196 196 parent: 1:ef3a871183d7
197 197 user: test
198 198 date: Thu Jan 01 00:00:00 1970 +0000
199 199 summary: c
200 200
201 201
202 202 $ hg --traceback strip 4
203 203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 204 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg
205 205 $ hg parents
206 206 changeset: 1:ef3a871183d7
207 207 user: test
208 208 date: Thu Jan 01 00:00:00 1970 +0000
209 209 summary: b
210 210
211 211 $ hg debugbundle .hg/strip-backup/*
212 212 Stream params: {Compression: BZ}
213 213 changegroup -- {nbchanges: 1, version: 02}
214 214 264128213d290d868c54642d13aeaa3675551a78
215 215 cache:rev-branch-cache -- {}
216 216 phase-heads -- {}
217 217 264128213d290d868c54642d13aeaa3675551a78 draft
218 218 $ hg unbundle .hg/strip-backup/*
219 219 adding changesets
220 220 adding manifests
221 221 adding file changes
222 222 added 1 changesets with 0 changes to 1 files (+1 heads)
223 223 new changesets 264128213d29
224 224 (run 'hg heads' to see heads, 'hg merge' to merge)
225 225 $ rm .hg/strip-backup/*
226 226 $ hg log --graph
227 227 o changeset: 4:264128213d29
228 228 | tag: tip
229 229 | parent: 1:ef3a871183d7
230 230 | user: test
231 231 | date: Thu Jan 01 00:00:00 1970 +0000
232 232 | summary: c
233 233 |
234 234 | o changeset: 3:443431ffac4f
235 235 | | user: test
236 236 | | date: Thu Jan 01 00:00:00 1970 +0000
237 237 | | summary: e
238 238 | |
239 239 | o changeset: 2:65bd5f99a4a3
240 240 |/ user: test
241 241 | date: Thu Jan 01 00:00:00 1970 +0000
242 242 | summary: d
243 243 |
244 244 @ changeset: 1:ef3a871183d7
245 245 | user: test
246 246 | date: Thu Jan 01 00:00:00 1970 +0000
247 247 | summary: b
248 248 |
249 249 o changeset: 0:9ab35a2d17cb
250 250 user: test
251 251 date: Thu Jan 01 00:00:00 1970 +0000
252 252 summary: a
253 253
254 254 $ hg up -C 2
255 255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 256 $ hg merge 4
257 257 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 258 (branch merge, don't forget to commit)
259 259
260 260 before strip of merge parent
261 261
262 262 $ hg parents
263 263 changeset: 2:65bd5f99a4a3
264 264 user: test
265 265 date: Thu Jan 01 00:00:00 1970 +0000
266 266 summary: d
267 267
268 268 changeset: 4:264128213d29
269 269 tag: tip
270 270 parent: 1:ef3a871183d7
271 271 user: test
272 272 date: Thu Jan 01 00:00:00 1970 +0000
273 273 summary: c
274 274
275 275 $ hg strip 4
276 276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 277 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
278 278
279 279 after strip of merge parent
280 280
281 281 $ hg parents
282 282 changeset: 1:ef3a871183d7
283 283 user: test
284 284 date: Thu Jan 01 00:00:00 1970 +0000
285 285 summary: b
286 286
287 287 $ restore
288 288
289 289 $ hg up
290 290 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 291 updated to "264128213d29: c"
292 292 1 other heads for branch "default"
293 293 $ hg log -G
294 294 @ changeset: 4:264128213d29
295 295 | tag: tip
296 296 | parent: 1:ef3a871183d7
297 297 | user: test
298 298 | date: Thu Jan 01 00:00:00 1970 +0000
299 299 | summary: c
300 300 |
301 301 | o changeset: 3:443431ffac4f
302 302 | | user: test
303 303 | | date: Thu Jan 01 00:00:00 1970 +0000
304 304 | | summary: e
305 305 | |
306 306 | o changeset: 2:65bd5f99a4a3
307 307 |/ user: test
308 308 | date: Thu Jan 01 00:00:00 1970 +0000
309 309 | summary: d
310 310 |
311 311 o changeset: 1:ef3a871183d7
312 312 | user: test
313 313 | date: Thu Jan 01 00:00:00 1970 +0000
314 314 | summary: b
315 315 |
316 316 o changeset: 0:9ab35a2d17cb
317 317 user: test
318 318 date: Thu Jan 01 00:00:00 1970 +0000
319 319 summary: a
320 320
321 321
322 322 2 is parent of 3, only one strip should happen
323 323
324 324 $ hg strip "roots(2)" 3
325 325 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
326 326 $ hg log -G
327 327 @ changeset: 2:264128213d29
328 328 | tag: tip
329 329 | user: test
330 330 | date: Thu Jan 01 00:00:00 1970 +0000
331 331 | summary: c
332 332 |
333 333 o changeset: 1:ef3a871183d7
334 334 | user: test
335 335 | date: Thu Jan 01 00:00:00 1970 +0000
336 336 | summary: b
337 337 |
338 338 o changeset: 0:9ab35a2d17cb
339 339 user: test
340 340 date: Thu Jan 01 00:00:00 1970 +0000
341 341 summary: a
342 342
343 343 $ restore
344 344 $ hg log -G
345 345 o changeset: 4:443431ffac4f
346 346 | tag: tip
347 347 | user: test
348 348 | date: Thu Jan 01 00:00:00 1970 +0000
349 349 | summary: e
350 350 |
351 351 o changeset: 3:65bd5f99a4a3
352 352 | parent: 1:ef3a871183d7
353 353 | user: test
354 354 | date: Thu Jan 01 00:00:00 1970 +0000
355 355 | summary: d
356 356 |
357 357 | @ changeset: 2:264128213d29
358 358 |/ user: test
359 359 | date: Thu Jan 01 00:00:00 1970 +0000
360 360 | summary: c
361 361 |
362 362 o changeset: 1:ef3a871183d7
363 363 | user: test
364 364 | date: Thu Jan 01 00:00:00 1970 +0000
365 365 | summary: b
366 366 |
367 367 o changeset: 0:9ab35a2d17cb
368 368 user: test
369 369 date: Thu Jan 01 00:00:00 1970 +0000
370 370 summary: a
371 371
372 372 Failed hook while applying "saveheads" bundle.
373 373
374 374 $ hg strip 2 --config hooks.pretxnchangegroup.bad=false
375 375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 376 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
377 377 transaction abort!
378 378 rollback completed
379 379 strip failed, backup bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
380 380 strip failed, unrecovered changes stored in '$TESTTMP/test/.hg/strip-backup/*-temp.hg' (glob)
381 381 (fix the problem, then recover the changesets with "hg unbundle '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)
382 382 abort: pretxnchangegroup.bad hook exited with status 1
383 383 [255]
384 384 $ restore
385 385 $ hg log -G
386 386 o changeset: 4:443431ffac4f
387 387 | tag: tip
388 388 | user: test
389 389 | date: Thu Jan 01 00:00:00 1970 +0000
390 390 | summary: e
391 391 |
392 392 o changeset: 3:65bd5f99a4a3
393 393 | parent: 1:ef3a871183d7
394 394 | user: test
395 395 | date: Thu Jan 01 00:00:00 1970 +0000
396 396 | summary: d
397 397 |
398 398 | o changeset: 2:264128213d29
399 399 |/ user: test
400 400 | date: Thu Jan 01 00:00:00 1970 +0000
401 401 | summary: c
402 402 |
403 403 @ changeset: 1:ef3a871183d7
404 404 | user: test
405 405 | date: Thu Jan 01 00:00:00 1970 +0000
406 406 | summary: b
407 407 |
408 408 o changeset: 0:9ab35a2d17cb
409 409 user: test
410 410 date: Thu Jan 01 00:00:00 1970 +0000
411 411 summary: a
412 412
413 413
414 414 2 different branches: 2 strips
415 415
416 416 $ hg strip 2 4
417 417 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
418 418 $ hg log -G
419 419 o changeset: 2:65bd5f99a4a3
420 420 | tag: tip
421 421 | user: test
422 422 | date: Thu Jan 01 00:00:00 1970 +0000
423 423 | summary: d
424 424 |
425 425 @ changeset: 1:ef3a871183d7
426 426 | user: test
427 427 | date: Thu Jan 01 00:00:00 1970 +0000
428 428 | summary: b
429 429 |
430 430 o changeset: 0:9ab35a2d17cb
431 431 user: test
432 432 date: Thu Jan 01 00:00:00 1970 +0000
433 433 summary: a
434 434
435 435 $ restore
436 436
437 437 2 different branches and a common ancestor: 1 strip
438 438
439 439 $ hg strip 1 "2|4"
440 440 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 441 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
442 442 $ restore
443 443
444 444 verify fncache is kept up-to-date
445 445
446 446 $ touch a
447 447 $ hg ci -qAm a
448 #if repofncache
448 449 $ cat .hg/store/fncache | sort
449 450 data/a.i
450 451 data/bar.i
452 #endif
451 453
452 454 $ hg strip tip
453 455 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
454 456 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
457 #if repofncache
455 458 $ cat .hg/store/fncache
456 459 data/bar.i
460 #endif
457 461
458 462 stripping an empty revset
459 463
460 464 $ hg strip "1 and not 1"
461 465 abort: empty revision set
462 466 [255]
463 467
464 468 remove branchy history for qimport tests
465 469
466 470 $ hg strip 3
467 471 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
468 472
469 473
470 474 strip of applied mq should cleanup status file
471 475
472 476 $ echo "mq=" >> $HGRCPATH
473 477 $ hg up -C 3
474 478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
475 479 $ echo fooagain >> bar
476 480 $ hg ci -mf
477 481 $ hg qimport -r tip:2
478 482
479 483 applied patches before strip
480 484
481 485 $ hg qapplied
482 486 d
483 487 e
484 488 f
485 489
486 490 stripping revision in queue
487 491
488 492 $ hg strip 3
489 493 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
490 494 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
491 495
492 496 applied patches after stripping rev in queue
493 497
494 498 $ hg qapplied
495 499 d
496 500
497 501 stripping ancestor of queue
498 502
499 503 $ hg strip 1
500 504 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 505 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
502 506
503 507 applied patches after stripping ancestor of queue
504 508
505 509 $ hg qapplied
506 510
507 511 Verify strip protects against stripping wc parent when there are uncommitted mods
508 512
509 513 $ echo b > b
510 514 $ echo bb > bar
511 515 $ hg add b
512 516 $ hg ci -m 'b'
513 517 $ hg log --graph
514 518 @ changeset: 1:76dcf9fab855
515 519 | tag: tip
516 520 | user: test
517 521 | date: Thu Jan 01 00:00:00 1970 +0000
518 522 | summary: b
519 523 |
520 524 o changeset: 0:9ab35a2d17cb
521 525 user: test
522 526 date: Thu Jan 01 00:00:00 1970 +0000
523 527 summary: a
524 528
525 529 $ hg up 0
526 530 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
527 531 $ echo c > bar
528 532 $ hg up -t false
529 533 merging bar
530 534 merging bar failed!
531 535 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
532 536 use 'hg resolve' to retry unresolved file merges
533 537 [1]
534 538 $ hg sum
535 539 parent: 1:76dcf9fab855 tip
536 540 b
537 541 branch: default
538 542 commit: 1 modified, 1 unknown, 1 unresolved
539 543 update: (current)
540 544 phases: 2 draft
541 545 mq: 3 unapplied
542 546
543 547 $ echo c > b
544 548 $ hg strip tip
545 549 abort: local changes found
546 550 [255]
547 551 $ hg strip tip --keep
548 552 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
549 553 $ hg log --graph
550 554 @ changeset: 0:9ab35a2d17cb
551 555 tag: tip
552 556 user: test
553 557 date: Thu Jan 01 00:00:00 1970 +0000
554 558 summary: a
555 559
556 560 $ hg status
557 561 M bar
558 562 ? b
559 563 ? bar.orig
560 564
561 565 $ rm bar.orig
562 566 $ hg sum
563 567 parent: 0:9ab35a2d17cb tip
564 568 a
565 569 branch: default
566 570 commit: 1 modified, 1 unknown
567 571 update: (current)
568 572 phases: 1 draft
569 573 mq: 3 unapplied
570 574
571 575 Strip adds, removes, modifies with --keep
572 576
573 577 $ touch b
574 578 $ hg add b
575 579 $ hg commit -mb
576 580 $ touch c
577 581
578 582 ... with a clean working dir
579 583
580 584 $ hg add c
581 585 $ hg rm bar
582 586 $ hg commit -mc
583 587 $ hg status
584 588 $ hg strip --keep tip
585 589 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
586 590 $ hg status
587 591 ! bar
588 592 ? c
589 593
590 594 ... with a dirty working dir
591 595
592 596 $ hg add c
593 597 $ hg rm bar
594 598 $ hg commit -mc
595 599 $ hg status
596 600 $ echo b > b
597 601 $ echo d > d
598 602 $ hg strip --keep tip
599 603 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
600 604 $ hg status
601 605 M b
602 606 ! bar
603 607 ? c
604 608 ? d
605 609
606 610 ... after updating the dirstate
607 611 $ hg add c
608 612 $ hg commit -mc
609 613 $ hg rm c
610 614 $ hg commit -mc
611 615 $ hg strip --keep '.^' -q
612 616 $ cd ..
613 617
614 618 stripping many nodes on a complex graph (issue3299)
615 619
616 620 $ hg init issue3299
617 621 $ cd issue3299
618 622 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
619 623 $ hg strip 'not ancestors(x)'
620 624 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
621 625
622 626 test hg strip -B bookmark
623 627
624 628 $ cd ..
625 629 $ hg init bookmarks
626 630 $ cd bookmarks
627 631 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
628 632 $ hg bookmark -r 'a' 'todelete'
629 633 $ hg bookmark -r 'b' 'B'
630 634 $ hg bookmark -r 'b' 'nostrip'
631 635 $ hg bookmark -r 'c' 'delete'
632 636 $ hg bookmark -r 'd' 'multipledelete1'
633 637 $ hg bookmark -r 'e' 'multipledelete2'
634 638 $ hg bookmark -r 'f' 'singlenode1'
635 639 $ hg bookmark -r 'f' 'singlenode2'
636 640 $ hg up -C todelete
637 641 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
638 642 (activating bookmark todelete)
639 643 $ hg strip -B nostrip
640 644 bookmark 'nostrip' deleted
641 645 abort: empty revision set
642 646 [255]
643 647 $ hg strip -B todelete
644 648 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
645 649 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
646 650 bookmark 'todelete' deleted
647 651 $ hg id -ir dcbb326fdec2
648 652 abort: unknown revision 'dcbb326fdec2'!
649 653 [255]
650 654 $ hg id -ir d62d843c9a01
651 655 d62d843c9a01
652 656 $ hg bookmarks
653 657 B 9:ff43616e5d0f
654 658 delete 6:2702dd0c91e7
655 659 multipledelete1 11:e46a4836065c
656 660 multipledelete2 12:b4594d867745
657 661 singlenode1 13:43227190fef8
658 662 singlenode2 13:43227190fef8
659 663 $ hg strip -B multipledelete1 -B multipledelete2
660 664 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg
661 665 bookmark 'multipledelete1' deleted
662 666 bookmark 'multipledelete2' deleted
663 667 $ hg id -ir e46a4836065c
664 668 abort: unknown revision 'e46a4836065c'!
665 669 [255]
666 670 $ hg id -ir b4594d867745
667 671 abort: unknown revision 'b4594d867745'!
668 672 [255]
669 673 $ hg strip -B singlenode1 -B singlenode2
670 674 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg
671 675 bookmark 'singlenode1' deleted
672 676 bookmark 'singlenode2' deleted
673 677 $ hg id -ir 43227190fef8
674 678 abort: unknown revision '43227190fef8'!
675 679 [255]
676 680 $ hg strip -B unknownbookmark
677 681 abort: bookmark 'unknownbookmark' not found
678 682 [255]
679 683 $ hg strip -B unknownbookmark1 -B unknownbookmark2
680 684 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
681 685 [255]
682 686 $ hg strip -B delete -B unknownbookmark
683 687 abort: bookmark 'unknownbookmark' not found
684 688 [255]
685 689 $ hg strip -B delete
686 690 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
687 691 bookmark 'delete' deleted
688 692 $ hg id -ir 6:2702dd0c91e7
689 693 abort: unknown revision '2702dd0c91e7'!
690 694 [255]
691 695 $ hg update B
692 696 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
693 697 (activating bookmark B)
694 698 $ echo a > a
695 699 $ hg add a
696 700 $ hg strip -B B
697 701 abort: local changes found
698 702 [255]
699 703 $ hg bookmarks
700 704 * B 6:ff43616e5d0f
701 705
702 706 Make sure no one adds back a -b option:
703 707
704 708 $ hg strip -b tip
705 709 hg strip: option -b not recognized
706 710 hg strip [-k] [-f] [-B bookmark] [-r] REV...
707 711
708 712 strip changesets and all their descendants from the repository
709 713
710 714 (use 'hg help -e strip' to show help for the strip extension)
711 715
712 716 options ([+] can be repeated):
713 717
714 718 -r --rev REV [+] strip specified revision (optional, can specify
715 719 revisions without this option)
716 720 -f --force force removal of changesets, discard uncommitted
717 721 changes (no backup)
718 722 --no-backup no backups
719 723 -k --keep do not modify working directory during strip
720 724 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
721 725 --mq operate on patch repository
722 726
723 727 (use 'hg strip -h' to show more help)
724 728 [255]
725 729
726 730 $ cd ..
727 731
728 732 Verify bundles don't get overwritten:
729 733
730 734 $ hg init doublebundle
731 735 $ cd doublebundle
732 736 $ touch a
733 737 $ hg commit -Aqm a
734 738 $ touch b
735 739 $ hg commit -Aqm b
736 740 $ hg strip -r 0
737 741 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
738 742 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg
739 743 $ ls .hg/strip-backup
740 744 3903775176ed-e68910bd-backup.hg
741 745 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
742 746 $ hg strip -r 0
743 747 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg
744 748 $ ls .hg/strip-backup
745 749 3903775176ed-54390173-backup.hg
746 750 3903775176ed-e68910bd-backup.hg
747 751 $ cd ..
748 752
749 753 Test that we only bundle the stripped changesets (issue4736)
750 754 ------------------------------------------------------------
751 755
752 756 initialization (previous repo is empty anyway)
753 757
754 758 $ hg init issue4736
755 759 $ cd issue4736
756 760 $ echo a > a
757 761 $ hg add a
758 762 $ hg commit -m commitA
759 763 $ echo b > b
760 764 $ hg add b
761 765 $ hg commit -m commitB
762 766 $ echo c > c
763 767 $ hg add c
764 768 $ hg commit -m commitC
765 769 $ hg up 'desc(commitB)'
766 770 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
767 771 $ echo d > d
768 772 $ hg add d
769 773 $ hg commit -m commitD
770 774 created new head
771 775 $ hg up 'desc(commitC)'
772 776 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
773 777 $ hg merge 'desc(commitD)'
774 778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
775 779 (branch merge, don't forget to commit)
776 780 $ hg ci -m 'mergeCD'
777 781 $ hg log -G
778 782 @ changeset: 4:d8db9d137221
779 783 |\ tag: tip
780 784 | | parent: 2:5c51d8d6557d
781 785 | | parent: 3:6625a5168474
782 786 | | user: test
783 787 | | date: Thu Jan 01 00:00:00 1970 +0000
784 788 | | summary: mergeCD
785 789 | |
786 790 | o changeset: 3:6625a5168474
787 791 | | parent: 1:eca11cf91c71
788 792 | | user: test
789 793 | | date: Thu Jan 01 00:00:00 1970 +0000
790 794 | | summary: commitD
791 795 | |
792 796 o | changeset: 2:5c51d8d6557d
793 797 |/ user: test
794 798 | date: Thu Jan 01 00:00:00 1970 +0000
795 799 | summary: commitC
796 800 |
797 801 o changeset: 1:eca11cf91c71
798 802 | user: test
799 803 | date: Thu Jan 01 00:00:00 1970 +0000
800 804 | summary: commitB
801 805 |
802 806 o changeset: 0:105141ef12d0
803 807 user: test
804 808 date: Thu Jan 01 00:00:00 1970 +0000
805 809 summary: commitA
806 810
807 811
808 812 Check bundle behavior:
809 813
810 814 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
811 815 2 changesets found
812 816 $ hg log -r 'bundle()' -R ../issue4736.hg
813 817 changeset: 3:6625a5168474
814 818 parent: 1:eca11cf91c71
815 819 user: test
816 820 date: Thu Jan 01 00:00:00 1970 +0000
817 821 summary: commitD
818 822
819 823 changeset: 4:d8db9d137221
820 824 tag: tip
821 825 parent: 2:5c51d8d6557d
822 826 parent: 3:6625a5168474
823 827 user: test
824 828 date: Thu Jan 01 00:00:00 1970 +0000
825 829 summary: mergeCD
826 830
827 831
828 832 check strip behavior
829 833
830 834 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
831 835 resolving manifests
832 836 branchmerge: False, force: True, partial: False
833 837 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
834 838 c: other deleted -> r
835 839 removing c
836 840 d: other deleted -> r
837 841 removing d
838 842 starting 4 threads for background file closing (?)
839 843 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
840 844 2 changesets found
841 845 list of changesets:
842 846 6625a516847449b6f0fa3737b9ba56e9f0f3032c
843 847 d8db9d1372214336d2b5570f20ee468d2c72fa8b
844 848 bundle2-output-bundle: "HG20", (1 params) 3 parts total
845 849 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
846 850 bundle2-output-part: "cache:rev-branch-cache" streamed payload
847 851 bundle2-output-part: "phase-heads" 24 bytes payload
848 852 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg
849 853 updating the branch cache
850 854 invalid branchheads cache (served): tip differs
851 855 $ hg log -G
852 856 o changeset: 2:5c51d8d6557d
853 857 | tag: tip
854 858 | user: test
855 859 | date: Thu Jan 01 00:00:00 1970 +0000
856 860 | summary: commitC
857 861 |
858 862 @ changeset: 1:eca11cf91c71
859 863 | user: test
860 864 | date: Thu Jan 01 00:00:00 1970 +0000
861 865 | summary: commitB
862 866 |
863 867 o changeset: 0:105141ef12d0
864 868 user: test
865 869 date: Thu Jan 01 00:00:00 1970 +0000
866 870 summary: commitA
867 871
868 872
869 873 strip backup content
870 874
871 875 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
872 876 changeset: 3:6625a5168474
873 877 parent: 1:eca11cf91c71
874 878 user: test
875 879 date: Thu Jan 01 00:00:00 1970 +0000
876 880 summary: commitD
877 881
878 882 changeset: 4:d8db9d137221
879 883 tag: tip
880 884 parent: 2:5c51d8d6557d
881 885 parent: 3:6625a5168474
882 886 user: test
883 887 date: Thu Jan 01 00:00:00 1970 +0000
884 888 summary: mergeCD
885 889
886 890 Check that the phase cache is properly invalidated after a strip with bookmark.
887 891
888 892 $ cat > ../stripstalephasecache.py << EOF
889 893 > from mercurial import extensions, localrepo
890 894 > def transactioncallback(orig, repo, desc, *args, **kwargs):
891 895 > def test(transaction):
892 896 > # observe cache inconsistency
893 897 > try:
894 898 > [repo.changelog.node(r) for r in repo.revs(b"not public()")]
895 899 > except IndexError:
896 900 > repo.ui.status(b"Index error!\n")
897 901 > transaction = orig(repo, desc, *args, **kwargs)
898 902 > # warm up the phase cache
899 903 > list(repo.revs(b"not public()"))
900 904 > if desc != b'strip':
901 905 > transaction.addpostclose(b"phase invalidation test", test)
902 906 > return transaction
903 907 > def extsetup(ui):
904 908 > extensions.wrapfunction(localrepo.localrepository, b"transaction",
905 909 > transactioncallback)
906 910 > EOF
907 911 $ hg up -C 2
908 912 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
909 913 $ echo k > k
910 914 $ hg add k
911 915 $ hg commit -m commitK
912 916 $ echo l > l
913 917 $ hg add l
914 918 $ hg commit -m commitL
915 919 $ hg book -r tip blah
916 920 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
917 921 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
918 922 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg
919 923 $ hg up -C 1
920 924 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
921 925
922 926 Error during post-close callback of the strip transaction
923 927 (They should be gracefully handled and reported)
924 928
925 929 $ cat > ../crashstrip.py << EOF
926 930 > from mercurial import error
927 931 > def reposetup(ui, repo):
928 932 > class crashstriprepo(repo.__class__):
929 933 > def transaction(self, desc, *args, **kwargs):
930 934 > tr = super(crashstriprepo, self).transaction(desc, *args, **kwargs)
931 935 > if desc == b'strip':
932 936 > def crash(tra): raise error.Abort(b'boom')
933 937 > tr.addpostclose(b'crash', crash)
934 938 > return tr
935 939 > repo.__class__ = crashstriprepo
936 940 > EOF
937 941 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
938 942 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg
939 943 strip failed, backup bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg'
940 944 abort: boom
941 945 [255]
942 946
943 947 test stripping a working directory parent doesn't switch named branches
944 948
945 949 $ hg log -G
946 950 @ changeset: 1:eca11cf91c71
947 951 | tag: tip
948 952 | user: test
949 953 | date: Thu Jan 01 00:00:00 1970 +0000
950 954 | summary: commitB
951 955 |
952 956 o changeset: 0:105141ef12d0
953 957 user: test
954 958 date: Thu Jan 01 00:00:00 1970 +0000
955 959 summary: commitA
956 960
957 961
958 962 $ hg branch new-branch
959 963 marked working directory as branch new-branch
960 964 (branches are permanent and global, did you want a bookmark?)
961 965 $ hg ci -m "start new branch"
962 966 $ echo 'foo' > foo.txt
963 967 $ hg ci -Aqm foo
964 968 $ hg up default
965 969 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
966 970 $ echo 'bar' > bar.txt
967 971 $ hg ci -Aqm bar
968 972 $ hg up new-branch
969 973 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
970 974 $ hg merge default
971 975 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
972 976 (branch merge, don't forget to commit)
973 977 $ hg log -G
974 978 @ changeset: 4:35358f982181
975 979 | tag: tip
976 980 | parent: 1:eca11cf91c71
977 981 | user: test
978 982 | date: Thu Jan 01 00:00:00 1970 +0000
979 983 | summary: bar
980 984 |
981 985 | @ changeset: 3:f62c6c09b707
982 986 | | branch: new-branch
983 987 | | user: test
984 988 | | date: Thu Jan 01 00:00:00 1970 +0000
985 989 | | summary: foo
986 990 | |
987 991 | o changeset: 2:b1d33a8cadd9
988 992 |/ branch: new-branch
989 993 | user: test
990 994 | date: Thu Jan 01 00:00:00 1970 +0000
991 995 | summary: start new branch
992 996 |
993 997 o changeset: 1:eca11cf91c71
994 998 | user: test
995 999 | date: Thu Jan 01 00:00:00 1970 +0000
996 1000 | summary: commitB
997 1001 |
998 1002 o changeset: 0:105141ef12d0
999 1003 user: test
1000 1004 date: Thu Jan 01 00:00:00 1970 +0000
1001 1005 summary: commitA
1002 1006
1003 1007
1004 1008 $ hg strip --force -r 35358f982181
1005 1009 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1006 1010 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-50d992d4-backup.hg
1007 1011 $ hg log -G
1008 1012 @ changeset: 3:f62c6c09b707
1009 1013 | branch: new-branch
1010 1014 | tag: tip
1011 1015 | user: test
1012 1016 | date: Thu Jan 01 00:00:00 1970 +0000
1013 1017 | summary: foo
1014 1018 |
1015 1019 o changeset: 2:b1d33a8cadd9
1016 1020 | branch: new-branch
1017 1021 | user: test
1018 1022 | date: Thu Jan 01 00:00:00 1970 +0000
1019 1023 | summary: start new branch
1020 1024 |
1021 1025 o changeset: 1:eca11cf91c71
1022 1026 | user: test
1023 1027 | date: Thu Jan 01 00:00:00 1970 +0000
1024 1028 | summary: commitB
1025 1029 |
1026 1030 o changeset: 0:105141ef12d0
1027 1031 user: test
1028 1032 date: Thu Jan 01 00:00:00 1970 +0000
1029 1033 summary: commitA
1030 1034
1031 1035
1032 1036 $ hg up default
1033 1037 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1034 1038 $ echo 'bar' > bar.txt
1035 1039 $ hg ci -Aqm bar
1036 1040 $ hg up new-branch
1037 1041 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1038 1042 $ hg merge default
1039 1043 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1040 1044 (branch merge, don't forget to commit)
1041 1045 $ hg ci -m merge
1042 1046 $ hg log -G
1043 1047 @ changeset: 5:4cf5e92caec2
1044 1048 |\ branch: new-branch
1045 1049 | | tag: tip
1046 1050 | | parent: 3:f62c6c09b707
1047 1051 | | parent: 4:35358f982181
1048 1052 | | user: test
1049 1053 | | date: Thu Jan 01 00:00:00 1970 +0000
1050 1054 | | summary: merge
1051 1055 | |
1052 1056 | o changeset: 4:35358f982181
1053 1057 | | parent: 1:eca11cf91c71
1054 1058 | | user: test
1055 1059 | | date: Thu Jan 01 00:00:00 1970 +0000
1056 1060 | | summary: bar
1057 1061 | |
1058 1062 o | changeset: 3:f62c6c09b707
1059 1063 | | branch: new-branch
1060 1064 | | user: test
1061 1065 | | date: Thu Jan 01 00:00:00 1970 +0000
1062 1066 | | summary: foo
1063 1067 | |
1064 1068 o | changeset: 2:b1d33a8cadd9
1065 1069 |/ branch: new-branch
1066 1070 | user: test
1067 1071 | date: Thu Jan 01 00:00:00 1970 +0000
1068 1072 | summary: start new branch
1069 1073 |
1070 1074 o changeset: 1:eca11cf91c71
1071 1075 | user: test
1072 1076 | date: Thu Jan 01 00:00:00 1970 +0000
1073 1077 | summary: commitB
1074 1078 |
1075 1079 o changeset: 0:105141ef12d0
1076 1080 user: test
1077 1081 date: Thu Jan 01 00:00:00 1970 +0000
1078 1082 summary: commitA
1079 1083
1080 1084
1081 1085 $ hg strip -r 35358f982181
1082 1086 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1083 1087 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1084 1088 $ hg log -G
1085 1089 @ changeset: 3:f62c6c09b707
1086 1090 | branch: new-branch
1087 1091 | tag: tip
1088 1092 | user: test
1089 1093 | date: Thu Jan 01 00:00:00 1970 +0000
1090 1094 | summary: foo
1091 1095 |
1092 1096 o changeset: 2:b1d33a8cadd9
1093 1097 | branch: new-branch
1094 1098 | user: test
1095 1099 | date: Thu Jan 01 00:00:00 1970 +0000
1096 1100 | summary: start new branch
1097 1101 |
1098 1102 o changeset: 1:eca11cf91c71
1099 1103 | user: test
1100 1104 | date: Thu Jan 01 00:00:00 1970 +0000
1101 1105 | summary: commitB
1102 1106 |
1103 1107 o changeset: 0:105141ef12d0
1104 1108 user: test
1105 1109 date: Thu Jan 01 00:00:00 1970 +0000
1106 1110 summary: commitA
1107 1111
1108 1112
1109 1113 $ hg unbundle -u $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1110 1114 adding changesets
1111 1115 adding manifests
1112 1116 adding file changes
1113 1117 added 2 changesets with 1 changes to 1 files
1114 1118 new changesets 35358f982181:4cf5e92caec2
1115 1119 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1116 1120
1117 1121 $ hg strip -k -r 35358f982181
1118 1122 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1119 1123 $ hg log -G
1120 1124 @ changeset: 3:f62c6c09b707
1121 1125 | branch: new-branch
1122 1126 | tag: tip
1123 1127 | user: test
1124 1128 | date: Thu Jan 01 00:00:00 1970 +0000
1125 1129 | summary: foo
1126 1130 |
1127 1131 o changeset: 2:b1d33a8cadd9
1128 1132 | branch: new-branch
1129 1133 | user: test
1130 1134 | date: Thu Jan 01 00:00:00 1970 +0000
1131 1135 | summary: start new branch
1132 1136 |
1133 1137 o changeset: 1:eca11cf91c71
1134 1138 | user: test
1135 1139 | date: Thu Jan 01 00:00:00 1970 +0000
1136 1140 | summary: commitB
1137 1141 |
1138 1142 o changeset: 0:105141ef12d0
1139 1143 user: test
1140 1144 date: Thu Jan 01 00:00:00 1970 +0000
1141 1145 summary: commitA
1142 1146
1143 1147 $ hg diff
1144 1148 diff -r f62c6c09b707 bar.txt
1145 1149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1146 1150 +++ b/bar.txt Thu Jan 01 00:00:00 1970 +0000
1147 1151 @@ -0,0 +1,1 @@
1148 1152 +bar
1149 1153
1150 1154 Use delayedstrip to strip inside a transaction
1151 1155
1152 1156 $ cd $TESTTMP
1153 1157 $ hg init delayedstrip
1154 1158 $ cd delayedstrip
1155 1159 $ hg debugdrawdag <<'EOS'
1156 1160 > D
1157 1161 > |
1158 1162 > C F H # Commit on top of "I",
1159 1163 > | |/| # Strip B+D+I+E+G+H+Z
1160 1164 > I B E G
1161 1165 > \|/
1162 1166 > A Z
1163 1167 > EOS
1164 1168 $ cp -R . ../scmutilcleanup
1165 1169
1166 1170 $ hg up -C I
1167 1171 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1168 1172 $ echo 3 >> I
1169 1173 $ cat > $TESTTMP/delayedstrip.py <<EOF
1170 1174 > from __future__ import absolute_import
1171 1175 > from mercurial import commands, registrar, repair
1172 1176 > cmdtable = {}
1173 1177 > command = registrar.command(cmdtable)
1174 1178 > @command(b'testdelayedstrip')
1175 1179 > def testdelayedstrip(ui, repo):
1176 1180 > def getnodes(expr):
1177 1181 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1178 1182 > with repo.wlock():
1179 1183 > with repo.lock():
1180 1184 > with repo.transaction(b'delayedstrip'):
1181 1185 > repair.delayedstrip(ui, repo, getnodes(b'B+I+Z+D+E'), b'J')
1182 1186 > repair.delayedstrip(ui, repo, getnodes(b'G+H+Z'), b'I')
1183 1187 > commands.commit(ui, repo, message=b'J', date=b'0 0')
1184 1188 > EOF
1185 1189 $ hg testdelayedstrip --config extensions.t=$TESTTMP/delayedstrip.py
1186 1190 warning: orphaned descendants detected, not stripping 08ebfeb61bac, 112478962961, 7fb047a69f22
1187 1191 saved backup bundle to $TESTTMP/delayedstrip/.hg/strip-backup/f585351a92f8-17475721-I.hg
1188 1192
1189 1193 $ hg log -G -T '{rev}:{node|short} {desc}' -r 'sort(all(), topo)'
1190 1194 @ 6:2f2d51af6205 J
1191 1195 |
1192 1196 o 3:08ebfeb61bac I
1193 1197 |
1194 1198 | o 5:64a8289d2492 F
1195 1199 | |
1196 1200 | o 2:7fb047a69f22 E
1197 1201 |/
1198 1202 | o 4:26805aba1e60 C
1199 1203 | |
1200 1204 | o 1:112478962961 B
1201 1205 |/
1202 1206 o 0:426bada5c675 A
1203 1207
1204 1208 Test high-level scmutil.cleanupnodes API
1205 1209
1206 1210 $ cd $TESTTMP/scmutilcleanup
1207 1211 $ hg debugdrawdag <<'EOS'
1208 1212 > D2 F2 G2 # D2, F2, G2 are replacements for D, F, G
1209 1213 > | | |
1210 1214 > C H G
1211 1215 > EOS
1212 1216 $ for i in B C D F G I Z; do
1213 1217 > hg bookmark -i -r $i b-$i
1214 1218 > done
1215 1219 $ hg bookmark -i -r E 'b-F@divergent1'
1216 1220 $ hg bookmark -i -r H 'b-F@divergent2'
1217 1221 $ hg bookmark -i -r G 'b-F@divergent3'
1218 1222 $ cp -R . ../scmutilcleanup.obsstore
1219 1223
1220 1224 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
1221 1225 > from mercurial import registrar, scmutil
1222 1226 > cmdtable = {}
1223 1227 > command = registrar.command(cmdtable)
1224 1228 > @command(b'testnodescleanup')
1225 1229 > def testnodescleanup(ui, repo):
1226 1230 > def nodes(expr):
1227 1231 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1228 1232 > def node(expr):
1229 1233 > return nodes(expr)[0]
1230 1234 > with repo.wlock():
1231 1235 > with repo.lock():
1232 1236 > with repo.transaction(b'delayedstrip'):
1233 1237 > mapping = {node(b'F'): [node(b'F2')],
1234 1238 > node(b'D'): [node(b'D2')],
1235 1239 > node(b'G'): [node(b'G2')]}
1236 1240 > scmutil.cleanupnodes(repo, mapping, b'replace')
1237 1241 > scmutil.cleanupnodes(repo, nodes(b'((B::)+I+Z)-D2'),
1238 1242 > b'replace')
1239 1243 > EOF
1240 1244 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1241 1245 warning: orphaned descendants detected, not stripping 112478962961, 1fc8102cda62, 26805aba1e60
1242 1246 saved backup bundle to $TESTTMP/scmutilcleanup/.hg/strip-backup/f585351a92f8-73fb7c03-replace.hg
1243 1247
1244 1248 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1245 1249 o 8:1473d4b996d1 G2 b-F@divergent3 b-G
1246 1250 |
1247 1251 | o 7:d11b3456a873 F2 b-F
1248 1252 | |
1249 1253 | o 5:5cb05ba470a7 H
1250 1254 |/|
1251 1255 | o 3:7fb047a69f22 E b-F@divergent1
1252 1256 | |
1253 1257 | | o 6:7c78f703e465 D2 b-D
1254 1258 | | |
1255 1259 | | o 4:26805aba1e60 C
1256 1260 | | |
1257 1261 | | o 2:112478962961 B
1258 1262 | |/
1259 1263 o | 1:1fc8102cda62 G
1260 1264 /
1261 1265 o 0:426bada5c675 A b-B b-C b-I
1262 1266
1263 1267 $ hg bookmark
1264 1268 b-B 0:426bada5c675
1265 1269 b-C 0:426bada5c675
1266 1270 b-D 6:7c78f703e465
1267 1271 b-F 7:d11b3456a873
1268 1272 b-F@divergent1 3:7fb047a69f22
1269 1273 b-F@divergent3 8:1473d4b996d1
1270 1274 b-G 8:1473d4b996d1
1271 1275 b-I 0:426bada5c675
1272 1276 b-Z -1:000000000000
1273 1277
1274 1278 Test the above using obsstore "by the way". Not directly related to strip, but
1275 1279 we have reusable code here
1276 1280
1277 1281 $ cd $TESTTMP/scmutilcleanup.obsstore
1278 1282 $ cat >> .hg/hgrc <<EOF
1279 1283 > [experimental]
1280 1284 > evolution=true
1281 1285 > evolution.track-operation=1
1282 1286 > EOF
1283 1287
1284 1288 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1285 1289 4 new orphan changesets
1286 1290
1287 1291 $ rm .hg/localtags
1288 1292 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1289 1293 * 12:1473d4b996d1 G2 b-F@divergent3 b-G
1290 1294 |
1291 1295 | * 11:d11b3456a873 F2 b-F
1292 1296 | |
1293 1297 | * 8:5cb05ba470a7 H
1294 1298 |/|
1295 1299 | o 4:7fb047a69f22 E b-F@divergent1
1296 1300 | |
1297 1301 | | * 10:7c78f703e465 D2 b-D
1298 1302 | | |
1299 1303 | | x 6:26805aba1e60 C
1300 1304 | | |
1301 1305 | | x 3:112478962961 B
1302 1306 | |/
1303 1307 x | 1:1fc8102cda62 G
1304 1308 /
1305 1309 o 0:426bada5c675 A b-B b-C b-I
1306 1310
1307 1311 $ hg debugobsolete
1308 1312 1fc8102cda6204549f031015641606ccf5513ec3 1473d4b996d1d1b121de6b39fab6a04fbf9d873e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1309 1313 64a8289d249234b9886244d379f15e6b650b28e3 d11b3456a873daec7c7bc53e5622e8df6d741bd2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1310 1314 f585351a92f85104bff7c284233c338b10eb1df7 7c78f703e465d73102cc8780667ce269c5208a40 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'replace', 'user': 'test'}
1311 1315 48b9aae0607f43ff110d84e6883c151942add5ab 0 {0000000000000000000000000000000000000000} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1312 1316 112478962961147124edd43549aedd1a335e44bf 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1313 1317 08ebfeb61bac6e3f12079de774d285a0d6689eba 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1314 1318 26805aba1e600a82e93661149f2313866a221a7b 0 {112478962961147124edd43549aedd1a335e44bf} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1315 1319 $ cd ..
1316 1320
1317 1321 Test that obsmarkers are restored even when not using generaldelta
1318 1322
1319 1323 $ hg --config format.usegeneraldelta=no init issue5678
1320 1324 $ cd issue5678
1321 1325 $ cat >> .hg/hgrc <<EOF
1322 1326 > [experimental]
1323 1327 > evolution=true
1324 1328 > EOF
1325 1329 $ echo a > a
1326 1330 $ hg ci -Aqm a
1327 1331 $ hg ci --amend -m a2
1328 1332 $ hg debugobsolete
1329 1333 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1330 1334 $ hg strip .
1331 1335 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1332 1336 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/489bac576828-bef27e14-backup.hg
1333 1337 $ hg unbundle -q .hg/strip-backup/*
1334 1338 $ hg debugobsolete
1335 1339 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1336 1340 $ cd ..
@@ -1,1211 +1,1205 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extdiff]
3 3 > # for portability:
4 4 > pdiff = sh "$RUNTESTDIR/pdiff"
5 5 > [progress]
6 6 > disable=False
7 7 > assume-tty = 1
8 8 > delay = 0
9 9 > # set changedelay really large so we don't see nested topics
10 10 > changedelay = 30000
11 11 > format = topic bar number
12 12 > refresh = 0
13 13 > width = 60
14 14 > EOF
15 15
16 16 Preparing the subrepository 'sub2'
17 17
18 18 $ hg init sub2
19 19 $ echo sub2 > sub2/sub2
20 20 $ hg add -R sub2
21 21 adding sub2/sub2
22 22 $ hg commit -R sub2 -m "sub2 import"
23 23
24 24 Preparing the 'sub1' repo which depends on the subrepo 'sub2'
25 25
26 26 $ hg init sub1
27 27 $ echo sub1 > sub1/sub1
28 28 $ echo "sub2 = ../sub2" > sub1/.hgsub
29 29 $ hg clone sub2 sub1/sub2
30 30 \r (no-eol) (esc)
31 31 linking [ <=> ] 1\r (no-eol) (esc)
32 32 linking [ <=> ] 2\r (no-eol) (esc)
33 33 linking [ <=> ] 3\r (no-eol) (esc)
34 34 linking [ <=> ] 4\r (no-eol) (esc)
35 35 linking [ <=> ] 5\r (no-eol) (esc)
36 36 linking [ <=> ] 6\r (no-eol) (esc)
37 linking [ <=> ] 7\r (no-eol) (esc) (reposimplestore !)
38 37 \r (no-eol) (esc)
39 38 \r (no-eol) (esc)
40 39 updating [===========================================>] 1/1\r (no-eol) (esc)
41 40 \r (no-eol) (esc)
42 41 updating to branch default
43 42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 43 $ hg add -R sub1
45 44 adding sub1/.hgsub
46 45 adding sub1/sub1
47 46 $ hg commit -R sub1 -m "sub1 import"
48 47
49 48 Preparing the 'main' repo which depends on the subrepo 'sub1'
50 49
51 50 $ hg init main
52 51 $ echo main > main/main
53 52 $ echo "sub1 = ../sub1" > main/.hgsub
54 53 $ hg clone sub1 main/sub1
55 54 \r (no-eol) (esc)
56 55 linking [ <=> ] 1\r (no-eol) (esc)
57 56 linking [ <=> ] 2\r (no-eol) (esc)
58 57 linking [ <=> ] 3\r (no-eol) (esc)
59 58 linking [ <=> ] 4\r (no-eol) (esc)
60 59 linking [ <=> ] 5\r (no-eol) (esc)
61 60 linking [ <=> ] 6\r (no-eol) (esc)
62 61 linking [ <=> ] 7\r (no-eol) (esc)
63 62 linking [ <=> ] 8\r (no-eol) (esc)
64 63 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
65 64 linking [ <=> ] 10\r (no-eol) (esc) (reposimplestore !)
66 linking [ <=> ] 11\r (no-eol) (esc) (reposimplestore !)
67 65 \r (no-eol) (esc)
68 66 \r (no-eol) (esc)
69 67 updating [===========================================>] 3/3\r (no-eol) (esc)
70 68 \r (no-eol) (esc)
71 69 \r (no-eol) (esc)
72 70 linking [ <=> ] 1\r (no-eol) (esc)
73 71 linking [ <=> ] 2\r (no-eol) (esc)
74 72 linking [ <=> ] 3\r (no-eol) (esc)
75 73 linking [ <=> ] 4\r (no-eol) (esc)
76 74 linking [ <=> ] 5\r (no-eol) (esc)
77 75 linking [ <=> ] 6\r (no-eol) (esc)
78 linking [ <=> ] 7\r (no-eol) (esc) (reposimplestore !)
79 76 updating [===========================================>] 1/1\r (no-eol) (esc)
80 77 \r (no-eol) (esc)
81 78 updating to branch default
82 79 cloning subrepo sub2 from $TESTTMP/sub2
83 80 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 81 $ hg add -R main
85 82 adding main/.hgsub
86 83 adding main/main
87 84 $ hg commit -R main -m "main import"
88 85
89 86 #if serve
90 87
91 88 Unfortunately, subrepos not at their nominal location cannot be cloned. But
92 89 they are still served from their location within the local repository. The only
93 90 reason why 'main' can be cloned via the filesystem is because 'sub1' and 'sub2'
94 91 are also available as siblings of 'main'.
95 92
96 93 $ hg serve -R main --debug -S -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
97 94 adding = $TESTTMP/main
98 95 adding sub1 = $TESTTMP/main/sub1
99 96 adding sub1/sub2 = $TESTTMP/main/sub1/sub2
100 97 listening at http://*:$HGPORT/ (bound to *:$HGPORT) (glob) (?)
101 98 adding = $TESTTMP/main (?)
102 99 adding sub1 = $TESTTMP/main/sub1 (?)
103 100 adding sub1/sub2 = $TESTTMP/main/sub1/sub2 (?)
104 101 $ cat hg1.pid >> $DAEMON_PIDS
105 102
106 103 $ hg clone http://localhost:$HGPORT httpclone --config progress.disable=True
107 104 requesting all changes
108 105 adding changesets
109 106 adding manifests
110 107 adding file changes
111 108 added 1 changesets with 3 changes to 3 files
112 109 new changesets 7f491f53a367
113 110 updating to branch default
114 111 abort: HTTP Error 404: Not Found
115 112 [255]
116 113
117 114 $ cat access.log
118 115 * "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
119 116 * "GET /?cmd=batch HTTP/1.1" 200 - * (glob)
120 117 * "GET /?cmd=getbundle HTTP/1.1" 200 - * (glob)
121 118 * "GET /../sub1?cmd=capabilities HTTP/1.1" 404 - (glob)
122 119 $ cat error.log
123 120
124 121 $ killdaemons.py
125 122 $ rm hg1.pid error.log access.log
126 123 #endif
127 124
128 125 Cleaning both repositories, just as a clone -U
129 126
130 127 $ hg up -C -R sub2 null
131 128 \r (no-eol) (esc)
132 129 updating [===========================================>] 1/1\r (no-eol) (esc)
133 130 \r (no-eol) (esc)
134 131 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
135 132 $ hg up -C -R sub1 null
136 133 \r (no-eol) (esc)
137 134 updating [===========================================>] 1/1\r (no-eol) (esc)
138 135 \r (no-eol) (esc)
139 136 \r (no-eol) (esc)
140 137 updating [===========================================>] 3/3\r (no-eol) (esc)
141 138 \r (no-eol) (esc)
142 139 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
143 140 $ hg up -C -R main null
144 141 \r (no-eol) (esc)
145 142 updating [===========================================>] 1/1\r (no-eol) (esc)
146 143 \r (no-eol) (esc)
147 144 \r (no-eol) (esc)
148 145 updating [===========================================>] 3/3\r (no-eol) (esc)
149 146 \r (no-eol) (esc)
150 147 \r (no-eol) (esc)
151 148 updating [===========================================>] 3/3\r (no-eol) (esc)
152 149 \r (no-eol) (esc)
153 150 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
154 151 $ rm -rf main/sub1
155 152 $ rm -rf sub1/sub2
156 153
157 154 Clone main
158 155
159 156 $ hg --config extensions.largefiles= clone main cloned
160 157 \r (no-eol) (esc)
161 158 linking [ <=> ] 1\r (no-eol) (esc)
162 159 linking [ <=> ] 2\r (no-eol) (esc)
163 160 linking [ <=> ] 3\r (no-eol) (esc)
164 161 linking [ <=> ] 4\r (no-eol) (esc)
165 162 linking [ <=> ] 5\r (no-eol) (esc)
166 163 linking [ <=> ] 6\r (no-eol) (esc)
167 164 linking [ <=> ] 7\r (no-eol) (esc)
168 165 linking [ <=> ] 8\r (no-eol) (esc)
169 166 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
170 167 linking [ <=> ] 10\r (no-eol) (esc) (reposimplestore !)
171 linking [ <=> ] 11\r (no-eol) (esc) (reposimplestore !)
172 168 \r (no-eol) (esc)
173 169 \r (no-eol) (esc)
174 170 updating [===========================================>] 3/3\r (no-eol) (esc)
175 171 \r (no-eol) (esc)
176 172 \r (no-eol) (esc)
177 173 linking [ <=> ] 1\r (no-eol) (esc)
178 174 linking [ <=> ] 2\r (no-eol) (esc)
179 175 linking [ <=> ] 3\r (no-eol) (esc)
180 176 linking [ <=> ] 4\r (no-eol) (esc)
181 177 linking [ <=> ] 5\r (no-eol) (esc)
182 178 linking [ <=> ] 6\r (no-eol) (esc)
183 179 linking [ <=> ] 7\r (no-eol) (esc)
184 180 linking [ <=> ] 8\r (no-eol) (esc)
185 181 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
186 182 linking [ <=> ] 10\r (no-eol) (esc) (reposimplestore !)
187 linking [ <=> ] 11\r (no-eol) (esc) (reposimplestore !)
188 183 updating [===========================================>] 3/3\r (no-eol) (esc)
189 184 \r (no-eol) (esc)
190 185 \r (no-eol) (esc)
191 186 linking [ <=> ] 1\r (no-eol) (esc) (no-reposimplestore !)
192 187 linking [ <=> ] 2\r (no-eol) (esc) (no-reposimplestore !)
193 188 linking [ <=> ] 3\r (no-eol) (esc) (no-reposimplestore !)
194 189 linking [ <=> ] 4\r (no-eol) (esc) (no-reposimplestore !)
195 190 linking [ <=> ] 5\r (no-eol) (esc) (no-reposimplestore !)
196 191 linking [ <=> ] 6\r (no-eol) (esc) (no-reposimplestore !)
197 192 linking [ <=> ] 1\r (no-eol) (esc) (reposimplestore !)
198 193 linking [ <=> ] 2\r (no-eol) (esc) (reposimplestore !)
199 194 linking [ <=> ] 3\r (no-eol) (esc) (reposimplestore !)
200 195 linking [ <=> ] 4\r (no-eol) (esc) (reposimplestore !)
201 196 linking [ <=> ] 5\r (no-eol) (esc) (reposimplestore !)
202 197 linking [ <=> ] 6\r (no-eol) (esc) (reposimplestore !)
203 linking [ <=> ] 7\r (no-eol) (esc) (reposimplestore !)
204 198 updating [===========================================>] 1/1\r (no-eol) (esc)
205 199 \r (no-eol) (esc)
206 200 updating to branch default
207 201 cloning subrepo sub1 from $TESTTMP/sub1
208 202 cloning subrepo sub1/sub2 from $TESTTMP/sub2
209 203 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 204
211 205 Largefiles is NOT enabled in the clone if the source repo doesn't require it
212 206 $ cat cloned/.hg/hgrc
213 207 # example repository config (see 'hg help config' for more info)
214 208 [paths]
215 209 default = $TESTTMP/main
216 210
217 211 # path aliases to other clones of this repo in URLs or filesystem paths
218 212 # (see 'hg help config.paths' for more info)
219 213 #
220 214 # default:pushurl = ssh://jdoe@example.net/hg/jdoes-fork
221 215 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
222 216 # my-clone = /home/jdoe/jdoes-clone
223 217
224 218 [ui]
225 219 # name and email (local to this repository, optional), e.g.
226 220 # username = Jane Doe <jdoe@example.com>
227 221
228 222 Checking cloned repo ids
229 223
230 224 $ printf "cloned " ; hg id -R cloned
231 225 cloned 7f491f53a367 tip
232 226 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
233 227 cloned/sub1 fc3b4ce2696f tip
234 228 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
235 229 cloned/sub1/sub2 c57a0840e3ba tip
236 230
237 231 debugsub output for main and sub1
238 232
239 233 $ hg debugsub -R cloned
240 234 path sub1
241 235 source ../sub1
242 236 revision fc3b4ce2696f7741438c79207583768f2ce6b0dd
243 237 $ hg debugsub -R cloned/sub1
244 238 path sub2
245 239 source ../sub2
246 240 revision c57a0840e3badd667ef3c3ef65471609acb2ba3c
247 241
248 242 Modifying deeply nested 'sub2'
249 243
250 244 $ echo modified > cloned/sub1/sub2/sub2
251 245 $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned
252 246 committing subrepository sub1
253 247 committing subrepository sub1/sub2
254 248
255 249 Checking modified node ids
256 250
257 251 $ printf "cloned " ; hg id -R cloned
258 252 cloned ffe6649062fe tip
259 253 $ printf "cloned/sub1 " ; hg id -R cloned/sub1
260 254 cloned/sub1 2ecb03bf44a9 tip
261 255 $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2
262 256 cloned/sub1/sub2 53dd3430bcaf tip
263 257
264 258 debugsub output for main and sub1
265 259
266 260 $ hg debugsub -R cloned
267 261 path sub1
268 262 source ../sub1
269 263 revision 2ecb03bf44a94e749e8669481dd9069526ce7cb9
270 264 $ hg debugsub -R cloned/sub1
271 265 path sub2
272 266 source ../sub2
273 267 revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487
274 268
275 269 Check that deep archiving works
276 270
277 271 $ cd cloned
278 272 $ echo 'test' > sub1/sub2/test.txt
279 273 $ hg --config extensions.largefiles=! add sub1/sub2/test.txt
280 274 $ mkdir sub1/sub2/folder
281 275 $ echo 'subfolder' > sub1/sub2/folder/test.txt
282 276 $ hg ci -ASm "add test.txt"
283 277 adding sub1/sub2/folder/test.txt
284 278 committing subrepository sub1
285 279 committing subrepository sub1/sub2
286 280
287 281 $ rm -r main
288 282 $ hg archive -S -qr 'wdir()' ../wdir
289 283 $ cat ../wdir/.hg_archival.txt
290 284 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
291 285 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
292 286 branch: default
293 287 latesttag: null
294 288 latesttagdistance: 4
295 289 changessincelatesttag: 4
296 290 $ hg update -Cq .
297 291
298 292 A deleted subrepo file is flagged as dirty, like the top level repo
299 293
300 294 $ rm -r ../wdir sub1/sub2/folder/test.txt
301 295 $ hg archive -S -qr 'wdir()' ../wdir
302 296 $ cat ../wdir/.hg_archival.txt
303 297 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
304 298 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
305 299 branch: default
306 300 latesttag: null
307 301 latesttagdistance: 4
308 302 changessincelatesttag: 4
309 303 $ hg update -Cq .
310 304 $ rm -r ../wdir
311 305
312 306 $ hg archive -S -qr 'wdir()' ../wdir \
313 307 > --config 'experimental.archivemetatemplate=archived {node|short}\n'
314 308 $ cat ../wdir/.hg_archival.txt
315 309 archived ffffffffffff
316 310 $ rm -r ../wdir
317 311
318 312 .. but first take a detour through some deep removal testing
319 313
320 314 $ hg remove -S -I 're:.*.txt' .
321 315 \r (no-eol) (esc)
322 316 searching [==========================================>] 1/1\r (no-eol) (esc)
323 317 searching [==========================================>] 1/1\r (no-eol) (esc)
324 318 \r (no-eol) (esc)
325 319 \r (no-eol) (esc)
326 320 deleting [=====================> ] 1/2\r (no-eol) (esc)
327 321 \r (no-eol) (esc)
328 322 \r (no-eol) (esc)
329 323 deleting [===========================================>] 2/2\r (no-eol) (esc)
330 324 \r (no-eol) (esc)
331 325 removing sub1/sub2/folder/test.txt
332 326 removing sub1/sub2/test.txt
333 327 $ hg status -S
334 328 R sub1/sub2/folder/test.txt
335 329 R sub1/sub2/test.txt
336 330 $ hg update -Cq
337 331 $ hg remove -I 're:.*.txt' sub1
338 332 \r (no-eol) (esc)
339 333 searching [==========================================>] 1/1\r (no-eol) (esc)
340 334 \r (no-eol) (esc)
341 335 \r (no-eol) (esc)
342 336 deleting [===========================================>] 1/1\r (no-eol) (esc)
343 337 \r (no-eol) (esc)
344 338 $ hg status -S
345 339 $ hg remove sub1/sub2/folder/test.txt
346 340 \r (no-eol) (esc)
347 341 searching [==========================================>] 1/1\r (no-eol) (esc)
348 342 searching [==========================================>] 1/1\r (no-eol) (esc)
349 343 \r (no-eol) (esc)
350 344 \r (no-eol) (esc)
351 345 deleting [===========================================>] 1/1\r (no-eol) (esc)
352 346 \r (no-eol) (esc)
353 347 \r (no-eol) (esc)
354 348 deleting [===========================================>] 1/1\r (no-eol) (esc)
355 349 \r (no-eol) (esc)
356 350 \r (no-eol) (esc)
357 351 deleting [===========================================>] 1/1\r (no-eol) (esc)
358 352 \r (no-eol) (esc)
359 353 $ hg remove sub1/.hgsubstate
360 354 \r (no-eol) (esc)
361 355 searching [==========================================>] 1/1\r (no-eol) (esc)
362 356 \r (no-eol) (esc)
363 357 \r (no-eol) (esc)
364 358 deleting [===========================================>] 1/1\r (no-eol) (esc)
365 359 \r (no-eol) (esc)
366 360 \r (no-eol) (esc)
367 361 deleting [===========================================>] 1/1\r (no-eol) (esc)
368 362 \r (no-eol) (esc)
369 363 $ mv sub1/.hgsub sub1/x.hgsub
370 364 $ hg status -S
371 365 warning: subrepo spec file 'sub1/.hgsub' not found
372 366 R sub1/.hgsubstate
373 367 R sub1/sub2/folder/test.txt
374 368 ! sub1/.hgsub
375 369 ? sub1/x.hgsub
376 370 $ mv sub1/x.hgsub sub1/.hgsub
377 371 $ hg update -Cq
378 372 $ touch sub1/foo
379 373 $ hg forget sub1/sub2/folder/test.txt
380 374 $ rm sub1/sub2/test.txt
381 375
382 376 Test relative path printing + subrepos
383 377 $ mkdir -p foo/bar
384 378 $ cd foo
385 379 $ touch bar/abc
386 380 $ hg addremove -S ..
387 381 \r (no-eol) (esc)
388 382 searching for exact renames [ ] 0/1\r (no-eol) (esc)
389 383 \r (no-eol) (esc)
390 384 adding ../sub1/sub2/folder/test.txt
391 385 removing ../sub1/sub2/test.txt
392 386 adding ../sub1/foo
393 387 adding bar/abc
394 388 $ cd ..
395 389 $ hg status -S
396 390 A foo/bar/abc
397 391 A sub1/foo
398 392 R sub1/sub2/test.txt
399 393
400 394 Archive wdir() with subrepos
401 395 $ hg rm main
402 396 \r (no-eol) (esc)
403 397 deleting [===========================================>] 1/1\r (no-eol) (esc)
404 398 \r (no-eol) (esc)
405 399 $ hg archive -S -r 'wdir()' ../wdir
406 400 \r (no-eol) (esc)
407 401 archiving [ ] 0/3\r (no-eol) (esc)
408 402 archiving [=============> ] 1/3\r (no-eol) (esc)
409 403 archiving [===========================> ] 2/3\r (no-eol) (esc)
410 404 archiving [==========================================>] 3/3\r (no-eol) (esc)
411 405 \r (no-eol) (esc)
412 406 \r (no-eol) (esc)
413 407 archiving (sub1) [ ] 0/4\r (no-eol) (esc)
414 408 archiving (sub1) [========> ] 1/4\r (no-eol) (esc)
415 409 archiving (sub1) [=================> ] 2/4\r (no-eol) (esc)
416 410 archiving (sub1) [==========================> ] 3/4\r (no-eol) (esc)
417 411 archiving (sub1) [===================================>] 4/4\r (no-eol) (esc)
418 412 \r (no-eol) (esc)
419 413 \r (no-eol) (esc)
420 414 archiving (sub1/sub2) [ ] 0/2\r (no-eol) (esc)
421 415 archiving (sub1/sub2) [==============> ] 1/2\r (no-eol) (esc)
422 416 archiving (sub1/sub2) [==============================>] 2/2\r (no-eol) (esc)
423 417 \r (no-eol) (esc)
424 418 $ diff -r . ../wdir | egrep -v '\.hg$|^Common subdirectories:'
425 419 Only in ../wdir: .hg_archival.txt
426 420
427 421 $ find ../wdir -type f | sort
428 422 ../wdir/.hg_archival.txt
429 423 ../wdir/.hgsub
430 424 ../wdir/.hgsubstate
431 425 ../wdir/foo/bar/abc
432 426 ../wdir/sub1/.hgsub
433 427 ../wdir/sub1/.hgsubstate
434 428 ../wdir/sub1/foo
435 429 ../wdir/sub1/sub1
436 430 ../wdir/sub1/sub2/folder/test.txt
437 431 ../wdir/sub1/sub2/sub2
438 432
439 433 $ cat ../wdir/.hg_archival.txt
440 434 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
441 435 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+
442 436 branch: default
443 437 latesttag: null
444 438 latesttagdistance: 4
445 439 changessincelatesttag: 4
446 440
447 441 Attempting to archive 'wdir()' with a missing file is handled gracefully
448 442 $ rm sub1/sub1
449 443 $ rm -r ../wdir
450 444 $ hg archive -v -S -r 'wdir()' ../wdir
451 445 \r (no-eol) (esc)
452 446 archiving [ ] 0/3\r (no-eol) (esc)
453 447 archiving [=============> ] 1/3\r (no-eol) (esc)
454 448 archiving [===========================> ] 2/3\r (no-eol) (esc)
455 449 archiving [==========================================>] 3/3\r (no-eol) (esc)
456 450 \r (no-eol) (esc)
457 451 \r (no-eol) (esc)
458 452 archiving (sub1) [ ] 0/3\r (no-eol) (esc)
459 453 archiving (sub1) [===========> ] 1/3\r (no-eol) (esc)
460 454 archiving (sub1) [=======================> ] 2/3\r (no-eol) (esc)
461 455 archiving (sub1) [===================================>] 3/3\r (no-eol) (esc)
462 456 \r (no-eol) (esc)
463 457 \r (no-eol) (esc)
464 458 archiving (sub1/sub2) [ ] 0/2\r (no-eol) (esc)
465 459 archiving (sub1/sub2) [==============> ] 1/2\r (no-eol) (esc)
466 460 archiving (sub1/sub2) [==============================>] 2/2\r (no-eol) (esc)
467 461 \r (no-eol) (esc)
468 462 $ find ../wdir -type f | sort
469 463 ../wdir/.hg_archival.txt
470 464 ../wdir/.hgsub
471 465 ../wdir/.hgsubstate
472 466 ../wdir/foo/bar/abc
473 467 ../wdir/sub1/.hgsub
474 468 ../wdir/sub1/.hgsubstate
475 469 ../wdir/sub1/foo
476 470 ../wdir/sub1/sub2/folder/test.txt
477 471 ../wdir/sub1/sub2/sub2
478 472
479 473 Continue relative path printing + subrepos
480 474 $ hg update -Cq
481 475 $ rm -r ../wdir
482 476 $ hg archive -S -r 'wdir()' ../wdir
483 477 \r (no-eol) (esc)
484 478 archiving [ ] 0/3\r (no-eol) (esc)
485 479 archiving [=============> ] 1/3\r (no-eol) (esc)
486 480 archiving [===========================> ] 2/3\r (no-eol) (esc)
487 481 archiving [==========================================>] 3/3\r (no-eol) (esc)
488 482 \r (no-eol) (esc)
489 483 \r (no-eol) (esc)
490 484 archiving (sub1) [ ] 0/3\r (no-eol) (esc)
491 485 archiving (sub1) [===========> ] 1/3\r (no-eol) (esc)
492 486 archiving (sub1) [=======================> ] 2/3\r (no-eol) (esc)
493 487 archiving (sub1) [===================================>] 3/3\r (no-eol) (esc)
494 488 \r (no-eol) (esc)
495 489 \r (no-eol) (esc)
496 490 archiving (sub1/sub2) [ ] 0/3\r (no-eol) (esc)
497 491 archiving (sub1/sub2) [=========> ] 1/3\r (no-eol) (esc)
498 492 archiving (sub1/sub2) [===================> ] 2/3\r (no-eol) (esc)
499 493 archiving (sub1/sub2) [==============================>] 3/3\r (no-eol) (esc)
500 494 \r (no-eol) (esc)
501 495 $ cat ../wdir/.hg_archival.txt
502 496 repo: 7f491f53a367861f47ee64a80eb997d1f341b77a
503 497 node: 9bb10eebee29dc0f1201dcf5977b811a540255fd
504 498 branch: default
505 499 latesttag: null
506 500 latesttagdistance: 4
507 501 changessincelatesttag: 4
508 502
509 503 $ touch sub1/sub2/folder/bar
510 504 $ hg addremove sub1/sub2
511 505 adding sub1/sub2/folder/bar
512 506 $ hg status -S
513 507 A sub1/sub2/folder/bar
514 508 ? foo/bar/abc
515 509 ? sub1/foo
516 510 $ hg update -Cq
517 511 $ hg addremove sub1
518 512 adding sub1/sub2/folder/bar
519 513 adding sub1/foo
520 514 $ hg update -Cq
521 515 $ rm sub1/sub2/folder/test.txt
522 516 $ rm sub1/sub2/test.txt
523 517 $ hg ci -ASm "remove test.txt"
524 518 adding sub1/sub2/folder/bar
525 519 removing sub1/sub2/folder/test.txt
526 520 removing sub1/sub2/test.txt
527 521 adding sub1/foo
528 522 adding foo/bar/abc
529 523 committing subrepository sub1
530 524 committing subrepository sub1/sub2
531 525
532 526 $ hg forget sub1/sub2/sub2
533 527 $ echo x > sub1/sub2/x.txt
534 528 $ hg add sub1/sub2/x.txt
535 529
536 530 Files sees uncommitted adds and removes in subrepos
537 531 $ hg files -S
538 532 .hgsub
539 533 .hgsubstate
540 534 foo/bar/abc
541 535 main
542 536 sub1/.hgsub
543 537 sub1/.hgsubstate
544 538 sub1/foo
545 539 sub1/sub1
546 540 sub1/sub2/folder/bar
547 541 sub1/sub2/x.txt
548 542
549 543 $ hg files -S "set:eol('dos') or eol('unix') or size('<= 0')"
550 544 .hgsub
551 545 .hgsubstate
552 546 foo/bar/abc
553 547 main
554 548 sub1/.hgsub
555 549 sub1/.hgsubstate
556 550 sub1/foo
557 551 sub1/sub1
558 552 sub1/sub2/folder/bar
559 553 sub1/sub2/x.txt
560 554
561 555 $ hg files -r '.^' -S "set:eol('dos') or eol('unix')"
562 556 .hgsub
563 557 .hgsubstate
564 558 main
565 559 sub1/.hgsub
566 560 sub1/.hgsubstate
567 561 sub1/sub1
568 562 sub1/sub2/folder/test.txt
569 563 sub1/sub2/sub2
570 564 sub1/sub2/test.txt
571 565
572 566 $ hg files sub1
573 567 sub1/.hgsub
574 568 sub1/.hgsubstate
575 569 sub1/foo
576 570 sub1/sub1
577 571 sub1/sub2/folder/bar
578 572 sub1/sub2/x.txt
579 573
580 574 $ hg files sub1/sub2
581 575 sub1/sub2/folder/bar
582 576 sub1/sub2/x.txt
583 577
584 578 $ hg files
585 579 .hgsub
586 580 .hgsubstate
587 581 foo/bar/abc
588 582 main
589 583
590 584 $ hg files -S -r '.^' sub1/sub2/folder
591 585 sub1/sub2/folder/test.txt
592 586
593 587 $ hg files -S -r '.^' sub1/sub2/missing
594 588 sub1/sub2/missing: no such file in rev 78026e779ea6
595 589 [1]
596 590
597 591 $ hg files -r '.^' sub1/
598 592 sub1/.hgsub
599 593 sub1/.hgsubstate
600 594 sub1/sub1
601 595 sub1/sub2/folder/test.txt
602 596 sub1/sub2/sub2
603 597 sub1/sub2/test.txt
604 598
605 599 $ hg files -r '.^' sub1/sub2
606 600 sub1/sub2/folder/test.txt
607 601 sub1/sub2/sub2
608 602 sub1/sub2/test.txt
609 603
610 604 $ hg rollback -q
611 605 $ hg up -Cq
612 606
613 607 $ hg --config extensions.largefiles=! archive -S ../archive_all
614 608 \r (no-eol) (esc)
615 609 archiving [ ] 0/3\r (no-eol) (esc)
616 610 archiving [=============> ] 1/3\r (no-eol) (esc)
617 611 archiving [===========================> ] 2/3\r (no-eol) (esc)
618 612 archiving [==========================================>] 3/3\r (no-eol) (esc)
619 613 \r (no-eol) (esc)
620 614 \r (no-eol) (esc)
621 615 archiving (sub1) [ ] 0/3\r (no-eol) (esc)
622 616 archiving (sub1) [===========> ] 1/3\r (no-eol) (esc)
623 617 archiving (sub1) [=======================> ] 2/3\r (no-eol) (esc)
624 618 archiving (sub1) [===================================>] 3/3\r (no-eol) (esc)
625 619 \r (no-eol) (esc)
626 620 \r (no-eol) (esc)
627 621 archiving (sub1/sub2) [ ] 0/3\r (no-eol) (esc)
628 622 archiving (sub1/sub2) [=========> ] 1/3\r (no-eol) (esc)
629 623 archiving (sub1/sub2) [===================> ] 2/3\r (no-eol) (esc)
630 624 archiving (sub1/sub2) [==============================>] 3/3\r (no-eol) (esc)
631 625 \r (no-eol) (esc)
632 626 $ find ../archive_all | sort
633 627 ../archive_all
634 628 ../archive_all/.hg_archival.txt
635 629 ../archive_all/.hgsub
636 630 ../archive_all/.hgsubstate
637 631 ../archive_all/main
638 632 ../archive_all/sub1
639 633 ../archive_all/sub1/.hgsub
640 634 ../archive_all/sub1/.hgsubstate
641 635 ../archive_all/sub1/sub1
642 636 ../archive_all/sub1/sub2
643 637 ../archive_all/sub1/sub2/folder
644 638 ../archive_all/sub1/sub2/folder/test.txt
645 639 ../archive_all/sub1/sub2/sub2
646 640 ../archive_all/sub1/sub2/test.txt
647 641
648 642 Check that archive -X works in deep subrepos
649 643
650 644 $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude
651 645 \r (no-eol) (esc)
652 646 archiving [ ] 0/3\r (no-eol) (esc)
653 647 archiving [=============> ] 1/3\r (no-eol) (esc)
654 648 archiving [===========================> ] 2/3\r (no-eol) (esc)
655 649 archiving [==========================================>] 3/3\r (no-eol) (esc)
656 650 \r (no-eol) (esc)
657 651 \r (no-eol) (esc)
658 652 archiving (sub1) [ ] 0/3\r (no-eol) (esc)
659 653 archiving (sub1) [===========> ] 1/3\r (no-eol) (esc)
660 654 archiving (sub1) [=======================> ] 2/3\r (no-eol) (esc)
661 655 archiving (sub1) [===================================>] 3/3\r (no-eol) (esc)
662 656 \r (no-eol) (esc)
663 657 \r (no-eol) (esc)
664 658 archiving (sub1/sub2) [ ] 0/1\r (no-eol) (esc)
665 659 archiving (sub1/sub2) [==============================>] 1/1\r (no-eol) (esc)
666 660 \r (no-eol) (esc)
667 661 $ find ../archive_exclude | sort
668 662 ../archive_exclude
669 663 ../archive_exclude/.hg_archival.txt
670 664 ../archive_exclude/.hgsub
671 665 ../archive_exclude/.hgsubstate
672 666 ../archive_exclude/main
673 667 ../archive_exclude/sub1
674 668 ../archive_exclude/sub1/.hgsub
675 669 ../archive_exclude/sub1/.hgsubstate
676 670 ../archive_exclude/sub1/sub1
677 671 ../archive_exclude/sub1/sub2
678 672 ../archive_exclude/sub1/sub2/sub2
679 673
680 674 $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include
681 675 \r (no-eol) (esc)
682 676 archiving (sub1) [ <=> ] 0\r (no-eol) (esc)
683 677 \r (no-eol) (esc)
684 678 \r (no-eol) (esc)
685 679 archiving (sub1/sub2) [ ] 0/2\r (no-eol) (esc)
686 680 archiving (sub1/sub2) [==============> ] 1/2\r (no-eol) (esc)
687 681 archiving (sub1/sub2) [==============================>] 2/2\r (no-eol) (esc)
688 682 \r (no-eol) (esc)
689 683 $ find ../archive_include | sort
690 684 ../archive_include
691 685 ../archive_include/sub1
692 686 ../archive_include/sub1/sub2
693 687 ../archive_include/sub1/sub2/folder
694 688 ../archive_include/sub1/sub2/folder/test.txt
695 689 ../archive_include/sub1/sub2/test.txt
696 690
697 691 Check that deep archive works with largefiles (which overrides hgsubrepo impl)
698 692 This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo
699 693 subrepos are archived properly.
700 694 Note that add --large through a subrepo currently adds the file as a normal file
701 695
702 696 $ echo "large" > sub1/sub2/large.bin
703 697 $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin
704 698 $ echo "large" > large.bin
705 699 $ hg --config extensions.largefiles= add --large large.bin
706 700 $ hg --config extensions.largefiles= ci -S -m "add large files"
707 701 committing subrepository sub1
708 702 committing subrepository sub1/sub2
709 703
710 704 $ hg --config extensions.largefiles= archive -S ../archive_lf
711 705 $ find ../archive_lf | sort
712 706 ../archive_lf
713 707 ../archive_lf/.hg_archival.txt
714 708 ../archive_lf/.hgsub
715 709 ../archive_lf/.hgsubstate
716 710 ../archive_lf/large.bin
717 711 ../archive_lf/main
718 712 ../archive_lf/sub1
719 713 ../archive_lf/sub1/.hgsub
720 714 ../archive_lf/sub1/.hgsubstate
721 715 ../archive_lf/sub1/sub1
722 716 ../archive_lf/sub1/sub2
723 717 ../archive_lf/sub1/sub2/folder
724 718 ../archive_lf/sub1/sub2/folder/test.txt
725 719 ../archive_lf/sub1/sub2/large.bin
726 720 ../archive_lf/sub1/sub2/sub2
727 721 ../archive_lf/sub1/sub2/test.txt
728 722 $ rm -rf ../archive_lf
729 723
730 724 Exclude large files from main and sub-sub repo
731 725
732 726 $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf
733 727 $ find ../archive_lf | sort
734 728 ../archive_lf
735 729 ../archive_lf/.hg_archival.txt
736 730 ../archive_lf/.hgsub
737 731 ../archive_lf/.hgsubstate
738 732 ../archive_lf/main
739 733 ../archive_lf/sub1
740 734 ../archive_lf/sub1/.hgsub
741 735 ../archive_lf/sub1/.hgsubstate
742 736 ../archive_lf/sub1/sub1
743 737 ../archive_lf/sub1/sub2
744 738 ../archive_lf/sub1/sub2/folder
745 739 ../archive_lf/sub1/sub2/folder/test.txt
746 740 ../archive_lf/sub1/sub2/sub2
747 741 ../archive_lf/sub1/sub2/test.txt
748 742 $ rm -rf ../archive_lf
749 743
750 744 Exclude normal files from main and sub-sub repo
751 745
752 746 $ hg --config extensions.largefiles= archive -S -X '**.txt' -p '.' ../archive_lf.tgz
753 747 $ tar -tzf ../archive_lf.tgz | sort
754 748 .hgsub
755 749 .hgsubstate
756 750 large.bin
757 751 main
758 752 sub1/.hgsub
759 753 sub1/.hgsubstate
760 754 sub1/sub1
761 755 sub1/sub2/large.bin
762 756 sub1/sub2/sub2
763 757
764 758 Include normal files from within a largefiles subrepo
765 759
766 760 $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf
767 761 $ find ../archive_lf | sort
768 762 ../archive_lf
769 763 ../archive_lf/.hg_archival.txt
770 764 ../archive_lf/sub1
771 765 ../archive_lf/sub1/sub2
772 766 ../archive_lf/sub1/sub2/folder
773 767 ../archive_lf/sub1/sub2/folder/test.txt
774 768 ../archive_lf/sub1/sub2/test.txt
775 769 $ rm -rf ../archive_lf
776 770
777 771 Include large files from within a largefiles subrepo
778 772
779 773 $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf
780 774 $ find ../archive_lf | sort
781 775 ../archive_lf
782 776 ../archive_lf/large.bin
783 777 ../archive_lf/sub1
784 778 ../archive_lf/sub1/sub2
785 779 ../archive_lf/sub1/sub2/large.bin
786 780 $ rm -rf ../archive_lf
787 781
788 782 Find an exact largefile match in a largefiles subrepo
789 783
790 784 $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf
791 785 $ find ../archive_lf | sort
792 786 ../archive_lf
793 787 ../archive_lf/sub1
794 788 ../archive_lf/sub1/sub2
795 789 ../archive_lf/sub1/sub2/large.bin
796 790 $ rm -rf ../archive_lf
797 791
798 792 The local repo enables largefiles if a largefiles repo is cloned
799 793 $ hg showconfig extensions
800 794 abort: repository requires features unknown to this Mercurial: largefiles!
801 795 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
802 796 [255]
803 797 $ hg --config extensions.largefiles= clone -qU . ../lfclone
804 798 $ cat ../lfclone/.hg/hgrc
805 799 # example repository config (see 'hg help config' for more info)
806 800 [paths]
807 801 default = $TESTTMP/cloned
808 802
809 803 # path aliases to other clones of this repo in URLs or filesystem paths
810 804 # (see 'hg help config.paths' for more info)
811 805 #
812 806 # default:pushurl = ssh://jdoe@example.net/hg/jdoes-fork
813 807 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
814 808 # my-clone = /home/jdoe/jdoes-clone
815 809
816 810 [ui]
817 811 # name and email (local to this repository, optional), e.g.
818 812 # username = Jane Doe <jdoe@example.com>
819 813
820 814 [extensions]
821 815 largefiles=
822 816
823 817 Find an exact match to a standin (should archive nothing)
824 818 $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf
825 819 $ find ../archive_lf 2> /dev/null | sort
826 820
827 821 $ cat >> $HGRCPATH <<EOF
828 822 > [extensions]
829 823 > largefiles=
830 824 > [largefiles]
831 825 > patterns=glob:**.dat
832 826 > EOF
833 827
834 828 Test forget through a deep subrepo with the largefiles extension, both a
835 829 largefile and a normal file. Then a largefile that hasn't been committed yet.
836 830 $ touch sub1/sub2/untracked.txt
837 831 $ touch sub1/sub2/large.dat
838 832 $ hg forget sub1/sub2/large.bin sub1/sub2/test.txt sub1/sub2/untracked.txt
839 833 not removing sub1/sub2/untracked.txt: file is already untracked
840 834 [1]
841 835 $ hg add --large --dry-run -v sub1/sub2/untracked.txt
842 836 adding sub1/sub2/untracked.txt as a largefile
843 837 $ hg add --large -v sub1/sub2/untracked.txt
844 838 adding sub1/sub2/untracked.txt as a largefile
845 839 $ hg add --normal -v sub1/sub2/large.dat
846 840 adding sub1/sub2/large.dat
847 841 $ hg forget -v sub1/sub2/untracked.txt
848 842 removing sub1/sub2/untracked.txt
849 843 $ hg status -S
850 844 A sub1/sub2/large.dat
851 845 R sub1/sub2/large.bin
852 846 R sub1/sub2/test.txt
853 847 ? foo/bar/abc
854 848 ? sub1/sub2/untracked.txt
855 849 ? sub1/sub2/x.txt
856 850 $ hg add sub1/sub2
857 851
858 852 $ hg archive -S -r 'wdir()' ../wdir2
859 853 $ diff -r . ../wdir2 | egrep -v '\.hg$|^Common subdirectories:'
860 854 Only in ../wdir2: .hg_archival.txt
861 855 Only in .: .hglf
862 856 Only in .: foo
863 857 Only in ./sub1/sub2: large.bin
864 858 Only in ./sub1/sub2: test.txt
865 859 Only in ./sub1/sub2: untracked.txt
866 860 Only in ./sub1/sub2: x.txt
867 861 $ find ../wdir2 -type f | sort
868 862 ../wdir2/.hg_archival.txt
869 863 ../wdir2/.hgsub
870 864 ../wdir2/.hgsubstate
871 865 ../wdir2/large.bin
872 866 ../wdir2/main
873 867 ../wdir2/sub1/.hgsub
874 868 ../wdir2/sub1/.hgsubstate
875 869 ../wdir2/sub1/sub1
876 870 ../wdir2/sub1/sub2/folder/test.txt
877 871 ../wdir2/sub1/sub2/large.dat
878 872 ../wdir2/sub1/sub2/sub2
879 873 $ hg status -S -mac -n | sort
880 874 .hgsub
881 875 .hgsubstate
882 876 large.bin
883 877 main
884 878 sub1/.hgsub
885 879 sub1/.hgsubstate
886 880 sub1/sub1
887 881 sub1/sub2/folder/test.txt
888 882 sub1/sub2/large.dat
889 883 sub1/sub2/sub2
890 884
891 885 $ hg ci -Sqm 'forget testing'
892 886
893 887 Test 'wdir()' modified file archiving with largefiles
894 888 $ echo 'mod' > main
895 889 $ echo 'mod' > large.bin
896 890 $ echo 'mod' > sub1/sub2/large.dat
897 891 $ hg archive -S -r 'wdir()' ../wdir3
898 892 $ diff -r . ../wdir3 | egrep -v '\.hg$|^Common subdirectories'
899 893 Only in ../wdir3: .hg_archival.txt
900 894 Only in .: .hglf
901 895 Only in .: foo
902 896 Only in ./sub1/sub2: large.bin
903 897 Only in ./sub1/sub2: test.txt
904 898 Only in ./sub1/sub2: untracked.txt
905 899 Only in ./sub1/sub2: x.txt
906 900 $ find ../wdir3 -type f | sort
907 901 ../wdir3/.hg_archival.txt
908 902 ../wdir3/.hgsub
909 903 ../wdir3/.hgsubstate
910 904 ../wdir3/large.bin
911 905 ../wdir3/main
912 906 ../wdir3/sub1/.hgsub
913 907 ../wdir3/sub1/.hgsubstate
914 908 ../wdir3/sub1/sub1
915 909 ../wdir3/sub1/sub2/folder/test.txt
916 910 ../wdir3/sub1/sub2/large.dat
917 911 ../wdir3/sub1/sub2/sub2
918 912 $ hg up -Cq
919 913
920 914 Test issue4330: commit a directory where only normal files have changed
921 915 $ touch foo/bar/large.dat
922 916 $ hg add --large foo/bar/large.dat
923 917 $ hg ci -m 'add foo/bar/large.dat'
924 918 $ touch a.txt
925 919 $ touch a.dat
926 920 $ hg add -v foo/bar/abc a.txt a.dat
927 921 adding a.dat as a largefile
928 922 adding a.txt
929 923 adding foo/bar/abc
930 924 $ hg ci -m 'dir commit with only normal file deltas' foo/bar
931 925 $ hg status
932 926 A a.dat
933 927 A a.txt
934 928
935 929 Test a directory commit with a changed largefile and a changed normal file
936 930 $ echo changed > foo/bar/large.dat
937 931 $ echo changed > foo/bar/abc
938 932 $ hg ci -m 'dir commit with normal and lf file deltas' foo
939 933 $ hg status
940 934 A a.dat
941 935 A a.txt
942 936
943 937 $ hg ci -m "add a.*"
944 938 $ hg mv a.dat b.dat
945 939 $ hg mv foo/bar/abc foo/bar/def
946 940 $ hg status -C
947 941 A b.dat
948 942 a.dat
949 943 A foo/bar/def
950 944 foo/bar/abc
951 945 R a.dat
952 946 R foo/bar/abc
953 947
954 948 $ hg ci -m "move large and normal"
955 949 $ hg status -C --rev '.^' --rev .
956 950 A b.dat
957 951 a.dat
958 952 A foo/bar/def
959 953 foo/bar/abc
960 954 R a.dat
961 955 R foo/bar/abc
962 956
963 957
964 958 $ echo foo > main
965 959 $ hg ci -m "mod parent only"
966 960 $ hg init sub3
967 961 $ echo "sub3 = sub3" >> .hgsub
968 962 $ echo xyz > sub3/a.txt
969 963 $ hg add sub3/a.txt
970 964 $ hg ci -Sm "add sub3"
971 965 committing subrepository sub3
972 966 $ cat .hgsub | grep -v sub3 > .hgsub1
973 967 $ mv .hgsub1 .hgsub
974 968 $ hg ci -m "remove sub3"
975 969
976 970 $ hg log -r "subrepo()" --style compact
977 971 0 7f491f53a367 1970-01-01 00:00 +0000 test
978 972 main import
979 973
980 974 1 ffe6649062fe 1970-01-01 00:00 +0000 test
981 975 deep nested modif should trigger a commit
982 976
983 977 2 9bb10eebee29 1970-01-01 00:00 +0000 test
984 978 add test.txt
985 979
986 980 3 7c64f035294f 1970-01-01 00:00 +0000 test
987 981 add large files
988 982
989 983 4 f734a59e2e35 1970-01-01 00:00 +0000 test
990 984 forget testing
991 985
992 986 11 9685a22af5db 1970-01-01 00:00 +0000 test
993 987 add sub3
994 988
995 989 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
996 990 remove sub3
997 991
998 992 $ hg log -r "subrepo('sub3')" --style compact
999 993 11 9685a22af5db 1970-01-01 00:00 +0000 test
1000 994 add sub3
1001 995
1002 996 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test
1003 997 remove sub3
1004 998
1005 999 $ hg log -r "subrepo('bogus')" --style compact
1006 1000
1007 1001
1008 1002 Test .hgsubstate in the R state
1009 1003
1010 1004 $ hg rm .hgsub .hgsubstate
1011 1005 \r (no-eol) (esc)
1012 1006 deleting [=====================> ] 1/2\r (no-eol) (esc)
1013 1007 deleting [===========================================>] 2/2\r (no-eol) (esc)
1014 1008 \r (no-eol) (esc)
1015 1009 $ hg ci -m 'trash subrepo tracking'
1016 1010
1017 1011 $ hg log -r "subrepo('re:sub\d+')" --style compact
1018 1012 0 7f491f53a367 1970-01-01 00:00 +0000 test
1019 1013 main import
1020 1014
1021 1015 1 ffe6649062fe 1970-01-01 00:00 +0000 test
1022 1016 deep nested modif should trigger a commit
1023 1017
1024 1018 2 9bb10eebee29 1970-01-01 00:00 +0000 test
1025 1019 add test.txt
1026 1020
1027 1021 3 7c64f035294f 1970-01-01 00:00 +0000 test
1028 1022 add large files
1029 1023
1030 1024 4 f734a59e2e35 1970-01-01 00:00 +0000 test
1031 1025 forget testing
1032 1026
1033 1027 11 9685a22af5db 1970-01-01 00:00 +0000 test
1034 1028 add sub3
1035 1029
1036 1030 12 2e0485b475b9 1970-01-01 00:00 +0000 test
1037 1031 remove sub3
1038 1032
1039 1033 13[tip] a68b2c361653 1970-01-01 00:00 +0000 test
1040 1034 trash subrepo tracking
1041 1035
1042 1036
1043 1037 Restore the trashed subrepo tracking
1044 1038
1045 1039 $ hg rollback -q
1046 1040 $ hg update -Cq .
1047 1041
1048 1042 Interaction with extdiff, largefiles and subrepos
1049 1043
1050 1044 $ hg --config extensions.extdiff= pdiff -S
1051 1045
1052 1046 $ hg --config extensions.extdiff= pdiff -r '.^' -S
1053 1047 \r (no-eol) (esc)
1054 1048 archiving [ ] 0/2\r (no-eol) (esc)
1055 1049 archiving [====================> ] 1/2\r (no-eol) (esc)
1056 1050 archiving [==========================================>] 2/2\r (no-eol) (esc)
1057 1051 \r (no-eol) (esc)
1058 1052 \r (no-eol) (esc)
1059 1053 archiving (sub1) [ <=> ] 0\r (no-eol) (esc)
1060 1054 \r (no-eol) (esc)
1061 1055 \r (no-eol) (esc)
1062 1056 archiving (sub1/sub2) [ <=> ] 0\r (no-eol) (esc)
1063 1057 \r (no-eol) (esc)
1064 1058 \r (no-eol) (esc)
1065 1059 archiving (sub3) [ <=> ] 0\r (no-eol) (esc)
1066 1060 \r (no-eol) (esc)
1067 1061 \r (no-eol) (esc)
1068 1062 archiving [ ] 0/2\r (no-eol) (esc)
1069 1063 archiving [====================> ] 1/2\r (no-eol) (esc)
1070 1064 archiving [==========================================>] 2/2\r (no-eol) (esc)
1071 1065 \r (no-eol) (esc)
1072 1066 \r (no-eol) (esc)
1073 1067 archiving (sub1) [ <=> ] 0\r (no-eol) (esc)
1074 1068 \r (no-eol) (esc)
1075 1069 \r (no-eol) (esc)
1076 1070 archiving (sub1/sub2) [ <=> ] 0\r (no-eol) (esc)
1077 1071 \r (no-eol) (esc)
1078 1072 diff -Nru cloned.*/.hgsub cloned/.hgsub (glob)
1079 1073 --- cloned.*/.hgsub * (glob)
1080 1074 +++ cloned/.hgsub * (glob)
1081 1075 @@ -1,2 +1* @@ (glob)
1082 1076 sub1 = ../sub1
1083 1077 -sub3 = sub3
1084 1078 diff -Nru cloned.*/.hgsubstate cloned/.hgsubstate (glob)
1085 1079 --- cloned.*/.hgsubstate * (glob)
1086 1080 +++ cloned/.hgsubstate * (glob)
1087 1081 @@ -1,2 +1* @@ (glob)
1088 1082 7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
1089 1083 -b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
1090 1084 [1]
1091 1085
1092 1086 $ hg --config extensions.extdiff= pdiff -r 0 -r '.^' -S
1093 1087 \r (no-eol) (esc)
1094 1088 archiving [ ] 0/3\r (no-eol) (esc)
1095 1089 archiving [=============> ] 1/3\r (no-eol) (esc)
1096 1090 archiving [===========================> ] 2/3\r (no-eol) (esc)
1097 1091 archiving [==========================================>] 3/3\r (no-eol) (esc)
1098 1092 \r (no-eol) (esc)
1099 1093 \r (no-eol) (esc)
1100 1094 archiving (sub1) [ ] 0/1\r (no-eol) (esc)
1101 1095 archiving (sub1) [===================================>] 1/1\r (no-eol) (esc)
1102 1096 \r (no-eol) (esc)
1103 1097 \r (no-eol) (esc)
1104 1098 archiving (sub1/sub2) [ ] 0/1\r (no-eol) (esc)
1105 1099 archiving (sub1/sub2) [==============================>] 1/1\r (no-eol) (esc)
1106 1100 \r (no-eol) (esc)
1107 1101 \r (no-eol) (esc)
1108 1102 archiving [ ] 0/8\r (no-eol) (esc)
1109 1103 archiving [====> ] 1/8\r (no-eol) (esc)
1110 1104 archiving [=========> ] 2/8\r (no-eol) (esc)
1111 1105 archiving [===============> ] 3/8\r (no-eol) (esc)
1112 1106 archiving [====================> ] 4/8\r (no-eol) (esc)
1113 1107 archiving [=========================> ] 5/8\r (no-eol) (esc)
1114 1108 archiving [===============================> ] 6/8\r (no-eol) (esc)
1115 1109 archiving [====================================> ] 7/8\r (no-eol) (esc)
1116 1110 archiving [==========================================>] 8/8\r (no-eol) (esc)
1117 1111 \r (no-eol) (esc)
1118 1112 \r (no-eol) (esc)
1119 1113 archiving (sub1) [ ] 0/1\r (no-eol) (esc)
1120 1114 archiving (sub1) [===================================>] 1/1\r (no-eol) (esc)
1121 1115 \r (no-eol) (esc)
1122 1116 \r (no-eol) (esc)
1123 1117 archiving (sub1/sub2) [ ] 0/3\r (no-eol) (esc)
1124 1118 archiving (sub1/sub2) [=========> ] 1/3\r (no-eol) (esc)
1125 1119 archiving (sub1/sub2) [===================> ] 2/3\r (no-eol) (esc)
1126 1120 archiving (sub1/sub2) [==============================>] 3/3\r (no-eol) (esc)
1127 1121 \r (no-eol) (esc)
1128 1122 \r (no-eol) (esc)
1129 1123 archiving (sub3) [ ] 0/1\r (no-eol) (esc)
1130 1124 archiving (sub3) [===================================>] 1/1\r (no-eol) (esc)
1131 1125 \r (no-eol) (esc)
1132 1126 diff -Nru cloned.*/.hglf/b.dat cloned.*/.hglf/b.dat (glob)
1133 1127 --- cloned.*/.hglf/b.dat * (glob)
1134 1128 +++ cloned.*/.hglf/b.dat * (glob)
1135 1129 @@ -*,0 +1* @@ (glob)
1136 1130 +da39a3ee5e6b4b0d3255bfef95601890afd80709
1137 1131 diff -Nru cloned.*/.hglf/foo/bar/large.dat cloned.*/.hglf/foo/bar/large.dat (glob)
1138 1132 --- cloned.*/.hglf/foo/bar/large.dat * (glob)
1139 1133 +++ cloned.*/.hglf/foo/bar/large.dat * (glob)
1140 1134 @@ -*,0 +1* @@ (glob)
1141 1135 +2f6933b5ee0f5fdd823d9717d8729f3c2523811b
1142 1136 diff -Nru cloned.*/.hglf/large.bin cloned.*/.hglf/large.bin (glob)
1143 1137 --- cloned.*/.hglf/large.bin * (glob)
1144 1138 +++ cloned.*/.hglf/large.bin * (glob)
1145 1139 @@ -*,0 +1* @@ (glob)
1146 1140 +7f7097b041ccf68cc5561e9600da4655d21c6d18
1147 1141 diff -Nru cloned.*/.hgsub cloned.*/.hgsub (glob)
1148 1142 --- cloned.*/.hgsub * (glob)
1149 1143 +++ cloned.*/.hgsub * (glob)
1150 1144 @@ -1* +1,2 @@ (glob)
1151 1145 sub1 = ../sub1
1152 1146 +sub3 = sub3
1153 1147 diff -Nru cloned.*/.hgsubstate cloned.*/.hgsubstate (glob)
1154 1148 --- cloned.*/.hgsubstate * (glob)
1155 1149 +++ cloned.*/.hgsubstate * (glob)
1156 1150 @@ -1* +1,2 @@ (glob)
1157 1151 -fc3b4ce2696f7741438c79207583768f2ce6b0dd sub1
1158 1152 +7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1
1159 1153 +b1a26de6f2a045a9f079323693614ee322f1ff7e sub3
1160 1154 diff -Nru cloned.*/foo/bar/def cloned.*/foo/bar/def (glob)
1161 1155 --- cloned.*/foo/bar/def * (glob)
1162 1156 +++ cloned.*/foo/bar/def * (glob)
1163 1157 @@ -*,0 +1* @@ (glob)
1164 1158 +changed
1165 1159 diff -Nru cloned.*/main cloned.*/main (glob)
1166 1160 --- cloned.*/main * (glob)
1167 1161 +++ cloned.*/main * (glob)
1168 1162 @@ -1* +1* @@ (glob)
1169 1163 -main
1170 1164 +foo
1171 1165 diff -Nru cloned.*/sub1/.hgsubstate cloned.*/sub1/.hgsubstate (glob)
1172 1166 --- cloned.*/sub1/.hgsubstate * (glob)
1173 1167 +++ cloned.*/sub1/.hgsubstate * (glob)
1174 1168 @@ -1* +1* @@ (glob)
1175 1169 -c57a0840e3badd667ef3c3ef65471609acb2ba3c sub2
1176 1170 +c77908c81ccea3794a896c79e98b0e004aee2e9e sub2
1177 1171 diff -Nru cloned.*/sub1/sub2/folder/test.txt cloned.*/sub1/sub2/folder/test.txt (glob)
1178 1172 --- cloned.*/sub1/sub2/folder/test.txt * (glob)
1179 1173 +++ cloned.*/sub1/sub2/folder/test.txt * (glob)
1180 1174 @@ -*,0 +1* @@ (glob)
1181 1175 +subfolder
1182 1176 diff -Nru cloned.*/sub1/sub2/sub2 cloned.*/sub1/sub2/sub2 (glob)
1183 1177 --- cloned.*/sub1/sub2/sub2 * (glob)
1184 1178 +++ cloned.*/sub1/sub2/sub2 * (glob)
1185 1179 @@ -1* +1* @@ (glob)
1186 1180 -sub2
1187 1181 +modified
1188 1182 diff -Nru cloned.*/sub3/a.txt cloned.*/sub3/a.txt (glob)
1189 1183 --- cloned.*/sub3/a.txt * (glob)
1190 1184 +++ cloned.*/sub3/a.txt * (glob)
1191 1185 @@ -*,0 +1* @@ (glob)
1192 1186 +xyz
1193 1187 [1]
1194 1188
1195 1189 $ echo mod > sub1/sub2/sub2
1196 1190 $ hg --config extensions.extdiff= pdiff -S
1197 1191 \r (no-eol) (esc)
1198 1192 archiving (sub1) [ <=> ] 0\r (no-eol) (esc)
1199 1193 \r (no-eol) (esc)
1200 1194 \r (no-eol) (esc)
1201 1195 archiving (sub1/sub2) [ ] 0/1\r (no-eol) (esc)
1202 1196 archiving (sub1/sub2) [==============================>] 1/1\r (no-eol) (esc)
1203 1197 \r (no-eol) (esc)
1204 1198 --- */cloned.*/sub1/sub2/sub2 * (glob)
1205 1199 +++ */cloned/sub1/sub2/sub2 * (glob)
1206 1200 @@ -1* +1* @@ (glob)
1207 1201 -modified
1208 1202 +mod
1209 1203 [1]
1210 1204
1211 1205 $ cd ..
@@ -1,711 +1,708 b''
1 1 Create test repository:
2 2
3 3 $ hg init repo
4 4 $ cd repo
5 5 $ echo x1 > x.txt
6 6
7 7 $ hg init foo
8 8 $ cd foo
9 9 $ echo y1 > y.txt
10 10
11 11 $ hg init bar
12 12 $ cd bar
13 13 $ echo z1 > z.txt
14 14
15 15 $ cd ..
16 16 $ echo 'bar = bar' > .hgsub
17 17
18 18 $ cd ..
19 19 $ echo 'foo = foo' > .hgsub
20 20
21 21 Add files --- .hgsub files must go first to trigger subrepos:
22 22
23 23 $ hg add -S .hgsub
24 24 $ hg add -S foo/.hgsub
25 25 $ hg add -S foo/bar
26 26 adding foo/bar/z.txt
27 27 $ hg add -S
28 28 adding x.txt
29 29 adding foo/y.txt
30 30
31 31 Test recursive status without committing anything:
32 32
33 33 $ hg status -S
34 34 A .hgsub
35 35 A foo/.hgsub
36 36 A foo/bar/z.txt
37 37 A foo/y.txt
38 38 A x.txt
39 39
40 40 Test recursive diff without committing anything:
41 41
42 42 $ hg diff --nodates -S foo
43 43 diff -r 000000000000 foo/.hgsub
44 44 --- /dev/null
45 45 +++ b/foo/.hgsub
46 46 @@ -0,0 +1,1 @@
47 47 +bar = bar
48 48 diff -r 000000000000 foo/y.txt
49 49 --- /dev/null
50 50 +++ b/foo/y.txt
51 51 @@ -0,0 +1,1 @@
52 52 +y1
53 53 diff -r 000000000000 foo/bar/z.txt
54 54 --- /dev/null
55 55 +++ b/foo/bar/z.txt
56 56 @@ -0,0 +1,1 @@
57 57 +z1
58 58
59 59 Commits:
60 60
61 61 $ hg commit -m fails
62 62 abort: uncommitted changes in subrepository "foo"
63 63 (use --subrepos for recursive commit)
64 64 [255]
65 65
66 66 The --subrepos flag overwrite the config setting:
67 67
68 68 $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos
69 69 committing subrepository foo
70 70 committing subrepository foo/bar
71 71
72 72 $ cd foo
73 73 $ echo y2 >> y.txt
74 74 $ hg commit -m 0-1-0
75 75
76 76 $ cd bar
77 77 $ echo z2 >> z.txt
78 78 $ hg commit -m 0-1-1
79 79
80 80 $ cd ..
81 81 $ hg commit -m 0-2-1
82 82
83 83 $ cd ..
84 84 $ hg commit -m 1-2-1
85 85
86 86 Change working directory:
87 87
88 88 $ echo y3 >> foo/y.txt
89 89 $ echo z3 >> foo/bar/z.txt
90 90 $ hg status -S
91 91 M foo/bar/z.txt
92 92 M foo/y.txt
93 93 $ hg diff --nodates -S
94 94 diff -r d254738c5f5e foo/y.txt
95 95 --- a/foo/y.txt
96 96 +++ b/foo/y.txt
97 97 @@ -1,2 +1,3 @@
98 98 y1
99 99 y2
100 100 +y3
101 101 diff -r 9647f22de499 foo/bar/z.txt
102 102 --- a/foo/bar/z.txt
103 103 +++ b/foo/bar/z.txt
104 104 @@ -1,2 +1,3 @@
105 105 z1
106 106 z2
107 107 +z3
108 108
109 109 Status call crossing repository boundaries:
110 110
111 111 $ hg status -S foo/bar/z.txt
112 112 M foo/bar/z.txt
113 113 $ hg status -S -I 'foo/?.txt'
114 114 M foo/y.txt
115 115 $ hg status -S -I '**/?.txt'
116 116 M foo/bar/z.txt
117 117 M foo/y.txt
118 118 $ hg diff --nodates -S -I '**/?.txt'
119 119 diff -r d254738c5f5e foo/y.txt
120 120 --- a/foo/y.txt
121 121 +++ b/foo/y.txt
122 122 @@ -1,2 +1,3 @@
123 123 y1
124 124 y2
125 125 +y3
126 126 diff -r 9647f22de499 foo/bar/z.txt
127 127 --- a/foo/bar/z.txt
128 128 +++ b/foo/bar/z.txt
129 129 @@ -1,2 +1,3 @@
130 130 z1
131 131 z2
132 132 +z3
133 133
134 134 Status from within a subdirectory:
135 135
136 136 $ mkdir dir
137 137 $ cd dir
138 138 $ echo a1 > a.txt
139 139 $ hg status -S
140 140 M foo/bar/z.txt
141 141 M foo/y.txt
142 142 ? dir/a.txt
143 143 $ hg diff --nodates -S
144 144 diff -r d254738c5f5e foo/y.txt
145 145 --- a/foo/y.txt
146 146 +++ b/foo/y.txt
147 147 @@ -1,2 +1,3 @@
148 148 y1
149 149 y2
150 150 +y3
151 151 diff -r 9647f22de499 foo/bar/z.txt
152 152 --- a/foo/bar/z.txt
153 153 +++ b/foo/bar/z.txt
154 154 @@ -1,2 +1,3 @@
155 155 z1
156 156 z2
157 157 +z3
158 158
159 159 Status with relative path:
160 160
161 161 $ hg status -S ..
162 162 M ../foo/bar/z.txt
163 163 M ../foo/y.txt
164 164 ? a.txt
165 165
166 166 XXX: filtering lfilesrepo.status() in 3.3-rc causes these files to be listed as
167 167 added instead of modified.
168 168 $ hg status -S .. --config extensions.largefiles=
169 169 M ../foo/bar/z.txt
170 170 M ../foo/y.txt
171 171 ? a.txt
172 172
173 173 $ hg diff --nodates -S ..
174 174 diff -r d254738c5f5e foo/y.txt
175 175 --- a/foo/y.txt
176 176 +++ b/foo/y.txt
177 177 @@ -1,2 +1,3 @@
178 178 y1
179 179 y2
180 180 +y3
181 181 diff -r 9647f22de499 foo/bar/z.txt
182 182 --- a/foo/bar/z.txt
183 183 +++ b/foo/bar/z.txt
184 184 @@ -1,2 +1,3 @@
185 185 z1
186 186 z2
187 187 +z3
188 188 $ cd ..
189 189
190 190 Cleanup and final commit:
191 191
192 192 $ rm -r dir
193 193 $ hg commit --subrepos -m 2-3-2
194 194 committing subrepository foo
195 195 committing subrepository foo/bar
196 196
197 197 Test explicit path commands within subrepos: add/forget
198 198 $ echo z1 > foo/bar/z2.txt
199 199 $ hg status -S
200 200 ? foo/bar/z2.txt
201 201 $ hg add foo/bar/z2.txt
202 202 $ hg status -S
203 203 A foo/bar/z2.txt
204 204 $ hg forget foo/bar/z2.txt
205 205 $ hg status -S
206 206 ? foo/bar/z2.txt
207 207 $ hg forget foo/bar/z2.txt
208 208 not removing foo/bar/z2.txt: file is already untracked
209 209 [1]
210 210 $ hg status -S
211 211 ? foo/bar/z2.txt
212 212 $ rm foo/bar/z2.txt
213 213
214 214 Log with the relationships between repo and its subrepo:
215 215
216 216 $ hg log --template '{rev}:{node|short} {desc}\n'
217 217 2:1326fa26d0c0 2-3-2
218 218 1:4b3c9ff4f66b 1-2-1
219 219 0:23376cbba0d8 0-0-0
220 220
221 221 $ hg -R foo log --template '{rev}:{node|short} {desc}\n'
222 222 3:65903cebad86 2-3-2
223 223 2:d254738c5f5e 0-2-1
224 224 1:8629ce7dcc39 0-1-0
225 225 0:af048e97ade2 0-0-0
226 226
227 227 $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n'
228 228 2:31ecbdafd357 2-3-2
229 229 1:9647f22de499 0-1-1
230 230 0:4904098473f9 0-0-0
231 231
232 232 Status between revisions:
233 233
234 234 $ hg status -S
235 235 $ hg status -S --rev 0:1
236 236 M .hgsubstate
237 237 M foo/.hgsubstate
238 238 M foo/bar/z.txt
239 239 M foo/y.txt
240 240 $ hg diff --nodates -S -I '**/?.txt' --rev 0:1
241 241 diff -r af048e97ade2 -r d254738c5f5e foo/y.txt
242 242 --- a/foo/y.txt
243 243 +++ b/foo/y.txt
244 244 @@ -1,1 +1,2 @@
245 245 y1
246 246 +y2
247 247 diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt
248 248 --- a/foo/bar/z.txt
249 249 +++ b/foo/bar/z.txt
250 250 @@ -1,1 +1,2 @@
251 251 z1
252 252 +z2
253 253
254 254 #if serve
255 255 $ cd ..
256 256 $ hg serve -R repo --debug -S -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
257 257 adding = $TESTTMP/repo
258 258 adding foo = $TESTTMP/repo/foo
259 259 adding foo/bar = $TESTTMP/repo/foo/bar
260 260 listening at http://*:$HGPORT/ (bound to *:$HGPORT) (glob) (?)
261 261 adding = $TESTTMP/repo (?)
262 262 adding foo = $TESTTMP/repo/foo (?)
263 263 adding foo/bar = $TESTTMP/repo/foo/bar (?)
264 264 $ cat hg1.pid >> $DAEMON_PIDS
265 265
266 266 $ hg clone http://localhost:$HGPORT clone --config progress.disable=True
267 267 requesting all changes
268 268 adding changesets
269 269 adding manifests
270 270 adding file changes
271 271 added 3 changesets with 5 changes to 3 files
272 272 new changesets 23376cbba0d8:1326fa26d0c0
273 273 updating to branch default
274 274 cloning subrepo foo from http://localhost:$HGPORT/foo
275 275 requesting all changes
276 276 adding changesets
277 277 adding manifests
278 278 adding file changes
279 279 added 4 changesets with 7 changes to 3 files
280 280 new changesets af048e97ade2:65903cebad86
281 281 cloning subrepo foo/bar from http://localhost:$HGPORT/foo/bar
282 282 requesting all changes
283 283 adding changesets
284 284 adding manifests
285 285 adding file changes
286 286 added 3 changesets with 3 changes to 1 files
287 287 new changesets 4904098473f9:31ecbdafd357
288 288 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 289
290 290 $ cat clone/foo/bar/z.txt
291 291 z1
292 292 z2
293 293 z3
294 294
295 295 Clone pooling from a remote URL will share the top level repo and the subrepos,
296 296 even if they are referenced by remote URL.
297 297
298 298 $ hg --config extensions.share= --config share.pool=$TESTTMP/pool \
299 299 > clone http://localhost:$HGPORT shared
300 300 (sharing from new pooled repository 23376cbba0d87c15906bb3652584927c140907bf)
301 301 requesting all changes
302 302 adding changesets
303 303 adding manifests
304 304 adding file changes
305 305 added 3 changesets with 5 changes to 3 files
306 306 new changesets 23376cbba0d8:1326fa26d0c0
307 307 searching for changes
308 308 no changes found
309 309 updating working directory
310 310 cloning subrepo foo from http://localhost:$HGPORT/foo
311 311 (sharing from new pooled repository af048e97ade2e236f754f05d07013e586af0f8bf)
312 312 requesting all changes
313 313 adding changesets
314 314 adding manifests
315 315 adding file changes
316 316 added 4 changesets with 7 changes to 3 files
317 317 new changesets af048e97ade2:65903cebad86
318 318 searching for changes
319 319 no changes found
320 320 cloning subrepo foo/bar from http://localhost:$HGPORT/foo/bar
321 321 (sharing from new pooled repository 4904098473f96c900fec436dad267edd4da59fad)
322 322 requesting all changes
323 323 adding changesets
324 324 adding manifests
325 325 adding file changes
326 326 added 3 changesets with 3 changes to 1 files
327 327 new changesets 4904098473f9:31ecbdafd357
328 328 searching for changes
329 329 no changes found
330 330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 331
332 332 $ cat access.log
333 333 * "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
334 334 * "GET /?cmd=batch HTTP/1.1" 200 - * (glob)
335 335 * "GET /?cmd=getbundle HTTP/1.1" 200 - * (glob)
336 336 * "GET /foo?cmd=capabilities HTTP/1.1" 200 - (glob)
337 337 * "GET /foo?cmd=batch HTTP/1.1" 200 - * (glob)
338 338 * "GET /foo?cmd=getbundle HTTP/1.1" 200 - * (glob)
339 339 * "GET /foo/bar?cmd=capabilities HTTP/1.1" 200 - (glob)
340 340 * "GET /foo/bar?cmd=batch HTTP/1.1" 200 - * (glob)
341 341 * "GET /foo/bar?cmd=getbundle HTTP/1.1" 200 - * (glob)
342 342 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
343 343 $LOCALIP - - [$LOGDATE$] "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=0 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
344 344 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
345 345 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
346 346 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=1326fa26d0c00d2146c63b56bb6a45149d7325ac&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
347 347 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D1326fa26d0c00d2146c63b56bb6a45149d7325ac x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
348 348 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=1326fa26d0c00d2146c63b56bb6a45149d7325ac&heads=1326fa26d0c00d2146c63b56bb6a45149d7325ac&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
349 349 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=capabilities HTTP/1.1" 200 - (glob)
350 350 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=0 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
351 351 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=capabilities HTTP/1.1" 200 - (glob)
352 352 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
353 353 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=65903cebad86f1a84bd4f1134f62fa7dcb7a1c98&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
354 354 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D65903cebad86f1a84bd4f1134f62fa7dcb7a1c98 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
355 355 $LOCALIP - - [$LOGDATE$] "GET /foo?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=65903cebad86f1a84bd4f1134f62fa7dcb7a1c98&heads=65903cebad86f1a84bd4f1134f62fa7dcb7a1c98&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
356 356 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=capabilities HTTP/1.1" 200 - (glob)
357 357 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=0 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
358 358 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=capabilities HTTP/1.1" 200 - (glob)
359 359 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
360 360 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=31ecbdafd357f54b281c9bd1d681bb90de219e22&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
361 361 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D31ecbdafd357f54b281c9bd1d681bb90de219e22 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
362 362 $LOCALIP - - [$LOGDATE$] "GET /foo/bar?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=31ecbdafd357f54b281c9bd1d681bb90de219e22&heads=31ecbdafd357f54b281c9bd1d681bb90de219e22&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ (glob)
363 363
364 364 $ killdaemons.py
365 365 $ rm hg1.pid error.log access.log
366 366 $ cd repo
367 367 #endif
368 368
369 369 Enable progress extension for archive tests:
370 370
371 371 $ cp $HGRCPATH $HGRCPATH.no-progress
372 372 $ cat >> $HGRCPATH <<EOF
373 373 > [progress]
374 374 > disable=False
375 375 > assume-tty = 1
376 376 > delay = 0
377 377 > # set changedelay really large so we don't see nested topics
378 378 > changedelay = 30000
379 379 > format = topic bar number
380 380 > refresh = 0
381 381 > width = 60
382 382 > EOF
383 383
384 384 Test archiving to a directory tree (the doubled lines in the output
385 385 only show up in the test output, not in real usage):
386 386
387 387 $ hg archive --subrepos ../archive
388 388 \r (no-eol) (esc)
389 389 archiving [ ] 0/3\r (no-eol) (esc)
390 390 archiving [=============> ] 1/3\r (no-eol) (esc)
391 391 archiving [===========================> ] 2/3\r (no-eol) (esc)
392 392 archiving [==========================================>] 3/3\r (no-eol) (esc)
393 393 \r (no-eol) (esc)
394 394 \r (no-eol) (esc)
395 395 archiving (foo) [ ] 0/3\r (no-eol) (esc)
396 396 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
397 397 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
398 398 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
399 399 \r (no-eol) (esc)
400 400 \r (no-eol) (esc)
401 401 archiving (foo/bar) [ ] 0/1\r (no-eol) (esc)
402 402 archiving (foo/bar) [================================>] 1/1\r (no-eol) (esc)
403 403 \r (no-eol) (esc)
404 404 $ find ../archive | sort
405 405 ../archive
406 406 ../archive/.hg_archival.txt
407 407 ../archive/.hgsub
408 408 ../archive/.hgsubstate
409 409 ../archive/foo
410 410 ../archive/foo/.hgsub
411 411 ../archive/foo/.hgsubstate
412 412 ../archive/foo/bar
413 413 ../archive/foo/bar/z.txt
414 414 ../archive/foo/y.txt
415 415 ../archive/x.txt
416 416
417 417 Test archiving to zip file (unzip output is unstable):
418 418
419 419 $ hg archive --subrepos --prefix '.' ../archive.zip
420 420 \r (no-eol) (esc)
421 421 archiving [ ] 0/3\r (no-eol) (esc)
422 422 archiving [=============> ] 1/3\r (no-eol) (esc)
423 423 archiving [===========================> ] 2/3\r (no-eol) (esc)
424 424 archiving [==========================================>] 3/3\r (no-eol) (esc)
425 425 \r (no-eol) (esc)
426 426 \r (no-eol) (esc)
427 427 archiving (foo) [ ] 0/3\r (no-eol) (esc)
428 428 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
429 429 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
430 430 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
431 431 \r (no-eol) (esc)
432 432 \r (no-eol) (esc)
433 433 archiving (foo/bar) [ ] 0/1\r (no-eol) (esc)
434 434 archiving (foo/bar) [================================>] 1/1\r (no-eol) (esc)
435 435 \r (no-eol) (esc)
436 436
437 437 (unzip date formating is unstable, we do not care about it and glob it out)
438 438
439 439 $ unzip -l ../archive.zip | grep -v -- ----- | egrep -v files$
440 440 Archive: ../archive.zip
441 441 Length [ ]* Date [ ]* Time [ ]* Name (re)
442 442 172 [0-9:\- ]* .hg_archival.txt (re)
443 443 10 [0-9:\- ]* .hgsub (re)
444 444 45 [0-9:\- ]* .hgsubstate (re)
445 445 3 [0-9:\- ]* x.txt (re)
446 446 10 [0-9:\- ]* foo/.hgsub (re)
447 447 45 [0-9:\- ]* foo/.hgsubstate (re)
448 448 9 [0-9:\- ]* foo/y.txt (re)
449 449 9 [0-9:\- ]* foo/bar/z.txt (re)
450 450
451 451 Test archiving a revision that references a subrepo that is not yet
452 452 cloned:
453 453
454 454 #if hardlink
455 455 $ hg clone -U . ../empty
456 456 \r (no-eol) (esc)
457 457 linking [ <=> ] 1\r (no-eol) (esc)
458 458 linking [ <=> ] 2\r (no-eol) (esc)
459 459 linking [ <=> ] 3\r (no-eol) (esc)
460 460 linking [ <=> ] 4\r (no-eol) (esc)
461 461 linking [ <=> ] 5\r (no-eol) (esc)
462 462 linking [ <=> ] 6\r (no-eol) (esc)
463 463 linking [ <=> ] 7\r (no-eol) (esc)
464 464 linking [ <=> ] 8\r (no-eol) (esc)
465 465 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
466 466 linking [ <=> ] 10\r (no-eol) (esc) (reposimplestore !)
467 467 linking [ <=> ] 11\r (no-eol) (esc) (reposimplestore !)
468 468 linking [ <=> ] 12\r (no-eol) (esc) (reposimplestore !)
469 linking [ <=> ] 13\r (no-eol) (esc) (reposimplestore !)
470 469 \r (no-eol) (esc)
471 470 #else
472 471 $ hg clone -U . ../empty
473 472 \r (no-eol) (esc)
474 473 linking [ <=> ] 1 (no-eol)
475 474 #endif
476 475
477 476 $ cd ../empty
478 477 #if hardlink
479 478 $ hg archive --subrepos -r tip --prefix './' ../archive.tar.gz
480 479 \r (no-eol) (esc)
481 480 archiving [ ] 0/3\r (no-eol) (esc)
482 481 archiving [=============> ] 1/3\r (no-eol) (esc)
483 482 archiving [===========================> ] 2/3\r (no-eol) (esc)
484 483 archiving [==========================================>] 3/3\r (no-eol) (esc)
485 484 \r (no-eol) (esc)
486 485 \r (no-eol) (esc)
487 486 linking [ <=> ] 1\r (no-eol) (esc)
488 487 linking [ <=> ] 2\r (no-eol) (esc)
489 488 linking [ <=> ] 3\r (no-eol) (esc)
490 489 linking [ <=> ] 4\r (no-eol) (esc)
491 490 linking [ <=> ] 5\r (no-eol) (esc)
492 491 linking [ <=> ] 6\r (no-eol) (esc)
493 492 linking [ <=> ] 7\r (no-eol) (esc)
494 493 linking [ <=> ] 8\r (no-eol) (esc)
495 494 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
496 495 linking [ <=> ] 10\r (no-eol) (esc) (reposimplestore !)
497 496 linking [ <=> ] 11\r (no-eol) (esc) (reposimplestore !)
498 497 linking [ <=> ] 12\r (no-eol) (esc) (reposimplestore !)
499 498 linking [ <=> ] 13\r (no-eol) (esc) (reposimplestore !)
500 499 linking [ <=> ] 14\r (no-eol) (esc) (reposimplestore !)
501 linking [ <=> ] 15\r (no-eol) (esc) (reposimplestore !)
502 500 \r (no-eol) (esc)
503 501 \r (no-eol) (esc)
504 502 archiving (foo) [ ] 0/3\r (no-eol) (esc)
505 503 archiving (foo) [===========> ] 1/3\r (no-eol) (esc)
506 504 archiving (foo) [=======================> ] 2/3\r (no-eol) (esc)
507 505 archiving (foo) [====================================>] 3/3\r (no-eol) (esc)
508 506 \r (no-eol) (esc)
509 507 \r (no-eol) (esc)
510 508 linking [ <=> ] 1\r (no-eol) (esc)
511 509 linking [ <=> ] 2\r (no-eol) (esc)
512 510 linking [ <=> ] 3\r (no-eol) (esc)
513 511 linking [ <=> ] 4\r (no-eol) (esc)
514 512 linking [ <=> ] 5\r (no-eol) (esc)
515 513 linking [ <=> ] 6\r (no-eol) (esc)
516 514 linking [ <=> ] 7\r (no-eol) (esc) (reposimplestore !)
517 515 linking [ <=> ] 8\r (no-eol) (esc) (reposimplestore !)
518 linking [ <=> ] 9\r (no-eol) (esc) (reposimplestore !)
519 516 \r (no-eol) (esc)
520 517 \r (no-eol) (esc)
521 518 archiving (foo/bar) [ ] 0/1\r (no-eol) (esc)
522 519 archiving (foo/bar) [================================>] 1/1\r (no-eol) (esc)
523 520 \r (no-eol) (esc)
524 521 cloning subrepo foo from $TESTTMP/repo/foo
525 522 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
526 523 #else
527 524 Note there's a slight output glitch on non-hardlink systems: the last
528 525 "linking" progress topic never gets closed, leading to slight output corruption on that platform.
529 526 $ hg archive --subrepos -r tip --prefix './' ../archive.tar.gz
530 527 \r (no-eol) (esc)
531 528 archiving [ ] 0/3\r (no-eol) (esc)
532 529 archiving [=============> ] 1/3\r (no-eol) (esc)
533 530 archiving [===========================> ] 2/3\r (no-eol) (esc)
534 531 archiving [==========================================>] 3/3\r (no-eol) (esc)
535 532 \r (no-eol) (esc)
536 533 \r (no-eol) (esc)
537 534 linking [ <=> ] 1\r (no-eol) (esc)
538 535 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
539 536 #endif
540 537
541 538 Archive + subrepos uses '/' for all component separators
542 539
543 540 $ tar -tzf ../archive.tar.gz | sort
544 541 .hg_archival.txt
545 542 .hgsub
546 543 .hgsubstate
547 544 foo/.hgsub
548 545 foo/.hgsubstate
549 546 foo/bar/z.txt
550 547 foo/y.txt
551 548 x.txt
552 549
553 550 The newly cloned subrepos contain no working copy:
554 551
555 552 $ hg -R foo summary
556 553 parent: -1:000000000000 (no revision checked out)
557 554 branch: default
558 555 commit: (clean)
559 556 update: 4 new changesets (update)
560 557
561 558 Sharing a local repo without the locally referenced subrepo (i.e. it was never
562 559 updated from null), fails the same as a clone operation.
563 560
564 561 $ hg --config progress.disable=True clone -U ../empty ../empty2
565 562
566 563 $ hg --config extensions.share= --config progress.disable=True \
567 564 > share ../empty2 ../empty_share
568 565 updating working directory
569 566 abort: repository $TESTTMP/empty2/foo not found!
570 567 [255]
571 568
572 569 $ hg --config progress.disable=True clone ../empty2 ../empty_clone
573 570 updating to branch default
574 571 abort: repository $TESTTMP/empty2/foo not found!
575 572 [255]
576 573
577 574 Disable progress extension and cleanup:
578 575
579 576 $ mv $HGRCPATH.no-progress $HGRCPATH
580 577
581 578 Test archiving when there is a directory in the way for a subrepo
582 579 created by archive:
583 580
584 581 $ hg clone -U . ../almost-empty
585 582 $ cd ../almost-empty
586 583 $ mkdir foo
587 584 $ echo f > foo/f
588 585 $ hg archive --subrepos -r tip archive
589 586 cloning subrepo foo from $TESTTMP/empty/foo
590 587 abort: destination '$TESTTMP/almost-empty/foo' is not empty (in subrepository "foo")
591 588 [255]
592 589
593 590 Clone and test outgoing:
594 591
595 592 $ cd ..
596 593 $ hg clone repo repo2
597 594 updating to branch default
598 595 cloning subrepo foo from $TESTTMP/repo/foo
599 596 cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
600 597 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 598 $ cd repo2
602 599 $ hg outgoing -S
603 600 comparing with $TESTTMP/repo
604 601 searching for changes
605 602 no changes found
606 603 comparing with $TESTTMP/repo/foo
607 604 searching for changes
608 605 no changes found
609 606 comparing with $TESTTMP/repo/foo/bar
610 607 searching for changes
611 608 no changes found
612 609 [1]
613 610
614 611 Make nested change:
615 612
616 613 $ echo y4 >> foo/y.txt
617 614 $ hg diff --nodates -S
618 615 diff -r 65903cebad86 foo/y.txt
619 616 --- a/foo/y.txt
620 617 +++ b/foo/y.txt
621 618 @@ -1,3 +1,4 @@
622 619 y1
623 620 y2
624 621 y3
625 622 +y4
626 623 $ hg commit --subrepos -m 3-4-2
627 624 committing subrepository foo
628 625 $ hg outgoing -S
629 626 comparing with $TESTTMP/repo
630 627 searching for changes
631 628 changeset: 3:2655b8ecc4ee
632 629 tag: tip
633 630 user: test
634 631 date: Thu Jan 01 00:00:00 1970 +0000
635 632 summary: 3-4-2
636 633
637 634 comparing with $TESTTMP/repo/foo
638 635 searching for changes
639 636 changeset: 4:e96193d6cb36
640 637 tag: tip
641 638 user: test
642 639 date: Thu Jan 01 00:00:00 1970 +0000
643 640 summary: 3-4-2
644 641
645 642 comparing with $TESTTMP/repo/foo/bar
646 643 searching for changes
647 644 no changes found
648 645
649 646
650 647 Switch to original repo and setup default path:
651 648
652 649 $ cd ../repo
653 650 $ echo '[paths]' >> .hg/hgrc
654 651 $ echo 'default = ../repo2' >> .hg/hgrc
655 652
656 653 Test incoming:
657 654
658 655 $ hg incoming -S
659 656 comparing with $TESTTMP/repo2
660 657 searching for changes
661 658 changeset: 3:2655b8ecc4ee
662 659 tag: tip
663 660 user: test
664 661 date: Thu Jan 01 00:00:00 1970 +0000
665 662 summary: 3-4-2
666 663
667 664 comparing with $TESTTMP/repo2/foo
668 665 searching for changes
669 666 changeset: 4:e96193d6cb36
670 667 tag: tip
671 668 user: test
672 669 date: Thu Jan 01 00:00:00 1970 +0000
673 670 summary: 3-4-2
674 671
675 672 comparing with $TESTTMP/repo2/foo/bar
676 673 searching for changes
677 674 no changes found
678 675
679 676 $ hg incoming -S --bundle incoming.hg
680 677 abort: cannot combine --bundle and --subrepos
681 678 [255]
682 679
683 680 Test missing subrepo:
684 681
685 682 $ rm -r foo
686 683 $ hg status -S
687 684 warning: error "unknown revision '65903cebad86f1a84bd4f1134f62fa7dcb7a1c98'" in subrepository "foo"
688 685
689 686 Issue2619: IndexError: list index out of range on hg add with subrepos
690 687 The subrepo must sorts after the explicit filename.
691 688
692 689 $ cd ..
693 690 $ hg init test
694 691 $ cd test
695 692 $ hg init x
696 693 $ echo abc > abc.txt
697 694 $ hg ci -Am "abc"
698 695 adding abc.txt
699 696 $ echo "x = x" >> .hgsub
700 697 $ hg add .hgsub
701 698 $ touch a x/a
702 699 $ hg add a x/a
703 700
704 701 $ hg ci -Sm "added x"
705 702 committing subrepository x
706 703 $ echo abc > x/a
707 704 $ hg revert --rev '.^' "set:subrepo('glob:x*')"
708 705 abort: subrepository 'x' does not exist in 25ac2c9b3180!
709 706 [255]
710 707
711 708 $ cd ..
@@ -1,876 +1,878 b''
1 1 #require killdaemons
2 2
3 3 $ cat << EOF >> $HGRCPATH
4 4 > [ui]
5 5 > ssh=$PYTHON "$TESTDIR/dummyssh"
6 6 > EOF
7 7
8 8 Set up repo
9 9
10 10 $ hg --config experimental.treemanifest=True init repo
11 11 $ cd repo
12 12
13 13 Requirements get set on init
14 14
15 15 $ grep treemanifest .hg/requires
16 16 treemanifest
17 17
18 18 Without directories, looks like any other repo
19 19
20 20 $ echo 0 > a
21 21 $ echo 0 > b
22 22 $ hg ci -Aqm initial
23 23 $ hg debugdata -m 0
24 24 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
25 25 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
26 26
27 27 Submanifest is stored in separate revlog
28 28
29 29 $ mkdir dir1
30 30 $ echo 1 > dir1/a
31 31 $ echo 1 > dir1/b
32 32 $ echo 1 > e
33 33 $ hg ci -Aqm 'add dir1'
34 34 $ hg debugdata -m 1
35 35 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
36 36 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
37 37 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
38 38 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
39 39 $ hg debugdata --dir dir1 0
40 40 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
41 41 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
42 42
43 43 Can add nested directories
44 44
45 45 $ mkdir dir1/dir1
46 46 $ echo 2 > dir1/dir1/a
47 47 $ echo 2 > dir1/dir1/b
48 48 $ mkdir dir1/dir2
49 49 $ echo 2 > dir1/dir2/a
50 50 $ echo 2 > dir1/dir2/b
51 51 $ hg ci -Aqm 'add dir1/dir1'
52 52 $ hg files -r .
53 53 a
54 54 b
55 55 dir1/a
56 56 dir1/b
57 57 dir1/dir1/a
58 58 dir1/dir1/b
59 59 dir1/dir2/a
60 60 dir1/dir2/b
61 61 e
62 62
63 63 The manifest command works
64 64
65 65 $ hg manifest
66 66 a
67 67 b
68 68 dir1/a
69 69 dir1/b
70 70 dir1/dir1/a
71 71 dir1/dir1/b
72 72 dir1/dir2/a
73 73 dir1/dir2/b
74 74 e
75 75
76 76 Revision is not created for unchanged directory
77 77
78 78 $ mkdir dir2
79 79 $ echo 3 > dir2/a
80 80 $ hg add dir2
81 81 adding dir2/a
82 82 $ hg debugindex --dir dir1 > before
83 83 $ hg ci -qm 'add dir2'
84 84 $ hg debugindex --dir dir1 > after
85 85 $ diff before after
86 86 $ rm before after
87 87
88 88 Removing directory does not create an revlog entry
89 89
90 90 $ hg rm dir1/dir1
91 91 removing dir1/dir1/a
92 92 removing dir1/dir1/b
93 93 $ hg debugindex --dir dir1/dir1 > before
94 94 $ hg ci -qm 'remove dir1/dir1'
95 95 $ hg debugindex --dir dir1/dir1 > after
96 96 $ diff before after
97 97 $ rm before after
98 98
99 99 Check that hg files (calls treemanifest.walk()) works
100 100 without loading all directory revlogs
101 101
102 102 $ hg co 'desc("add dir2")'
103 103 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 104 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
105 105 $ hg files -r . dir1
106 106 dir1/a
107 107 dir1/b
108 108 dir1/dir1/a
109 109 dir1/dir1/b
110 110 dir1/dir2/a
111 111 dir1/dir2/b
112 112
113 113 Check that status between revisions works (calls treemanifest.matches())
114 114 without loading all directory revlogs
115 115
116 116 $ hg status --rev 'desc("add dir1")' --rev . dir1
117 117 A dir1/dir1/a
118 118 A dir1/dir1/b
119 119 A dir1/dir2/a
120 120 A dir1/dir2/b
121 121 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
122 122
123 123 Merge creates 2-parent revision of directory revlog
124 124
125 125 $ echo 5 > dir1/a
126 126 $ hg ci -Aqm 'modify dir1/a'
127 127 $ hg co '.^'
128 128 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 129 $ echo 6 > dir1/b
130 130 $ hg ci -Aqm 'modify dir1/b'
131 131 $ hg merge 'desc("modify dir1/a")'
132 132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 133 (branch merge, don't forget to commit)
134 134 $ hg ci -m 'conflict-free merge involving dir1/'
135 135 $ cat dir1/a
136 136 5
137 137 $ cat dir1/b
138 138 6
139 139 $ hg debugindex --dir dir1
140 140 rev linkrev nodeid p1 p2
141 141 0 1 8b3ffd73f901 000000000000 000000000000
142 142 1 2 68e9d057c5a8 8b3ffd73f901 000000000000
143 143 2 4 4698198d2624 68e9d057c5a8 000000000000
144 144 3 5 44844058ccce 68e9d057c5a8 000000000000
145 145 4 6 bf3d9b744927 68e9d057c5a8 000000000000
146 146 5 7 dde7c0af2a03 bf3d9b744927 44844058ccce
147 147
148 148 Merge keeping directory from parent 1 does not create revlog entry. (Note that
149 149 dir1's manifest does change, but only because dir1/a's filelog changes.)
150 150
151 151 $ hg co 'desc("add dir2")'
152 152 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 153 $ echo 8 > dir2/a
154 154 $ hg ci -m 'modify dir2/a'
155 155 created new head
156 156
157 157 $ hg debugindex --dir dir2 > before
158 158 $ hg merge 'desc("modify dir1/a")'
159 159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 (branch merge, don't forget to commit)
161 161 $ hg revert -r 'desc("modify dir2/a")' .
162 162 reverting dir1/a
163 163 $ hg ci -m 'merge, keeping parent 1'
164 164 $ hg debugindex --dir dir2 > after
165 165 $ diff before after
166 166 $ rm before after
167 167
168 168 Merge keeping directory from parent 2 does not create revlog entry. (Note that
169 169 dir2's manifest does change, but only because dir2/a's filelog changes.)
170 170
171 171 $ hg co 'desc("modify dir2/a")'
172 172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 173 $ hg debugindex --dir dir1 > before
174 174 $ hg merge 'desc("modify dir1/a")'
175 175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 176 (branch merge, don't forget to commit)
177 177 $ hg revert -r 'desc("modify dir1/a")' .
178 178 reverting dir2/a
179 179 $ hg ci -m 'merge, keeping parent 2'
180 180 created new head
181 181 $ hg debugindex --dir dir1 > after
182 182 $ diff before after
183 183 $ rm before after
184 184
185 185 Create flat source repo for tests with mixed flat/tree manifests
186 186
187 187 $ cd ..
188 188 $ hg init repo-flat
189 189 $ cd repo-flat
190 190
191 191 Create a few commits with flat manifest
192 192
193 193 $ echo 0 > a
194 194 $ echo 0 > b
195 195 $ echo 0 > e
196 196 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
197 197 > do
198 198 > mkdir $d
199 199 > echo 0 > $d/a
200 200 > echo 0 > $d/b
201 201 > done
202 202 $ hg ci -Aqm initial
203 203
204 204 $ echo 1 > a
205 205 $ echo 1 > dir1/a
206 206 $ echo 1 > dir1/dir1/a
207 207 $ hg ci -Aqm 'modify on branch 1'
208 208
209 209 $ hg co 0
210 210 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 211 $ echo 2 > b
212 212 $ echo 2 > dir1/b
213 213 $ echo 2 > dir1/dir1/b
214 214 $ hg ci -Aqm 'modify on branch 2'
215 215
216 216 $ hg merge 1
217 217 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 218 (branch merge, don't forget to commit)
219 219 $ hg ci -m 'merge of flat manifests to new flat manifest'
220 220
221 221 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
222 222 $ cat hg.pid >> $DAEMON_PIDS
223 223
224 224 Create clone with tree manifests enabled
225 225
226 226 $ cd ..
227 227 $ hg clone --config experimental.treemanifest=1 \
228 228 > http://localhost:$HGPORT repo-mixed -r 1
229 229 adding changesets
230 230 adding manifests
231 231 adding file changes
232 232 added 2 changesets with 14 changes to 11 files
233 233 new changesets 5b02a3e8db7e:581ef6037d8b
234 234 updating to branch default
235 235 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 236 $ cd repo-mixed
237 237 $ test -d .hg/store/meta
238 238 [1]
239 239 $ grep treemanifest .hg/requires
240 240 treemanifest
241 241
242 242 Should be possible to push updates from flat to tree manifest repo
243 243
244 244 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
245 245 pushing to ssh://user@dummy/repo-mixed
246 246 searching for changes
247 247 remote: adding changesets
248 248 remote: adding manifests
249 249 remote: adding file changes
250 250 remote: added 2 changesets with 3 changes to 3 files
251 251
252 252 Commit should store revlog per directory
253 253
254 254 $ hg co 1
255 255 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 256 $ echo 3 > a
257 257 $ echo 3 > dir1/a
258 258 $ echo 3 > dir1/dir1/a
259 259 $ hg ci -m 'first tree'
260 260 created new head
261 261 $ find .hg/store/meta | sort
262 262 .hg/store/meta
263 263 .hg/store/meta/dir1
264 264 .hg/store/meta/dir1/00manifest.i
265 265 .hg/store/meta/dir1/dir1
266 266 .hg/store/meta/dir1/dir1/00manifest.i
267 267 .hg/store/meta/dir1/dir2
268 268 .hg/store/meta/dir1/dir2/00manifest.i
269 269 .hg/store/meta/dir2
270 270 .hg/store/meta/dir2/00manifest.i
271 271
272 272 Merge of two trees
273 273
274 274 $ hg co 2
275 275 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 276 $ hg merge 1
277 277 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 278 (branch merge, don't forget to commit)
279 279 $ hg ci -m 'merge of flat manifests to new tree manifest'
280 280 created new head
281 281 $ hg diff -r 3
282 282
283 283 Parent of tree root manifest should be flat manifest, and two for merge
284 284
285 285 $ hg debugindex -m
286 286 rev linkrev nodeid p1 p2
287 287 0 0 40536115ed9e 000000000000 000000000000
288 288 1 1 f3376063c255 40536115ed9e 000000000000
289 289 2 2 5d9b9da231a2 40536115ed9e 000000000000
290 290 3 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
291 291 4 4 51e32a8c60ee f3376063c255 000000000000
292 292 5 5 cc5baa78b230 5d9b9da231a2 f3376063c255
293 293
294 294
295 295 Status across flat/tree boundary should work
296 296
297 297 $ hg status --rev '.^' --rev .
298 298 M a
299 299 M dir1/a
300 300 M dir1/dir1/a
301 301
302 302
303 303 Turning off treemanifest config has no effect
304 304
305 305 $ hg debugindex --dir dir1
306 306 rev linkrev nodeid p1 p2
307 307 0 4 064927a0648a 000000000000 000000000000
308 308 1 5 25ecb8cb8618 000000000000 000000000000
309 309 $ echo 2 > dir1/a
310 310 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
311 311 $ hg debugindex --dir dir1
312 312 rev linkrev nodeid p1 p2
313 313 0 4 064927a0648a 000000000000 000000000000
314 314 1 5 25ecb8cb8618 000000000000 000000000000
315 315 2 6 5b16163a30c6 25ecb8cb8618 000000000000
316 316
317 317 Stripping and recovering changes should work
318 318
319 319 $ hg st --change tip
320 320 M dir1/a
321 321 $ hg --config extensions.strip= strip tip
322 322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 323 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
324 324 $ hg debugindex --dir dir1
325 325 rev linkrev nodeid p1 p2
326 326 0 4 064927a0648a 000000000000 000000000000
327 327 1 5 25ecb8cb8618 000000000000 000000000000
328 328
329 329 #if repobundlerepo
330 330 $ hg incoming .hg/strip-backup/*
331 331 comparing with .hg/strip-backup/*-backup.hg (glob)
332 332 searching for changes
333 333 changeset: 6:51cfd7b1e13b
334 334 tag: tip
335 335 user: test
336 336 date: Thu Jan 01 00:00:00 1970 +0000
337 337 summary: modify dir1/a
338 338
339 339 #endif
340 340
341 341 $ hg unbundle .hg/strip-backup/*
342 342 adding changesets
343 343 adding manifests
344 344 adding file changes
345 345 added 1 changesets with 1 changes to 1 files
346 346 new changesets 51cfd7b1e13b
347 347 (run 'hg update' to get a working copy)
348 348 $ hg --config extensions.strip= strip tip
349 349 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/*-backup.hg (glob)
350 350 $ hg unbundle -q .hg/strip-backup/*
351 351 $ hg debugindex --dir dir1
352 352 rev linkrev nodeid p1 p2
353 353 0 4 064927a0648a 000000000000 000000000000
354 354 1 5 25ecb8cb8618 000000000000 000000000000
355 355 2 6 5b16163a30c6 25ecb8cb8618 000000000000
356 356 $ hg st --change tip
357 357 M dir1/a
358 358
359 359 Shelving and unshelving should work
360 360
361 361 $ echo foo >> dir1/a
362 362 $ hg --config extensions.shelve= shelve
363 363 shelved as default
364 364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 365 $ hg --config extensions.shelve= unshelve
366 366 unshelving change 'default'
367 367 $ hg diff --nodates
368 368 diff -r 708a273da119 dir1/a
369 369 --- a/dir1/a
370 370 +++ b/dir1/a
371 371 @@ -1,1 +1,2 @@
372 372 1
373 373 +foo
374 374
375 375 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
376 376
377 377 $ cd ..
378 378 $ hg init empty-repo
379 379 $ cat << EOF >> empty-repo/.hg/hgrc
380 380 > [experimental]
381 381 > changegroup3=yes
382 382 > EOF
383 383 $ grep treemanifest empty-repo/.hg/requires
384 384 [1]
385 385 $ hg push -R repo -r 0 empty-repo
386 386 pushing to empty-repo
387 387 searching for changes
388 388 adding changesets
389 389 adding manifests
390 390 adding file changes
391 391 added 1 changesets with 2 changes to 2 files
392 392 $ grep treemanifest empty-repo/.hg/requires
393 393 treemanifest
394 394
395 395 Pushing to an empty repo works
396 396
397 397 $ hg --config experimental.treemanifest=1 init clone
398 398 $ grep treemanifest clone/.hg/requires
399 399 treemanifest
400 400 $ hg push -R repo clone
401 401 pushing to clone
402 402 searching for changes
403 403 adding changesets
404 404 adding manifests
405 405 adding file changes
406 406 added 11 changesets with 15 changes to 10 files (+3 heads)
407 407 $ grep treemanifest clone/.hg/requires
408 408 treemanifest
409 409 $ hg -R clone verify
410 410 checking changesets
411 411 checking manifests
412 412 checking directory manifests
413 413 crosschecking files in changesets and manifests
414 414 checking files
415 415 10 files, 11 changesets, 15 total revisions
416 416
417 417 Create deeper repo with tree manifests.
418 418
419 419 $ hg --config experimental.treemanifest=True init deeprepo
420 420 $ cd deeprepo
421 421
422 422 $ mkdir .A
423 423 $ mkdir b
424 424 $ mkdir b/bar
425 425 $ mkdir b/bar/orange
426 426 $ mkdir b/bar/orange/fly
427 427 $ mkdir b/foo
428 428 $ mkdir b/foo/apple
429 429 $ mkdir b/foo/apple/bees
430 430
431 431 $ touch .A/one.txt
432 432 $ touch .A/two.txt
433 433 $ touch b/bar/fruits.txt
434 434 $ touch b/bar/orange/fly/gnat.py
435 435 $ touch b/bar/orange/fly/housefly.txt
436 436 $ touch b/foo/apple/bees/flower.py
437 437 $ touch c.txt
438 438 $ touch d.py
439 439
440 440 $ hg ci -Aqm 'initial'
441 441
442 442 $ echo >> .A/one.txt
443 443 $ echo >> .A/two.txt
444 444 $ echo >> b/bar/fruits.txt
445 445 $ echo >> b/bar/orange/fly/gnat.py
446 446 $ echo >> b/bar/orange/fly/housefly.txt
447 447 $ echo >> b/foo/apple/bees/flower.py
448 448 $ echo >> c.txt
449 449 $ echo >> d.py
450 450 $ hg ci -Aqm 'second'
451 451
452 452 We'll see that visitdir works by removing some treemanifest revlogs and running
453 453 the files command with various parameters.
454 454
455 455 Test files from the root.
456 456
457 457 $ hg files -r .
458 458 .A/one.txt
459 459 .A/two.txt
460 460 b/bar/fruits.txt
461 461 b/bar/orange/fly/gnat.py
462 462 b/bar/orange/fly/housefly.txt
463 463 b/foo/apple/bees/flower.py
464 464 c.txt
465 465 d.py
466 466
467 467 Excludes with a glob should not exclude everything from the glob's root
468 468
469 469 $ hg files -r . -X 'b/fo?' b
470 470 b/bar/fruits.txt
471 471 b/bar/orange/fly/gnat.py
472 472 b/bar/orange/fly/housefly.txt
473 473 $ cp -R .hg/store .hg/store-copy
474 474
475 475 Test files for a subdirectory.
476 476
477 477 $ rm -r .hg/store/meta/~2e_a
478 478 $ hg files -r . b
479 479 b/bar/fruits.txt
480 480 b/bar/orange/fly/gnat.py
481 481 b/bar/orange/fly/housefly.txt
482 482 b/foo/apple/bees/flower.py
483 483 $ hg diff -r '.^' -r . --stat b
484 484 b/bar/fruits.txt | 1 +
485 485 b/bar/orange/fly/gnat.py | 1 +
486 486 b/bar/orange/fly/housefly.txt | 1 +
487 487 b/foo/apple/bees/flower.py | 1 +
488 488 4 files changed, 4 insertions(+), 0 deletions(-)
489 489 $ cp -R .hg/store-copy/. .hg/store
490 490
491 491 Test files with just includes and excludes.
492 492
493 493 $ rm -r .hg/store/meta/~2e_a
494 494 $ rm -r .hg/store/meta/b/bar/orange/fly
495 495 $ rm -r .hg/store/meta/b/foo/apple/bees
496 496 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
497 497 b/bar/fruits.txt
498 498 $ hg diff -r '.^' -r . --stat -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
499 499 b/bar/fruits.txt | 1 +
500 500 1 files changed, 1 insertions(+), 0 deletions(-)
501 501 $ cp -R .hg/store-copy/. .hg/store
502 502
503 503 Test files for a subdirectory, excluding a directory within it.
504 504
505 505 $ rm -r .hg/store/meta/~2e_a
506 506 $ rm -r .hg/store/meta/b/foo
507 507 $ hg files -r . -X path:b/foo b
508 508 b/bar/fruits.txt
509 509 b/bar/orange/fly/gnat.py
510 510 b/bar/orange/fly/housefly.txt
511 511 $ hg diff -r '.^' -r . --stat -X path:b/foo b
512 512 b/bar/fruits.txt | 1 +
513 513 b/bar/orange/fly/gnat.py | 1 +
514 514 b/bar/orange/fly/housefly.txt | 1 +
515 515 3 files changed, 3 insertions(+), 0 deletions(-)
516 516 $ cp -R .hg/store-copy/. .hg/store
517 517
518 518 Test files for a sub directory, including only a directory within it, and
519 519 including an unrelated directory.
520 520
521 521 $ rm -r .hg/store/meta/~2e_a
522 522 $ rm -r .hg/store/meta/b/foo
523 523 $ hg files -r . -I path:b/bar/orange -I path:a b
524 524 b/bar/orange/fly/gnat.py
525 525 b/bar/orange/fly/housefly.txt
526 526 $ hg diff -r '.^' -r . --stat -I path:b/bar/orange -I path:a b
527 527 b/bar/orange/fly/gnat.py | 1 +
528 528 b/bar/orange/fly/housefly.txt | 1 +
529 529 2 files changed, 2 insertions(+), 0 deletions(-)
530 530 $ cp -R .hg/store-copy/. .hg/store
531 531
532 532 Test files for a pattern, including a directory, and excluding a directory
533 533 within that.
534 534
535 535 $ rm -r .hg/store/meta/~2e_a
536 536 $ rm -r .hg/store/meta/b/foo
537 537 $ rm -r .hg/store/meta/b/bar/orange
538 538 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
539 539 b/bar/fruits.txt
540 540 $ hg diff -r '.^' -r . --stat glob:**.txt -I path:b/bar -X path:b/bar/orange
541 541 b/bar/fruits.txt | 1 +
542 542 1 files changed, 1 insertions(+), 0 deletions(-)
543 543 $ cp -R .hg/store-copy/. .hg/store
544 544
545 545 Add some more changes to the deep repo
546 546 $ echo narf >> b/bar/fruits.txt
547 547 $ hg ci -m narf
548 548 $ echo troz >> b/bar/orange/fly/gnat.py
549 549 $ hg ci -m troz
550 550
551 551 Verify works
552 552 $ hg verify
553 553 checking changesets
554 554 checking manifests
555 555 checking directory manifests
556 556 crosschecking files in changesets and manifests
557 557 checking files
558 558 8 files, 4 changesets, 18 total revisions
559 559
560 #if repofncache
560 561 Dirlogs are included in fncache
561 562 $ grep meta/.A/00manifest.i .hg/store/fncache
562 563 meta/.A/00manifest.i
563 564
564 565 Rebuilt fncache includes dirlogs
565 566 $ rm .hg/store/fncache
566 567 $ hg debugrebuildfncache
567 568 adding data/.A/one.txt.i
568 569 adding data/.A/two.txt.i
569 570 adding data/b/bar/fruits.txt.i
570 571 adding data/b/bar/orange/fly/gnat.py.i
571 572 adding data/b/bar/orange/fly/housefly.txt.i
572 573 adding data/b/foo/apple/bees/flower.py.i
573 574 adding data/c.txt.i
574 575 adding data/d.py.i
575 576 adding meta/.A/00manifest.i
576 577 adding meta/b/00manifest.i
577 578 adding meta/b/bar/00manifest.i
578 579 adding meta/b/bar/orange/00manifest.i
579 580 adding meta/b/bar/orange/fly/00manifest.i
580 581 adding meta/b/foo/00manifest.i
581 582 adding meta/b/foo/apple/00manifest.i
582 583 adding meta/b/foo/apple/bees/00manifest.i
583 584 16 items added, 0 removed from fncache
585 #endif
584 586
585 587 Finish first server
586 588 $ killdaemons.py
587 589
588 590 Back up the recently added revlogs
589 591 $ cp -R .hg/store .hg/store-newcopy
590 592
591 593 Verify reports missing dirlog
592 594 $ rm .hg/store/meta/b/00manifest.*
593 595 $ hg verify
594 596 checking changesets
595 597 checking manifests
596 598 checking directory manifests
597 599 0: empty or missing b/
598 600 b/@0: parent-directory manifest refers to unknown revision 67688a370455
599 601 b/@1: parent-directory manifest refers to unknown revision f065da70369e
600 602 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
601 603 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
602 604 warning: orphan data file 'meta/b/bar/00manifest.i'
603 605 warning: orphan data file 'meta/b/bar/orange/00manifest.i'
604 606 warning: orphan data file 'meta/b/bar/orange/fly/00manifest.i'
605 607 warning: orphan data file 'meta/b/foo/00manifest.i'
606 608 warning: orphan data file 'meta/b/foo/apple/00manifest.i'
607 609 warning: orphan data file 'meta/b/foo/apple/bees/00manifest.i'
608 610 crosschecking files in changesets and manifests
609 611 b/bar/fruits.txt@0: in changeset but not in manifest
610 612 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
611 613 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
612 614 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
613 615 checking files
614 616 8 files, 4 changesets, 18 total revisions
615 617 6 warnings encountered!
616 618 9 integrity errors encountered!
617 619 (first damaged changeset appears to be 0)
618 620 [1]
619 621 $ cp -R .hg/store-newcopy/. .hg/store
620 622
621 623 Verify reports missing dirlog entry
622 624 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
623 625 $ hg verify
624 626 checking changesets
625 627 checking manifests
626 628 checking directory manifests
627 629 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
628 630 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
629 631 b/bar/@?: rev 2 points to unexpected changeset 2
630 632 b/bar/@?: 44d7e1146e0d not in parent-directory manifest
631 633 b/bar/@?: rev 3 points to unexpected changeset 3
632 634 b/bar/@?: 70b10c6b17b7 not in parent-directory manifest
633 635 b/bar/orange/@?: rev 2 points to unexpected changeset 3
634 636 (expected None)
635 637 b/bar/orange/fly/@?: rev 2 points to unexpected changeset 3
636 638 (expected None)
637 639 crosschecking files in changesets and manifests
638 640 checking files
639 641 8 files, 4 changesets, 18 total revisions
640 642 2 warnings encountered!
641 643 8 integrity errors encountered!
642 644 (first damaged changeset appears to be 2)
643 645 [1]
644 646 $ cp -R .hg/store-newcopy/. .hg/store
645 647
646 648 Test cloning a treemanifest repo over http.
647 649 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
648 650 $ cat hg.pid >> $DAEMON_PIDS
649 651 $ cd ..
650 652 We can clone even with the knob turned off and we'll get a treemanifest repo.
651 653 $ hg clone --config experimental.treemanifest=False \
652 654 > --config experimental.changegroup3=True \
653 655 > http://localhost:$HGPORT deepclone
654 656 requesting all changes
655 657 adding changesets
656 658 adding manifests
657 659 adding file changes
658 660 added 4 changesets with 18 changes to 8 files
659 661 new changesets 775704be6f52:523e5c631710
660 662 updating to branch default
661 663 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 664 No server errors.
663 665 $ cat deeprepo/errors.log
664 666 requires got updated to include treemanifest
665 667 $ cat deepclone/.hg/requires | grep treemanifest
666 668 treemanifest
667 669 Tree manifest revlogs exist.
668 670 $ find deepclone/.hg/store/meta | sort
669 671 deepclone/.hg/store/meta
670 672 deepclone/.hg/store/meta/b
671 673 deepclone/.hg/store/meta/b/00manifest.i
672 674 deepclone/.hg/store/meta/b/bar
673 675 deepclone/.hg/store/meta/b/bar/00manifest.i
674 676 deepclone/.hg/store/meta/b/bar/orange
675 677 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
676 678 deepclone/.hg/store/meta/b/bar/orange/fly
677 679 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
678 680 deepclone/.hg/store/meta/b/foo
679 681 deepclone/.hg/store/meta/b/foo/00manifest.i
680 682 deepclone/.hg/store/meta/b/foo/apple
681 683 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
682 684 deepclone/.hg/store/meta/b/foo/apple/bees
683 685 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
684 686 deepclone/.hg/store/meta/~2e_a
685 687 deepclone/.hg/store/meta/~2e_a/00manifest.i
686 688 Verify passes.
687 689 $ cd deepclone
688 690 $ hg verify
689 691 checking changesets
690 692 checking manifests
691 693 checking directory manifests
692 694 crosschecking files in changesets and manifests
693 695 checking files
694 696 8 files, 4 changesets, 18 total revisions
695 697 $ cd ..
696 698
697 699 Create clones using old repo formats to use in later tests
698 700 $ hg clone --config format.usestore=False \
699 701 > --config experimental.changegroup3=True \
700 702 > http://localhost:$HGPORT deeprepo-basicstore
701 703 requesting all changes
702 704 adding changesets
703 705 adding manifests
704 706 adding file changes
705 707 added 4 changesets with 18 changes to 8 files
706 708 new changesets 775704be6f52:523e5c631710
707 709 updating to branch default
708 710 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
709 711 $ cd deeprepo-basicstore
710 712 $ grep store .hg/requires
711 713 [1]
712 714 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
713 715 $ cat hg.pid >> $DAEMON_PIDS
714 716 $ cd ..
715 717 $ hg clone --config format.usefncache=False \
716 718 > --config experimental.changegroup3=True \
717 719 > http://localhost:$HGPORT deeprepo-encodedstore
718 720 requesting all changes
719 721 adding changesets
720 722 adding manifests
721 723 adding file changes
722 724 added 4 changesets with 18 changes to 8 files
723 725 new changesets 775704be6f52:523e5c631710
724 726 updating to branch default
725 727 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 728 $ cd deeprepo-encodedstore
727 729 $ grep fncache .hg/requires
728 730 [1]
729 731 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
730 732 $ cat hg.pid >> $DAEMON_PIDS
731 733 $ cd ..
732 734
733 735 Local clone with basicstore
734 736 $ hg clone -U deeprepo-basicstore local-clone-basicstore
735 737 $ hg -R local-clone-basicstore verify
736 738 checking changesets
737 739 checking manifests
738 740 checking directory manifests
739 741 crosschecking files in changesets and manifests
740 742 checking files
741 743 8 files, 4 changesets, 18 total revisions
742 744
743 745 Local clone with encodedstore
744 746 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
745 747 $ hg -R local-clone-encodedstore verify
746 748 checking changesets
747 749 checking manifests
748 750 checking directory manifests
749 751 crosschecking files in changesets and manifests
750 752 checking files
751 753 8 files, 4 changesets, 18 total revisions
752 754
753 755 Local clone with fncachestore
754 756 $ hg clone -U deeprepo local-clone-fncachestore
755 757 $ hg -R local-clone-fncachestore verify
756 758 checking changesets
757 759 checking manifests
758 760 checking directory manifests
759 761 crosschecking files in changesets and manifests
760 762 checking files
761 763 8 files, 4 changesets, 18 total revisions
762 764
763 765 Stream clone with basicstore
764 766 $ hg clone --config experimental.changegroup3=True --stream -U \
765 767 > http://localhost:$HGPORT1 stream-clone-basicstore
766 768 streaming all changes
767 769 18 files to transfer, * of data (glob)
768 770 transferred * in * seconds (*) (glob)
769 771 searching for changes
770 772 no changes found
771 773 $ hg -R stream-clone-basicstore verify
772 774 checking changesets
773 775 checking manifests
774 776 checking directory manifests
775 777 crosschecking files in changesets and manifests
776 778 checking files
777 779 8 files, 4 changesets, 18 total revisions
778 780
779 781 Stream clone with encodedstore
780 782 $ hg clone --config experimental.changegroup3=True --stream -U \
781 783 > http://localhost:$HGPORT2 stream-clone-encodedstore
782 784 streaming all changes
783 785 18 files to transfer, * of data (glob)
784 786 transferred * in * seconds (*) (glob)
785 787 searching for changes
786 788 no changes found
787 789 $ hg -R stream-clone-encodedstore verify
788 790 checking changesets
789 791 checking manifests
790 792 checking directory manifests
791 793 crosschecking files in changesets and manifests
792 794 checking files
793 795 8 files, 4 changesets, 18 total revisions
794 796
795 797 Stream clone with fncachestore
796 798 $ hg clone --config experimental.changegroup3=True --stream -U \
797 799 > http://localhost:$HGPORT stream-clone-fncachestore
798 800 streaming all changes
799 801 18 files to transfer, * of data (glob)
800 802 transferred * in * seconds (*) (glob)
801 803 searching for changes
802 804 no changes found
803 805 $ hg -R stream-clone-fncachestore verify
804 806 checking changesets
805 807 checking manifests
806 808 checking directory manifests
807 809 crosschecking files in changesets and manifests
808 810 checking files
809 811 8 files, 4 changesets, 18 total revisions
810 812
811 813 Packed bundle
812 814 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
813 815 writing 5330 bytes for 18 files
814 816 bundle requirements: generaldelta, revlogv1, treemanifest
815 817 $ hg debugbundle --spec repo-packed.hg
816 818 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
817 819
818 820 Bundle with changegroup2 is not supported
819 821
820 822 $ hg -R deeprepo bundle --all -t v2 deeprepo.bundle
821 823 abort: repository does not support bundle version 02
822 824 [255]
823 825
824 826 Pull does not include changegroup for manifest the client already has from
825 827 other branch
826 828
827 829 $ mkdir grafted-dir-repo
828 830 $ cd grafted-dir-repo
829 831 $ hg --config experimental.treemanifest=1 init
830 832 $ mkdir dir
831 833 $ echo a > dir/file
832 834 $ echo a > file
833 835 $ hg ci -Am initial
834 836 adding dir/file
835 837 adding file
836 838 $ echo b > dir/file
837 839 $ hg ci -m updated
838 840 $ hg co '.^'
839 841 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 842 $ hg revert -r tip dir/
841 843 reverting dir/file
842 844 $ echo b > file # to make sure root manifest is sent
843 845 $ hg ci -m grafted
844 846 created new head
845 847 $ cd ..
846 848
847 849 $ hg --config experimental.treemanifest=1 clone --pull -r 1 \
848 850 > grafted-dir-repo grafted-dir-repo-clone
849 851 adding changesets
850 852 adding manifests
851 853 adding file changes
852 854 added 2 changesets with 3 changes to 2 files
853 855 new changesets d84f4c419457:09ab742f3b0f
854 856 updating to branch default
855 857 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
856 858 $ cd grafted-dir-repo-clone
857 859 $ hg pull -r 2
858 860 pulling from $TESTTMP/grafted-dir-repo
859 861 searching for changes
860 862 adding changesets
861 863 adding manifests
862 864 adding file changes
863 865 added 1 changesets with 1 changes to 1 files (+1 heads)
864 866 new changesets 73699489fb7c
865 867 (run 'hg heads' to see heads, 'hg merge' to merge)
866 868
867 869 Committing a empty commit does not duplicate root treemanifest
868 870 $ echo z >> z
869 871 $ hg commit -Aqm 'pre-empty commit'
870 872 $ hg rm z
871 873 $ hg commit --amend -m 'empty commit'
872 874 saved backup bundle to $TESTTMP/grafted-dir-repo-clone/.hg/strip-backup/cb99d5717cea-9e3b6b02-amend.hg
873 875 $ hg log -r 'tip + tip^' -T '{manifest}\n'
874 876 1:678d3574b88c
875 877 1:678d3574b88c
876 878 $ hg --config extensions.strip= strip -r . -q
General Comments 0
You need to be logged in to leave comments. Login now