test-commandserver.t
1156 lines
| 35.8 KiB
| text/troff
|
Tads3Lexer
/ tests / test-commandserver.t
|
r22568 | #if windows | ||
$ PYTHONPATH="$TESTDIR/../contrib;$PYTHONPATH" | ||||
#else | ||||
$ PYTHONPATH="$TESTDIR/../contrib:$PYTHONPATH" | ||||
#endif | ||||
$ export PYTHONPATH | ||||
|
r23053 | typical client does not want echo-back messages, so test without it: | ||
$ grep -v '^promptecho ' < $HGRCPATH >> $HGRCPATH.new | ||||
$ mv $HGRCPATH.new $HGRCPATH | ||||
|
r22568 | $ hg init repo | ||
$ cd repo | ||||
|
r40391 | >>> from __future__ import absolute_import | ||
|
r33923 | >>> import os | ||
>>> import sys | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def hellomessage(server): | ||||
... ch, data = readchannel(server) | ||||
|
r40391 | ... bprint(b'%c, %r' % (ch, data)) | ||
|
r22568 | ... # run an arbitrary command to make sure the next thing the server | ||
... # sends isn't part of the hello message | ||||
|
r40390 | ... runcommand(server, [b'id']) | ||
|
r23036 | o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob) | ||
|
r22572 | *** runcommand id | ||
|
r22567 | 000000000000 tip | ||
|
r22568 | |||
>>> from hgclient import check | ||||
>>> @check | ||||
... def unknowncommand(server): | ||||
|
r40390 | ... server.stdin.write(b'unknowncommand\n') | ||
|
r22567 | abort: unknown command unknowncommand | ||
|
r22568 | |||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def checkruncommand(server): | ||||
... # hello block | ||||
... readchannel(server) | ||||
... | ||||
... # no args | ||||
... runcommand(server, []) | ||||
... | ||||
... # global options | ||||
|
r40390 | ... runcommand(server, [b'id', b'--quiet']) | ||
|
r22568 | ... | ||
... # make sure global options don't stick through requests | ||||
|
r40390 | ... runcommand(server, [b'id']) | ||
|
r22568 | ... | ||
... # --config | ||||
|
r40390 | ... runcommand(server, [b'id', b'--config', b'ui.quiet=True']) | ||
|
r22568 | ... | ||
... # make sure --config doesn't stick | ||||
|
r40390 | ... runcommand(server, [b'id']) | ||
|
r22568 | ... | ||
... # negative return code should be masked | ||||
|
r40390 | ... runcommand(server, [b'id', b'-runknown']) | ||
|
r22572 | *** runcommand | ||
|
r22567 | Mercurial Distributed SCM | ||
basic commands: | ||||
add add the specified files on the next commit | ||||
annotate show changeset information by line for each file | ||||
clone make a copy of an existing repository | ||||
commit commit the specified files or all outstanding changes | ||||
diff diff repository (or selected files) | ||||
export dump the header and diffs for one or more changesets | ||||
forget forget the specified files on the next commit | ||||
init create a new repository in the given directory | ||||
log show revision history of entire repository or files | ||||
|
r23400 | merge merge another revision into working directory | ||
|
r22567 | pull pull changes from the specified source | ||
push push changes to the specified destination | ||||
remove remove the specified files on the next commit | ||||
serve start stand-alone webserver | ||||
status show changed files in the working directory | ||||
summary summarize working directory state | ||||
update update working directory (or switch revisions) | ||||
|
r29974 | (use 'hg help' for the full list of commands or 'hg -v' for details) | ||
|
r22572 | *** runcommand id --quiet | ||
|
r22567 | 000000000000 | ||
|
r22572 | *** runcommand id | ||
|
r22567 | 000000000000 tip | ||
|
r22572 | *** runcommand id --config ui.quiet=True | ||
|
r22567 | 000000000000 | ||
|
r22572 | *** runcommand id | ||
|
r22567 | 000000000000 tip | ||
|
r22572 | *** runcommand id -runknown | ||
|
r22567 | abort: unknown revision 'unknown'! | ||
[255] | ||||
|
r22568 | |||
|
r40391 | >>> from hgclient import bprint, check, readchannel | ||
|
r22568 | >>> @check | ||
... def inputeof(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... server.stdin.write(b'runcommand\n') | ||
|
r22568 | ... # close stdin while server is waiting for input | ||
... server.stdin.close() | ||||
... | ||||
... # server exits with 1 if the pipe closed while reading the command | ||||
|
r40391 | ... bprint(b'server exit code =', b'%d' % server.wait()) | ||
|
r22567 | server exit code = 1 | ||
|
r22568 | |||
|
r33923 | >>> from hgclient import check, readchannel, runcommand, stringio | ||
|
r22568 | >>> @check | ||
... def serverinput(server): | ||||
... readchannel(server) | ||||
... | ||||
|
r40390 | ... patch = b""" | ||
|
r22568 | ... # HG changeset patch | ||
... # User test | ||||
... # Date 0 0 | ||||
... # Node ID c103a3dec114d882c98382d684d8af798d09d857 | ||||
... # Parent 0000000000000000000000000000000000000000 | ||||
... 1 | ||||
... | ||||
... diff -r 000000000000 -r c103a3dec114 a | ||||
... --- /dev/null Thu Jan 01 00:00:00 1970 +0000 | ||||
... +++ b/a Thu Jan 01 00:00:00 1970 +0000 | ||||
... @@ -0,0 +1,1 @@ | ||||
... +1 | ||||
... """ | ||||
... | ||||
|
r40390 | ... runcommand(server, [b'import', b'-'], input=stringio(patch)) | ||
... runcommand(server, [b'log']) | ||||
|
r22572 | *** runcommand import - | ||
|
r22567 | applying patch from stdin | ||
|
r22572 | *** runcommand log | ||
|
r22567 | changeset: 0:eff892de26ec | ||
tag: tip | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: 1 | ||||
|
r22568 | |||
|
r35180 | check strict parsing of early options: | ||
>>> import os | ||||
>>> from hgclient import check, readchannel, runcommand | ||||
>>> os.environ['HGPLAIN'] = '+strictflags' | ||||
>>> @check | ||||
... def cwd(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'log', b'-b', b'--config=alias.log=!echo pwned', | ||
... b'default']) | ||||
|
r35180 | *** runcommand log -b --config=alias.log=!echo pwned default | ||
abort: unknown revision '--config=alias.log=!echo pwned'! | ||||
[255] | ||||
|
r30262 | check that "histedit --commands=-" can read rules from the input channel: | ||
|
r40392 | >>> from hgclient import check, readchannel, runcommand, stringio | ||
|
r30262 | >>> @check | ||
... def serverinput(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... rules = b'pick eff892de26ec\n' | ||
... runcommand(server, [b'histedit', b'0', b'--commands=-', | ||||
... b'--config', b'extensions.histedit='], | ||||
|
r40392 | ... input=stringio(rules)) | ||
|
r30262 | *** runcommand histedit 0 --commands=- --config extensions.histedit= | ||
|
r22568 | check that --cwd doesn't persist between requests: | ||
$ mkdir foo | ||||
$ touch foo/bar | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def cwd(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'--cwd', b'foo', b'st', b'bar']) | ||
... runcommand(server, [b'st', b'foo/bar']) | ||||
|
r22572 | *** runcommand --cwd foo st bar | ||
|
r22567 | ? bar | ||
|
r22572 | *** runcommand st foo/bar | ||
|
r22567 | ? foo/bar | ||
|
r22568 | |||
$ rm foo/bar | ||||
check that local configs for the cached repo aren't inherited when -R is used: | ||||
$ cat <<EOF >> .hg/hgrc | ||||
> [ui] | ||||
> foo = bar | ||||
> EOF | ||||
|
r37445 | #if no-extraextensions | ||
|
r33923 | >>> from hgclient import check, readchannel, runcommand, sep | ||
|
r22568 | >>> @check | ||
... def localhgrc(server): | ||||
... readchannel(server) | ||||
... | ||||
... # the cached repo local hgrc contains ui.foo=bar, so showconfig should | ||||
... # show it | ||||
|
r40390 | ... runcommand(server, [b'showconfig'], outfilter=sep) | ||
|
r22568 | ... | ||
... # but not for this repo | ||||
|
r40390 | ... runcommand(server, [b'init', b'foo']) | ||
... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults']) | ||||
|
r22572 | *** runcommand showconfig | ||
|
r22567 | bundle.mainreporoot=$TESTTMP/repo | ||
|
r25290 | devel.all-warnings=true | ||
r32410 | devel.default-date=0 0 | |||
|
r33426 | extensions.fsmonitor= (fsmonitor !) | ||
|
r23388 | largefiles.usercache=$TESTTMP/.cache/largefiles | ||
|
r35281 | lfs.usercache=$TESTTMP/.cache/lfs | ||
|
r22567 | ui.slash=True | ||
ui.interactive=False | ||||
|
r40506 | ui.merge=internal:merge | ||
|
r22567 | ui.mergemarkers=detailed | ||
ui.foo=bar | ||||
ui.nontty=true | ||||
|
r31009 | web.address=localhost | ||
|
r31010 | web\.ipv6=(?:True|False) (re) | ||
|
r37027 | web.server-header=testing stub value | ||
|
r22572 | *** runcommand init foo | ||
*** runcommand -R foo showconfig ui defaults | ||||
|
r22567 | ui.slash=True | ||
ui.interactive=False | ||||
|
r40506 | ui.merge=internal:merge | ||
|
r22567 | ui.mergemarkers=detailed | ||
ui.nontty=true | ||||
|
r37445 | #endif | ||
|
r22568 | |||
$ rm -R foo | ||||
#if windows | ||||
$ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH" | ||||
#else | ||||
$ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH" | ||||
#endif | ||||
$ cat <<EOF > hook.py | ||||
> import sys | ||||
|
r40391 | > from hgclient import bprint | ||
|
r22568 | > def hook(**args): | ||
|
r40391 | > bprint(b'hook talking') | ||
> bprint(b'now try to read something: %r' % sys.stdin.read()) | ||||
|
r22568 | > EOF | ||
|
r33923 | >>> from hgclient import check, readchannel, runcommand, stringio | ||
|
r22568 | >>> @check | ||
... def hookoutput(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'--config', | ||
... b'hooks.pre-identify=python:hook.hook', | ||||
... b'id'], | ||||
... input=stringio(b'some input')) | ||||
|
r22572 | *** runcommand --config hooks.pre-identify=python:hook.hook id | ||
|
r22567 | eff892de26ec tip | ||
|
r37237 | hook talking | ||
now try to read something: '' | ||||
|
r22568 | |||
|
r33609 | Clean hook cached version | ||
|
r22568 | $ rm hook.py* | ||
|
r33609 | $ rm -Rf __pycache__ | ||
|
r22568 | |||
$ echo a >> a | ||||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def outsidechanges(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'status']) | ||
|
r22568 | ... os.system('hg ci -Am2') | ||
|
r40390 | ... runcommand(server, [b'tip']) | ||
... runcommand(server, [b'status']) | ||||
|
r22572 | *** runcommand status | ||
|
r22567 | M a | ||
|
r22572 | *** runcommand tip | ||
|
r22567 | changeset: 1:d3a0a68be6de | ||
tag: tip | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: 2 | ||||
|
r22572 | *** runcommand status | ||
|
r22568 | |||
>>> import os | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def bookmarks(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'bookmarks']) | ||
|
r22568 | ... | ||
... # changes .hg/bookmarks | ||||
... os.system('hg bookmark -i bm1') | ||||
... os.system('hg bookmark -i bm2') | ||||
|
r40390 | ... runcommand(server, [b'bookmarks']) | ||
|
r22568 | ... | ||
... # changes .hg/bookmarks.current | ||||
... os.system('hg upd bm1 -q') | ||||
|
r40390 | ... runcommand(server, [b'bookmarks']) | ||
|
r22568 | ... | ||
|
r40390 | ... runcommand(server, [b'bookmarks', b'bm3']) | ||
|
r22568 | ... f = open('a', 'ab') | ||
|
r40390 | ... f.write(b'a\n') and None | ||
|
r22568 | ... f.close() | ||
|
r40390 | ... runcommand(server, [b'commit', b'-Amm']) | ||
... runcommand(server, [b'bookmarks']) | ||||
|
r40391 | ... bprint(b'') | ||
|
r22572 | *** runcommand bookmarks | ||
|
r22567 | no bookmarks set | ||
|
r22572 | *** runcommand bookmarks | ||
|
r22567 | bm1 1:d3a0a68be6de | ||
bm2 1:d3a0a68be6de | ||||
|
r22572 | *** runcommand bookmarks | ||
|
r22567 | * bm1 1:d3a0a68be6de | ||
bm2 1:d3a0a68be6de | ||||
|
r22572 | *** runcommand bookmarks bm3 | ||
*** runcommand commit -Amm | ||||
*** runcommand bookmarks | ||||
|
r22567 | bm1 1:d3a0a68be6de | ||
bm2 1:d3a0a68be6de | ||||
* bm3 2:aef17e88f5f0 | ||||
|
r33922 | |||
|
r22568 | |||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def tagscache(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'id', b'-t', b'-r', b'0']) | ||
|
r22568 | ... os.system('hg tag -r 0 foo') | ||
|
r40390 | ... runcommand(server, [b'id', b'-t', b'-r', b'0']) | ||
|
r22572 | *** runcommand id -t -r 0 | ||
|
r22567 | |||
|
r22572 | *** runcommand id -t -r 0 | ||
|
r22567 | foo | ||
|
r22568 | |||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def setphase(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'phase', b'-r', b'.']) | ||
|
r22568 | ... os.system('hg phase -r . -p') | ||
|
r40390 | ... runcommand(server, [b'phase', b'-r', b'.']) | ||
|
r22572 | *** runcommand phase -r . | ||
|
r22567 | 3: draft | ||
|
r22572 | *** runcommand phase -r . | ||
|
r22567 | 3: public | ||
|
r22568 | |||
$ echo a >> a | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def rollback(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'phase', b'-r', b'.', b'-p']) | ||
... runcommand(server, [b'commit', b'-Am.']) | ||||
... runcommand(server, [b'rollback']) | ||||
... runcommand(server, [b'phase', b'-r', b'.']) | ||||
|
r40391 | ... bprint(b'') | ||
|
r22572 | *** runcommand phase -r . -p | ||
|
r22567 | no phases changed | ||
|
r22572 | *** runcommand commit -Am. | ||
*** runcommand rollback | ||||
|
r22567 | repository tip rolled back to revision 3 (undo commit) | ||
working directory now based on revision 3 | ||||
|
r22572 | *** runcommand phase -r . | ||
|
r22567 | 3: public | ||
|
r33922 | |||
|
r22568 | |||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def branch(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'branch']) | ||
|
r22568 | ... os.system('hg branch foo') | ||
|
r40390 | ... runcommand(server, [b'branch']) | ||
|
r22568 | ... os.system('hg branch default') | ||
|
r22572 | *** runcommand branch | ||
|
r22567 | default | ||
marked working directory as branch foo | ||||
(branches are permanent and global, did you want a bookmark?) | ||||
|
r22572 | *** runcommand branch | ||
|
r22567 | foo | ||
marked working directory as branch default | ||||
(branches are permanent and global, did you want a bookmark?) | ||||
|
r22568 | |||
$ touch .hgignore | ||||
>>> import os | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def hgignore(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', b'-Am.']) | ||
|
r22568 | ... f = open('ignored-file', 'ab') | ||
|
r40390 | ... f.write(b'') and None | ||
|
r22568 | ... f.close() | ||
... f = open('.hgignore', 'ab') | ||||
|
r40390 | ... f.write(b'ignored-file') | ||
|
r22568 | ... f.close() | ||
|
r40390 | ... runcommand(server, [b'status', b'-i', b'-u']) | ||
|
r40391 | ... bprint(b'') | ||
|
r22572 | *** runcommand commit -Am. | ||
|
r22567 | adding .hgignore | ||
|
r22572 | *** runcommand status -i -u | ||
|
r22567 | I ignored-file | ||
|
r33922 | |||
|
r22568 | |||
|
r26405 | cache of non-public revisions should be invalidated on repository change | ||
(issue4855): | ||||
>>> import os | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r26405 | >>> @check | ||
... def phasesetscacheaftercommit(server): | ||||
... readchannel(server) | ||||
... # load _phasecache._phaserevs and _phasesets | ||||
|
r40390 | ... runcommand(server, [b'log', b'-qr', b'draft()']) | ||
|
r26405 | ... # create draft commits by another process | ||
|
r36303 | ... for i in range(5, 7): | ||
|
r26431 | ... f = open('a', 'ab') | ||
... f.seek(0, os.SEEK_END) | ||||
|
r40390 | ... f.write(b'a\n') and None | ||
|
r26431 | ... f.close() | ||
|
r26405 | ... os.system('hg commit -Aqm%d' % i) | ||
... # new commits should be listed as draft revisions | ||||
|
r40390 | ... runcommand(server, [b'log', b'-qr', b'draft()']) | ||
|
r40391 | ... bprint(b'') | ||
|
r26405 | *** runcommand log -qr draft() | ||
4:7966c8e3734d | ||||
*** runcommand log -qr draft() | ||||
4:7966c8e3734d | ||||
5:41f6602d1c4f | ||||
6:10501e202c35 | ||||
|
r33922 | |||
|
r26405 | |||
>>> import os | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r26405 | >>> @check | ||
... def phasesetscacheafterstrip(server): | ||||
... readchannel(server) | ||||
... # load _phasecache._phaserevs and _phasesets | ||||
|
r40390 | ... runcommand(server, [b'log', b'-qr', b'draft()']) | ||
|
r26405 | ... # strip cached revisions by another process | ||
... os.system('hg --config extensions.strip= strip -q 5') | ||||
... # shouldn't abort by "unknown revision '6'" | ||||
|
r40390 | ... runcommand(server, [b'log', b'-qr', b'draft()']) | ||
|
r40391 | ... bprint(b'') | ||
|
r26405 | *** runcommand log -qr draft() | ||
4:7966c8e3734d | ||||
5:41f6602d1c4f | ||||
6:10501e202c35 | ||||
*** runcommand log -qr draft() | ||||
4:7966c8e3734d | ||||
|
r33922 | |||
|
r26405 | |||
cache of phase roots should be invalidated on strip (issue3827): | ||||
|
r22568 | >>> import os | ||
|
r33923 | >>> from hgclient import check, readchannel, runcommand, sep | ||
|
r22568 | >>> @check | ||
... def phasecacheafterstrip(server): | ||||
... readchannel(server) | ||||
... | ||||
... # create new head, 5:731265503d86 | ||||
|
r40390 | ... runcommand(server, [b'update', b'-C', b'0']) | ||
|
r22568 | ... f = open('a', 'ab') | ||
|
r40390 | ... f.write(b'a\n') and None | ||
|
r22568 | ... f.close() | ||
|
r40390 | ... runcommand(server, [b'commit', b'-Am.', b'a']) | ||
... runcommand(server, [b'log', b'-Gq']) | ||||
|
r22568 | ... | ||
... # make it public; draft marker moves to 4:7966c8e3734d | ||||
|
r40390 | ... runcommand(server, [b'phase', b'-p', b'.']) | ||
|
r22568 | ... # load _phasecache.phaseroots | ||
|
r40390 | ... runcommand(server, [b'phase', b'.'], outfilter=sep) | ||
|
r22568 | ... | ||
... # strip 1::4 outside server | ||||
... os.system('hg -q --config extensions.mq= strip 1') | ||||
... | ||||
... # shouldn't raise "7966c8e3734d: no node!" | ||||
|
r40390 | ... runcommand(server, [b'branches']) | ||
|
r22572 | *** runcommand update -C 0 | ||
|
r22567 | 1 files updated, 0 files merged, 2 files removed, 0 files unresolved | ||
(leaving bookmark bm3) | ||||
|
r22572 | *** runcommand commit -Am. a | ||
|
r22567 | created new head | ||
|
r22572 | *** runcommand log -Gq | ||
|
r22567 | @ 5:731265503d86 | ||
| | ||||
| o 4:7966c8e3734d | ||||
| | | ||||
| o 3:b9b85890c400 | ||||
| | | ||||
| o 2:aef17e88f5f0 | ||||
| | | ||||
| o 1:d3a0a68be6de | ||||
|/ | ||||
o 0:eff892de26ec | ||||
|
r22572 | *** runcommand phase -p . | ||
*** runcommand phase . | ||||
|
r22567 | 5: public | ||
|
r22572 | *** runcommand branches | ||
|
r22567 | default 1:731265503d86 | ||
|
r22568 | |||
|
r26251 | in-memory cache must be reloaded if transaction is aborted. otherwise | ||
changelog and manifest would have invalid node: | ||||
$ echo a >> a | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r26251 | >>> @check | ||
... def txabort(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', b'--config', b'hooks.pretxncommit=false', | ||
... b'-mfoo']) | ||||
... runcommand(server, [b'verify']) | ||||
|
r26251 | *** runcommand commit --config hooks.pretxncommit=false -mfoo | ||
transaction abort! | ||||
rollback completed | ||||
abort: pretxncommit hook exited with status 1 | ||||
[255] | ||||
*** runcommand verify | ||||
checking changesets | ||||
checking manifests | ||||
crosschecking files in changesets and manifests | ||||
checking files | ||||
|
r39525 | checked 2 changesets with 2 changes to 1 files | ||
|
r26251 | $ hg revert --no-backup -aq | ||
|
r22955 | $ cat >> .hg/hgrc << EOF | ||
> [experimental] | ||||
|
r34867 | > evolution.createmarkers=True | ||
|
r22568 | > EOF | ||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def obsolete(server): | ||||
... readchannel(server) | ||||
... | ||||
|
r40390 | ... runcommand(server, [b'up', b'null']) | ||
... runcommand(server, [b'phase', b'-df', b'tip']) | ||||
|
r22568 | ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`' | ||
... if os.name == 'nt': | ||||
... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe | ||||
... os.system(cmd) | ||||
|
r40390 | ... runcommand(server, [b'log', b'--hidden']) | ||
... runcommand(server, [b'log']) | ||||
|
r22572 | *** runcommand up null | ||
|
r22567 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | ||
|
r22572 | *** runcommand phase -df tip | ||
r43163 | 1 new obsolescence markers | |||
|
r33542 | obsoleted 1 changesets | ||
|
r22572 | *** runcommand log --hidden | ||
|
r22567 | changeset: 1:731265503d86 | ||
tag: tip | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
|
r34901 | obsolete: pruned | ||
|
r22567 | summary: . | ||
changeset: 0:eff892de26ec | ||||
bookmark: bm1 | ||||
bookmark: bm2 | ||||
bookmark: bm3 | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: 1 | ||||
|
r22572 | *** runcommand log | ||
|
r22567 | changeset: 0:eff892de26ec | ||
bookmark: bm1 | ||||
bookmark: bm2 | ||||
bookmark: bm3 | ||||
tag: tip | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: 1 | ||||
|
r22568 | |||
$ cat <<EOF >> .hg/hgrc | ||||
> [extensions] | ||||
> mq = | ||||
> EOF | ||||
>>> import os | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def mqoutsidechanges(server): | ||||
... readchannel(server) | ||||
... | ||||
... # load repo.mq | ||||
|
r40390 | ... runcommand(server, [b'qapplied']) | ||
|
r22568 | ... os.system('hg qnew 0.diff') | ||
... # repo.mq should be invalidated | ||||
|
r40390 | ... runcommand(server, [b'qapplied']) | ||
|
r22568 | ... | ||
|
r40390 | ... runcommand(server, [b'qpop', b'--all']) | ||
|
r22568 | ... os.system('hg qqueue --create foo') | ||
... # repo.mq should be recreated to point to new queue | ||||
|
r40390 | ... runcommand(server, [b'qqueue', b'--active']) | ||
|
r22572 | *** runcommand qapplied | ||
*** runcommand qapplied | ||||
|
r22567 | 0.diff | ||
|
r22572 | *** runcommand qpop --all | ||
|
r22567 | popping 0.diff | ||
patch queue now empty | ||||
|
r22572 | *** runcommand qqueue --active | ||
|
r22567 | foo | ||
|
r22568 | |||
|
r40627 | $ cat <<'EOF' > ../dbgui.py | ||
|
r33923 | > import os | ||
> import sys | ||||
|
r32337 | > from mercurial import commands, registrar | ||
|
r22568 | > cmdtable = {} | ||
|
r32337 | > command = registrar.command(cmdtable) | ||
|
r33097 | > @command(b"debuggetpass", norepo=True) | ||
|
r22568 | > def debuggetpass(ui): | ||
|
r40627 | > ui.write(b"%s\n" % ui.getpass()) | ||
|
r33097 | > @command(b"debugprompt", norepo=True) | ||
|
r22783 | > def debugprompt(ui): | ||
|
r40627 | > ui.write(b"%s\n" % ui.prompt(b"prompt:")) | ||
|
r40628 | > @command(b"debugpromptchoice", norepo=True) | ||
> def debugpromptchoice(ui): | ||||
> msg = b"promptchoice (y/n)? $$ &Yes $$ &No" | ||||
> ui.write(b"%d\n" % ui.promptchoice(msg)) | ||||
|
r33097 | > @command(b"debugreadstdin", norepo=True) | ||
|
r23324 | > def debugreadstdin(ui): | ||
|
r40390 | > ui.write(b"read: %r\n" % sys.stdin.read(1)) | ||
|
r33097 | > @command(b"debugwritestdout", norepo=True) | ||
|
r23324 | > def debugwritestdout(ui): | ||
|
r40390 | > os.write(1, b"low-level stdout fd and\n") | ||
|
r37237 | > sys.stdout.write("stdout should be redirected to stderr\n") | ||
|
r23324 | > sys.stdout.flush() | ||
|
r22568 | > EOF | ||
$ cat <<EOF >> .hg/hgrc | ||||
> [extensions] | ||||
|
r40627 | > dbgui = ../dbgui.py | ||
|
r22568 | > EOF | ||
|
r33923 | >>> from hgclient import check, readchannel, runcommand, stringio | ||
|
r22568 | >>> @check | ||
... def getpass(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'debuggetpass', b'--config', | ||
... b'ui.interactive=True'], | ||||
... input=stringio(b'1234\n')) | ||||
... runcommand(server, [b'debuggetpass', b'--config', | ||||
... b'ui.interactive=True'], | ||||
... input=stringio(b'\n')) | ||||
... runcommand(server, [b'debuggetpass', b'--config', | ||||
... b'ui.interactive=True'], | ||||
... input=stringio(b'')) | ||||
... runcommand(server, [b'debugprompt', b'--config', | ||||
... b'ui.interactive=True'], | ||||
... input=stringio(b'5678\n')) | ||||
|
r44857 | ... runcommand(server, [b'debugprompt', b'--config', | ||
... b'ui.interactive=True'], | ||||
... input=stringio(b'\nremainder\nshould\nnot\nbe\nread\n')) | ||||
|
r40390 | ... runcommand(server, [b'debugreadstdin']) | ||
... runcommand(server, [b'debugwritestdout']) | ||||
|
r22572 | *** runcommand debuggetpass --config ui.interactive=True | ||
|
r22567 | password: 1234 | ||
|
r30814 | *** runcommand debuggetpass --config ui.interactive=True | ||
password: | ||||
*** runcommand debuggetpass --config ui.interactive=True | ||||
password: abort: response expected | ||||
[255] | ||||
|
r22783 | *** runcommand debugprompt --config ui.interactive=True | ||
prompt: 5678 | ||||
|
r44857 | *** runcommand debugprompt --config ui.interactive=True | ||
prompt: y | ||||
|
r23324 | *** runcommand debugreadstdin | ||
read: '' | ||||
*** runcommand debugwritestdout | ||||
|
r37237 | low-level stdout fd and | ||
stdout should be redirected to stderr | ||||
|
r22568 | |||
|
r23322 | run commandserver in commandserver, which is silly but should work: | ||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand, stringio | ||
|
r23322 | >>> @check | ||
... def nested(server): | ||||
|
r40391 | ... bprint(b'%c, %r' % readchannel(server)) | ||
|
r23322 | ... class nestedserver(object): | ||
|
r40390 | ... stdin = stringio(b'getencoding\n') | ||
|
r28836 | ... stdout = stringio() | ||
|
r40390 | ... runcommand(server, [b'serve', b'--cmdserver', b'pipe'], | ||
|
r23322 | ... output=nestedserver.stdout, input=nestedserver.stdin) | ||
... nestedserver.stdout.seek(0) | ||||
|
r40391 | ... bprint(b'%c, %r' % readchannel(nestedserver)) # hello | ||
... bprint(b'%c, %r' % readchannel(nestedserver)) # getencoding | ||||
|
r23322 | o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob) | ||
*** runcommand serve --cmdserver pipe | ||||
o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob) | ||||
r, '*' (glob) | ||||
|
r22568 | |||
start without repository: | ||||
$ cd .. | ||||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def hellomessage(server): | ||||
... ch, data = readchannel(server) | ||||
|
r40391 | ... bprint(b'%c, %r' % (ch, data)) | ||
|
r22568 | ... # run an arbitrary command to make sure the next thing the server | ||
... # sends isn't part of the hello message | ||||
|
r40390 | ... runcommand(server, [b'id']) | ||
|
r23036 | o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob) | ||
|
r22572 | *** runcommand id | ||
|
r22567 | abort: there is no Mercurial repository here (.hg not found) | ||
[255] | ||||
|
r22568 | |||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r22568 | >>> @check | ||
... def startwithoutrepo(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'init', b'repo2']) | ||
... runcommand(server, [b'id', b'-R', b'repo2']) | ||||
|
r22572 | *** runcommand init repo2 | ||
*** runcommand id -R repo2 | ||||
|
r22567 | 000000000000 tip | ||
|
r22994 | |||
|
r26142 | don't fall back to cwd if invalid -R path is specified (issue4805): | ||
$ cd repo | ||||
$ hg serve --cmdserver pipe -R ../nonexistent | ||||
abort: repository ../nonexistent not found! | ||||
[255] | ||||
$ cd .. | ||||
|
r45602 | #if no-windows | ||
option to not shutdown on SIGINT: | ||||
$ cat <<'EOF' > dbgint.py | ||||
> import os | ||||
> import signal | ||||
> import time | ||||
> from mercurial import commands, registrar | ||||
> cmdtable = {} | ||||
> command = registrar.command(cmdtable) | ||||
> @command(b"debugsleep", norepo=True) | ||||
> def debugsleep(ui): | ||||
> time.sleep(1) | ||||
> @command(b"debugsuicide", norepo=True) | ||||
> def debugsuicide(ui): | ||||
> os.kill(os.getpid(), signal.SIGINT) | ||||
> time.sleep(1) | ||||
> EOF | ||||
>>> import signal | ||||
>>> import time | ||||
>>> from hgclient import checkwith, readchannel, runcommand | ||||
>>> @checkwith(extraargs=[b'--config', b'cmdserver.shutdown-on-interrupt=False', | ||||
... b'--config', b'extensions.dbgint=dbgint.py']) | ||||
... def nointr(server): | ||||
... readchannel(server) | ||||
... server.send_signal(signal.SIGINT) # server won't be terminated | ||||
... time.sleep(1) | ||||
... runcommand(server, [b'debugsleep']) | ||||
... server.send_signal(signal.SIGINT) # server won't be terminated | ||||
... runcommand(server, [b'debugsleep']) | ||||
... runcommand(server, [b'debugsuicide']) # command can be interrupted | ||||
... server.send_signal(signal.SIGTERM) # server will be terminated | ||||
... time.sleep(1) | ||||
*** runcommand debugsleep | ||||
*** runcommand debugsleep | ||||
*** runcommand debugsuicide | ||||
interrupted! | ||||
killed! | ||||
[255] | ||||
#endif | ||||
|
r40625 | structured message channel: | ||
$ cat <<'EOF' >> repo2/.hg/hgrc | ||||
> [ui] | ||||
> # server --config should precede repository option | ||||
> message-output = stdio | ||||
> EOF | ||||
>>> from hgclient import bprint, checkwith, readchannel, runcommand | ||||
>>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel', | ||||
... b'--config', b'cmdserver.message-encodings=foo cbor']) | ||||
... def verify(server): | ||||
... _ch, data = readchannel(server) | ||||
... bprint(data) | ||||
... runcommand(server, [b'-R', b'repo2', b'verify']) | ||||
capabilities: getencoding runcommand | ||||
encoding: ascii | ||||
message-encoding: cbor | ||||
pid: * (glob) | ||||
|
r40689 | pgid: * (glob) (no-windows !) | ||
|
r40625 | *** runcommand -R repo2 verify | ||
|
r40626 | message: '\xa2DdataTchecking changesets\nDtypeFstatus' | ||
|
r40630 | message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@' | ||
|
r40626 | message: '\xa2DdataSchecking manifests\nDtypeFstatus' | ||
|
r40630 | message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@' | ||
|
r40626 | message: '\xa2DdataX0crosschecking files in changesets and manifests\nDtypeFstatus' | ||
|
r40630 | message: '\xa6Ditem@Cpos\xf6EtopicMcrosscheckingEtotal\xf6DtypeHprogressDunit@' | ||
|
r40626 | message: '\xa2DdataOchecking files\nDtypeFstatus' | ||
|
r40630 | message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@' | ||
|
r40626 | message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus' | ||
|
r40625 | |||
|
r40628 | >>> from hgclient import checkwith, readchannel, runcommand, stringio | ||
>>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel', | ||||
... b'--config', b'cmdserver.message-encodings=cbor', | ||||
... b'--config', b'extensions.dbgui=dbgui.py']) | ||||
... def prompt(server): | ||||
... readchannel(server) | ||||
... interactive = [b'--config', b'ui.interactive=True'] | ||||
|
r40629 | ... runcommand(server, [b'debuggetpass'] + interactive, | ||
... input=stringio(b'1234\n')) | ||||
|
r40628 | ... runcommand(server, [b'debugprompt'] + interactive, | ||
... input=stringio(b'5678\n')) | ||||
... runcommand(server, [b'debugpromptchoice'] + interactive, | ||||
... input=stringio(b'n\n')) | ||||
|
r40629 | *** runcommand debuggetpass --config ui.interactive=True | ||
message: '\xa3DdataJpassword: Hpassword\xf5DtypeFprompt' | ||||
1234 | ||||
|
r40628 | *** runcommand debugprompt --config ui.interactive=True | ||
message: '\xa3DdataGprompt:GdefaultAyDtypeFprompt' | ||||
5678 | ||||
*** runcommand debugpromptchoice --config ui.interactive=True | ||||
message: '\xa4Gchoices\x82\x82AyCYes\x82AnBNoDdataTpromptchoice (y/n)? GdefaultAyDtypeFprompt' | ||||
1 | ||||
|
r40625 | bad message encoding: | ||
$ hg serve --cmdserver pipe --config ui.message-output=channel | ||||
abort: no supported message encodings: | ||||
[255] | ||||
$ hg serve --cmdserver pipe --config ui.message-output=channel \ | ||||
> --config cmdserver.message-encodings='foo bar' | ||||
abort: no supported message encodings: foo bar | ||||
[255] | ||||
|
r22994 | unix domain socket: | ||
$ cd repo | ||||
$ hg update -q | ||||
|
r23095 | #if unix-socket unix-permissions | ||
|
r22994 | |||
|
r40391 | >>> from hgclient import bprint, check, readchannel, runcommand, stringio, unixserver | ||
|
r40390 | >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log') | ||
|
r22994 | >>> def hellomessage(conn): | ||
... ch, data = readchannel(conn) | ||||
|
r40391 | ... bprint(b'%c, %r' % (ch, data)) | ||
|
r40390 | ... runcommand(conn, [b'id']) | ||
|
r22994 | >>> check(hellomessage, server.connect) | ||
|
r23036 | o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob) | ||
|
r22994 | *** runcommand id | ||
eff892de26ec tip bm1/bm2/bm3 | ||||
>>> def unknowncommand(conn): | ||||
... readchannel(conn) | ||||
|
r40390 | ... conn.stdin.write(b'unknowncommand\n') | ||
|
r22994 | >>> check(unknowncommand, server.connect) # error sent to server.log | ||
>>> def serverinput(conn): | ||||
... readchannel(conn) | ||||
|
r40390 | ... patch = b""" | ||
|
r22994 | ... # HG changeset patch | ||
... # User test | ||||
... # Date 0 0 | ||||
... 2 | ||||
... | ||||
... diff -r eff892de26ec -r 1ed24be7e7a0 a | ||||
... --- a/a | ||||
... +++ b/a | ||||
... @@ -1,1 +1,2 @@ | ||||
... 1 | ||||
... +2 | ||||
... """ | ||||
|
r40390 | ... runcommand(conn, [b'import', b'-'], input=stringio(patch)) | ||
... runcommand(conn, [b'log', b'-rtip', b'-q']) | ||||
|
r22994 | >>> check(serverinput, server.connect) | ||
*** runcommand import - | ||||
applying patch from stdin | ||||
*** runcommand log -rtip -q | ||||
2:1ed24be7e7a0 | ||||
>>> server.shutdown() | ||||
$ cat .hg/server.log | ||||
listening at .hg/server.sock | ||||
abort: unknown command unknowncommand | ||||
killed! | ||||
|
r28511 | $ rm .hg/server.log | ||
if server crashed before hello, traceback will be sent to 'e' channel as | ||||
last ditch: | ||||
|
r40857 | $ cat <<'EOF' > ../earlycrasher.py | ||
> from mercurial import commandserver, extensions | ||||
|
r40911 | > def _serverequest(orig, ui, repo, conn, createcmdserver, prereposetups): | ||
|
r40857 | > def createcmdserver(*args, **kwargs): | ||
> raise Exception('crash') | ||||
|
r40911 | > return orig(ui, repo, conn, createcmdserver, prereposetups) | ||
|
r40857 | > def extsetup(ui): | ||
> extensions.wrapfunction(commandserver, b'_serverequest', _serverequest) | ||||
> EOF | ||||
|
r28511 | $ cat <<EOF >> .hg/hgrc | ||
|
r40857 | > [extensions] | ||
> earlycrasher = ../earlycrasher.py | ||||
|
r28511 | > EOF | ||
|
r40391 | >>> from hgclient import bprint, check, readchannel, unixserver | ||
|
r40390 | >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log') | ||
|
r28511 | >>> def earlycrash(conn): | ||
... while True: | ||||
... try: | ||||
... ch, data = readchannel(conn) | ||||
|
r40397 | ... for l in data.splitlines(True): | ||
... if not l.startswith(b' '): | ||||
... bprint(b'%c, %r' % (ch, l)) | ||||
|
r28511 | ... except EOFError: | ||
... break | ||||
>>> check(earlycrash, server.connect) | ||||
e, 'Traceback (most recent call last):\n' | ||||
|
r40857 | e, 'Exception: crash\n' | ||
|
r28511 | >>> server.shutdown() | ||
$ cat .hg/server.log | grep -v '^ ' | ||||
listening at .hg/server.sock | ||||
Traceback (most recent call last): | ||||
|
r40857 | Exception: crash | ||
|
r28511 | killed! | ||
|
r23095 | #endif | ||
#if no-unix-socket | ||||
|
r22994 | |||
$ hg serve --cmdserver unix -a .hg/server.sock | ||||
abort: unsupported platform | ||||
[255] | ||||
#endif | ||||
|
r28265 | |||
$ cd .. | ||||
Test that accessing to invalid changelog cache is avoided at | ||||
subsequent operations even if repo object is reused even after failure | ||||
of transaction (see 0a7610758c42 also) | ||||
"hg log" after failure of transaction is needed to detect invalid | ||||
cache in repoview: this can't detect by "hg verify" only. | ||||
Combination of "finalization" and "empty-ness of changelog" (2 x 2 = | ||||
4) are tested, because '00changelog.i' are differently changed in each | ||||
cases. | ||||
$ cat > $TESTTMP/failafterfinalize.py <<EOF | ||||
> # extension to abort transaction after finalization forcibly | ||||
> from mercurial import commands, error, extensions, lock as lockmod | ||||
|
r34766 | > from mercurial import registrar | ||
> cmdtable = {} | ||||
> command = registrar.command(cmdtable) | ||||
> configtable = {} | ||||
> configitem = registrar.configitem(configtable) | ||||
|
r40390 | > configitem(b'failafterfinalize', b'fail', | ||
|
r34766 | > default=None, | ||
> ) | ||||
|
r28265 | > def fail(tr): | ||
|
r40390 | > raise error.Abort(b'fail after finalization') | ||
|
r28265 | > def reposetup(ui, repo): | ||
> class failrepo(repo.__class__): | ||||
|
r42839 | > def commitctx(self, ctx, error=False, origctx=None): | ||
|
r40390 | > if self.ui.configbool(b'failafterfinalize', b'fail'): | ||
|
r28265 | > # 'sorted()' by ASCII code on category names causes | ||
> # invoking 'fail' after finalization of changelog | ||||
> # using "'cl-%i' % id(self)" as category name | ||||
|
r40390 | > self.currenttransaction().addfinalize(b'zzzzzzzz', fail) | ||
|
r42839 | > return super(failrepo, self).commitctx(ctx, error, origctx) | ||
|
r28265 | > repo.__class__ = failrepo | ||
> EOF | ||||
$ hg init repo3 | ||||
$ cd repo3 | ||||
$ cat <<EOF >> $HGRCPATH | ||||
> [ui] | ||||
> logtemplate = {rev} {desc|firstline} ({files})\n | ||||
> | ||||
> [extensions] | ||||
> failafterfinalize = $TESTTMP/failafterfinalize.py | ||||
> EOF | ||||
- test failure with "empty changelog" | ||||
$ echo foo > foo | ||||
$ hg add foo | ||||
|
r30332 | (failure before finalization) | ||
|
r28265 | |||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r28265 | >>> @check | ||
... def abort(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', | ||
... b'--config', b'hooks.pretxncommit=false', | ||||
... b'-mfoo']) | ||||
... runcommand(server, [b'log']) | ||||
... runcommand(server, [b'verify', b'-q']) | ||||
|
r28265 | *** runcommand commit --config hooks.pretxncommit=false -mfoo | ||
transaction abort! | ||||
rollback completed | ||||
abort: pretxncommit hook exited with status 1 | ||||
[255] | ||||
*** runcommand log | ||||
*** runcommand verify -q | ||||
|
r30332 | (failure after finalization) | ||
|
r28265 | |||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r28265 | >>> @check | ||
... def abort(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', | ||
... b'--config', b'failafterfinalize.fail=true', | ||||
... b'-mfoo']) | ||||
... runcommand(server, [b'log']) | ||||
... runcommand(server, [b'verify', b'-q']) | ||||
|
r28265 | *** runcommand commit --config failafterfinalize.fail=true -mfoo | ||
transaction abort! | ||||
rollback completed | ||||
abort: fail after finalization | ||||
[255] | ||||
*** runcommand log | ||||
*** runcommand verify -q | ||||
- test failure with "not-empty changelog" | ||||
$ echo bar > bar | ||||
$ hg add bar | ||||
$ hg commit -mbar bar | ||||
(failure before finalization) | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r28265 | >>> @check | ||
... def abort(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', | ||
... b'--config', b'hooks.pretxncommit=false', | ||||
... b'-mfoo', b'foo']) | ||||
... runcommand(server, [b'log']) | ||||
... runcommand(server, [b'verify', b'-q']) | ||||
|
r28265 | *** runcommand commit --config hooks.pretxncommit=false -mfoo foo | ||
transaction abort! | ||||
rollback completed | ||||
abort: pretxncommit hook exited with status 1 | ||||
[255] | ||||
*** runcommand log | ||||
0 bar (bar) | ||||
*** runcommand verify -q | ||||
(failure after finalization) | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r28265 | >>> @check | ||
... def abort(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'commit', | ||
... b'--config', b'failafterfinalize.fail=true', | ||||
... b'-mfoo', b'foo']) | ||||
... runcommand(server, [b'log']) | ||||
... runcommand(server, [b'verify', b'-q']) | ||||
|
r28265 | *** runcommand commit --config failafterfinalize.fail=true -mfoo foo | ||
transaction abort! | ||||
rollback completed | ||||
abort: fail after finalization | ||||
[255] | ||||
*** runcommand log | ||||
0 bar (bar) | ||||
*** runcommand verify -q | ||||
|
r33721 | |||
$ cd .. | ||||
Test symlink traversal over cached audited paths: | ||||
------------------------------------------------- | ||||
#if symlink | ||||
set up symlink hell | ||||
$ mkdir merge-symlink-out | ||||
$ hg init merge-symlink | ||||
$ cd merge-symlink | ||||
$ touch base | ||||
$ hg commit -qAm base | ||||
$ ln -s ../merge-symlink-out a | ||||
$ hg commit -qAm 'symlink a -> ../merge-symlink-out' | ||||
$ hg up -q 0 | ||||
$ mkdir a | ||||
$ touch a/poisoned | ||||
$ hg commit -qAm 'file a/poisoned' | ||||
$ hg log -G -T '{rev}: {desc}\n' | ||||
@ 2: file a/poisoned | ||||
| | ||||
| o 1: symlink a -> ../merge-symlink-out | ||||
|/ | ||||
o 0: base | ||||
try trivial merge after update: cache of audited paths should be discarded, | ||||
and the merge should fail (issue5628) | ||||
$ hg up -q null | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r33721 | >>> @check | ||
... def merge(server): | ||||
... readchannel(server) | ||||
... # audit a/poisoned as a good path | ||||
|
r40390 | ... runcommand(server, [b'up', b'-qC', b'2']) | ||
... runcommand(server, [b'up', b'-qC', b'1']) | ||||
|
r33721 | ... # here a is a symlink, so a/poisoned is bad | ||
|
r40390 | ... runcommand(server, [b'merge', b'2']) | ||
|
r33721 | *** runcommand up -qC 2 | ||
*** runcommand up -qC 1 | ||||
*** runcommand merge 2 | ||||
|
r34943 | abort: path 'a/poisoned' traverses symbolic link 'a' | ||
[255] | ||||
|
r33721 | $ ls ../merge-symlink-out | ||
cache of repo.auditor should be discarded, so matcher would never traverse | ||||
symlinks: | ||||
$ hg up -qC 0 | ||||
$ touch ../merge-symlink-out/poisoned | ||||
|
r33923 | >>> from hgclient import check, readchannel, runcommand | ||
|
r33721 | >>> @check | ||
... def files(server): | ||||
... readchannel(server) | ||||
|
r40390 | ... runcommand(server, [b'up', b'-qC', b'2']) | ||
|
r33721 | ... # audit a/poisoned as a good path | ||
|
r40390 | ... runcommand(server, [b'files', b'a/poisoned']) | ||
... runcommand(server, [b'up', b'-qC', b'0']) | ||||
... runcommand(server, [b'up', b'-qC', b'1']) | ||||
|
r33721 | ... # here 'a' is a symlink, so a/poisoned should be warned | ||
|
r40390 | ... runcommand(server, [b'files', b'a/poisoned']) | ||
|
r33721 | *** runcommand up -qC 2 | ||
*** runcommand files a/poisoned | ||||
a/poisoned | ||||
*** runcommand up -qC 0 | ||||
*** runcommand up -qC 1 | ||||
*** runcommand files a/poisoned | ||||
|
r33722 | abort: path 'a/poisoned' traverses symbolic link 'a' | ||
[255] | ||||
|
r33721 | |||
$ cd .. | ||||
#endif | ||||