##// END OF EJS Templates
httppeer: reintroduce _abort that accidentally was removed in 167047ba3cfa...
Mads Kiilerich -
r21188:d36440d8 stable
parent child Browse files
Show More
@@ -1,269 +1,272 b''
1 # httppeer.py - HTTP repository proxy classes for mercurial
1 # httppeer.py - HTTP repository proxy classes for mercurial
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from node import nullid
9 from node import nullid
10 from i18n import _
10 from i18n import _
11 import tempfile
11 import tempfile
12 import changegroup, statichttprepo, error, httpconnection, url, util, wireproto
12 import changegroup, statichttprepo, error, httpconnection, url, util, wireproto
13 import os, urllib, urllib2, zlib, httplib
13 import os, urllib, urllib2, zlib, httplib
14 import errno, socket
14 import errno, socket
15
15
16 def zgenerator(f):
16 def zgenerator(f):
17 zd = zlib.decompressobj()
17 zd = zlib.decompressobj()
18 try:
18 try:
19 for chunk in util.filechunkiter(f):
19 for chunk in util.filechunkiter(f):
20 while chunk:
20 while chunk:
21 yield zd.decompress(chunk, 2**18)
21 yield zd.decompress(chunk, 2**18)
22 chunk = zd.unconsumed_tail
22 chunk = zd.unconsumed_tail
23 except httplib.HTTPException:
23 except httplib.HTTPException:
24 raise IOError(None, _('connection ended unexpectedly'))
24 raise IOError(None, _('connection ended unexpectedly'))
25 yield zd.flush()
25 yield zd.flush()
26
26
27 class httppeer(wireproto.wirepeer):
27 class httppeer(wireproto.wirepeer):
28 def __init__(self, ui, path):
28 def __init__(self, ui, path):
29 self.path = path
29 self.path = path
30 self.caps = None
30 self.caps = None
31 self.handler = None
31 self.handler = None
32 self.urlopener = None
32 self.urlopener = None
33 u = util.url(path)
33 u = util.url(path)
34 if u.query or u.fragment:
34 if u.query or u.fragment:
35 raise util.Abort(_('unsupported URL component: "%s"') %
35 raise util.Abort(_('unsupported URL component: "%s"') %
36 (u.query or u.fragment))
36 (u.query or u.fragment))
37
37
38 # urllib cannot handle URLs with embedded user or passwd
38 # urllib cannot handle URLs with embedded user or passwd
39 self._url, authinfo = u.authinfo()
39 self._url, authinfo = u.authinfo()
40
40
41 self.ui = ui
41 self.ui = ui
42 self.ui.debug('using %s\n' % self._url)
42 self.ui.debug('using %s\n' % self._url)
43
43
44 self.urlopener = url.opener(ui, authinfo)
44 self.urlopener = url.opener(ui, authinfo)
45
45
46 def __del__(self):
46 def __del__(self):
47 if self.urlopener:
47 if self.urlopener:
48 for h in self.urlopener.handlers:
48 for h in self.urlopener.handlers:
49 h.close()
49 h.close()
50 getattr(h, "close_all", lambda : None)()
50 getattr(h, "close_all", lambda : None)()
51
51
52 def url(self):
52 def url(self):
53 return self.path
53 return self.path
54
54
55 # look up capabilities only when needed
55 # look up capabilities only when needed
56
56
57 def _fetchcaps(self):
57 def _fetchcaps(self):
58 self.caps = set(self._call('capabilities').split())
58 self.caps = set(self._call('capabilities').split())
59
59
60 def _capabilities(self):
60 def _capabilities(self):
61 if self.caps is None:
61 if self.caps is None:
62 try:
62 try:
63 self._fetchcaps()
63 self._fetchcaps()
64 except error.RepoError:
64 except error.RepoError:
65 self.caps = set()
65 self.caps = set()
66 self.ui.debug('capabilities: %s\n' %
66 self.ui.debug('capabilities: %s\n' %
67 (' '.join(self.caps or ['none'])))
67 (' '.join(self.caps or ['none'])))
68 return self.caps
68 return self.caps
69
69
70 def lock(self):
70 def lock(self):
71 raise util.Abort(_('operation not supported over http'))
71 raise util.Abort(_('operation not supported over http'))
72
72
73 def _callstream(self, cmd, **args):
73 def _callstream(self, cmd, **args):
74 if cmd == 'pushkey':
74 if cmd == 'pushkey':
75 args['data'] = ''
75 args['data'] = ''
76 data = args.pop('data', None)
76 data = args.pop('data', None)
77 size = 0
77 size = 0
78 if util.safehasattr(data, 'length'):
78 if util.safehasattr(data, 'length'):
79 size = data.length
79 size = data.length
80 elif data is not None:
80 elif data is not None:
81 size = len(data)
81 size = len(data)
82 headers = args.pop('headers', {})
82 headers = args.pop('headers', {})
83 if data is not None and 'Content-Type' not in headers:
83 if data is not None and 'Content-Type' not in headers:
84 headers['Content-Type'] = 'application/mercurial-0.1'
84 headers['Content-Type'] = 'application/mercurial-0.1'
85
85
86
86
87 if size and self.ui.configbool('ui', 'usehttp2', False):
87 if size and self.ui.configbool('ui', 'usehttp2', False):
88 headers['Expect'] = '100-Continue'
88 headers['Expect'] = '100-Continue'
89 headers['X-HgHttp2'] = '1'
89 headers['X-HgHttp2'] = '1'
90
90
91 self.ui.debug("sending %s command\n" % cmd)
91 self.ui.debug("sending %s command\n" % cmd)
92 q = [('cmd', cmd)]
92 q = [('cmd', cmd)]
93 headersize = 0
93 headersize = 0
94 if len(args) > 0:
94 if len(args) > 0:
95 httpheader = self.capable('httpheader')
95 httpheader = self.capable('httpheader')
96 if httpheader:
96 if httpheader:
97 headersize = int(httpheader.split(',')[0])
97 headersize = int(httpheader.split(',')[0])
98 if headersize > 0:
98 if headersize > 0:
99 # The headers can typically carry more data than the URL.
99 # The headers can typically carry more data than the URL.
100 encargs = urllib.urlencode(sorted(args.items()))
100 encargs = urllib.urlencode(sorted(args.items()))
101 headerfmt = 'X-HgArg-%s'
101 headerfmt = 'X-HgArg-%s'
102 contentlen = headersize - len(headerfmt % '000' + ': \r\n')
102 contentlen = headersize - len(headerfmt % '000' + ': \r\n')
103 headernum = 0
103 headernum = 0
104 for i in xrange(0, len(encargs), contentlen):
104 for i in xrange(0, len(encargs), contentlen):
105 headernum += 1
105 headernum += 1
106 header = headerfmt % str(headernum)
106 header = headerfmt % str(headernum)
107 headers[header] = encargs[i:i + contentlen]
107 headers[header] = encargs[i:i + contentlen]
108 varyheaders = [headerfmt % str(h) for h in range(1, headernum + 1)]
108 varyheaders = [headerfmt % str(h) for h in range(1, headernum + 1)]
109 headers['Vary'] = ','.join(varyheaders)
109 headers['Vary'] = ','.join(varyheaders)
110 else:
110 else:
111 q += sorted(args.items())
111 q += sorted(args.items())
112 qs = '?%s' % urllib.urlencode(q)
112 qs = '?%s' % urllib.urlencode(q)
113 cu = "%s%s" % (self._url, qs)
113 cu = "%s%s" % (self._url, qs)
114 req = urllib2.Request(cu, data, headers)
114 req = urllib2.Request(cu, data, headers)
115 if data is not None:
115 if data is not None:
116 self.ui.debug("sending %s bytes\n" % size)
116 self.ui.debug("sending %s bytes\n" % size)
117 req.add_unredirected_header('Content-Length', '%d' % size)
117 req.add_unredirected_header('Content-Length', '%d' % size)
118 try:
118 try:
119 resp = self.urlopener.open(req)
119 resp = self.urlopener.open(req)
120 except urllib2.HTTPError, inst:
120 except urllib2.HTTPError, inst:
121 if inst.code == 401:
121 if inst.code == 401:
122 raise util.Abort(_('authorization failed'))
122 raise util.Abort(_('authorization failed'))
123 raise
123 raise
124 except httplib.HTTPException, inst:
124 except httplib.HTTPException, inst:
125 self.ui.debug('http error while sending %s command\n' % cmd)
125 self.ui.debug('http error while sending %s command\n' % cmd)
126 self.ui.traceback()
126 self.ui.traceback()
127 raise IOError(None, inst)
127 raise IOError(None, inst)
128 except IndexError:
128 except IndexError:
129 # this only happens with Python 2.3, later versions raise URLError
129 # this only happens with Python 2.3, later versions raise URLError
130 raise util.Abort(_('http error, possibly caused by proxy setting'))
130 raise util.Abort(_('http error, possibly caused by proxy setting'))
131 # record the url we got redirected to
131 # record the url we got redirected to
132 resp_url = resp.geturl()
132 resp_url = resp.geturl()
133 if resp_url.endswith(qs):
133 if resp_url.endswith(qs):
134 resp_url = resp_url[:-len(qs)]
134 resp_url = resp_url[:-len(qs)]
135 if self._url.rstrip('/') != resp_url.rstrip('/'):
135 if self._url.rstrip('/') != resp_url.rstrip('/'):
136 if not self.ui.quiet:
136 if not self.ui.quiet:
137 self.ui.warn(_('real URL is %s\n') % resp_url)
137 self.ui.warn(_('real URL is %s\n') % resp_url)
138 self._url = resp_url
138 self._url = resp_url
139 try:
139 try:
140 proto = resp.getheader('content-type')
140 proto = resp.getheader('content-type')
141 except AttributeError:
141 except AttributeError:
142 proto = resp.headers.get('content-type', '')
142 proto = resp.headers.get('content-type', '')
143
143
144 safeurl = util.hidepassword(self._url)
144 safeurl = util.hidepassword(self._url)
145 if proto.startswith('application/hg-error'):
145 if proto.startswith('application/hg-error'):
146 raise error.OutOfBandError(resp.read())
146 raise error.OutOfBandError(resp.read())
147 # accept old "text/plain" and "application/hg-changegroup" for now
147 # accept old "text/plain" and "application/hg-changegroup" for now
148 if not (proto.startswith('application/mercurial-') or
148 if not (proto.startswith('application/mercurial-') or
149 (proto.startswith('text/plain')
149 (proto.startswith('text/plain')
150 and not resp.headers.get('content-length')) or
150 and not resp.headers.get('content-length')) or
151 proto.startswith('application/hg-changegroup')):
151 proto.startswith('application/hg-changegroup')):
152 self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu))
152 self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu))
153 raise error.RepoError(
153 raise error.RepoError(
154 _("'%s' does not appear to be an hg repository:\n"
154 _("'%s' does not appear to be an hg repository:\n"
155 "---%%<--- (%s)\n%s\n---%%<---\n")
155 "---%%<--- (%s)\n%s\n---%%<---\n")
156 % (safeurl, proto or 'no content-type', resp.read(1024)))
156 % (safeurl, proto or 'no content-type', resp.read(1024)))
157
157
158 if proto.startswith('application/mercurial-'):
158 if proto.startswith('application/mercurial-'):
159 try:
159 try:
160 version = proto.split('-', 1)[1]
160 version = proto.split('-', 1)[1]
161 version_info = tuple([int(n) for n in version.split('.')])
161 version_info = tuple([int(n) for n in version.split('.')])
162 except ValueError:
162 except ValueError:
163 raise error.RepoError(_("'%s' sent a broken Content-Type "
163 raise error.RepoError(_("'%s' sent a broken Content-Type "
164 "header (%s)") % (safeurl, proto))
164 "header (%s)") % (safeurl, proto))
165 if version_info > (0, 1):
165 if version_info > (0, 1):
166 raise error.RepoError(_("'%s' uses newer protocol %s") %
166 raise error.RepoError(_("'%s' uses newer protocol %s") %
167 (safeurl, version))
167 (safeurl, version))
168
168
169 return resp
169 return resp
170
170
171 def _call(self, cmd, **args):
171 def _call(self, cmd, **args):
172 fp = self._callstream(cmd, **args)
172 fp = self._callstream(cmd, **args)
173 try:
173 try:
174 return fp.read()
174 return fp.read()
175 finally:
175 finally:
176 # if using keepalive, allow connection to be reused
176 # if using keepalive, allow connection to be reused
177 fp.close()
177 fp.close()
178
178
179 def _callpush(self, cmd, cg, **args):
179 def _callpush(self, cmd, cg, **args):
180 # have to stream bundle to a temp file because we do not have
180 # have to stream bundle to a temp file because we do not have
181 # http 1.1 chunked transfer.
181 # http 1.1 chunked transfer.
182
182
183 types = self.capable('unbundle')
183 types = self.capable('unbundle')
184 try:
184 try:
185 types = types.split(',')
185 types = types.split(',')
186 except AttributeError:
186 except AttributeError:
187 # servers older than d1b16a746db6 will send 'unbundle' as a
187 # servers older than d1b16a746db6 will send 'unbundle' as a
188 # boolean capability. They only support headerless/uncompressed
188 # boolean capability. They only support headerless/uncompressed
189 # bundles.
189 # bundles.
190 types = [""]
190 types = [""]
191 for x in types:
191 for x in types:
192 if x in changegroup.bundletypes:
192 if x in changegroup.bundletypes:
193 type = x
193 type = x
194 break
194 break
195
195
196 tempname = changegroup.writebundle(cg, None, type)
196 tempname = changegroup.writebundle(cg, None, type)
197 fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
197 fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
198 headers = {'Content-Type': 'application/mercurial-0.1'}
198 headers = {'Content-Type': 'application/mercurial-0.1'}
199
199
200 try:
200 try:
201 try:
201 try:
202 r = self._call(cmd, data=fp, headers=headers, **args)
202 r = self._call(cmd, data=fp, headers=headers, **args)
203 vals = r.split('\n', 1)
203 vals = r.split('\n', 1)
204 if len(vals) < 2:
204 if len(vals) < 2:
205 raise error.ResponseError(_("unexpected response:"), r)
205 raise error.ResponseError(_("unexpected response:"), r)
206 return vals
206 return vals
207 except socket.error, err:
207 except socket.error, err:
208 if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
208 if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
209 raise util.Abort(_('push failed: %s') % err.args[1])
209 raise util.Abort(_('push failed: %s') % err.args[1])
210 raise util.Abort(err.args[1])
210 raise util.Abort(err.args[1])
211 finally:
211 finally:
212 fp.close()
212 fp.close()
213 os.unlink(tempname)
213 os.unlink(tempname)
214
214
215 def _calltwowaystream(self, cmd, fp, **args):
215 def _calltwowaystream(self, cmd, fp, **args):
216 fh = None
216 fh = None
217 filename = None
217 filename = None
218 try:
218 try:
219 # dump bundle to disk
219 # dump bundle to disk
220 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
220 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
221 fh = os.fdopen(fd, "wb")
221 fh = os.fdopen(fd, "wb")
222 d = fp.read(4096)
222 d = fp.read(4096)
223 while d:
223 while d:
224 fh.write(d)
224 fh.write(d)
225 d = fp.read(4096)
225 d = fp.read(4096)
226 fh.close()
226 fh.close()
227 # start http push
227 # start http push
228 fp = httpconnection.httpsendfile(self.ui, filename, "rb")
228 fp = httpconnection.httpsendfile(self.ui, filename, "rb")
229 headers = {'Content-Type': 'application/mercurial-0.1'}
229 headers = {'Content-Type': 'application/mercurial-0.1'}
230 return self._callstream(cmd, data=fp, headers=headers, **args)
230 return self._callstream(cmd, data=fp, headers=headers, **args)
231 finally:
231 finally:
232 if fh is not None:
232 if fh is not None:
233 fh.close()
233 fh.close()
234 os.unlink(filename)
234 os.unlink(filename)
235
235
236 def _callcompressable(self, cmd, **args):
236 def _callcompressable(self, cmd, **args):
237 stream = self._callstream(cmd, **args)
237 stream = self._callstream(cmd, **args)
238 return util.chunkbuffer(zgenerator(stream))
238 return util.chunkbuffer(zgenerator(stream))
239
239
240 def _abort(self, exception):
241 raise exception
242
240 class httpspeer(httppeer):
243 class httpspeer(httppeer):
241 def __init__(self, ui, path):
244 def __init__(self, ui, path):
242 if not url.has_https:
245 if not url.has_https:
243 raise util.Abort(_('Python support for SSL and HTTPS '
246 raise util.Abort(_('Python support for SSL and HTTPS '
244 'is not installed'))
247 'is not installed'))
245 httppeer.__init__(self, ui, path)
248 httppeer.__init__(self, ui, path)
246
249
247 def instance(ui, path, create):
250 def instance(ui, path, create):
248 if create:
251 if create:
249 raise util.Abort(_('cannot create new http repository'))
252 raise util.Abort(_('cannot create new http repository'))
250 try:
253 try:
251 if path.startswith('https:'):
254 if path.startswith('https:'):
252 inst = httpspeer(ui, path)
255 inst = httpspeer(ui, path)
253 else:
256 else:
254 inst = httppeer(ui, path)
257 inst = httppeer(ui, path)
255 try:
258 try:
256 # Try to do useful work when checking compatibility.
259 # Try to do useful work when checking compatibility.
257 # Usually saves a roundtrip since we want the caps anyway.
260 # Usually saves a roundtrip since we want the caps anyway.
258 inst._fetchcaps()
261 inst._fetchcaps()
259 except error.RepoError:
262 except error.RepoError:
260 # No luck, try older compatibility check.
263 # No luck, try older compatibility check.
261 inst.between([(nullid, nullid)])
264 inst.between([(nullid, nullid)])
262 return inst
265 return inst
263 except error.RepoError, httpexception:
266 except error.RepoError, httpexception:
264 try:
267 try:
265 r = statichttprepo.instance(ui, "static-" + path, create)
268 r = statichttprepo.instance(ui, "static-" + path, create)
266 ui.note('(falling back to static-http)\n')
269 ui.note('(falling back to static-http)\n')
267 return r
270 return r
268 except error.RepoError:
271 except error.RepoError:
269 raise httpexception # use the original http RepoError instead
272 raise httpexception # use the original http RepoError instead
@@ -1,126 +1,132 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 #if no-outer-repo
3 #if no-outer-repo
4
4
5 no repo
5 no repo
6
6
7 $ hg id
7 $ hg id
8 abort: there is no Mercurial repository here (.hg not found)
8 abort: there is no Mercurial repository here (.hg not found)
9 [255]
9 [255]
10
10
11 #endif
11 #endif
12
12
13 create repo
13 create repo
14
14
15 $ hg init test
15 $ hg init test
16 $ cd test
16 $ cd test
17 $ echo a > a
17 $ echo a > a
18 $ hg ci -Ama
18 $ hg ci -Ama
19 adding a
19 adding a
20
20
21 basic id usage
21 basic id usage
22
22
23 $ hg id
23 $ hg id
24 cb9a9f314b8b tip
24 cb9a9f314b8b tip
25 $ hg id --debug
25 $ hg id --debug
26 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b tip
26 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b tip
27 $ hg id -q
27 $ hg id -q
28 cb9a9f314b8b
28 cb9a9f314b8b
29 $ hg id -v
29 $ hg id -v
30 cb9a9f314b8b tip
30 cb9a9f314b8b tip
31
31
32 with options
32 with options
33
33
34 $ hg id -r.
34 $ hg id -r.
35 cb9a9f314b8b tip
35 cb9a9f314b8b tip
36 $ hg id -n
36 $ hg id -n
37 0
37 0
38 $ hg id -t
38 $ hg id -t
39 tip
39 tip
40 $ hg id -b
40 $ hg id -b
41 default
41 default
42 $ hg id -i
42 $ hg id -i
43 cb9a9f314b8b
43 cb9a9f314b8b
44 $ hg id -n -t -b -i
44 $ hg id -n -t -b -i
45 cb9a9f314b8b 0 default tip
45 cb9a9f314b8b 0 default tip
46
46
47 with modifications
47 with modifications
48
48
49 $ echo b > a
49 $ echo b > a
50 $ hg id -n -t -b -i
50 $ hg id -n -t -b -i
51 cb9a9f314b8b+ 0+ default tip
51 cb9a9f314b8b+ 0+ default tip
52
52
53 other local repo
53 other local repo
54
54
55 $ cd ..
55 $ cd ..
56 $ hg -R test id
56 $ hg -R test id
57 cb9a9f314b8b+ tip
57 cb9a9f314b8b+ tip
58 #if no-outer-repo
58 #if no-outer-repo
59 $ hg id test
59 $ hg id test
60 cb9a9f314b8b+ tip
60 cb9a9f314b8b+ tip
61 #endif
61 #endif
62
62
63 with remote http repo
63 with remote http repo
64
64
65 $ cd test
65 $ cd test
66 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid
66 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid
67 $ cat hg.pid >> $DAEMON_PIDS
67 $ cat hg.pid >> $DAEMON_PIDS
68 $ hg id http://localhost:$HGPORT1/
68 $ hg id http://localhost:$HGPORT1/
69 cb9a9f314b8b
69 cb9a9f314b8b
70
70
71 remote with rev number?
71 remote with rev number?
72
72
73 $ hg id -n http://localhost:$HGPORT1/
73 $ hg id -n http://localhost:$HGPORT1/
74 abort: can't query remote revision number, branch, or tags
74 abort: can't query remote revision number, branch, or tags
75 [255]
75 [255]
76
76
77 remote with tags?
77 remote with tags?
78
78
79 $ hg id -t http://localhost:$HGPORT1/
79 $ hg id -t http://localhost:$HGPORT1/
80 abort: can't query remote revision number, branch, or tags
80 abort: can't query remote revision number, branch, or tags
81 [255]
81 [255]
82
82
83 remote with branch?
83 remote with branch?
84
84
85 $ hg id -b http://localhost:$HGPORT1/
85 $ hg id -b http://localhost:$HGPORT1/
86 abort: can't query remote revision number, branch, or tags
86 abort: can't query remote revision number, branch, or tags
87 [255]
87 [255]
88
88
89 test bookmark support
89 test bookmark support
90
90
91 $ hg bookmark Y
91 $ hg bookmark Y
92 $ hg bookmark Z
92 $ hg bookmark Z
93 $ hg bookmarks
93 $ hg bookmarks
94 Y 0:cb9a9f314b8b
94 Y 0:cb9a9f314b8b
95 * Z 0:cb9a9f314b8b
95 * Z 0:cb9a9f314b8b
96 $ hg id
96 $ hg id
97 cb9a9f314b8b+ tip Y/Z
97 cb9a9f314b8b+ tip Y/Z
98 $ hg id --bookmarks
98 $ hg id --bookmarks
99 Y Z
99 Y Z
100
100
101 test remote identify with bookmarks
101 test remote identify with bookmarks
102
102
103 $ hg id http://localhost:$HGPORT1/
103 $ hg id http://localhost:$HGPORT1/
104 cb9a9f314b8b Y/Z
104 cb9a9f314b8b Y/Z
105 $ hg id --bookmarks http://localhost:$HGPORT1/
105 $ hg id --bookmarks http://localhost:$HGPORT1/
106 Y Z
106 Y Z
107 $ hg id -r . http://localhost:$HGPORT1/
107 $ hg id -r . http://localhost:$HGPORT1/
108 cb9a9f314b8b Y/Z
108 cb9a9f314b8b Y/Z
109 $ hg id --bookmarks -r . http://localhost:$HGPORT1/
109 $ hg id --bookmarks -r . http://localhost:$HGPORT1/
110 Y Z
110 Y Z
111
111
112 test invalid lookup
113
114 $ hg id -r noNoNO http://localhost:$HGPORT1/
115 abort: unknown revision 'noNoNO'!
116 [255]
117
112 Make sure we do not obscure unknown requires file entries (issue2649)
118 Make sure we do not obscure unknown requires file entries (issue2649)
113
119
114 $ echo fake >> .hg/requires
120 $ echo fake >> .hg/requires
115 $ hg id
121 $ hg id
116 abort: repository requires features unknown to this Mercurial: fake!
122 abort: repository requires features unknown to this Mercurial: fake!
117 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
123 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
118 [255]
124 [255]
119
125
120 $ cd ..
126 $ cd ..
121 #if no-outer-repo
127 #if no-outer-repo
122 $ hg id test
128 $ hg id test
123 abort: repository requires features unknown to this Mercurial: fake!
129 abort: repository requires features unknown to this Mercurial: fake!
124 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
130 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
125 [255]
131 [255]
126 #endif
132 #endif
@@ -1,384 +1,389 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 $ cat <<EOF > .hg/hgrc
12 $ cat <<EOF > .hg/hgrc
13 > [server]
13 > [server]
14 > uncompressed = True
14 > uncompressed = True
15 >
15 >
16 > [hooks]
16 > [hooks]
17 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
17 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
18 > EOF
18 > EOF
19 $ cd ..
19 $ cd ..
20
20
21 repo not found error
21 repo not found error
22
22
23 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
23 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
24 remote: abort: there is no Mercurial repository here (.hg not found)!
24 remote: abort: there is no Mercurial repository here (.hg not found)!
25 abort: no suitable response from remote hg!
25 abort: no suitable response from remote hg!
26 [255]
26 [255]
27
27
28 non-existent absolute path
28 non-existent absolute path
29
29
30 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
30 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
31 remote: abort: there is no Mercurial repository here (.hg not found)!
31 remote: abort: there is no Mercurial repository here (.hg not found)!
32 abort: no suitable response from remote hg!
32 abort: no suitable response from remote hg!
33 [255]
33 [255]
34
34
35 clone remote via stream
35 clone remote via stream
36
36
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
38 streaming all changes
38 streaming all changes
39 4 files to transfer, 392 bytes of data
39 4 files to transfer, 392 bytes of data
40 transferred 392 bytes in * seconds (*/sec) (glob)
40 transferred 392 bytes in * seconds (*/sec) (glob)
41 updating to branch default
41 updating to branch default
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ cd local-stream
43 $ cd local-stream
44 $ hg verify
44 $ hg verify
45 checking changesets
45 checking changesets
46 checking manifests
46 checking manifests
47 crosschecking files in changesets and manifests
47 crosschecking files in changesets and manifests
48 checking files
48 checking files
49 2 files, 1 changesets, 2 total revisions
49 2 files, 1 changesets, 2 total revisions
50 $ cd ..
50 $ cd ..
51
51
52 clone remote via pull
52 clone remote via pull
53
53
54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
55 requesting all changes
55 requesting all changes
56 adding changesets
56 adding changesets
57 adding manifests
57 adding manifests
58 adding file changes
58 adding file changes
59 added 1 changesets with 2 changes to 2 files
59 added 1 changesets with 2 changes to 2 files
60 updating to branch default
60 updating to branch default
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62
62
63 verify
63 verify
64
64
65 $ cd local
65 $ cd local
66 $ hg verify
66 $ hg verify
67 checking changesets
67 checking changesets
68 checking manifests
68 checking manifests
69 crosschecking files in changesets and manifests
69 crosschecking files in changesets and manifests
70 checking files
70 checking files
71 2 files, 1 changesets, 2 total revisions
71 2 files, 1 changesets, 2 total revisions
72 $ echo '[hooks]' >> .hg/hgrc
72 $ echo '[hooks]' >> .hg/hgrc
73 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
73 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
74
74
75 empty default pull
75 empty default pull
76
76
77 $ hg paths
77 $ hg paths
78 default = ssh://user@dummy/remote
78 default = ssh://user@dummy/remote
79 $ hg pull -e "python \"$TESTDIR/dummyssh\""
79 $ hg pull -e "python \"$TESTDIR/dummyssh\""
80 pulling from ssh://user@dummy/remote
80 pulling from ssh://user@dummy/remote
81 searching for changes
81 searching for changes
82 no changes found
82 no changes found
83
83
84 local change
84 local change
85
85
86 $ echo bleah > foo
86 $ echo bleah > foo
87 $ hg ci -m "add"
87 $ hg ci -m "add"
88
88
89 updating rc
89 updating rc
90
90
91 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
91 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
92 $ echo "[ui]" >> .hg/hgrc
92 $ echo "[ui]" >> .hg/hgrc
93 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
93 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
94
94
95 find outgoing
95 find outgoing
96
96
97 $ hg out ssh://user@dummy/remote
97 $ hg out ssh://user@dummy/remote
98 comparing with ssh://user@dummy/remote
98 comparing with ssh://user@dummy/remote
99 searching for changes
99 searching for changes
100 changeset: 1:a28a9d1a809c
100 changeset: 1:a28a9d1a809c
101 tag: tip
101 tag: tip
102 user: test
102 user: test
103 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
104 summary: add
104 summary: add
105
105
106
106
107 find incoming on the remote side
107 find incoming on the remote side
108
108
109 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
109 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
110 comparing with ssh://user@dummy/local
110 comparing with ssh://user@dummy/local
111 searching for changes
111 searching for changes
112 changeset: 1:a28a9d1a809c
112 changeset: 1:a28a9d1a809c
113 tag: tip
113 tag: tip
114 user: test
114 user: test
115 date: Thu Jan 01 00:00:00 1970 +0000
115 date: Thu Jan 01 00:00:00 1970 +0000
116 summary: add
116 summary: add
117
117
118
118
119 find incoming on the remote side (using absolute path)
119 find incoming on the remote side (using absolute path)
120
120
121 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
121 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
122 comparing with ssh://user@dummy/$TESTTMP/local
122 comparing with ssh://user@dummy/$TESTTMP/local
123 searching for changes
123 searching for changes
124 changeset: 1:a28a9d1a809c
124 changeset: 1:a28a9d1a809c
125 tag: tip
125 tag: tip
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: add
128 summary: add
129
129
130
130
131 push
131 push
132
132
133 $ hg push
133 $ hg push
134 pushing to ssh://user@dummy/remote
134 pushing to ssh://user@dummy/remote
135 searching for changes
135 searching for changes
136 remote: adding changesets
136 remote: adding changesets
137 remote: adding manifests
137 remote: adding manifests
138 remote: adding file changes
138 remote: adding file changes
139 remote: added 1 changesets with 1 changes to 1 files
139 remote: added 1 changesets with 1 changes to 1 files
140 $ cd ../remote
140 $ cd ../remote
141
141
142 check remote tip
142 check remote tip
143
143
144 $ hg tip
144 $ hg tip
145 changeset: 1:a28a9d1a809c
145 changeset: 1:a28a9d1a809c
146 tag: tip
146 tag: tip
147 user: test
147 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
148 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: add
149 summary: add
150
150
151 $ hg verify
151 $ hg verify
152 checking changesets
152 checking changesets
153 checking manifests
153 checking manifests
154 crosschecking files in changesets and manifests
154 crosschecking files in changesets and manifests
155 checking files
155 checking files
156 2 files, 2 changesets, 3 total revisions
156 2 files, 2 changesets, 3 total revisions
157 $ hg cat -r tip foo
157 $ hg cat -r tip foo
158 bleah
158 bleah
159 $ echo z > z
159 $ echo z > z
160 $ hg ci -A -m z z
160 $ hg ci -A -m z z
161 created new head
161 created new head
162
162
163 test pushkeys and bookmarks
163 test pushkeys and bookmarks
164
164
165 $ cd ../local
165 $ cd ../local
166 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
166 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
167 bookmarks
167 bookmarks
168 namespaces
168 namespaces
169 phases
169 phases
170 $ hg book foo -r 0
170 $ hg book foo -r 0
171 $ hg out -B
171 $ hg out -B
172 comparing with ssh://user@dummy/remote
172 comparing with ssh://user@dummy/remote
173 searching for changed bookmarks
173 searching for changed bookmarks
174 foo 1160648e36ce
174 foo 1160648e36ce
175 $ hg push -B foo
175 $ hg push -B foo
176 pushing to ssh://user@dummy/remote
176 pushing to ssh://user@dummy/remote
177 searching for changes
177 searching for changes
178 no changes found
178 no changes found
179 exporting bookmark foo
179 exporting bookmark foo
180 [1]
180 [1]
181 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
181 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
182 foo 1160648e36cec0054048a7edc4110c6f84fde594
182 foo 1160648e36cec0054048a7edc4110c6f84fde594
183 $ hg book -f foo
183 $ hg book -f foo
184 $ hg push --traceback
184 $ hg push --traceback
185 pushing to ssh://user@dummy/remote
185 pushing to ssh://user@dummy/remote
186 searching for changes
186 searching for changes
187 no changes found
187 no changes found
188 updating bookmark foo
188 updating bookmark foo
189 [1]
189 [1]
190 $ hg book -d foo
190 $ hg book -d foo
191 $ hg in -B
191 $ hg in -B
192 comparing with ssh://user@dummy/remote
192 comparing with ssh://user@dummy/remote
193 searching for changed bookmarks
193 searching for changed bookmarks
194 foo a28a9d1a809c
194 foo a28a9d1a809c
195 $ hg book -f -r 0 foo
195 $ hg book -f -r 0 foo
196 $ hg pull -B foo
196 $ hg pull -B foo
197 pulling from ssh://user@dummy/remote
197 pulling from ssh://user@dummy/remote
198 no changes found
198 no changes found
199 updating bookmark foo
199 updating bookmark foo
200 importing bookmark foo
200 importing bookmark foo
201 $ hg book -d foo
201 $ hg book -d foo
202 $ hg push -B foo
202 $ hg push -B foo
203 pushing to ssh://user@dummy/remote
203 pushing to ssh://user@dummy/remote
204 searching for changes
204 searching for changes
205 no changes found
205 no changes found
206 deleting remote bookmark foo
206 deleting remote bookmark foo
207 [1]
207 [1]
208
208
209 a bad, evil hook that prints to stdout
209 a bad, evil hook that prints to stdout
210
210
211 $ cat <<EOF > $TESTTMP/badhook
211 $ cat <<EOF > $TESTTMP/badhook
212 > import sys
212 > import sys
213 > sys.stdout.write("KABOOM\n")
213 > sys.stdout.write("KABOOM\n")
214 > EOF
214 > EOF
215
215
216 $ echo '[hooks]' >> ../remote/.hg/hgrc
216 $ echo '[hooks]' >> ../remote/.hg/hgrc
217 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
217 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
218 $ echo r > r
218 $ echo r > r
219 $ hg ci -A -m z r
219 $ hg ci -A -m z r
220
220
221 push should succeed even though it has an unexpected response
221 push should succeed even though it has an unexpected response
222
222
223 $ hg push
223 $ hg push
224 pushing to ssh://user@dummy/remote
224 pushing to ssh://user@dummy/remote
225 searching for changes
225 searching for changes
226 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
226 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
227 remote: adding changesets
227 remote: adding changesets
228 remote: adding manifests
228 remote: adding manifests
229 remote: adding file changes
229 remote: adding file changes
230 remote: added 1 changesets with 1 changes to 1 files
230 remote: added 1 changesets with 1 changes to 1 files
231 remote: KABOOM
231 remote: KABOOM
232 $ hg -R ../remote heads
232 $ hg -R ../remote heads
233 changeset: 3:1383141674ec
233 changeset: 3:1383141674ec
234 tag: tip
234 tag: tip
235 parent: 1:a28a9d1a809c
235 parent: 1:a28a9d1a809c
236 user: test
236 user: test
237 date: Thu Jan 01 00:00:00 1970 +0000
237 date: Thu Jan 01 00:00:00 1970 +0000
238 summary: z
238 summary: z
239
239
240 changeset: 2:6c0482d977a3
240 changeset: 2:6c0482d977a3
241 parent: 0:1160648e36ce
241 parent: 0:1160648e36ce
242 user: test
242 user: test
243 date: Thu Jan 01 00:00:00 1970 +0000
243 date: Thu Jan 01 00:00:00 1970 +0000
244 summary: z
244 summary: z
245
245
246
246
247 clone bookmarks
247 clone bookmarks
248
248
249 $ hg -R ../remote bookmark test
249 $ hg -R ../remote bookmark test
250 $ hg -R ../remote bookmarks
250 $ hg -R ../remote bookmarks
251 * test 2:6c0482d977a3
251 * test 2:6c0482d977a3
252 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
252 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
253 requesting all changes
253 requesting all changes
254 adding changesets
254 adding changesets
255 adding manifests
255 adding manifests
256 adding file changes
256 adding file changes
257 added 4 changesets with 5 changes to 4 files (+1 heads)
257 added 4 changesets with 5 changes to 4 files (+1 heads)
258 updating to branch default
258 updating to branch default
259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 $ hg -R local-bookmarks bookmarks
260 $ hg -R local-bookmarks bookmarks
261 test 2:6c0482d977a3
261 test 2:6c0482d977a3
262
262
263 passwords in ssh urls are not supported
263 passwords in ssh urls are not supported
264 (we use a glob here because different Python versions give different
264 (we use a glob here because different Python versions give different
265 results here)
265 results here)
266
266
267 $ hg push ssh://user:erroneouspwd@dummy/remote
267 $ hg push ssh://user:erroneouspwd@dummy/remote
268 pushing to ssh://user:*@dummy/remote (glob)
268 pushing to ssh://user:*@dummy/remote (glob)
269 abort: password in URL not supported!
269 abort: password in URL not supported!
270 [255]
270 [255]
271
271
272 $ cd ..
272 $ cd ..
273
273
274 hide outer repo
274 hide outer repo
275 $ hg init
275 $ hg init
276
276
277 Test remote paths with spaces (issue2983):
277 Test remote paths with spaces (issue2983):
278
278
279 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
279 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
280 $ touch "$TESTTMP/a repo/test"
280 $ touch "$TESTTMP/a repo/test"
281 $ hg -R 'a repo' commit -A -m "test"
281 $ hg -R 'a repo' commit -A -m "test"
282 adding test
282 adding test
283 $ hg -R 'a repo' tag tag
283 $ hg -R 'a repo' tag tag
284 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
284 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
285 73649e48688a
285 73649e48688a
286
286
287 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
288 abort: unknown revision 'noNoNO'!
289 [255]
290
287 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
291 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
288
292
289 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
293 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
290 destination directory: a repo
294 destination directory: a repo
291 abort: destination 'a repo' is not empty
295 abort: destination 'a repo' is not empty
292 [255]
296 [255]
293
297
294 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
298 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
295 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
299 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
296 parameters:
300 parameters:
297
301
298 $ cat > ssh.sh << EOF
302 $ cat > ssh.sh << EOF
299 > userhost="\$1"
303 > userhost="\$1"
300 > SSH_ORIGINAL_COMMAND="\$2"
304 > SSH_ORIGINAL_COMMAND="\$2"
301 > export SSH_ORIGINAL_COMMAND
305 > export SSH_ORIGINAL_COMMAND
302 > PYTHONPATH="$PYTHONPATH"
306 > PYTHONPATH="$PYTHONPATH"
303 > export PYTHONPATH
307 > export PYTHONPATH
304 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
308 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
305 > EOF
309 > EOF
306
310
307 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
311 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
308 73649e48688a
312 73649e48688a
309
313
310 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
314 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
311 remote: Illegal repository "$TESTTMP/a'repo" (glob)
315 remote: Illegal repository "$TESTTMP/a'repo" (glob)
312 abort: no suitable response from remote hg!
316 abort: no suitable response from remote hg!
313 [255]
317 [255]
314
318
315 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
319 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
316 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
320 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
317 abort: no suitable response from remote hg!
321 abort: no suitable response from remote hg!
318 [255]
322 [255]
319
323
320 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
324 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
321 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
325 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
322 [255]
326 [255]
323
327
324 Test hg-ssh in read-only mode:
328 Test hg-ssh in read-only mode:
325
329
326 $ cat > ssh.sh << EOF
330 $ cat > ssh.sh << EOF
327 > userhost="\$1"
331 > userhost="\$1"
328 > SSH_ORIGINAL_COMMAND="\$2"
332 > SSH_ORIGINAL_COMMAND="\$2"
329 > export SSH_ORIGINAL_COMMAND
333 > export SSH_ORIGINAL_COMMAND
330 > PYTHONPATH="$PYTHONPATH"
334 > PYTHONPATH="$PYTHONPATH"
331 > export PYTHONPATH
335 > export PYTHONPATH
332 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
336 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
333 > EOF
337 > EOF
334
338
335 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
339 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
336 requesting all changes
340 requesting all changes
337 adding changesets
341 adding changesets
338 adding manifests
342 adding manifests
339 adding file changes
343 adding file changes
340 added 4 changesets with 5 changes to 4 files (+1 heads)
344 added 4 changesets with 5 changes to 4 files (+1 heads)
341 updating to branch default
345 updating to branch default
342 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
343
347
344 $ cd read-only-local
348 $ cd read-only-local
345 $ echo "baz" > bar
349 $ echo "baz" > bar
346 $ hg ci -A -m "unpushable commit" bar
350 $ hg ci -A -m "unpushable commit" bar
347 $ hg push --ssh "sh ../ssh.sh"
351 $ hg push --ssh "sh ../ssh.sh"
348 pushing to ssh://user@dummy/*/remote (glob)
352 pushing to ssh://user@dummy/*/remote (glob)
349 searching for changes
353 searching for changes
350 remote: Permission denied
354 remote: Permission denied
351 remote: abort: prechangegroup.hg-ssh hook failed
355 remote: abort: prechangegroup.hg-ssh hook failed
352 remote: Permission denied
356 remote: Permission denied
353 remote: abort: prepushkey.hg-ssh hook failed
357 remote: abort: prepushkey.hg-ssh hook failed
354 abort: unexpected response: empty string
358 abort: unexpected response: empty string
355 [255]
359 [255]
356
360
357 $ cd ..
361 $ cd ..
358
362
359 $ cat dummylog
363 $ cat dummylog
360 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
364 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
361 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
365 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
362 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
366 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
363 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
367 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
364 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
368 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
365 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
369 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
366 Got arguments 1:user@dummy 2:hg -R local serve --stdio
370 Got arguments 1:user@dummy 2:hg -R local serve --stdio
367 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
371 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
368 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
372 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
369 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
373 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
370 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
374 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
371 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
375 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
372 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
376 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
373 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
377 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
374 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
378 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
375 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
379 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
376 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
380 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
377 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
381 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
378 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
382 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
379 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
383 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
380 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
384 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
381 Got arguments 1:user@dummy 2:hg init 'a repo'
385 Got arguments 1:user@dummy 2:hg init 'a repo'
382 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
386 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
383 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
387 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
384 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
388 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
389 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
General Comments 0
You need to be logged in to leave comments. Login now