##// END OF EJS Templates
hg-ssh: reject push earlier (on pretxnopen)...
Pierre-Yves David -
r25127:2b9cda90 default
parent child Browse files
Show More
@@ -1,86 +1,86 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
3 # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
4 #
4 #
5 # Author(s):
5 # Author(s):
6 # Thomas Arendsen Hein <thomas@intevation.de>
6 # Thomas Arendsen Hein <thomas@intevation.de>
7 #
7 #
8 # This software may be used and distributed according to the terms of the
8 # This software may be used and distributed according to the terms of the
9 # GNU General Public License version 2 or any later version.
9 # GNU General Public License version 2 or any later version.
10
10
11 """
11 """
12 hg-ssh - a wrapper for ssh access to a limited set of mercurial repos
12 hg-ssh - a wrapper for ssh access to a limited set of mercurial repos
13
13
14 To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8):
14 To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8):
15 command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...
15 command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...
16 (probably together with these other useful options:
16 (probably together with these other useful options:
17 no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
17 no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
18
18
19 This allows pull/push over ssh from/to the repositories given as arguments.
19 This allows pull/push over ssh from/to the repositories given as arguments.
20
20
21 If all your repositories are subdirectories of a common directory, you can
21 If all your repositories are subdirectories of a common directory, you can
22 allow shorter paths with:
22 allow shorter paths with:
23 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
23 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
24
24
25 You can use pattern matching of your normal shell, e.g.:
25 You can use pattern matching of your normal shell, e.g.:
26 command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
26 command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
27
27
28 You can also add a --read-only flag to allow read-only access to a key, e.g.:
28 You can also add a --read-only flag to allow read-only access to a key, e.g.:
29 command="hg-ssh --read-only repos/*"
29 command="hg-ssh --read-only repos/*"
30 """
30 """
31
31
32 # enable importing on demand to reduce startup time
32 # enable importing on demand to reduce startup time
33 from mercurial import demandimport; demandimport.enable()
33 from mercurial import demandimport; demandimport.enable()
34
34
35 from mercurial import dispatch
35 from mercurial import dispatch
36
36
37 import sys, os, shlex
37 import sys, os, shlex
38
38
39 def main():
39 def main():
40 cwd = os.getcwd()
40 cwd = os.getcwd()
41 readonly = False
41 readonly = False
42 args = sys.argv[1:]
42 args = sys.argv[1:]
43 while len(args):
43 while len(args):
44 if args[0] == '--read-only':
44 if args[0] == '--read-only':
45 readonly = True
45 readonly = True
46 args.pop(0)
46 args.pop(0)
47 else:
47 else:
48 break
48 break
49 allowed_paths = [os.path.normpath(os.path.join(cwd,
49 allowed_paths = [os.path.normpath(os.path.join(cwd,
50 os.path.expanduser(path)))
50 os.path.expanduser(path)))
51 for path in args]
51 for path in args]
52 orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
52 orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
53 try:
53 try:
54 cmdargv = shlex.split(orig_cmd)
54 cmdargv = shlex.split(orig_cmd)
55 except ValueError, e:
55 except ValueError, e:
56 sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
56 sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
57 sys.exit(255)
57 sys.exit(255)
58
58
59 if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']:
59 if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']:
60 path = cmdargv[2]
60 path = cmdargv[2]
61 repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
61 repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
62 if repo in allowed_paths:
62 if repo in allowed_paths:
63 cmd = ['-R', repo, 'serve', '--stdio']
63 cmd = ['-R', repo, 'serve', '--stdio']
64 if readonly:
64 if readonly:
65 cmd += [
65 cmd += [
66 '--config',
66 '--config',
67 'hooks.prechangegroup.hg-ssh=python:__main__.rejectpush',
67 'hooks.pretxnopen.hg-ssh=python:__main__.rejectpush',
68 '--config',
68 '--config',
69 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush'
69 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush'
70 ]
70 ]
71 dispatch.dispatch(dispatch.request(cmd))
71 dispatch.dispatch(dispatch.request(cmd))
72 else:
72 else:
73 sys.stderr.write('Illegal repository "%s"\n' % repo)
73 sys.stderr.write('Illegal repository "%s"\n' % repo)
74 sys.exit(255)
74 sys.exit(255)
75 else:
75 else:
76 sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
76 sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
77 sys.exit(255)
77 sys.exit(255)
78
78
79 def rejectpush(ui, **kwargs):
79 def rejectpush(ui, **kwargs):
80 ui.warn("Permission denied\n")
80 ui.warn("Permission denied\n")
81 # mercurial hooks use unix process conventions for hook return values
81 # mercurial hooks use unix process conventions for hook return values
82 # so a truthy return means failure
82 # so a truthy return means failure
83 return True
83 return True
84
84
85 if __name__ == '__main__':
85 if __name__ == '__main__':
86 main()
86 main()
@@ -1,480 +1,480 b''
1
1
2
2
3 This test tries to exercise the ssh functionality with a dummy script
3 This test tries to exercise the ssh functionality with a dummy script
4
4
5 creating 'remote' repo
5 creating 'remote' repo
6
6
7 $ hg init remote
7 $ hg init remote
8 $ cd remote
8 $ cd remote
9 $ echo this > foo
9 $ echo this > foo
10 $ echo this > fooO
10 $ echo this > fooO
11 $ hg ci -A -m "init" foo fooO
11 $ hg ci -A -m "init" foo fooO
12
12
13 insert a closed branch (issue4428)
13 insert a closed branch (issue4428)
14
14
15 $ hg up null
15 $ hg up null
16 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
17 $ hg branch closed
17 $ hg branch closed
18 marked working directory as branch closed
18 marked working directory as branch closed
19 (branches are permanent and global, did you want a bookmark?)
19 (branches are permanent and global, did you want a bookmark?)
20 $ hg ci -mc0
20 $ hg ci -mc0
21 $ hg ci --close-branch -mc1
21 $ hg ci --close-branch -mc1
22 $ hg up -q default
22 $ hg up -q default
23
23
24 configure for serving
24 configure for serving
25
25
26 $ cat <<EOF > .hg/hgrc
26 $ cat <<EOF > .hg/hgrc
27 > [server]
27 > [server]
28 > uncompressed = True
28 > uncompressed = True
29 >
29 >
30 > [hooks]
30 > [hooks]
31 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
31 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
32 > EOF
32 > EOF
33 $ cd ..
33 $ cd ..
34
34
35 repo not found error
35 repo not found error
36
36
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
38 remote: abort: there is no Mercurial repository here (.hg not found)!
38 remote: abort: there is no Mercurial repository here (.hg not found)!
39 abort: no suitable response from remote hg!
39 abort: no suitable response from remote hg!
40 [255]
40 [255]
41
41
42 non-existent absolute path
42 non-existent absolute path
43
43
44 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
44 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
45 remote: abort: there is no Mercurial repository here (.hg not found)!
45 remote: abort: there is no Mercurial repository here (.hg not found)!
46 abort: no suitable response from remote hg!
46 abort: no suitable response from remote hg!
47 [255]
47 [255]
48
48
49 clone remote via stream
49 clone remote via stream
50
50
51 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
51 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
52 streaming all changes
52 streaming all changes
53 4 files to transfer, 615 bytes of data
53 4 files to transfer, 615 bytes of data
54 transferred 615 bytes in * seconds (*) (glob)
54 transferred 615 bytes in * seconds (*) (glob)
55 searching for changes
55 searching for changes
56 no changes found
56 no changes found
57 updating to branch default
57 updating to branch default
58 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 $ cd local-stream
59 $ cd local-stream
60 $ hg verify
60 $ hg verify
61 checking changesets
61 checking changesets
62 checking manifests
62 checking manifests
63 crosschecking files in changesets and manifests
63 crosschecking files in changesets and manifests
64 checking files
64 checking files
65 2 files, 3 changesets, 2 total revisions
65 2 files, 3 changesets, 2 total revisions
66 $ hg branches
66 $ hg branches
67 default 0:1160648e36ce
67 default 0:1160648e36ce
68 $ cd ..
68 $ cd ..
69
69
70 clone bookmarks via stream
70 clone bookmarks via stream
71
71
72 $ hg -R local-stream book mybook
72 $ hg -R local-stream book mybook
73 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
73 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
74 streaming all changes
74 streaming all changes
75 4 files to transfer, 615 bytes of data
75 4 files to transfer, 615 bytes of data
76 transferred 615 bytes in * seconds (*) (glob)
76 transferred 615 bytes in * seconds (*) (glob)
77 searching for changes
77 searching for changes
78 no changes found
78 no changes found
79 updating to branch default
79 updating to branch default
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 $ cd stream2
81 $ cd stream2
82 $ hg book
82 $ hg book
83 mybook 0:1160648e36ce
83 mybook 0:1160648e36ce
84 $ cd ..
84 $ cd ..
85 $ rm -rf local-stream stream2
85 $ rm -rf local-stream stream2
86
86
87 clone remote via pull
87 clone remote via pull
88
88
89 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
89 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
90 requesting all changes
90 requesting all changes
91 adding changesets
91 adding changesets
92 adding manifests
92 adding manifests
93 adding file changes
93 adding file changes
94 added 3 changesets with 2 changes to 2 files
94 added 3 changesets with 2 changes to 2 files
95 updating to branch default
95 updating to branch default
96 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
96 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
97
97
98 verify
98 verify
99
99
100 $ cd local
100 $ cd local
101 $ hg verify
101 $ hg verify
102 checking changesets
102 checking changesets
103 checking manifests
103 checking manifests
104 crosschecking files in changesets and manifests
104 crosschecking files in changesets and manifests
105 checking files
105 checking files
106 2 files, 3 changesets, 2 total revisions
106 2 files, 3 changesets, 2 total revisions
107 $ echo '[hooks]' >> .hg/hgrc
107 $ echo '[hooks]' >> .hg/hgrc
108 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
108 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
109
109
110 empty default pull
110 empty default pull
111
111
112 $ hg paths
112 $ hg paths
113 default = ssh://user@dummy/remote
113 default = ssh://user@dummy/remote
114 $ hg pull -e "python \"$TESTDIR/dummyssh\""
114 $ hg pull -e "python \"$TESTDIR/dummyssh\""
115 pulling from ssh://user@dummy/remote
115 pulling from ssh://user@dummy/remote
116 searching for changes
116 searching for changes
117 no changes found
117 no changes found
118
118
119 pull from wrong ssh URL
119 pull from wrong ssh URL
120
120
121 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
121 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
122 pulling from ssh://user@dummy/doesnotexist
122 pulling from ssh://user@dummy/doesnotexist
123 remote: abort: there is no Mercurial repository here (.hg not found)!
123 remote: abort: there is no Mercurial repository here (.hg not found)!
124 abort: no suitable response from remote hg!
124 abort: no suitable response from remote hg!
125 [255]
125 [255]
126
126
127 local change
127 local change
128
128
129 $ echo bleah > foo
129 $ echo bleah > foo
130 $ hg ci -m "add"
130 $ hg ci -m "add"
131
131
132 updating rc
132 updating rc
133
133
134 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
134 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
135 $ echo "[ui]" >> .hg/hgrc
135 $ echo "[ui]" >> .hg/hgrc
136 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
136 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
137
137
138 find outgoing
138 find outgoing
139
139
140 $ hg out ssh://user@dummy/remote
140 $ hg out ssh://user@dummy/remote
141 comparing with ssh://user@dummy/remote
141 comparing with ssh://user@dummy/remote
142 searching for changes
142 searching for changes
143 changeset: 3:a28a9d1a809c
143 changeset: 3:a28a9d1a809c
144 tag: tip
144 tag: tip
145 parent: 0:1160648e36ce
145 parent: 0:1160648e36ce
146 user: test
146 user: test
147 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
148 summary: add
148 summary: add
149
149
150
150
151 find incoming on the remote side
151 find incoming on the remote side
152
152
153 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
153 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
154 comparing with ssh://user@dummy/local
154 comparing with ssh://user@dummy/local
155 searching for changes
155 searching for changes
156 changeset: 3:a28a9d1a809c
156 changeset: 3:a28a9d1a809c
157 tag: tip
157 tag: tip
158 parent: 0:1160648e36ce
158 parent: 0:1160648e36ce
159 user: test
159 user: test
160 date: Thu Jan 01 00:00:00 1970 +0000
160 date: Thu Jan 01 00:00:00 1970 +0000
161 summary: add
161 summary: add
162
162
163
163
164 find incoming on the remote side (using absolute path)
164 find incoming on the remote side (using absolute path)
165
165
166 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
166 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
167 comparing with ssh://user@dummy/$TESTTMP/local
167 comparing with ssh://user@dummy/$TESTTMP/local
168 searching for changes
168 searching for changes
169 changeset: 3:a28a9d1a809c
169 changeset: 3:a28a9d1a809c
170 tag: tip
170 tag: tip
171 parent: 0:1160648e36ce
171 parent: 0:1160648e36ce
172 user: test
172 user: test
173 date: Thu Jan 01 00:00:00 1970 +0000
173 date: Thu Jan 01 00:00:00 1970 +0000
174 summary: add
174 summary: add
175
175
176
176
177 push
177 push
178
178
179 $ hg push
179 $ hg push
180 pushing to ssh://user@dummy/remote
180 pushing to ssh://user@dummy/remote
181 searching for changes
181 searching for changes
182 remote: adding changesets
182 remote: adding changesets
183 remote: adding manifests
183 remote: adding manifests
184 remote: adding file changes
184 remote: adding file changes
185 remote: added 1 changesets with 1 changes to 1 files
185 remote: added 1 changesets with 1 changes to 1 files
186 $ cd ../remote
186 $ cd ../remote
187
187
188 check remote tip
188 check remote tip
189
189
190 $ hg tip
190 $ hg tip
191 changeset: 3:a28a9d1a809c
191 changeset: 3:a28a9d1a809c
192 tag: tip
192 tag: tip
193 parent: 0:1160648e36ce
193 parent: 0:1160648e36ce
194 user: test
194 user: test
195 date: Thu Jan 01 00:00:00 1970 +0000
195 date: Thu Jan 01 00:00:00 1970 +0000
196 summary: add
196 summary: add
197
197
198 $ hg verify
198 $ hg verify
199 checking changesets
199 checking changesets
200 checking manifests
200 checking manifests
201 crosschecking files in changesets and manifests
201 crosschecking files in changesets and manifests
202 checking files
202 checking files
203 2 files, 4 changesets, 3 total revisions
203 2 files, 4 changesets, 3 total revisions
204 $ hg cat -r tip foo
204 $ hg cat -r tip foo
205 bleah
205 bleah
206 $ echo z > z
206 $ echo z > z
207 $ hg ci -A -m z z
207 $ hg ci -A -m z z
208 created new head
208 created new head
209
209
210 test pushkeys and bookmarks
210 test pushkeys and bookmarks
211
211
212 $ cd ../local
212 $ cd ../local
213 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
213 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
214 bookmarks
214 bookmarks
215 namespaces
215 namespaces
216 phases
216 phases
217 $ hg book foo -r 0
217 $ hg book foo -r 0
218 $ hg out -B
218 $ hg out -B
219 comparing with ssh://user@dummy/remote
219 comparing with ssh://user@dummy/remote
220 searching for changed bookmarks
220 searching for changed bookmarks
221 foo 1160648e36ce
221 foo 1160648e36ce
222 $ hg push -B foo
222 $ hg push -B foo
223 pushing to ssh://user@dummy/remote
223 pushing to ssh://user@dummy/remote
224 searching for changes
224 searching for changes
225 no changes found
225 no changes found
226 exporting bookmark foo
226 exporting bookmark foo
227 [1]
227 [1]
228 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
228 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
229 foo 1160648e36cec0054048a7edc4110c6f84fde594
229 foo 1160648e36cec0054048a7edc4110c6f84fde594
230 $ hg book -f foo
230 $ hg book -f foo
231 $ hg push --traceback
231 $ hg push --traceback
232 pushing to ssh://user@dummy/remote
232 pushing to ssh://user@dummy/remote
233 searching for changes
233 searching for changes
234 no changes found
234 no changes found
235 updating bookmark foo
235 updating bookmark foo
236 [1]
236 [1]
237 $ hg book -d foo
237 $ hg book -d foo
238 $ hg in -B
238 $ hg in -B
239 comparing with ssh://user@dummy/remote
239 comparing with ssh://user@dummy/remote
240 searching for changed bookmarks
240 searching for changed bookmarks
241 foo a28a9d1a809c
241 foo a28a9d1a809c
242 $ hg book -f -r 0 foo
242 $ hg book -f -r 0 foo
243 $ hg pull -B foo
243 $ hg pull -B foo
244 pulling from ssh://user@dummy/remote
244 pulling from ssh://user@dummy/remote
245 no changes found
245 no changes found
246 updating bookmark foo
246 updating bookmark foo
247 $ hg book -d foo
247 $ hg book -d foo
248 $ hg push -B foo
248 $ hg push -B foo
249 pushing to ssh://user@dummy/remote
249 pushing to ssh://user@dummy/remote
250 searching for changes
250 searching for changes
251 no changes found
251 no changes found
252 deleting remote bookmark foo
252 deleting remote bookmark foo
253 [1]
253 [1]
254
254
255 a bad, evil hook that prints to stdout
255 a bad, evil hook that prints to stdout
256
256
257 $ cat <<EOF > $TESTTMP/badhook
257 $ cat <<EOF > $TESTTMP/badhook
258 > import sys
258 > import sys
259 > sys.stdout.write("KABOOM\n")
259 > sys.stdout.write("KABOOM\n")
260 > EOF
260 > EOF
261
261
262 $ echo '[hooks]' >> ../remote/.hg/hgrc
262 $ echo '[hooks]' >> ../remote/.hg/hgrc
263 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
263 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
264 $ echo r > r
264 $ echo r > r
265 $ hg ci -A -m z r
265 $ hg ci -A -m z r
266
266
267 push should succeed even though it has an unexpected response
267 push should succeed even though it has an unexpected response
268
268
269 $ hg push
269 $ hg push
270 pushing to ssh://user@dummy/remote
270 pushing to ssh://user@dummy/remote
271 searching for changes
271 searching for changes
272 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
272 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
273 remote: adding changesets
273 remote: adding changesets
274 remote: adding manifests
274 remote: adding manifests
275 remote: adding file changes
275 remote: adding file changes
276 remote: added 1 changesets with 1 changes to 1 files
276 remote: added 1 changesets with 1 changes to 1 files
277 remote: KABOOM
277 remote: KABOOM
278 $ hg -R ../remote heads
278 $ hg -R ../remote heads
279 changeset: 5:1383141674ec
279 changeset: 5:1383141674ec
280 tag: tip
280 tag: tip
281 parent: 3:a28a9d1a809c
281 parent: 3:a28a9d1a809c
282 user: test
282 user: test
283 date: Thu Jan 01 00:00:00 1970 +0000
283 date: Thu Jan 01 00:00:00 1970 +0000
284 summary: z
284 summary: z
285
285
286 changeset: 4:6c0482d977a3
286 changeset: 4:6c0482d977a3
287 parent: 0:1160648e36ce
287 parent: 0:1160648e36ce
288 user: test
288 user: test
289 date: Thu Jan 01 00:00:00 1970 +0000
289 date: Thu Jan 01 00:00:00 1970 +0000
290 summary: z
290 summary: z
291
291
292
292
293 clone bookmarks
293 clone bookmarks
294
294
295 $ hg -R ../remote bookmark test
295 $ hg -R ../remote bookmark test
296 $ hg -R ../remote bookmarks
296 $ hg -R ../remote bookmarks
297 * test 4:6c0482d977a3
297 * test 4:6c0482d977a3
298 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
298 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
299 requesting all changes
299 requesting all changes
300 adding changesets
300 adding changesets
301 adding manifests
301 adding manifests
302 adding file changes
302 adding file changes
303 added 6 changesets with 5 changes to 4 files (+1 heads)
303 added 6 changesets with 5 changes to 4 files (+1 heads)
304 updating to branch default
304 updating to branch default
305 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
306 $ hg -R local-bookmarks bookmarks
306 $ hg -R local-bookmarks bookmarks
307 test 4:6c0482d977a3
307 test 4:6c0482d977a3
308
308
309 passwords in ssh urls are not supported
309 passwords in ssh urls are not supported
310 (we use a glob here because different Python versions give different
310 (we use a glob here because different Python versions give different
311 results here)
311 results here)
312
312
313 $ hg push ssh://user:erroneouspwd@dummy/remote
313 $ hg push ssh://user:erroneouspwd@dummy/remote
314 pushing to ssh://user:*@dummy/remote (glob)
314 pushing to ssh://user:*@dummy/remote (glob)
315 abort: password in URL not supported!
315 abort: password in URL not supported!
316 [255]
316 [255]
317
317
318 $ cd ..
318 $ cd ..
319
319
320 hide outer repo
320 hide outer repo
321 $ hg init
321 $ hg init
322
322
323 Test remote paths with spaces (issue2983):
323 Test remote paths with spaces (issue2983):
324
324
325 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
325 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
326 $ touch "$TESTTMP/a repo/test"
326 $ touch "$TESTTMP/a repo/test"
327 $ hg -R 'a repo' commit -A -m "test"
327 $ hg -R 'a repo' commit -A -m "test"
328 adding test
328 adding test
329 $ hg -R 'a repo' tag tag
329 $ hg -R 'a repo' tag tag
330 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
330 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
331 73649e48688a
331 73649e48688a
332
332
333 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
333 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
334 abort: unknown revision 'noNoNO'!
334 abort: unknown revision 'noNoNO'!
335 [255]
335 [255]
336
336
337 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
337 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
338
338
339 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
339 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
340 destination directory: a repo
340 destination directory: a repo
341 abort: destination 'a repo' is not empty
341 abort: destination 'a repo' is not empty
342 [255]
342 [255]
343
343
344 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
344 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
345 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
345 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
346 parameters:
346 parameters:
347
347
348 $ cat > ssh.sh << EOF
348 $ cat > ssh.sh << EOF
349 > userhost="\$1"
349 > userhost="\$1"
350 > SSH_ORIGINAL_COMMAND="\$2"
350 > SSH_ORIGINAL_COMMAND="\$2"
351 > export SSH_ORIGINAL_COMMAND
351 > export SSH_ORIGINAL_COMMAND
352 > PYTHONPATH="$PYTHONPATH"
352 > PYTHONPATH="$PYTHONPATH"
353 > export PYTHONPATH
353 > export PYTHONPATH
354 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
354 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
355 > EOF
355 > EOF
356
356
357 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
357 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
358 73649e48688a
358 73649e48688a
359
359
360 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
360 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
361 remote: Illegal repository "$TESTTMP/a'repo" (glob)
361 remote: Illegal repository "$TESTTMP/a'repo" (glob)
362 abort: no suitable response from remote hg!
362 abort: no suitable response from remote hg!
363 [255]
363 [255]
364
364
365 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
365 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
366 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
366 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
367 abort: no suitable response from remote hg!
367 abort: no suitable response from remote hg!
368 [255]
368 [255]
369
369
370 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
370 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
371 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
371 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
372 [255]
372 [255]
373
373
374 Test hg-ssh in read-only mode:
374 Test hg-ssh in read-only mode:
375
375
376 $ cat > ssh.sh << EOF
376 $ cat > ssh.sh << EOF
377 > userhost="\$1"
377 > userhost="\$1"
378 > SSH_ORIGINAL_COMMAND="\$2"
378 > SSH_ORIGINAL_COMMAND="\$2"
379 > export SSH_ORIGINAL_COMMAND
379 > export SSH_ORIGINAL_COMMAND
380 > PYTHONPATH="$PYTHONPATH"
380 > PYTHONPATH="$PYTHONPATH"
381 > export PYTHONPATH
381 > export PYTHONPATH
382 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
382 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
383 > EOF
383 > EOF
384
384
385 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
385 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
386 requesting all changes
386 requesting all changes
387 adding changesets
387 adding changesets
388 adding manifests
388 adding manifests
389 adding file changes
389 adding file changes
390 added 6 changesets with 5 changes to 4 files (+1 heads)
390 added 6 changesets with 5 changes to 4 files (+1 heads)
391 updating to branch default
391 updating to branch default
392 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
392 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
393
393
394 $ cd read-only-local
394 $ cd read-only-local
395 $ echo "baz" > bar
395 $ echo "baz" > bar
396 $ hg ci -A -m "unpushable commit" bar
396 $ hg ci -A -m "unpushable commit" bar
397 $ hg push --ssh "sh ../ssh.sh"
397 $ hg push --ssh "sh ../ssh.sh"
398 pushing to ssh://user@dummy/*/remote (glob)
398 pushing to ssh://user@dummy/*/remote (glob)
399 searching for changes
399 searching for changes
400 remote: Permission denied
400 remote: Permission denied
401 remote: abort: prechangegroup.hg-ssh hook failed
401 remote: abort: pretxnopen.hg-ssh hook failed
402 remote: Permission denied
402 remote: Permission denied
403 remote: pushkey-abort: prepushkey.hg-ssh hook failed
403 remote: pushkey-abort: prepushkey.hg-ssh hook failed
404 updating 6c0482d977a3 to public failed!
404 updating 6c0482d977a3 to public failed!
405 [1]
405 [1]
406
406
407 $ cd ..
407 $ cd ..
408
408
409 stderr from remote commands should be printed before stdout from local code (issue4336)
409 stderr from remote commands should be printed before stdout from local code (issue4336)
410
410
411 $ hg clone remote stderr-ordering
411 $ hg clone remote stderr-ordering
412 updating to branch default
412 updating to branch default
413 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
413 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
414 $ cd stderr-ordering
414 $ cd stderr-ordering
415 $ cat >> localwrite.py << EOF
415 $ cat >> localwrite.py << EOF
416 > from mercurial import exchange, extensions
416 > from mercurial import exchange, extensions
417 >
417 >
418 > def wrappedpush(orig, repo, *args, **kwargs):
418 > def wrappedpush(orig, repo, *args, **kwargs):
419 > res = orig(repo, *args, **kwargs)
419 > res = orig(repo, *args, **kwargs)
420 > repo.ui.write('local stdout\n')
420 > repo.ui.write('local stdout\n')
421 > return res
421 > return res
422 >
422 >
423 > def extsetup(ui):
423 > def extsetup(ui):
424 > extensions.wrapfunction(exchange, 'push', wrappedpush)
424 > extensions.wrapfunction(exchange, 'push', wrappedpush)
425 > EOF
425 > EOF
426
426
427 $ cat >> .hg/hgrc << EOF
427 $ cat >> .hg/hgrc << EOF
428 > [paths]
428 > [paths]
429 > default-push = ssh://user@dummy/remote
429 > default-push = ssh://user@dummy/remote
430 > [ui]
430 > [ui]
431 > ssh = python "$TESTDIR/dummyssh"
431 > ssh = python "$TESTDIR/dummyssh"
432 > [extensions]
432 > [extensions]
433 > localwrite = localwrite.py
433 > localwrite = localwrite.py
434 > EOF
434 > EOF
435
435
436 $ echo localwrite > foo
436 $ echo localwrite > foo
437 $ hg commit -m 'testing localwrite'
437 $ hg commit -m 'testing localwrite'
438 $ hg push
438 $ hg push
439 pushing to ssh://user@dummy/remote
439 pushing to ssh://user@dummy/remote
440 searching for changes
440 searching for changes
441 remote: adding changesets
441 remote: adding changesets
442 remote: adding manifests
442 remote: adding manifests
443 remote: adding file changes
443 remote: adding file changes
444 remote: added 1 changesets with 1 changes to 1 files
444 remote: added 1 changesets with 1 changes to 1 files
445 remote: KABOOM
445 remote: KABOOM
446 local stdout
446 local stdout
447
447
448 $ cd ..
448 $ cd ..
449
449
450 $ cat dummylog
450 $ cat dummylog
451 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
451 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
452 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
452 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
453 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
453 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
454 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
454 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
455 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
455 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
456 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
456 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
457 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
457 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
458 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
458 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
459 Got arguments 1:user@dummy 2:hg -R local serve --stdio
459 Got arguments 1:user@dummy 2:hg -R local serve --stdio
460 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
460 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
461 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
461 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
462 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
462 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
463 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
463 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
464 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
464 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
465 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
465 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
466 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
466 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
467 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
467 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
468 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
468 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
469 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
469 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
470 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
470 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
471 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
471 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
472 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
472 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
473 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
473 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
474 Got arguments 1:user@dummy 2:hg init 'a repo'
474 Got arguments 1:user@dummy 2:hg init 'a repo'
475 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
475 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
476 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
476 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
477 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
477 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
478 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
478 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
479 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
479 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
480 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
480 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
General Comments 0
You need to be logged in to leave comments. Login now