##// END OF EJS Templates
tests: stabilize test-commandserver.t on Windows...
Matt Harbison -
r40689:6d0fdeda default
parent child Browse files
Show More
@@ -1,1096 +1,1096 b''
1 #if windows
1 #if windows
2 $ PYTHONPATH="$TESTDIR/../contrib;$PYTHONPATH"
2 $ PYTHONPATH="$TESTDIR/../contrib;$PYTHONPATH"
3 #else
3 #else
4 $ PYTHONPATH="$TESTDIR/../contrib:$PYTHONPATH"
4 $ PYTHONPATH="$TESTDIR/../contrib:$PYTHONPATH"
5 #endif
5 #endif
6 $ export PYTHONPATH
6 $ export PYTHONPATH
7
7
8 typical client does not want echo-back messages, so test without it:
8 typical client does not want echo-back messages, so test without it:
9
9
10 $ grep -v '^promptecho ' < $HGRCPATH >> $HGRCPATH.new
10 $ grep -v '^promptecho ' < $HGRCPATH >> $HGRCPATH.new
11 $ mv $HGRCPATH.new $HGRCPATH
11 $ mv $HGRCPATH.new $HGRCPATH
12
12
13 $ hg init repo
13 $ hg init repo
14 $ cd repo
14 $ cd repo
15
15
16 >>> from __future__ import absolute_import
16 >>> from __future__ import absolute_import
17 >>> import os
17 >>> import os
18 >>> import sys
18 >>> import sys
19 >>> from hgclient import bprint, check, readchannel, runcommand
19 >>> from hgclient import bprint, check, readchannel, runcommand
20 >>> @check
20 >>> @check
21 ... def hellomessage(server):
21 ... def hellomessage(server):
22 ... ch, data = readchannel(server)
22 ... ch, data = readchannel(server)
23 ... bprint(b'%c, %r' % (ch, data))
23 ... bprint(b'%c, %r' % (ch, data))
24 ... # run an arbitrary command to make sure the next thing the server
24 ... # run an arbitrary command to make sure the next thing the server
25 ... # sends isn't part of the hello message
25 ... # sends isn't part of the hello message
26 ... runcommand(server, [b'id'])
26 ... runcommand(server, [b'id'])
27 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
27 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
28 *** runcommand id
28 *** runcommand id
29 000000000000 tip
29 000000000000 tip
30
30
31 >>> from hgclient import check
31 >>> from hgclient import check
32 >>> @check
32 >>> @check
33 ... def unknowncommand(server):
33 ... def unknowncommand(server):
34 ... server.stdin.write(b'unknowncommand\n')
34 ... server.stdin.write(b'unknowncommand\n')
35 abort: unknown command unknowncommand
35 abort: unknown command unknowncommand
36
36
37 >>> from hgclient import check, readchannel, runcommand
37 >>> from hgclient import check, readchannel, runcommand
38 >>> @check
38 >>> @check
39 ... def checkruncommand(server):
39 ... def checkruncommand(server):
40 ... # hello block
40 ... # hello block
41 ... readchannel(server)
41 ... readchannel(server)
42 ...
42 ...
43 ... # no args
43 ... # no args
44 ... runcommand(server, [])
44 ... runcommand(server, [])
45 ...
45 ...
46 ... # global options
46 ... # global options
47 ... runcommand(server, [b'id', b'--quiet'])
47 ... runcommand(server, [b'id', b'--quiet'])
48 ...
48 ...
49 ... # make sure global options don't stick through requests
49 ... # make sure global options don't stick through requests
50 ... runcommand(server, [b'id'])
50 ... runcommand(server, [b'id'])
51 ...
51 ...
52 ... # --config
52 ... # --config
53 ... runcommand(server, [b'id', b'--config', b'ui.quiet=True'])
53 ... runcommand(server, [b'id', b'--config', b'ui.quiet=True'])
54 ...
54 ...
55 ... # make sure --config doesn't stick
55 ... # make sure --config doesn't stick
56 ... runcommand(server, [b'id'])
56 ... runcommand(server, [b'id'])
57 ...
57 ...
58 ... # negative return code should be masked
58 ... # negative return code should be masked
59 ... runcommand(server, [b'id', b'-runknown'])
59 ... runcommand(server, [b'id', b'-runknown'])
60 *** runcommand
60 *** runcommand
61 Mercurial Distributed SCM
61 Mercurial Distributed SCM
62
62
63 basic commands:
63 basic commands:
64
64
65 add add the specified files on the next commit
65 add add the specified files on the next commit
66 annotate show changeset information by line for each file
66 annotate show changeset information by line for each file
67 clone make a copy of an existing repository
67 clone make a copy of an existing repository
68 commit commit the specified files or all outstanding changes
68 commit commit the specified files or all outstanding changes
69 diff diff repository (or selected files)
69 diff diff repository (or selected files)
70 export dump the header and diffs for one or more changesets
70 export dump the header and diffs for one or more changesets
71 forget forget the specified files on the next commit
71 forget forget the specified files on the next commit
72 init create a new repository in the given directory
72 init create a new repository in the given directory
73 log show revision history of entire repository or files
73 log show revision history of entire repository or files
74 merge merge another revision into working directory
74 merge merge another revision into working directory
75 pull pull changes from the specified source
75 pull pull changes from the specified source
76 push push changes to the specified destination
76 push push changes to the specified destination
77 remove remove the specified files on the next commit
77 remove remove the specified files on the next commit
78 serve start stand-alone webserver
78 serve start stand-alone webserver
79 status show changed files in the working directory
79 status show changed files in the working directory
80 summary summarize working directory state
80 summary summarize working directory state
81 update update working directory (or switch revisions)
81 update update working directory (or switch revisions)
82
82
83 (use 'hg help' for the full list of commands or 'hg -v' for details)
83 (use 'hg help' for the full list of commands or 'hg -v' for details)
84 *** runcommand id --quiet
84 *** runcommand id --quiet
85 000000000000
85 000000000000
86 *** runcommand id
86 *** runcommand id
87 000000000000 tip
87 000000000000 tip
88 *** runcommand id --config ui.quiet=True
88 *** runcommand id --config ui.quiet=True
89 000000000000
89 000000000000
90 *** runcommand id
90 *** runcommand id
91 000000000000 tip
91 000000000000 tip
92 *** runcommand id -runknown
92 *** runcommand id -runknown
93 abort: unknown revision 'unknown'!
93 abort: unknown revision 'unknown'!
94 [255]
94 [255]
95
95
96 >>> from hgclient import bprint, check, readchannel
96 >>> from hgclient import bprint, check, readchannel
97 >>> @check
97 >>> @check
98 ... def inputeof(server):
98 ... def inputeof(server):
99 ... readchannel(server)
99 ... readchannel(server)
100 ... server.stdin.write(b'runcommand\n')
100 ... server.stdin.write(b'runcommand\n')
101 ... # close stdin while server is waiting for input
101 ... # close stdin while server is waiting for input
102 ... server.stdin.close()
102 ... server.stdin.close()
103 ...
103 ...
104 ... # server exits with 1 if the pipe closed while reading the command
104 ... # server exits with 1 if the pipe closed while reading the command
105 ... bprint(b'server exit code =', b'%d' % server.wait())
105 ... bprint(b'server exit code =', b'%d' % server.wait())
106 server exit code = 1
106 server exit code = 1
107
107
108 >>> from hgclient import check, readchannel, runcommand, stringio
108 >>> from hgclient import check, readchannel, runcommand, stringio
109 >>> @check
109 >>> @check
110 ... def serverinput(server):
110 ... def serverinput(server):
111 ... readchannel(server)
111 ... readchannel(server)
112 ...
112 ...
113 ... patch = b"""
113 ... patch = b"""
114 ... # HG changeset patch
114 ... # HG changeset patch
115 ... # User test
115 ... # User test
116 ... # Date 0 0
116 ... # Date 0 0
117 ... # Node ID c103a3dec114d882c98382d684d8af798d09d857
117 ... # Node ID c103a3dec114d882c98382d684d8af798d09d857
118 ... # Parent 0000000000000000000000000000000000000000
118 ... # Parent 0000000000000000000000000000000000000000
119 ... 1
119 ... 1
120 ...
120 ...
121 ... diff -r 000000000000 -r c103a3dec114 a
121 ... diff -r 000000000000 -r c103a3dec114 a
122 ... --- /dev/null Thu Jan 01 00:00:00 1970 +0000
122 ... --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123 ... +++ b/a Thu Jan 01 00:00:00 1970 +0000
123 ... +++ b/a Thu Jan 01 00:00:00 1970 +0000
124 ... @@ -0,0 +1,1 @@
124 ... @@ -0,0 +1,1 @@
125 ... +1
125 ... +1
126 ... """
126 ... """
127 ...
127 ...
128 ... runcommand(server, [b'import', b'-'], input=stringio(patch))
128 ... runcommand(server, [b'import', b'-'], input=stringio(patch))
129 ... runcommand(server, [b'log'])
129 ... runcommand(server, [b'log'])
130 *** runcommand import -
130 *** runcommand import -
131 applying patch from stdin
131 applying patch from stdin
132 *** runcommand log
132 *** runcommand log
133 changeset: 0:eff892de26ec
133 changeset: 0:eff892de26ec
134 tag: tip
134 tag: tip
135 user: test
135 user: test
136 date: Thu Jan 01 00:00:00 1970 +0000
136 date: Thu Jan 01 00:00:00 1970 +0000
137 summary: 1
137 summary: 1
138
138
139
139
140 check strict parsing of early options:
140 check strict parsing of early options:
141
141
142 >>> import os
142 >>> import os
143 >>> from hgclient import check, readchannel, runcommand
143 >>> from hgclient import check, readchannel, runcommand
144 >>> os.environ['HGPLAIN'] = '+strictflags'
144 >>> os.environ['HGPLAIN'] = '+strictflags'
145 >>> @check
145 >>> @check
146 ... def cwd(server):
146 ... def cwd(server):
147 ... readchannel(server)
147 ... readchannel(server)
148 ... runcommand(server, [b'log', b'-b', b'--config=alias.log=!echo pwned',
148 ... runcommand(server, [b'log', b'-b', b'--config=alias.log=!echo pwned',
149 ... b'default'])
149 ... b'default'])
150 *** runcommand log -b --config=alias.log=!echo pwned default
150 *** runcommand log -b --config=alias.log=!echo pwned default
151 abort: unknown revision '--config=alias.log=!echo pwned'!
151 abort: unknown revision '--config=alias.log=!echo pwned'!
152 [255]
152 [255]
153
153
154 check that "histedit --commands=-" can read rules from the input channel:
154 check that "histedit --commands=-" can read rules from the input channel:
155
155
156 >>> from hgclient import check, readchannel, runcommand, stringio
156 >>> from hgclient import check, readchannel, runcommand, stringio
157 >>> @check
157 >>> @check
158 ... def serverinput(server):
158 ... def serverinput(server):
159 ... readchannel(server)
159 ... readchannel(server)
160 ... rules = b'pick eff892de26ec\n'
160 ... rules = b'pick eff892de26ec\n'
161 ... runcommand(server, [b'histedit', b'0', b'--commands=-',
161 ... runcommand(server, [b'histedit', b'0', b'--commands=-',
162 ... b'--config', b'extensions.histedit='],
162 ... b'--config', b'extensions.histedit='],
163 ... input=stringio(rules))
163 ... input=stringio(rules))
164 *** runcommand histedit 0 --commands=- --config extensions.histedit=
164 *** runcommand histedit 0 --commands=- --config extensions.histedit=
165
165
166 check that --cwd doesn't persist between requests:
166 check that --cwd doesn't persist between requests:
167
167
168 $ mkdir foo
168 $ mkdir foo
169 $ touch foo/bar
169 $ touch foo/bar
170 >>> from hgclient import check, readchannel, runcommand
170 >>> from hgclient import check, readchannel, runcommand
171 >>> @check
171 >>> @check
172 ... def cwd(server):
172 ... def cwd(server):
173 ... readchannel(server)
173 ... readchannel(server)
174 ... runcommand(server, [b'--cwd', b'foo', b'st', b'bar'])
174 ... runcommand(server, [b'--cwd', b'foo', b'st', b'bar'])
175 ... runcommand(server, [b'st', b'foo/bar'])
175 ... runcommand(server, [b'st', b'foo/bar'])
176 *** runcommand --cwd foo st bar
176 *** runcommand --cwd foo st bar
177 ? bar
177 ? bar
178 *** runcommand st foo/bar
178 *** runcommand st foo/bar
179 ? foo/bar
179 ? foo/bar
180
180
181 $ rm foo/bar
181 $ rm foo/bar
182
182
183
183
184 check that local configs for the cached repo aren't inherited when -R is used:
184 check that local configs for the cached repo aren't inherited when -R is used:
185
185
186 $ cat <<EOF >> .hg/hgrc
186 $ cat <<EOF >> .hg/hgrc
187 > [ui]
187 > [ui]
188 > foo = bar
188 > foo = bar
189 > EOF
189 > EOF
190
190
191 #if no-extraextensions
191 #if no-extraextensions
192
192
193 >>> from hgclient import check, readchannel, runcommand, sep
193 >>> from hgclient import check, readchannel, runcommand, sep
194 >>> @check
194 >>> @check
195 ... def localhgrc(server):
195 ... def localhgrc(server):
196 ... readchannel(server)
196 ... readchannel(server)
197 ...
197 ...
198 ... # the cached repo local hgrc contains ui.foo=bar, so showconfig should
198 ... # the cached repo local hgrc contains ui.foo=bar, so showconfig should
199 ... # show it
199 ... # show it
200 ... runcommand(server, [b'showconfig'], outfilter=sep)
200 ... runcommand(server, [b'showconfig'], outfilter=sep)
201 ...
201 ...
202 ... # but not for this repo
202 ... # but not for this repo
203 ... runcommand(server, [b'init', b'foo'])
203 ... runcommand(server, [b'init', b'foo'])
204 ... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults'])
204 ... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults'])
205 *** runcommand showconfig
205 *** runcommand showconfig
206 bundle.mainreporoot=$TESTTMP/repo
206 bundle.mainreporoot=$TESTTMP/repo
207 devel.all-warnings=true
207 devel.all-warnings=true
208 devel.default-date=0 0
208 devel.default-date=0 0
209 extensions.fsmonitor= (fsmonitor !)
209 extensions.fsmonitor= (fsmonitor !)
210 largefiles.usercache=$TESTTMP/.cache/largefiles
210 largefiles.usercache=$TESTTMP/.cache/largefiles
211 lfs.usercache=$TESTTMP/.cache/lfs
211 lfs.usercache=$TESTTMP/.cache/lfs
212 ui.slash=True
212 ui.slash=True
213 ui.interactive=False
213 ui.interactive=False
214 ui.merge=internal:merge
214 ui.merge=internal:merge
215 ui.mergemarkers=detailed
215 ui.mergemarkers=detailed
216 ui.foo=bar
216 ui.foo=bar
217 ui.nontty=true
217 ui.nontty=true
218 web.address=localhost
218 web.address=localhost
219 web\.ipv6=(?:True|False) (re)
219 web\.ipv6=(?:True|False) (re)
220 web.server-header=testing stub value
220 web.server-header=testing stub value
221 *** runcommand init foo
221 *** runcommand init foo
222 *** runcommand -R foo showconfig ui defaults
222 *** runcommand -R foo showconfig ui defaults
223 ui.slash=True
223 ui.slash=True
224 ui.interactive=False
224 ui.interactive=False
225 ui.merge=internal:merge
225 ui.merge=internal:merge
226 ui.mergemarkers=detailed
226 ui.mergemarkers=detailed
227 ui.nontty=true
227 ui.nontty=true
228 #endif
228 #endif
229
229
230 $ rm -R foo
230 $ rm -R foo
231
231
232 #if windows
232 #if windows
233 $ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH"
233 $ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH"
234 #else
234 #else
235 $ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH"
235 $ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH"
236 #endif
236 #endif
237
237
238 $ cat <<EOF > hook.py
238 $ cat <<EOF > hook.py
239 > import sys
239 > import sys
240 > from hgclient import bprint
240 > from hgclient import bprint
241 > def hook(**args):
241 > def hook(**args):
242 > bprint(b'hook talking')
242 > bprint(b'hook talking')
243 > bprint(b'now try to read something: %r' % sys.stdin.read())
243 > bprint(b'now try to read something: %r' % sys.stdin.read())
244 > EOF
244 > EOF
245
245
246 >>> from hgclient import check, readchannel, runcommand, stringio
246 >>> from hgclient import check, readchannel, runcommand, stringio
247 >>> @check
247 >>> @check
248 ... def hookoutput(server):
248 ... def hookoutput(server):
249 ... readchannel(server)
249 ... readchannel(server)
250 ... runcommand(server, [b'--config',
250 ... runcommand(server, [b'--config',
251 ... b'hooks.pre-identify=python:hook.hook',
251 ... b'hooks.pre-identify=python:hook.hook',
252 ... b'id'],
252 ... b'id'],
253 ... input=stringio(b'some input'))
253 ... input=stringio(b'some input'))
254 *** runcommand --config hooks.pre-identify=python:hook.hook id
254 *** runcommand --config hooks.pre-identify=python:hook.hook id
255 eff892de26ec tip
255 eff892de26ec tip
256 hook talking
256 hook talking
257 now try to read something: ''
257 now try to read something: ''
258
258
259 Clean hook cached version
259 Clean hook cached version
260 $ rm hook.py*
260 $ rm hook.py*
261 $ rm -Rf __pycache__
261 $ rm -Rf __pycache__
262
262
263 $ echo a >> a
263 $ echo a >> a
264 >>> import os
264 >>> import os
265 >>> from hgclient import check, readchannel, runcommand
265 >>> from hgclient import check, readchannel, runcommand
266 >>> @check
266 >>> @check
267 ... def outsidechanges(server):
267 ... def outsidechanges(server):
268 ... readchannel(server)
268 ... readchannel(server)
269 ... runcommand(server, [b'status'])
269 ... runcommand(server, [b'status'])
270 ... os.system('hg ci -Am2')
270 ... os.system('hg ci -Am2')
271 ... runcommand(server, [b'tip'])
271 ... runcommand(server, [b'tip'])
272 ... runcommand(server, [b'status'])
272 ... runcommand(server, [b'status'])
273 *** runcommand status
273 *** runcommand status
274 M a
274 M a
275 *** runcommand tip
275 *** runcommand tip
276 changeset: 1:d3a0a68be6de
276 changeset: 1:d3a0a68be6de
277 tag: tip
277 tag: tip
278 user: test
278 user: test
279 date: Thu Jan 01 00:00:00 1970 +0000
279 date: Thu Jan 01 00:00:00 1970 +0000
280 summary: 2
280 summary: 2
281
281
282 *** runcommand status
282 *** runcommand status
283
283
284 >>> import os
284 >>> import os
285 >>> from hgclient import bprint, check, readchannel, runcommand
285 >>> from hgclient import bprint, check, readchannel, runcommand
286 >>> @check
286 >>> @check
287 ... def bookmarks(server):
287 ... def bookmarks(server):
288 ... readchannel(server)
288 ... readchannel(server)
289 ... runcommand(server, [b'bookmarks'])
289 ... runcommand(server, [b'bookmarks'])
290 ...
290 ...
291 ... # changes .hg/bookmarks
291 ... # changes .hg/bookmarks
292 ... os.system('hg bookmark -i bm1')
292 ... os.system('hg bookmark -i bm1')
293 ... os.system('hg bookmark -i bm2')
293 ... os.system('hg bookmark -i bm2')
294 ... runcommand(server, [b'bookmarks'])
294 ... runcommand(server, [b'bookmarks'])
295 ...
295 ...
296 ... # changes .hg/bookmarks.current
296 ... # changes .hg/bookmarks.current
297 ... os.system('hg upd bm1 -q')
297 ... os.system('hg upd bm1 -q')
298 ... runcommand(server, [b'bookmarks'])
298 ... runcommand(server, [b'bookmarks'])
299 ...
299 ...
300 ... runcommand(server, [b'bookmarks', b'bm3'])
300 ... runcommand(server, [b'bookmarks', b'bm3'])
301 ... f = open('a', 'ab')
301 ... f = open('a', 'ab')
302 ... f.write(b'a\n') and None
302 ... f.write(b'a\n') and None
303 ... f.close()
303 ... f.close()
304 ... runcommand(server, [b'commit', b'-Amm'])
304 ... runcommand(server, [b'commit', b'-Amm'])
305 ... runcommand(server, [b'bookmarks'])
305 ... runcommand(server, [b'bookmarks'])
306 ... bprint(b'')
306 ... bprint(b'')
307 *** runcommand bookmarks
307 *** runcommand bookmarks
308 no bookmarks set
308 no bookmarks set
309 *** runcommand bookmarks
309 *** runcommand bookmarks
310 bm1 1:d3a0a68be6de
310 bm1 1:d3a0a68be6de
311 bm2 1:d3a0a68be6de
311 bm2 1:d3a0a68be6de
312 *** runcommand bookmarks
312 *** runcommand bookmarks
313 * bm1 1:d3a0a68be6de
313 * bm1 1:d3a0a68be6de
314 bm2 1:d3a0a68be6de
314 bm2 1:d3a0a68be6de
315 *** runcommand bookmarks bm3
315 *** runcommand bookmarks bm3
316 *** runcommand commit -Amm
316 *** runcommand commit -Amm
317 *** runcommand bookmarks
317 *** runcommand bookmarks
318 bm1 1:d3a0a68be6de
318 bm1 1:d3a0a68be6de
319 bm2 1:d3a0a68be6de
319 bm2 1:d3a0a68be6de
320 * bm3 2:aef17e88f5f0
320 * bm3 2:aef17e88f5f0
321
321
322
322
323 >>> import os
323 >>> import os
324 >>> from hgclient import check, readchannel, runcommand
324 >>> from hgclient import check, readchannel, runcommand
325 >>> @check
325 >>> @check
326 ... def tagscache(server):
326 ... def tagscache(server):
327 ... readchannel(server)
327 ... readchannel(server)
328 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
328 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
329 ... os.system('hg tag -r 0 foo')
329 ... os.system('hg tag -r 0 foo')
330 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
330 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
331 *** runcommand id -t -r 0
331 *** runcommand id -t -r 0
332
332
333 *** runcommand id -t -r 0
333 *** runcommand id -t -r 0
334 foo
334 foo
335
335
336 >>> import os
336 >>> import os
337 >>> from hgclient import check, readchannel, runcommand
337 >>> from hgclient import check, readchannel, runcommand
338 >>> @check
338 >>> @check
339 ... def setphase(server):
339 ... def setphase(server):
340 ... readchannel(server)
340 ... readchannel(server)
341 ... runcommand(server, [b'phase', b'-r', b'.'])
341 ... runcommand(server, [b'phase', b'-r', b'.'])
342 ... os.system('hg phase -r . -p')
342 ... os.system('hg phase -r . -p')
343 ... runcommand(server, [b'phase', b'-r', b'.'])
343 ... runcommand(server, [b'phase', b'-r', b'.'])
344 *** runcommand phase -r .
344 *** runcommand phase -r .
345 3: draft
345 3: draft
346 *** runcommand phase -r .
346 *** runcommand phase -r .
347 3: public
347 3: public
348
348
349 $ echo a >> a
349 $ echo a >> a
350 >>> from hgclient import bprint, check, readchannel, runcommand
350 >>> from hgclient import bprint, check, readchannel, runcommand
351 >>> @check
351 >>> @check
352 ... def rollback(server):
352 ... def rollback(server):
353 ... readchannel(server)
353 ... readchannel(server)
354 ... runcommand(server, [b'phase', b'-r', b'.', b'-p'])
354 ... runcommand(server, [b'phase', b'-r', b'.', b'-p'])
355 ... runcommand(server, [b'commit', b'-Am.'])
355 ... runcommand(server, [b'commit', b'-Am.'])
356 ... runcommand(server, [b'rollback'])
356 ... runcommand(server, [b'rollback'])
357 ... runcommand(server, [b'phase', b'-r', b'.'])
357 ... runcommand(server, [b'phase', b'-r', b'.'])
358 ... bprint(b'')
358 ... bprint(b'')
359 *** runcommand phase -r . -p
359 *** runcommand phase -r . -p
360 no phases changed
360 no phases changed
361 *** runcommand commit -Am.
361 *** runcommand commit -Am.
362 *** runcommand rollback
362 *** runcommand rollback
363 repository tip rolled back to revision 3 (undo commit)
363 repository tip rolled back to revision 3 (undo commit)
364 working directory now based on revision 3
364 working directory now based on revision 3
365 *** runcommand phase -r .
365 *** runcommand phase -r .
366 3: public
366 3: public
367
367
368
368
369 >>> import os
369 >>> import os
370 >>> from hgclient import check, readchannel, runcommand
370 >>> from hgclient import check, readchannel, runcommand
371 >>> @check
371 >>> @check
372 ... def branch(server):
372 ... def branch(server):
373 ... readchannel(server)
373 ... readchannel(server)
374 ... runcommand(server, [b'branch'])
374 ... runcommand(server, [b'branch'])
375 ... os.system('hg branch foo')
375 ... os.system('hg branch foo')
376 ... runcommand(server, [b'branch'])
376 ... runcommand(server, [b'branch'])
377 ... os.system('hg branch default')
377 ... os.system('hg branch default')
378 *** runcommand branch
378 *** runcommand branch
379 default
379 default
380 marked working directory as branch foo
380 marked working directory as branch foo
381 (branches are permanent and global, did you want a bookmark?)
381 (branches are permanent and global, did you want a bookmark?)
382 *** runcommand branch
382 *** runcommand branch
383 foo
383 foo
384 marked working directory as branch default
384 marked working directory as branch default
385 (branches are permanent and global, did you want a bookmark?)
385 (branches are permanent and global, did you want a bookmark?)
386
386
387 $ touch .hgignore
387 $ touch .hgignore
388 >>> import os
388 >>> import os
389 >>> from hgclient import bprint, check, readchannel, runcommand
389 >>> from hgclient import bprint, check, readchannel, runcommand
390 >>> @check
390 >>> @check
391 ... def hgignore(server):
391 ... def hgignore(server):
392 ... readchannel(server)
392 ... readchannel(server)
393 ... runcommand(server, [b'commit', b'-Am.'])
393 ... runcommand(server, [b'commit', b'-Am.'])
394 ... f = open('ignored-file', 'ab')
394 ... f = open('ignored-file', 'ab')
395 ... f.write(b'') and None
395 ... f.write(b'') and None
396 ... f.close()
396 ... f.close()
397 ... f = open('.hgignore', 'ab')
397 ... f = open('.hgignore', 'ab')
398 ... f.write(b'ignored-file')
398 ... f.write(b'ignored-file')
399 ... f.close()
399 ... f.close()
400 ... runcommand(server, [b'status', b'-i', b'-u'])
400 ... runcommand(server, [b'status', b'-i', b'-u'])
401 ... bprint(b'')
401 ... bprint(b'')
402 *** runcommand commit -Am.
402 *** runcommand commit -Am.
403 adding .hgignore
403 adding .hgignore
404 *** runcommand status -i -u
404 *** runcommand status -i -u
405 I ignored-file
405 I ignored-file
406
406
407
407
408 cache of non-public revisions should be invalidated on repository change
408 cache of non-public revisions should be invalidated on repository change
409 (issue4855):
409 (issue4855):
410
410
411 >>> import os
411 >>> import os
412 >>> from hgclient import bprint, check, readchannel, runcommand
412 >>> from hgclient import bprint, check, readchannel, runcommand
413 >>> @check
413 >>> @check
414 ... def phasesetscacheaftercommit(server):
414 ... def phasesetscacheaftercommit(server):
415 ... readchannel(server)
415 ... readchannel(server)
416 ... # load _phasecache._phaserevs and _phasesets
416 ... # load _phasecache._phaserevs and _phasesets
417 ... runcommand(server, [b'log', b'-qr', b'draft()'])
417 ... runcommand(server, [b'log', b'-qr', b'draft()'])
418 ... # create draft commits by another process
418 ... # create draft commits by another process
419 ... for i in range(5, 7):
419 ... for i in range(5, 7):
420 ... f = open('a', 'ab')
420 ... f = open('a', 'ab')
421 ... f.seek(0, os.SEEK_END)
421 ... f.seek(0, os.SEEK_END)
422 ... f.write(b'a\n') and None
422 ... f.write(b'a\n') and None
423 ... f.close()
423 ... f.close()
424 ... os.system('hg commit -Aqm%d' % i)
424 ... os.system('hg commit -Aqm%d' % i)
425 ... # new commits should be listed as draft revisions
425 ... # new commits should be listed as draft revisions
426 ... runcommand(server, [b'log', b'-qr', b'draft()'])
426 ... runcommand(server, [b'log', b'-qr', b'draft()'])
427 ... bprint(b'')
427 ... bprint(b'')
428 *** runcommand log -qr draft()
428 *** runcommand log -qr draft()
429 4:7966c8e3734d
429 4:7966c8e3734d
430 *** runcommand log -qr draft()
430 *** runcommand log -qr draft()
431 4:7966c8e3734d
431 4:7966c8e3734d
432 5:41f6602d1c4f
432 5:41f6602d1c4f
433 6:10501e202c35
433 6:10501e202c35
434
434
435
435
436 >>> import os
436 >>> import os
437 >>> from hgclient import bprint, check, readchannel, runcommand
437 >>> from hgclient import bprint, check, readchannel, runcommand
438 >>> @check
438 >>> @check
439 ... def phasesetscacheafterstrip(server):
439 ... def phasesetscacheafterstrip(server):
440 ... readchannel(server)
440 ... readchannel(server)
441 ... # load _phasecache._phaserevs and _phasesets
441 ... # load _phasecache._phaserevs and _phasesets
442 ... runcommand(server, [b'log', b'-qr', b'draft()'])
442 ... runcommand(server, [b'log', b'-qr', b'draft()'])
443 ... # strip cached revisions by another process
443 ... # strip cached revisions by another process
444 ... os.system('hg --config extensions.strip= strip -q 5')
444 ... os.system('hg --config extensions.strip= strip -q 5')
445 ... # shouldn't abort by "unknown revision '6'"
445 ... # shouldn't abort by "unknown revision '6'"
446 ... runcommand(server, [b'log', b'-qr', b'draft()'])
446 ... runcommand(server, [b'log', b'-qr', b'draft()'])
447 ... bprint(b'')
447 ... bprint(b'')
448 *** runcommand log -qr draft()
448 *** runcommand log -qr draft()
449 4:7966c8e3734d
449 4:7966c8e3734d
450 5:41f6602d1c4f
450 5:41f6602d1c4f
451 6:10501e202c35
451 6:10501e202c35
452 *** runcommand log -qr draft()
452 *** runcommand log -qr draft()
453 4:7966c8e3734d
453 4:7966c8e3734d
454
454
455
455
456 cache of phase roots should be invalidated on strip (issue3827):
456 cache of phase roots should be invalidated on strip (issue3827):
457
457
458 >>> import os
458 >>> import os
459 >>> from hgclient import check, readchannel, runcommand, sep
459 >>> from hgclient import check, readchannel, runcommand, sep
460 >>> @check
460 >>> @check
461 ... def phasecacheafterstrip(server):
461 ... def phasecacheafterstrip(server):
462 ... readchannel(server)
462 ... readchannel(server)
463 ...
463 ...
464 ... # create new head, 5:731265503d86
464 ... # create new head, 5:731265503d86
465 ... runcommand(server, [b'update', b'-C', b'0'])
465 ... runcommand(server, [b'update', b'-C', b'0'])
466 ... f = open('a', 'ab')
466 ... f = open('a', 'ab')
467 ... f.write(b'a\n') and None
467 ... f.write(b'a\n') and None
468 ... f.close()
468 ... f.close()
469 ... runcommand(server, [b'commit', b'-Am.', b'a'])
469 ... runcommand(server, [b'commit', b'-Am.', b'a'])
470 ... runcommand(server, [b'log', b'-Gq'])
470 ... runcommand(server, [b'log', b'-Gq'])
471 ...
471 ...
472 ... # make it public; draft marker moves to 4:7966c8e3734d
472 ... # make it public; draft marker moves to 4:7966c8e3734d
473 ... runcommand(server, [b'phase', b'-p', b'.'])
473 ... runcommand(server, [b'phase', b'-p', b'.'])
474 ... # load _phasecache.phaseroots
474 ... # load _phasecache.phaseroots
475 ... runcommand(server, [b'phase', b'.'], outfilter=sep)
475 ... runcommand(server, [b'phase', b'.'], outfilter=sep)
476 ...
476 ...
477 ... # strip 1::4 outside server
477 ... # strip 1::4 outside server
478 ... os.system('hg -q --config extensions.mq= strip 1')
478 ... os.system('hg -q --config extensions.mq= strip 1')
479 ...
479 ...
480 ... # shouldn't raise "7966c8e3734d: no node!"
480 ... # shouldn't raise "7966c8e3734d: no node!"
481 ... runcommand(server, [b'branches'])
481 ... runcommand(server, [b'branches'])
482 *** runcommand update -C 0
482 *** runcommand update -C 0
483 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
483 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
484 (leaving bookmark bm3)
484 (leaving bookmark bm3)
485 *** runcommand commit -Am. a
485 *** runcommand commit -Am. a
486 created new head
486 created new head
487 *** runcommand log -Gq
487 *** runcommand log -Gq
488 @ 5:731265503d86
488 @ 5:731265503d86
489 |
489 |
490 | o 4:7966c8e3734d
490 | o 4:7966c8e3734d
491 | |
491 | |
492 | o 3:b9b85890c400
492 | o 3:b9b85890c400
493 | |
493 | |
494 | o 2:aef17e88f5f0
494 | o 2:aef17e88f5f0
495 | |
495 | |
496 | o 1:d3a0a68be6de
496 | o 1:d3a0a68be6de
497 |/
497 |/
498 o 0:eff892de26ec
498 o 0:eff892de26ec
499
499
500 *** runcommand phase -p .
500 *** runcommand phase -p .
501 *** runcommand phase .
501 *** runcommand phase .
502 5: public
502 5: public
503 *** runcommand branches
503 *** runcommand branches
504 default 1:731265503d86
504 default 1:731265503d86
505
505
506 in-memory cache must be reloaded if transaction is aborted. otherwise
506 in-memory cache must be reloaded if transaction is aborted. otherwise
507 changelog and manifest would have invalid node:
507 changelog and manifest would have invalid node:
508
508
509 $ echo a >> a
509 $ echo a >> a
510 >>> from hgclient import check, readchannel, runcommand
510 >>> from hgclient import check, readchannel, runcommand
511 >>> @check
511 >>> @check
512 ... def txabort(server):
512 ... def txabort(server):
513 ... readchannel(server)
513 ... readchannel(server)
514 ... runcommand(server, [b'commit', b'--config', b'hooks.pretxncommit=false',
514 ... runcommand(server, [b'commit', b'--config', b'hooks.pretxncommit=false',
515 ... b'-mfoo'])
515 ... b'-mfoo'])
516 ... runcommand(server, [b'verify'])
516 ... runcommand(server, [b'verify'])
517 *** runcommand commit --config hooks.pretxncommit=false -mfoo
517 *** runcommand commit --config hooks.pretxncommit=false -mfoo
518 transaction abort!
518 transaction abort!
519 rollback completed
519 rollback completed
520 abort: pretxncommit hook exited with status 1
520 abort: pretxncommit hook exited with status 1
521 [255]
521 [255]
522 *** runcommand verify
522 *** runcommand verify
523 checking changesets
523 checking changesets
524 checking manifests
524 checking manifests
525 crosschecking files in changesets and manifests
525 crosschecking files in changesets and manifests
526 checking files
526 checking files
527 checked 2 changesets with 2 changes to 1 files
527 checked 2 changesets with 2 changes to 1 files
528 $ hg revert --no-backup -aq
528 $ hg revert --no-backup -aq
529
529
530 $ cat >> .hg/hgrc << EOF
530 $ cat >> .hg/hgrc << EOF
531 > [experimental]
531 > [experimental]
532 > evolution.createmarkers=True
532 > evolution.createmarkers=True
533 > EOF
533 > EOF
534
534
535 >>> import os
535 >>> import os
536 >>> from hgclient import check, readchannel, runcommand
536 >>> from hgclient import check, readchannel, runcommand
537 >>> @check
537 >>> @check
538 ... def obsolete(server):
538 ... def obsolete(server):
539 ... readchannel(server)
539 ... readchannel(server)
540 ...
540 ...
541 ... runcommand(server, [b'up', b'null'])
541 ... runcommand(server, [b'up', b'null'])
542 ... runcommand(server, [b'phase', b'-df', b'tip'])
542 ... runcommand(server, [b'phase', b'-df', b'tip'])
543 ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
543 ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
544 ... if os.name == 'nt':
544 ... if os.name == 'nt':
545 ... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
545 ... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
546 ... os.system(cmd)
546 ... os.system(cmd)
547 ... runcommand(server, [b'log', b'--hidden'])
547 ... runcommand(server, [b'log', b'--hidden'])
548 ... runcommand(server, [b'log'])
548 ... runcommand(server, [b'log'])
549 *** runcommand up null
549 *** runcommand up null
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
551 *** runcommand phase -df tip
551 *** runcommand phase -df tip
552 obsoleted 1 changesets
552 obsoleted 1 changesets
553 *** runcommand log --hidden
553 *** runcommand log --hidden
554 changeset: 1:731265503d86
554 changeset: 1:731265503d86
555 tag: tip
555 tag: tip
556 user: test
556 user: test
557 date: Thu Jan 01 00:00:00 1970 +0000
557 date: Thu Jan 01 00:00:00 1970 +0000
558 obsolete: pruned
558 obsolete: pruned
559 summary: .
559 summary: .
560
560
561 changeset: 0:eff892de26ec
561 changeset: 0:eff892de26ec
562 bookmark: bm1
562 bookmark: bm1
563 bookmark: bm2
563 bookmark: bm2
564 bookmark: bm3
564 bookmark: bm3
565 user: test
565 user: test
566 date: Thu Jan 01 00:00:00 1970 +0000
566 date: Thu Jan 01 00:00:00 1970 +0000
567 summary: 1
567 summary: 1
568
568
569 *** runcommand log
569 *** runcommand log
570 changeset: 0:eff892de26ec
570 changeset: 0:eff892de26ec
571 bookmark: bm1
571 bookmark: bm1
572 bookmark: bm2
572 bookmark: bm2
573 bookmark: bm3
573 bookmark: bm3
574 tag: tip
574 tag: tip
575 user: test
575 user: test
576 date: Thu Jan 01 00:00:00 1970 +0000
576 date: Thu Jan 01 00:00:00 1970 +0000
577 summary: 1
577 summary: 1
578
578
579
579
580 $ cat <<EOF >> .hg/hgrc
580 $ cat <<EOF >> .hg/hgrc
581 > [extensions]
581 > [extensions]
582 > mq =
582 > mq =
583 > EOF
583 > EOF
584
584
585 >>> import os
585 >>> import os
586 >>> from hgclient import check, readchannel, runcommand
586 >>> from hgclient import check, readchannel, runcommand
587 >>> @check
587 >>> @check
588 ... def mqoutsidechanges(server):
588 ... def mqoutsidechanges(server):
589 ... readchannel(server)
589 ... readchannel(server)
590 ...
590 ...
591 ... # load repo.mq
591 ... # load repo.mq
592 ... runcommand(server, [b'qapplied'])
592 ... runcommand(server, [b'qapplied'])
593 ... os.system('hg qnew 0.diff')
593 ... os.system('hg qnew 0.diff')
594 ... # repo.mq should be invalidated
594 ... # repo.mq should be invalidated
595 ... runcommand(server, [b'qapplied'])
595 ... runcommand(server, [b'qapplied'])
596 ...
596 ...
597 ... runcommand(server, [b'qpop', b'--all'])
597 ... runcommand(server, [b'qpop', b'--all'])
598 ... os.system('hg qqueue --create foo')
598 ... os.system('hg qqueue --create foo')
599 ... # repo.mq should be recreated to point to new queue
599 ... # repo.mq should be recreated to point to new queue
600 ... runcommand(server, [b'qqueue', b'--active'])
600 ... runcommand(server, [b'qqueue', b'--active'])
601 *** runcommand qapplied
601 *** runcommand qapplied
602 *** runcommand qapplied
602 *** runcommand qapplied
603 0.diff
603 0.diff
604 *** runcommand qpop --all
604 *** runcommand qpop --all
605 popping 0.diff
605 popping 0.diff
606 patch queue now empty
606 patch queue now empty
607 *** runcommand qqueue --active
607 *** runcommand qqueue --active
608 foo
608 foo
609
609
610 $ cat <<'EOF' > ../dbgui.py
610 $ cat <<'EOF' > ../dbgui.py
611 > import os
611 > import os
612 > import sys
612 > import sys
613 > from mercurial import commands, registrar
613 > from mercurial import commands, registrar
614 > cmdtable = {}
614 > cmdtable = {}
615 > command = registrar.command(cmdtable)
615 > command = registrar.command(cmdtable)
616 > @command(b"debuggetpass", norepo=True)
616 > @command(b"debuggetpass", norepo=True)
617 > def debuggetpass(ui):
617 > def debuggetpass(ui):
618 > ui.write(b"%s\n" % ui.getpass())
618 > ui.write(b"%s\n" % ui.getpass())
619 > @command(b"debugprompt", norepo=True)
619 > @command(b"debugprompt", norepo=True)
620 > def debugprompt(ui):
620 > def debugprompt(ui):
621 > ui.write(b"%s\n" % ui.prompt(b"prompt:"))
621 > ui.write(b"%s\n" % ui.prompt(b"prompt:"))
622 > @command(b"debugpromptchoice", norepo=True)
622 > @command(b"debugpromptchoice", norepo=True)
623 > def debugpromptchoice(ui):
623 > def debugpromptchoice(ui):
624 > msg = b"promptchoice (y/n)? $$ &Yes $$ &No"
624 > msg = b"promptchoice (y/n)? $$ &Yes $$ &No"
625 > ui.write(b"%d\n" % ui.promptchoice(msg))
625 > ui.write(b"%d\n" % ui.promptchoice(msg))
626 > @command(b"debugreadstdin", norepo=True)
626 > @command(b"debugreadstdin", norepo=True)
627 > def debugreadstdin(ui):
627 > def debugreadstdin(ui):
628 > ui.write(b"read: %r\n" % sys.stdin.read(1))
628 > ui.write(b"read: %r\n" % sys.stdin.read(1))
629 > @command(b"debugwritestdout", norepo=True)
629 > @command(b"debugwritestdout", norepo=True)
630 > def debugwritestdout(ui):
630 > def debugwritestdout(ui):
631 > os.write(1, b"low-level stdout fd and\n")
631 > os.write(1, b"low-level stdout fd and\n")
632 > sys.stdout.write("stdout should be redirected to stderr\n")
632 > sys.stdout.write("stdout should be redirected to stderr\n")
633 > sys.stdout.flush()
633 > sys.stdout.flush()
634 > EOF
634 > EOF
635 $ cat <<EOF >> .hg/hgrc
635 $ cat <<EOF >> .hg/hgrc
636 > [extensions]
636 > [extensions]
637 > dbgui = ../dbgui.py
637 > dbgui = ../dbgui.py
638 > EOF
638 > EOF
639
639
640 >>> from hgclient import check, readchannel, runcommand, stringio
640 >>> from hgclient import check, readchannel, runcommand, stringio
641 >>> @check
641 >>> @check
642 ... def getpass(server):
642 ... def getpass(server):
643 ... readchannel(server)
643 ... readchannel(server)
644 ... runcommand(server, [b'debuggetpass', b'--config',
644 ... runcommand(server, [b'debuggetpass', b'--config',
645 ... b'ui.interactive=True'],
645 ... b'ui.interactive=True'],
646 ... input=stringio(b'1234\n'))
646 ... input=stringio(b'1234\n'))
647 ... runcommand(server, [b'debuggetpass', b'--config',
647 ... runcommand(server, [b'debuggetpass', b'--config',
648 ... b'ui.interactive=True'],
648 ... b'ui.interactive=True'],
649 ... input=stringio(b'\n'))
649 ... input=stringio(b'\n'))
650 ... runcommand(server, [b'debuggetpass', b'--config',
650 ... runcommand(server, [b'debuggetpass', b'--config',
651 ... b'ui.interactive=True'],
651 ... b'ui.interactive=True'],
652 ... input=stringio(b''))
652 ... input=stringio(b''))
653 ... runcommand(server, [b'debugprompt', b'--config',
653 ... runcommand(server, [b'debugprompt', b'--config',
654 ... b'ui.interactive=True'],
654 ... b'ui.interactive=True'],
655 ... input=stringio(b'5678\n'))
655 ... input=stringio(b'5678\n'))
656 ... runcommand(server, [b'debugreadstdin'])
656 ... runcommand(server, [b'debugreadstdin'])
657 ... runcommand(server, [b'debugwritestdout'])
657 ... runcommand(server, [b'debugwritestdout'])
658 *** runcommand debuggetpass --config ui.interactive=True
658 *** runcommand debuggetpass --config ui.interactive=True
659 password: 1234
659 password: 1234
660 *** runcommand debuggetpass --config ui.interactive=True
660 *** runcommand debuggetpass --config ui.interactive=True
661 password:
661 password:
662 *** runcommand debuggetpass --config ui.interactive=True
662 *** runcommand debuggetpass --config ui.interactive=True
663 password: abort: response expected
663 password: abort: response expected
664 [255]
664 [255]
665 *** runcommand debugprompt --config ui.interactive=True
665 *** runcommand debugprompt --config ui.interactive=True
666 prompt: 5678
666 prompt: 5678
667 *** runcommand debugreadstdin
667 *** runcommand debugreadstdin
668 read: ''
668 read: ''
669 *** runcommand debugwritestdout
669 *** runcommand debugwritestdout
670 low-level stdout fd and
670 low-level stdout fd and
671 stdout should be redirected to stderr
671 stdout should be redirected to stderr
672
672
673
673
674 run commandserver in commandserver, which is silly but should work:
674 run commandserver in commandserver, which is silly but should work:
675
675
676 >>> from hgclient import bprint, check, readchannel, runcommand, stringio
676 >>> from hgclient import bprint, check, readchannel, runcommand, stringio
677 >>> @check
677 >>> @check
678 ... def nested(server):
678 ... def nested(server):
679 ... bprint(b'%c, %r' % readchannel(server))
679 ... bprint(b'%c, %r' % readchannel(server))
680 ... class nestedserver(object):
680 ... class nestedserver(object):
681 ... stdin = stringio(b'getencoding\n')
681 ... stdin = stringio(b'getencoding\n')
682 ... stdout = stringio()
682 ... stdout = stringio()
683 ... runcommand(server, [b'serve', b'--cmdserver', b'pipe'],
683 ... runcommand(server, [b'serve', b'--cmdserver', b'pipe'],
684 ... output=nestedserver.stdout, input=nestedserver.stdin)
684 ... output=nestedserver.stdout, input=nestedserver.stdin)
685 ... nestedserver.stdout.seek(0)
685 ... nestedserver.stdout.seek(0)
686 ... bprint(b'%c, %r' % readchannel(nestedserver)) # hello
686 ... bprint(b'%c, %r' % readchannel(nestedserver)) # hello
687 ... bprint(b'%c, %r' % readchannel(nestedserver)) # getencoding
687 ... bprint(b'%c, %r' % readchannel(nestedserver)) # getencoding
688 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
688 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
689 *** runcommand serve --cmdserver pipe
689 *** runcommand serve --cmdserver pipe
690 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
690 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
691 r, '*' (glob)
691 r, '*' (glob)
692
692
693
693
694 start without repository:
694 start without repository:
695
695
696 $ cd ..
696 $ cd ..
697
697
698 >>> from hgclient import bprint, check, readchannel, runcommand
698 >>> from hgclient import bprint, check, readchannel, runcommand
699 >>> @check
699 >>> @check
700 ... def hellomessage(server):
700 ... def hellomessage(server):
701 ... ch, data = readchannel(server)
701 ... ch, data = readchannel(server)
702 ... bprint(b'%c, %r' % (ch, data))
702 ... bprint(b'%c, %r' % (ch, data))
703 ... # run an arbitrary command to make sure the next thing the server
703 ... # run an arbitrary command to make sure the next thing the server
704 ... # sends isn't part of the hello message
704 ... # sends isn't part of the hello message
705 ... runcommand(server, [b'id'])
705 ... runcommand(server, [b'id'])
706 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
706 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
707 *** runcommand id
707 *** runcommand id
708 abort: there is no Mercurial repository here (.hg not found)
708 abort: there is no Mercurial repository here (.hg not found)
709 [255]
709 [255]
710
710
711 >>> from hgclient import check, readchannel, runcommand
711 >>> from hgclient import check, readchannel, runcommand
712 >>> @check
712 >>> @check
713 ... def startwithoutrepo(server):
713 ... def startwithoutrepo(server):
714 ... readchannel(server)
714 ... readchannel(server)
715 ... runcommand(server, [b'init', b'repo2'])
715 ... runcommand(server, [b'init', b'repo2'])
716 ... runcommand(server, [b'id', b'-R', b'repo2'])
716 ... runcommand(server, [b'id', b'-R', b'repo2'])
717 *** runcommand init repo2
717 *** runcommand init repo2
718 *** runcommand id -R repo2
718 *** runcommand id -R repo2
719 000000000000 tip
719 000000000000 tip
720
720
721
721
722 don't fall back to cwd if invalid -R path is specified (issue4805):
722 don't fall back to cwd if invalid -R path is specified (issue4805):
723
723
724 $ cd repo
724 $ cd repo
725 $ hg serve --cmdserver pipe -R ../nonexistent
725 $ hg serve --cmdserver pipe -R ../nonexistent
726 abort: repository ../nonexistent not found!
726 abort: repository ../nonexistent not found!
727 [255]
727 [255]
728 $ cd ..
728 $ cd ..
729
729
730
730
731 structured message channel:
731 structured message channel:
732
732
733 $ cat <<'EOF' >> repo2/.hg/hgrc
733 $ cat <<'EOF' >> repo2/.hg/hgrc
734 > [ui]
734 > [ui]
735 > # server --config should precede repository option
735 > # server --config should precede repository option
736 > message-output = stdio
736 > message-output = stdio
737 > EOF
737 > EOF
738
738
739 >>> from hgclient import bprint, checkwith, readchannel, runcommand
739 >>> from hgclient import bprint, checkwith, readchannel, runcommand
740 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
740 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
741 ... b'--config', b'cmdserver.message-encodings=foo cbor'])
741 ... b'--config', b'cmdserver.message-encodings=foo cbor'])
742 ... def verify(server):
742 ... def verify(server):
743 ... _ch, data = readchannel(server)
743 ... _ch, data = readchannel(server)
744 ... bprint(data)
744 ... bprint(data)
745 ... runcommand(server, [b'-R', b'repo2', b'verify'])
745 ... runcommand(server, [b'-R', b'repo2', b'verify'])
746 capabilities: getencoding runcommand
746 capabilities: getencoding runcommand
747 encoding: ascii
747 encoding: ascii
748 message-encoding: cbor
748 message-encoding: cbor
749 pid: * (glob)
749 pid: * (glob)
750 pgid: * (glob)
750 pgid: * (glob) (no-windows !)
751 *** runcommand -R repo2 verify
751 *** runcommand -R repo2 verify
752 message: '\xa2DdataTchecking changesets\nDtypeFstatus'
752 message: '\xa2DdataTchecking changesets\nDtypeFstatus'
753 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
753 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
754 message: '\xa2DdataSchecking manifests\nDtypeFstatus'
754 message: '\xa2DdataSchecking manifests\nDtypeFstatus'
755 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
755 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
756 message: '\xa2DdataX0crosschecking files in changesets and manifests\nDtypeFstatus'
756 message: '\xa2DdataX0crosschecking files in changesets and manifests\nDtypeFstatus'
757 message: '\xa6Ditem@Cpos\xf6EtopicMcrosscheckingEtotal\xf6DtypeHprogressDunit@'
757 message: '\xa6Ditem@Cpos\xf6EtopicMcrosscheckingEtotal\xf6DtypeHprogressDunit@'
758 message: '\xa2DdataOchecking files\nDtypeFstatus'
758 message: '\xa2DdataOchecking files\nDtypeFstatus'
759 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
759 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
760 message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus'
760 message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus'
761
761
762 >>> from hgclient import checkwith, readchannel, runcommand, stringio
762 >>> from hgclient import checkwith, readchannel, runcommand, stringio
763 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
763 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
764 ... b'--config', b'cmdserver.message-encodings=cbor',
764 ... b'--config', b'cmdserver.message-encodings=cbor',
765 ... b'--config', b'extensions.dbgui=dbgui.py'])
765 ... b'--config', b'extensions.dbgui=dbgui.py'])
766 ... def prompt(server):
766 ... def prompt(server):
767 ... readchannel(server)
767 ... readchannel(server)
768 ... interactive = [b'--config', b'ui.interactive=True']
768 ... interactive = [b'--config', b'ui.interactive=True']
769 ... runcommand(server, [b'debuggetpass'] + interactive,
769 ... runcommand(server, [b'debuggetpass'] + interactive,
770 ... input=stringio(b'1234\n'))
770 ... input=stringio(b'1234\n'))
771 ... runcommand(server, [b'debugprompt'] + interactive,
771 ... runcommand(server, [b'debugprompt'] + interactive,
772 ... input=stringio(b'5678\n'))
772 ... input=stringio(b'5678\n'))
773 ... runcommand(server, [b'debugpromptchoice'] + interactive,
773 ... runcommand(server, [b'debugpromptchoice'] + interactive,
774 ... input=stringio(b'n\n'))
774 ... input=stringio(b'n\n'))
775 *** runcommand debuggetpass --config ui.interactive=True
775 *** runcommand debuggetpass --config ui.interactive=True
776 message: '\xa3DdataJpassword: Hpassword\xf5DtypeFprompt'
776 message: '\xa3DdataJpassword: Hpassword\xf5DtypeFprompt'
777 1234
777 1234
778 *** runcommand debugprompt --config ui.interactive=True
778 *** runcommand debugprompt --config ui.interactive=True
779 message: '\xa3DdataGprompt:GdefaultAyDtypeFprompt'
779 message: '\xa3DdataGprompt:GdefaultAyDtypeFprompt'
780 5678
780 5678
781 *** runcommand debugpromptchoice --config ui.interactive=True
781 *** runcommand debugpromptchoice --config ui.interactive=True
782 message: '\xa4Gchoices\x82\x82AyCYes\x82AnBNoDdataTpromptchoice (y/n)? GdefaultAyDtypeFprompt'
782 message: '\xa4Gchoices\x82\x82AyCYes\x82AnBNoDdataTpromptchoice (y/n)? GdefaultAyDtypeFprompt'
783 1
783 1
784
784
785 bad message encoding:
785 bad message encoding:
786
786
787 $ hg serve --cmdserver pipe --config ui.message-output=channel
787 $ hg serve --cmdserver pipe --config ui.message-output=channel
788 abort: no supported message encodings:
788 abort: no supported message encodings:
789 [255]
789 [255]
790 $ hg serve --cmdserver pipe --config ui.message-output=channel \
790 $ hg serve --cmdserver pipe --config ui.message-output=channel \
791 > --config cmdserver.message-encodings='foo bar'
791 > --config cmdserver.message-encodings='foo bar'
792 abort: no supported message encodings: foo bar
792 abort: no supported message encodings: foo bar
793 [255]
793 [255]
794
794
795 unix domain socket:
795 unix domain socket:
796
796
797 $ cd repo
797 $ cd repo
798 $ hg update -q
798 $ hg update -q
799
799
800 #if unix-socket unix-permissions
800 #if unix-socket unix-permissions
801
801
802 >>> from hgclient import bprint, check, readchannel, runcommand, stringio, unixserver
802 >>> from hgclient import bprint, check, readchannel, runcommand, stringio, unixserver
803 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
803 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
804 >>> def hellomessage(conn):
804 >>> def hellomessage(conn):
805 ... ch, data = readchannel(conn)
805 ... ch, data = readchannel(conn)
806 ... bprint(b'%c, %r' % (ch, data))
806 ... bprint(b'%c, %r' % (ch, data))
807 ... runcommand(conn, [b'id'])
807 ... runcommand(conn, [b'id'])
808 >>> check(hellomessage, server.connect)
808 >>> check(hellomessage, server.connect)
809 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
809 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
810 *** runcommand id
810 *** runcommand id
811 eff892de26ec tip bm1/bm2/bm3
811 eff892de26ec tip bm1/bm2/bm3
812 >>> def unknowncommand(conn):
812 >>> def unknowncommand(conn):
813 ... readchannel(conn)
813 ... readchannel(conn)
814 ... conn.stdin.write(b'unknowncommand\n')
814 ... conn.stdin.write(b'unknowncommand\n')
815 >>> check(unknowncommand, server.connect) # error sent to server.log
815 >>> check(unknowncommand, server.connect) # error sent to server.log
816 >>> def serverinput(conn):
816 >>> def serverinput(conn):
817 ... readchannel(conn)
817 ... readchannel(conn)
818 ... patch = b"""
818 ... patch = b"""
819 ... # HG changeset patch
819 ... # HG changeset patch
820 ... # User test
820 ... # User test
821 ... # Date 0 0
821 ... # Date 0 0
822 ... 2
822 ... 2
823 ...
823 ...
824 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
824 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
825 ... --- a/a
825 ... --- a/a
826 ... +++ b/a
826 ... +++ b/a
827 ... @@ -1,1 +1,2 @@
827 ... @@ -1,1 +1,2 @@
828 ... 1
828 ... 1
829 ... +2
829 ... +2
830 ... """
830 ... """
831 ... runcommand(conn, [b'import', b'-'], input=stringio(patch))
831 ... runcommand(conn, [b'import', b'-'], input=stringio(patch))
832 ... runcommand(conn, [b'log', b'-rtip', b'-q'])
832 ... runcommand(conn, [b'log', b'-rtip', b'-q'])
833 >>> check(serverinput, server.connect)
833 >>> check(serverinput, server.connect)
834 *** runcommand import -
834 *** runcommand import -
835 applying patch from stdin
835 applying patch from stdin
836 *** runcommand log -rtip -q
836 *** runcommand log -rtip -q
837 2:1ed24be7e7a0
837 2:1ed24be7e7a0
838 >>> server.shutdown()
838 >>> server.shutdown()
839
839
840 $ cat .hg/server.log
840 $ cat .hg/server.log
841 listening at .hg/server.sock
841 listening at .hg/server.sock
842 abort: unknown command unknowncommand
842 abort: unknown command unknowncommand
843 killed!
843 killed!
844 $ rm .hg/server.log
844 $ rm .hg/server.log
845
845
846 if server crashed before hello, traceback will be sent to 'e' channel as
846 if server crashed before hello, traceback will be sent to 'e' channel as
847 last ditch:
847 last ditch:
848
848
849 $ cat <<EOF >> .hg/hgrc
849 $ cat <<EOF >> .hg/hgrc
850 > [cmdserver]
850 > [cmdserver]
851 > log = inexistent/path.log
851 > log = inexistent/path.log
852 > EOF
852 > EOF
853 >>> from hgclient import bprint, check, readchannel, unixserver
853 >>> from hgclient import bprint, check, readchannel, unixserver
854 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
854 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
855 >>> def earlycrash(conn):
855 >>> def earlycrash(conn):
856 ... while True:
856 ... while True:
857 ... try:
857 ... try:
858 ... ch, data = readchannel(conn)
858 ... ch, data = readchannel(conn)
859 ... for l in data.splitlines(True):
859 ... for l in data.splitlines(True):
860 ... if not l.startswith(b' '):
860 ... if not l.startswith(b' '):
861 ... bprint(b'%c, %r' % (ch, l))
861 ... bprint(b'%c, %r' % (ch, l))
862 ... except EOFError:
862 ... except EOFError:
863 ... break
863 ... break
864 >>> check(earlycrash, server.connect)
864 >>> check(earlycrash, server.connect)
865 e, 'Traceback (most recent call last):\n'
865 e, 'Traceback (most recent call last):\n'
866 e, "(IOError|FileNotFoundError): .*" (re)
866 e, "(IOError|FileNotFoundError): .*" (re)
867 >>> server.shutdown()
867 >>> server.shutdown()
868
868
869 $ cat .hg/server.log | grep -v '^ '
869 $ cat .hg/server.log | grep -v '^ '
870 listening at .hg/server.sock
870 listening at .hg/server.sock
871 Traceback (most recent call last):
871 Traceback (most recent call last):
872 (IOError|FileNotFoundError): .* (re)
872 (IOError|FileNotFoundError): .* (re)
873 killed!
873 killed!
874 #endif
874 #endif
875 #if no-unix-socket
875 #if no-unix-socket
876
876
877 $ hg serve --cmdserver unix -a .hg/server.sock
877 $ hg serve --cmdserver unix -a .hg/server.sock
878 abort: unsupported platform
878 abort: unsupported platform
879 [255]
879 [255]
880
880
881 #endif
881 #endif
882
882
883 $ cd ..
883 $ cd ..
884
884
885 Test that accessing to invalid changelog cache is avoided at
885 Test that accessing to invalid changelog cache is avoided at
886 subsequent operations even if repo object is reused even after failure
886 subsequent operations even if repo object is reused even after failure
887 of transaction (see 0a7610758c42 also)
887 of transaction (see 0a7610758c42 also)
888
888
889 "hg log" after failure of transaction is needed to detect invalid
889 "hg log" after failure of transaction is needed to detect invalid
890 cache in repoview: this can't detect by "hg verify" only.
890 cache in repoview: this can't detect by "hg verify" only.
891
891
892 Combination of "finalization" and "empty-ness of changelog" (2 x 2 =
892 Combination of "finalization" and "empty-ness of changelog" (2 x 2 =
893 4) are tested, because '00changelog.i' are differently changed in each
893 4) are tested, because '00changelog.i' are differently changed in each
894 cases.
894 cases.
895
895
896 $ cat > $TESTTMP/failafterfinalize.py <<EOF
896 $ cat > $TESTTMP/failafterfinalize.py <<EOF
897 > # extension to abort transaction after finalization forcibly
897 > # extension to abort transaction after finalization forcibly
898 > from mercurial import commands, error, extensions, lock as lockmod
898 > from mercurial import commands, error, extensions, lock as lockmod
899 > from mercurial import registrar
899 > from mercurial import registrar
900 > cmdtable = {}
900 > cmdtable = {}
901 > command = registrar.command(cmdtable)
901 > command = registrar.command(cmdtable)
902 > configtable = {}
902 > configtable = {}
903 > configitem = registrar.configitem(configtable)
903 > configitem = registrar.configitem(configtable)
904 > configitem(b'failafterfinalize', b'fail',
904 > configitem(b'failafterfinalize', b'fail',
905 > default=None,
905 > default=None,
906 > )
906 > )
907 > def fail(tr):
907 > def fail(tr):
908 > raise error.Abort(b'fail after finalization')
908 > raise error.Abort(b'fail after finalization')
909 > def reposetup(ui, repo):
909 > def reposetup(ui, repo):
910 > class failrepo(repo.__class__):
910 > class failrepo(repo.__class__):
911 > def commitctx(self, ctx, error=False):
911 > def commitctx(self, ctx, error=False):
912 > if self.ui.configbool(b'failafterfinalize', b'fail'):
912 > if self.ui.configbool(b'failafterfinalize', b'fail'):
913 > # 'sorted()' by ASCII code on category names causes
913 > # 'sorted()' by ASCII code on category names causes
914 > # invoking 'fail' after finalization of changelog
914 > # invoking 'fail' after finalization of changelog
915 > # using "'cl-%i' % id(self)" as category name
915 > # using "'cl-%i' % id(self)" as category name
916 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
916 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
917 > return super(failrepo, self).commitctx(ctx, error)
917 > return super(failrepo, self).commitctx(ctx, error)
918 > repo.__class__ = failrepo
918 > repo.__class__ = failrepo
919 > EOF
919 > EOF
920
920
921 $ hg init repo3
921 $ hg init repo3
922 $ cd repo3
922 $ cd repo3
923
923
924 $ cat <<EOF >> $HGRCPATH
924 $ cat <<EOF >> $HGRCPATH
925 > [ui]
925 > [ui]
926 > logtemplate = {rev} {desc|firstline} ({files})\n
926 > logtemplate = {rev} {desc|firstline} ({files})\n
927 >
927 >
928 > [extensions]
928 > [extensions]
929 > failafterfinalize = $TESTTMP/failafterfinalize.py
929 > failafterfinalize = $TESTTMP/failafterfinalize.py
930 > EOF
930 > EOF
931
931
932 - test failure with "empty changelog"
932 - test failure with "empty changelog"
933
933
934 $ echo foo > foo
934 $ echo foo > foo
935 $ hg add foo
935 $ hg add foo
936
936
937 (failure before finalization)
937 (failure before finalization)
938
938
939 >>> from hgclient import check, readchannel, runcommand
939 >>> from hgclient import check, readchannel, runcommand
940 >>> @check
940 >>> @check
941 ... def abort(server):
941 ... def abort(server):
942 ... readchannel(server)
942 ... readchannel(server)
943 ... runcommand(server, [b'commit',
943 ... runcommand(server, [b'commit',
944 ... b'--config', b'hooks.pretxncommit=false',
944 ... b'--config', b'hooks.pretxncommit=false',
945 ... b'-mfoo'])
945 ... b'-mfoo'])
946 ... runcommand(server, [b'log'])
946 ... runcommand(server, [b'log'])
947 ... runcommand(server, [b'verify', b'-q'])
947 ... runcommand(server, [b'verify', b'-q'])
948 *** runcommand commit --config hooks.pretxncommit=false -mfoo
948 *** runcommand commit --config hooks.pretxncommit=false -mfoo
949 transaction abort!
949 transaction abort!
950 rollback completed
950 rollback completed
951 abort: pretxncommit hook exited with status 1
951 abort: pretxncommit hook exited with status 1
952 [255]
952 [255]
953 *** runcommand log
953 *** runcommand log
954 *** runcommand verify -q
954 *** runcommand verify -q
955
955
956 (failure after finalization)
956 (failure after finalization)
957
957
958 >>> from hgclient import check, readchannel, runcommand
958 >>> from hgclient import check, readchannel, runcommand
959 >>> @check
959 >>> @check
960 ... def abort(server):
960 ... def abort(server):
961 ... readchannel(server)
961 ... readchannel(server)
962 ... runcommand(server, [b'commit',
962 ... runcommand(server, [b'commit',
963 ... b'--config', b'failafterfinalize.fail=true',
963 ... b'--config', b'failafterfinalize.fail=true',
964 ... b'-mfoo'])
964 ... b'-mfoo'])
965 ... runcommand(server, [b'log'])
965 ... runcommand(server, [b'log'])
966 ... runcommand(server, [b'verify', b'-q'])
966 ... runcommand(server, [b'verify', b'-q'])
967 *** runcommand commit --config failafterfinalize.fail=true -mfoo
967 *** runcommand commit --config failafterfinalize.fail=true -mfoo
968 transaction abort!
968 transaction abort!
969 rollback completed
969 rollback completed
970 abort: fail after finalization
970 abort: fail after finalization
971 [255]
971 [255]
972 *** runcommand log
972 *** runcommand log
973 *** runcommand verify -q
973 *** runcommand verify -q
974
974
975 - test failure with "not-empty changelog"
975 - test failure with "not-empty changelog"
976
976
977 $ echo bar > bar
977 $ echo bar > bar
978 $ hg add bar
978 $ hg add bar
979 $ hg commit -mbar bar
979 $ hg commit -mbar bar
980
980
981 (failure before finalization)
981 (failure before finalization)
982
982
983 >>> from hgclient import check, readchannel, runcommand
983 >>> from hgclient import check, readchannel, runcommand
984 >>> @check
984 >>> @check
985 ... def abort(server):
985 ... def abort(server):
986 ... readchannel(server)
986 ... readchannel(server)
987 ... runcommand(server, [b'commit',
987 ... runcommand(server, [b'commit',
988 ... b'--config', b'hooks.pretxncommit=false',
988 ... b'--config', b'hooks.pretxncommit=false',
989 ... b'-mfoo', b'foo'])
989 ... b'-mfoo', b'foo'])
990 ... runcommand(server, [b'log'])
990 ... runcommand(server, [b'log'])
991 ... runcommand(server, [b'verify', b'-q'])
991 ... runcommand(server, [b'verify', b'-q'])
992 *** runcommand commit --config hooks.pretxncommit=false -mfoo foo
992 *** runcommand commit --config hooks.pretxncommit=false -mfoo foo
993 transaction abort!
993 transaction abort!
994 rollback completed
994 rollback completed
995 abort: pretxncommit hook exited with status 1
995 abort: pretxncommit hook exited with status 1
996 [255]
996 [255]
997 *** runcommand log
997 *** runcommand log
998 0 bar (bar)
998 0 bar (bar)
999 *** runcommand verify -q
999 *** runcommand verify -q
1000
1000
1001 (failure after finalization)
1001 (failure after finalization)
1002
1002
1003 >>> from hgclient import check, readchannel, runcommand
1003 >>> from hgclient import check, readchannel, runcommand
1004 >>> @check
1004 >>> @check
1005 ... def abort(server):
1005 ... def abort(server):
1006 ... readchannel(server)
1006 ... readchannel(server)
1007 ... runcommand(server, [b'commit',
1007 ... runcommand(server, [b'commit',
1008 ... b'--config', b'failafterfinalize.fail=true',
1008 ... b'--config', b'failafterfinalize.fail=true',
1009 ... b'-mfoo', b'foo'])
1009 ... b'-mfoo', b'foo'])
1010 ... runcommand(server, [b'log'])
1010 ... runcommand(server, [b'log'])
1011 ... runcommand(server, [b'verify', b'-q'])
1011 ... runcommand(server, [b'verify', b'-q'])
1012 *** runcommand commit --config failafterfinalize.fail=true -mfoo foo
1012 *** runcommand commit --config failafterfinalize.fail=true -mfoo foo
1013 transaction abort!
1013 transaction abort!
1014 rollback completed
1014 rollback completed
1015 abort: fail after finalization
1015 abort: fail after finalization
1016 [255]
1016 [255]
1017 *** runcommand log
1017 *** runcommand log
1018 0 bar (bar)
1018 0 bar (bar)
1019 *** runcommand verify -q
1019 *** runcommand verify -q
1020
1020
1021 $ cd ..
1021 $ cd ..
1022
1022
1023 Test symlink traversal over cached audited paths:
1023 Test symlink traversal over cached audited paths:
1024 -------------------------------------------------
1024 -------------------------------------------------
1025
1025
1026 #if symlink
1026 #if symlink
1027
1027
1028 set up symlink hell
1028 set up symlink hell
1029
1029
1030 $ mkdir merge-symlink-out
1030 $ mkdir merge-symlink-out
1031 $ hg init merge-symlink
1031 $ hg init merge-symlink
1032 $ cd merge-symlink
1032 $ cd merge-symlink
1033 $ touch base
1033 $ touch base
1034 $ hg commit -qAm base
1034 $ hg commit -qAm base
1035 $ ln -s ../merge-symlink-out a
1035 $ ln -s ../merge-symlink-out a
1036 $ hg commit -qAm 'symlink a -> ../merge-symlink-out'
1036 $ hg commit -qAm 'symlink a -> ../merge-symlink-out'
1037 $ hg up -q 0
1037 $ hg up -q 0
1038 $ mkdir a
1038 $ mkdir a
1039 $ touch a/poisoned
1039 $ touch a/poisoned
1040 $ hg commit -qAm 'file a/poisoned'
1040 $ hg commit -qAm 'file a/poisoned'
1041 $ hg log -G -T '{rev}: {desc}\n'
1041 $ hg log -G -T '{rev}: {desc}\n'
1042 @ 2: file a/poisoned
1042 @ 2: file a/poisoned
1043 |
1043 |
1044 | o 1: symlink a -> ../merge-symlink-out
1044 | o 1: symlink a -> ../merge-symlink-out
1045 |/
1045 |/
1046 o 0: base
1046 o 0: base
1047
1047
1048
1048
1049 try trivial merge after update: cache of audited paths should be discarded,
1049 try trivial merge after update: cache of audited paths should be discarded,
1050 and the merge should fail (issue5628)
1050 and the merge should fail (issue5628)
1051
1051
1052 $ hg up -q null
1052 $ hg up -q null
1053 >>> from hgclient import check, readchannel, runcommand
1053 >>> from hgclient import check, readchannel, runcommand
1054 >>> @check
1054 >>> @check
1055 ... def merge(server):
1055 ... def merge(server):
1056 ... readchannel(server)
1056 ... readchannel(server)
1057 ... # audit a/poisoned as a good path
1057 ... # audit a/poisoned as a good path
1058 ... runcommand(server, [b'up', b'-qC', b'2'])
1058 ... runcommand(server, [b'up', b'-qC', b'2'])
1059 ... runcommand(server, [b'up', b'-qC', b'1'])
1059 ... runcommand(server, [b'up', b'-qC', b'1'])
1060 ... # here a is a symlink, so a/poisoned is bad
1060 ... # here a is a symlink, so a/poisoned is bad
1061 ... runcommand(server, [b'merge', b'2'])
1061 ... runcommand(server, [b'merge', b'2'])
1062 *** runcommand up -qC 2
1062 *** runcommand up -qC 2
1063 *** runcommand up -qC 1
1063 *** runcommand up -qC 1
1064 *** runcommand merge 2
1064 *** runcommand merge 2
1065 abort: path 'a/poisoned' traverses symbolic link 'a'
1065 abort: path 'a/poisoned' traverses symbolic link 'a'
1066 [255]
1066 [255]
1067 $ ls ../merge-symlink-out
1067 $ ls ../merge-symlink-out
1068
1068
1069 cache of repo.auditor should be discarded, so matcher would never traverse
1069 cache of repo.auditor should be discarded, so matcher would never traverse
1070 symlinks:
1070 symlinks:
1071
1071
1072 $ hg up -qC 0
1072 $ hg up -qC 0
1073 $ touch ../merge-symlink-out/poisoned
1073 $ touch ../merge-symlink-out/poisoned
1074 >>> from hgclient import check, readchannel, runcommand
1074 >>> from hgclient import check, readchannel, runcommand
1075 >>> @check
1075 >>> @check
1076 ... def files(server):
1076 ... def files(server):
1077 ... readchannel(server)
1077 ... readchannel(server)
1078 ... runcommand(server, [b'up', b'-qC', b'2'])
1078 ... runcommand(server, [b'up', b'-qC', b'2'])
1079 ... # audit a/poisoned as a good path
1079 ... # audit a/poisoned as a good path
1080 ... runcommand(server, [b'files', b'a/poisoned'])
1080 ... runcommand(server, [b'files', b'a/poisoned'])
1081 ... runcommand(server, [b'up', b'-qC', b'0'])
1081 ... runcommand(server, [b'up', b'-qC', b'0'])
1082 ... runcommand(server, [b'up', b'-qC', b'1'])
1082 ... runcommand(server, [b'up', b'-qC', b'1'])
1083 ... # here 'a' is a symlink, so a/poisoned should be warned
1083 ... # here 'a' is a symlink, so a/poisoned should be warned
1084 ... runcommand(server, [b'files', b'a/poisoned'])
1084 ... runcommand(server, [b'files', b'a/poisoned'])
1085 *** runcommand up -qC 2
1085 *** runcommand up -qC 2
1086 *** runcommand files a/poisoned
1086 *** runcommand files a/poisoned
1087 a/poisoned
1087 a/poisoned
1088 *** runcommand up -qC 0
1088 *** runcommand up -qC 0
1089 *** runcommand up -qC 1
1089 *** runcommand up -qC 1
1090 *** runcommand files a/poisoned
1090 *** runcommand files a/poisoned
1091 abort: path 'a/poisoned' traverses symbolic link 'a'
1091 abort: path 'a/poisoned' traverses symbolic link 'a'
1092 [255]
1092 [255]
1093
1093
1094 $ cd ..
1094 $ cd ..
1095
1095
1096 #endif
1096 #endif
General Comments 0
You need to be logged in to leave comments. Login now