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