##// END OF EJS Templates
dispatch: error out on invalid -R path even if optionalrepo (issue4805) (BC)...
Yuya Nishihara -
r26142:7332bf4a default
parent child Browse files
Show More
@@ -1,1037 +1,1039 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import atexit
10 import atexit
11 import difflib
11 import difflib
12 import errno
12 import errno
13 import os
13 import os
14 import pdb
14 import pdb
15 import re
15 import re
16 import shlex
16 import shlex
17 import signal
17 import signal
18 import socket
18 import socket
19 import sys
19 import sys
20 import time
20 import time
21 import traceback
21 import traceback
22
22
23
23
24 from .i18n import _
24 from .i18n import _
25
25
26 from . import (
26 from . import (
27 cmdutil,
27 cmdutil,
28 commands,
28 commands,
29 demandimport,
29 demandimport,
30 encoding,
30 encoding,
31 error,
31 error,
32 extensions,
32 extensions,
33 fancyopts,
33 fancyopts,
34 hg,
34 hg,
35 hook,
35 hook,
36 ui as uimod,
36 ui as uimod,
37 util,
37 util,
38 )
38 )
39
39
40 class request(object):
40 class request(object):
41 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
41 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
42 ferr=None):
42 ferr=None):
43 self.args = args
43 self.args = args
44 self.ui = ui
44 self.ui = ui
45 self.repo = repo
45 self.repo = repo
46
46
47 # input/output/error streams
47 # input/output/error streams
48 self.fin = fin
48 self.fin = fin
49 self.fout = fout
49 self.fout = fout
50 self.ferr = ferr
50 self.ferr = ferr
51
51
52 def run():
52 def run():
53 "run the command in sys.argv"
53 "run the command in sys.argv"
54 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
54 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
55
55
56 def _getsimilar(symbols, value):
56 def _getsimilar(symbols, value):
57 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
57 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
58 # The cutoff for similarity here is pretty arbitrary. It should
58 # The cutoff for similarity here is pretty arbitrary. It should
59 # probably be investigated and tweaked.
59 # probably be investigated and tweaked.
60 return [s for s in symbols if sim(s) > 0.6]
60 return [s for s in symbols if sim(s) > 0.6]
61
61
62 def _formatparse(write, inst):
62 def _formatparse(write, inst):
63 similar = []
63 similar = []
64 if isinstance(inst, error.UnknownIdentifier):
64 if isinstance(inst, error.UnknownIdentifier):
65 # make sure to check fileset first, as revset can invoke fileset
65 # make sure to check fileset first, as revset can invoke fileset
66 similar = _getsimilar(inst.symbols, inst.function)
66 similar = _getsimilar(inst.symbols, inst.function)
67 if len(inst.args) > 1:
67 if len(inst.args) > 1:
68 write(_("hg: parse error at %s: %s\n") %
68 write(_("hg: parse error at %s: %s\n") %
69 (inst.args[1], inst.args[0]))
69 (inst.args[1], inst.args[0]))
70 if (inst.args[0][0] == ' '):
70 if (inst.args[0][0] == ' '):
71 write(_("unexpected leading whitespace\n"))
71 write(_("unexpected leading whitespace\n"))
72 else:
72 else:
73 write(_("hg: parse error: %s\n") % inst.args[0])
73 write(_("hg: parse error: %s\n") % inst.args[0])
74 if similar:
74 if similar:
75 if len(similar) == 1:
75 if len(similar) == 1:
76 write(_("(did you mean %r?)\n") % similar[0])
76 write(_("(did you mean %r?)\n") % similar[0])
77 else:
77 else:
78 ss = ", ".join(sorted(similar))
78 ss = ", ".join(sorted(similar))
79 write(_("(did you mean one of %s?)\n") % ss)
79 write(_("(did you mean one of %s?)\n") % ss)
80
80
81 def dispatch(req):
81 def dispatch(req):
82 "run the command specified in req.args"
82 "run the command specified in req.args"
83 if req.ferr:
83 if req.ferr:
84 ferr = req.ferr
84 ferr = req.ferr
85 elif req.ui:
85 elif req.ui:
86 ferr = req.ui.ferr
86 ferr = req.ui.ferr
87 else:
87 else:
88 ferr = sys.stderr
88 ferr = sys.stderr
89
89
90 try:
90 try:
91 if not req.ui:
91 if not req.ui:
92 req.ui = uimod.ui()
92 req.ui = uimod.ui()
93 if '--traceback' in req.args:
93 if '--traceback' in req.args:
94 req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
94 req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
95
95
96 # set ui streams from the request
96 # set ui streams from the request
97 if req.fin:
97 if req.fin:
98 req.ui.fin = req.fin
98 req.ui.fin = req.fin
99 if req.fout:
99 if req.fout:
100 req.ui.fout = req.fout
100 req.ui.fout = req.fout
101 if req.ferr:
101 if req.ferr:
102 req.ui.ferr = req.ferr
102 req.ui.ferr = req.ferr
103 except util.Abort as inst:
103 except util.Abort as inst:
104 ferr.write(_("abort: %s\n") % inst)
104 ferr.write(_("abort: %s\n") % inst)
105 if inst.hint:
105 if inst.hint:
106 ferr.write(_("(%s)\n") % inst.hint)
106 ferr.write(_("(%s)\n") % inst.hint)
107 return -1
107 return -1
108 except error.ParseError as inst:
108 except error.ParseError as inst:
109 _formatparse(ferr.write, inst)
109 _formatparse(ferr.write, inst)
110 return -1
110 return -1
111
111
112 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
112 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
113 starttime = time.time()
113 starttime = time.time()
114 ret = None
114 ret = None
115 try:
115 try:
116 ret = _runcatch(req)
116 ret = _runcatch(req)
117 return ret
117 return ret
118 finally:
118 finally:
119 duration = time.time() - starttime
119 duration = time.time() - starttime
120 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
120 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
121 msg, ret or 0, duration)
121 msg, ret or 0, duration)
122
122
123 def _runcatch(req):
123 def _runcatch(req):
124 def catchterm(*args):
124 def catchterm(*args):
125 raise error.SignalInterrupt
125 raise error.SignalInterrupt
126
126
127 ui = req.ui
127 ui = req.ui
128 try:
128 try:
129 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
129 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
130 num = getattr(signal, name, None)
130 num = getattr(signal, name, None)
131 if num:
131 if num:
132 signal.signal(num, catchterm)
132 signal.signal(num, catchterm)
133 except ValueError:
133 except ValueError:
134 pass # happens if called in a thread
134 pass # happens if called in a thread
135
135
136 try:
136 try:
137 try:
137 try:
138 debugger = 'pdb'
138 debugger = 'pdb'
139 debugtrace = {
139 debugtrace = {
140 'pdb' : pdb.set_trace
140 'pdb' : pdb.set_trace
141 }
141 }
142 debugmortem = {
142 debugmortem = {
143 'pdb' : pdb.post_mortem
143 'pdb' : pdb.post_mortem
144 }
144 }
145
145
146 # read --config before doing anything else
146 # read --config before doing anything else
147 # (e.g. to change trust settings for reading .hg/hgrc)
147 # (e.g. to change trust settings for reading .hg/hgrc)
148 cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args))
148 cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args))
149
149
150 if req.repo:
150 if req.repo:
151 # copy configs that were passed on the cmdline (--config) to
151 # copy configs that were passed on the cmdline (--config) to
152 # the repo ui
152 # the repo ui
153 for sec, name, val in cfgs:
153 for sec, name, val in cfgs:
154 req.repo.ui.setconfig(sec, name, val, source='--config')
154 req.repo.ui.setconfig(sec, name, val, source='--config')
155
155
156 # developer config: ui.debugger
156 # developer config: ui.debugger
157 debugger = ui.config("ui", "debugger")
157 debugger = ui.config("ui", "debugger")
158 debugmod = pdb
158 debugmod = pdb
159 if not debugger or ui.plain():
159 if not debugger or ui.plain():
160 # if we are in HGPLAIN mode, then disable custom debugging
160 # if we are in HGPLAIN mode, then disable custom debugging
161 debugger = 'pdb'
161 debugger = 'pdb'
162 elif '--debugger' in req.args:
162 elif '--debugger' in req.args:
163 # This import can be slow for fancy debuggers, so only
163 # This import can be slow for fancy debuggers, so only
164 # do it when absolutely necessary, i.e. when actual
164 # do it when absolutely necessary, i.e. when actual
165 # debugging has been requested
165 # debugging has been requested
166 with demandimport.deactivated():
166 with demandimport.deactivated():
167 try:
167 try:
168 debugmod = __import__(debugger)
168 debugmod = __import__(debugger)
169 except ImportError:
169 except ImportError:
170 pass # Leave debugmod = pdb
170 pass # Leave debugmod = pdb
171
171
172 debugtrace[debugger] = debugmod.set_trace
172 debugtrace[debugger] = debugmod.set_trace
173 debugmortem[debugger] = debugmod.post_mortem
173 debugmortem[debugger] = debugmod.post_mortem
174
174
175 # enter the debugger before command execution
175 # enter the debugger before command execution
176 if '--debugger' in req.args:
176 if '--debugger' in req.args:
177 ui.warn(_("entering debugger - "
177 ui.warn(_("entering debugger - "
178 "type c to continue starting hg or h for help\n"))
178 "type c to continue starting hg or h for help\n"))
179
179
180 if (debugger != 'pdb' and
180 if (debugger != 'pdb' and
181 debugtrace[debugger] == debugtrace['pdb']):
181 debugtrace[debugger] == debugtrace['pdb']):
182 ui.warn(_("%s debugger specified "
182 ui.warn(_("%s debugger specified "
183 "but its module was not found\n") % debugger)
183 "but its module was not found\n") % debugger)
184
184
185 debugtrace[debugger]()
185 debugtrace[debugger]()
186 try:
186 try:
187 return _dispatch(req)
187 return _dispatch(req)
188 finally:
188 finally:
189 ui.flush()
189 ui.flush()
190 except: # re-raises
190 except: # re-raises
191 # enter the debugger when we hit an exception
191 # enter the debugger when we hit an exception
192 if '--debugger' in req.args:
192 if '--debugger' in req.args:
193 traceback.print_exc()
193 traceback.print_exc()
194 debugmortem[debugger](sys.exc_info()[2])
194 debugmortem[debugger](sys.exc_info()[2])
195 ui.traceback()
195 ui.traceback()
196 raise
196 raise
197
197
198 # Global exception handling, alphabetically
198 # Global exception handling, alphabetically
199 # Mercurial-specific first, followed by built-in and library exceptions
199 # Mercurial-specific first, followed by built-in and library exceptions
200 except error.AmbiguousCommand as inst:
200 except error.AmbiguousCommand as inst:
201 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
201 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
202 (inst.args[0], " ".join(inst.args[1])))
202 (inst.args[0], " ".join(inst.args[1])))
203 except error.ParseError as inst:
203 except error.ParseError as inst:
204 _formatparse(ui.warn, inst)
204 _formatparse(ui.warn, inst)
205 return -1
205 return -1
206 except error.LockHeld as inst:
206 except error.LockHeld as inst:
207 if inst.errno == errno.ETIMEDOUT:
207 if inst.errno == errno.ETIMEDOUT:
208 reason = _('timed out waiting for lock held by %s') % inst.locker
208 reason = _('timed out waiting for lock held by %s') % inst.locker
209 else:
209 else:
210 reason = _('lock held by %s') % inst.locker
210 reason = _('lock held by %s') % inst.locker
211 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
211 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
212 except error.LockUnavailable as inst:
212 except error.LockUnavailable as inst:
213 ui.warn(_("abort: could not lock %s: %s\n") %
213 ui.warn(_("abort: could not lock %s: %s\n") %
214 (inst.desc or inst.filename, inst.strerror))
214 (inst.desc or inst.filename, inst.strerror))
215 except error.CommandError as inst:
215 except error.CommandError as inst:
216 if inst.args[0]:
216 if inst.args[0]:
217 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
217 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
218 commands.help_(ui, inst.args[0], full=False, command=True)
218 commands.help_(ui, inst.args[0], full=False, command=True)
219 else:
219 else:
220 ui.warn(_("hg: %s\n") % inst.args[1])
220 ui.warn(_("hg: %s\n") % inst.args[1])
221 commands.help_(ui, 'shortlist')
221 commands.help_(ui, 'shortlist')
222 except error.OutOfBandError as inst:
222 except error.OutOfBandError as inst:
223 if inst.args:
223 if inst.args:
224 msg = _("abort: remote error:\n")
224 msg = _("abort: remote error:\n")
225 else:
225 else:
226 msg = _("abort: remote error\n")
226 msg = _("abort: remote error\n")
227 ui.warn(msg)
227 ui.warn(msg)
228 if inst.args:
228 if inst.args:
229 ui.warn(''.join(inst.args))
229 ui.warn(''.join(inst.args))
230 if inst.hint:
230 if inst.hint:
231 ui.warn('(%s)\n' % inst.hint)
231 ui.warn('(%s)\n' % inst.hint)
232 except error.RepoError as inst:
232 except error.RepoError as inst:
233 ui.warn(_("abort: %s!\n") % inst)
233 ui.warn(_("abort: %s!\n") % inst)
234 if inst.hint:
234 if inst.hint:
235 ui.warn(_("(%s)\n") % inst.hint)
235 ui.warn(_("(%s)\n") % inst.hint)
236 except error.ResponseError as inst:
236 except error.ResponseError as inst:
237 ui.warn(_("abort: %s") % inst.args[0])
237 ui.warn(_("abort: %s") % inst.args[0])
238 if not isinstance(inst.args[1], basestring):
238 if not isinstance(inst.args[1], basestring):
239 ui.warn(" %r\n" % (inst.args[1],))
239 ui.warn(" %r\n" % (inst.args[1],))
240 elif not inst.args[1]:
240 elif not inst.args[1]:
241 ui.warn(_(" empty string\n"))
241 ui.warn(_(" empty string\n"))
242 else:
242 else:
243 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
243 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
244 except error.CensoredNodeError as inst:
244 except error.CensoredNodeError as inst:
245 ui.warn(_("abort: file censored %s!\n") % inst)
245 ui.warn(_("abort: file censored %s!\n") % inst)
246 except error.RevlogError as inst:
246 except error.RevlogError as inst:
247 ui.warn(_("abort: %s!\n") % inst)
247 ui.warn(_("abort: %s!\n") % inst)
248 except error.SignalInterrupt:
248 except error.SignalInterrupt:
249 ui.warn(_("killed!\n"))
249 ui.warn(_("killed!\n"))
250 except error.UnknownCommand as inst:
250 except error.UnknownCommand as inst:
251 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
251 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
252 try:
252 try:
253 # check if the command is in a disabled extension
253 # check if the command is in a disabled extension
254 # (but don't check for extensions themselves)
254 # (but don't check for extensions themselves)
255 commands.help_(ui, inst.args[0], unknowncmd=True)
255 commands.help_(ui, inst.args[0], unknowncmd=True)
256 except error.UnknownCommand:
256 except error.UnknownCommand:
257 suggested = False
257 suggested = False
258 if len(inst.args) == 2:
258 if len(inst.args) == 2:
259 sim = _getsimilar(inst.args[1], inst.args[0])
259 sim = _getsimilar(inst.args[1], inst.args[0])
260 if sim:
260 if sim:
261 ui.warn(_('(did you mean one of %s?)\n') %
261 ui.warn(_('(did you mean one of %s?)\n') %
262 ', '.join(sorted(sim)))
262 ', '.join(sorted(sim)))
263 suggested = True
263 suggested = True
264 if not suggested:
264 if not suggested:
265 commands.help_(ui, 'shortlist')
265 commands.help_(ui, 'shortlist')
266 except error.InterventionRequired as inst:
266 except error.InterventionRequired as inst:
267 ui.warn("%s\n" % inst)
267 ui.warn("%s\n" % inst)
268 return 1
268 return 1
269 except util.Abort as inst:
269 except util.Abort as inst:
270 ui.warn(_("abort: %s\n") % inst)
270 ui.warn(_("abort: %s\n") % inst)
271 if inst.hint:
271 if inst.hint:
272 ui.warn(_("(%s)\n") % inst.hint)
272 ui.warn(_("(%s)\n") % inst.hint)
273 except ImportError as inst:
273 except ImportError as inst:
274 ui.warn(_("abort: %s!\n") % inst)
274 ui.warn(_("abort: %s!\n") % inst)
275 m = str(inst).split()[-1]
275 m = str(inst).split()[-1]
276 if m in "mpatch bdiff".split():
276 if m in "mpatch bdiff".split():
277 ui.warn(_("(did you forget to compile extensions?)\n"))
277 ui.warn(_("(did you forget to compile extensions?)\n"))
278 elif m in "zlib".split():
278 elif m in "zlib".split():
279 ui.warn(_("(is your Python install correct?)\n"))
279 ui.warn(_("(is your Python install correct?)\n"))
280 except IOError as inst:
280 except IOError as inst:
281 if util.safehasattr(inst, "code"):
281 if util.safehasattr(inst, "code"):
282 ui.warn(_("abort: %s\n") % inst)
282 ui.warn(_("abort: %s\n") % inst)
283 elif util.safehasattr(inst, "reason"):
283 elif util.safehasattr(inst, "reason"):
284 try: # usually it is in the form (errno, strerror)
284 try: # usually it is in the form (errno, strerror)
285 reason = inst.reason.args[1]
285 reason = inst.reason.args[1]
286 except (AttributeError, IndexError):
286 except (AttributeError, IndexError):
287 # it might be anything, for example a string
287 # it might be anything, for example a string
288 reason = inst.reason
288 reason = inst.reason
289 if isinstance(reason, unicode):
289 if isinstance(reason, unicode):
290 # SSLError of Python 2.7.9 contains a unicode
290 # SSLError of Python 2.7.9 contains a unicode
291 reason = reason.encode(encoding.encoding, 'replace')
291 reason = reason.encode(encoding.encoding, 'replace')
292 ui.warn(_("abort: error: %s\n") % reason)
292 ui.warn(_("abort: error: %s\n") % reason)
293 elif (util.safehasattr(inst, "args")
293 elif (util.safehasattr(inst, "args")
294 and inst.args and inst.args[0] == errno.EPIPE):
294 and inst.args and inst.args[0] == errno.EPIPE):
295 if ui.debugflag:
295 if ui.debugflag:
296 ui.warn(_("broken pipe\n"))
296 ui.warn(_("broken pipe\n"))
297 elif getattr(inst, "strerror", None):
297 elif getattr(inst, "strerror", None):
298 if getattr(inst, "filename", None):
298 if getattr(inst, "filename", None):
299 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
299 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
300 else:
300 else:
301 ui.warn(_("abort: %s\n") % inst.strerror)
301 ui.warn(_("abort: %s\n") % inst.strerror)
302 else:
302 else:
303 raise
303 raise
304 except OSError as inst:
304 except OSError as inst:
305 if getattr(inst, "filename", None) is not None:
305 if getattr(inst, "filename", None) is not None:
306 ui.warn(_("abort: %s: '%s'\n") % (inst.strerror, inst.filename))
306 ui.warn(_("abort: %s: '%s'\n") % (inst.strerror, inst.filename))
307 else:
307 else:
308 ui.warn(_("abort: %s\n") % inst.strerror)
308 ui.warn(_("abort: %s\n") % inst.strerror)
309 except KeyboardInterrupt:
309 except KeyboardInterrupt:
310 try:
310 try:
311 ui.warn(_("interrupted!\n"))
311 ui.warn(_("interrupted!\n"))
312 except IOError as inst:
312 except IOError as inst:
313 if inst.errno == errno.EPIPE:
313 if inst.errno == errno.EPIPE:
314 if ui.debugflag:
314 if ui.debugflag:
315 ui.warn(_("\nbroken pipe\n"))
315 ui.warn(_("\nbroken pipe\n"))
316 else:
316 else:
317 raise
317 raise
318 except MemoryError:
318 except MemoryError:
319 ui.warn(_("abort: out of memory\n"))
319 ui.warn(_("abort: out of memory\n"))
320 except SystemExit as inst:
320 except SystemExit as inst:
321 # Commands shouldn't sys.exit directly, but give a return code.
321 # Commands shouldn't sys.exit directly, but give a return code.
322 # Just in case catch this and and pass exit code to caller.
322 # Just in case catch this and and pass exit code to caller.
323 return inst.code
323 return inst.code
324 except socket.error as inst:
324 except socket.error as inst:
325 ui.warn(_("abort: %s\n") % inst.args[-1])
325 ui.warn(_("abort: %s\n") % inst.args[-1])
326 except: # re-raises
326 except: # re-raises
327 myver = util.version()
327 myver = util.version()
328 # For compatibility checking, we discard the portion of the hg
328 # For compatibility checking, we discard the portion of the hg
329 # version after the + on the assumption that if a "normal
329 # version after the + on the assumption that if a "normal
330 # user" is running a build with a + in it the packager
330 # user" is running a build with a + in it the packager
331 # probably built from fairly close to a tag and anyone with a
331 # probably built from fairly close to a tag and anyone with a
332 # 'make local' copy of hg (where the version number can be out
332 # 'make local' copy of hg (where the version number can be out
333 # of date) will be clueful enough to notice the implausible
333 # of date) will be clueful enough to notice the implausible
334 # version number and try updating.
334 # version number and try updating.
335 compare = myver.split('+')[0]
335 compare = myver.split('+')[0]
336 ct = tuplever(compare)
336 ct = tuplever(compare)
337 worst = None, ct, ''
337 worst = None, ct, ''
338 for name, mod in extensions.extensions():
338 for name, mod in extensions.extensions():
339 testedwith = getattr(mod, 'testedwith', '')
339 testedwith = getattr(mod, 'testedwith', '')
340 report = getattr(mod, 'buglink', _('the extension author.'))
340 report = getattr(mod, 'buglink', _('the extension author.'))
341 if not testedwith.strip():
341 if not testedwith.strip():
342 # We found an untested extension. It's likely the culprit.
342 # We found an untested extension. It's likely the culprit.
343 worst = name, 'unknown', report
343 worst = name, 'unknown', report
344 break
344 break
345
345
346 # Never blame on extensions bundled with Mercurial.
346 # Never blame on extensions bundled with Mercurial.
347 if testedwith == 'internal':
347 if testedwith == 'internal':
348 continue
348 continue
349
349
350 tested = [tuplever(t) for t in testedwith.split()]
350 tested = [tuplever(t) for t in testedwith.split()]
351 if ct in tested:
351 if ct in tested:
352 continue
352 continue
353
353
354 lower = [t for t in tested if t < ct]
354 lower = [t for t in tested if t < ct]
355 nearest = max(lower or tested)
355 nearest = max(lower or tested)
356 if worst[0] is None or nearest < worst[1]:
356 if worst[0] is None or nearest < worst[1]:
357 worst = name, nearest, report
357 worst = name, nearest, report
358 if worst[0] is not None:
358 if worst[0] is not None:
359 name, testedwith, report = worst
359 name, testedwith, report = worst
360 if not isinstance(testedwith, str):
360 if not isinstance(testedwith, str):
361 testedwith = '.'.join([str(c) for c in testedwith])
361 testedwith = '.'.join([str(c) for c in testedwith])
362 warning = (_('** Unknown exception encountered with '
362 warning = (_('** Unknown exception encountered with '
363 'possibly-broken third-party extension %s\n'
363 'possibly-broken third-party extension %s\n'
364 '** which supports versions %s of Mercurial.\n'
364 '** which supports versions %s of Mercurial.\n'
365 '** Please disable %s and try your action again.\n'
365 '** Please disable %s and try your action again.\n'
366 '** If that fixes the bug please report it to %s\n')
366 '** If that fixes the bug please report it to %s\n')
367 % (name, testedwith, name, report))
367 % (name, testedwith, name, report))
368 else:
368 else:
369 warning = (_("** unknown exception encountered, "
369 warning = (_("** unknown exception encountered, "
370 "please report by visiting\n") +
370 "please report by visiting\n") +
371 _("** http://mercurial.selenic.com/wiki/BugTracker\n"))
371 _("** http://mercurial.selenic.com/wiki/BugTracker\n"))
372 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
372 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
373 (_("** Mercurial Distributed SCM (version %s)\n") % myver) +
373 (_("** Mercurial Distributed SCM (version %s)\n") % myver) +
374 (_("** Extensions loaded: %s\n") %
374 (_("** Extensions loaded: %s\n") %
375 ", ".join([x[0] for x in extensions.extensions()])))
375 ", ".join([x[0] for x in extensions.extensions()])))
376 ui.log("commandexception", "%s\n%s\n", warning, traceback.format_exc())
376 ui.log("commandexception", "%s\n%s\n", warning, traceback.format_exc())
377 ui.warn(warning)
377 ui.warn(warning)
378 raise
378 raise
379
379
380 return -1
380 return -1
381
381
382 def tuplever(v):
382 def tuplever(v):
383 try:
383 try:
384 # Assertion: tuplever is only used for extension compatibility
384 # Assertion: tuplever is only used for extension compatibility
385 # checking. Otherwise, the discarding of extra version fields is
385 # checking. Otherwise, the discarding of extra version fields is
386 # incorrect.
386 # incorrect.
387 return tuple([int(i) for i in v.split('.')[0:2]])
387 return tuple([int(i) for i in v.split('.')[0:2]])
388 except ValueError:
388 except ValueError:
389 return tuple()
389 return tuple()
390
390
391 def aliasargs(fn, givenargs):
391 def aliasargs(fn, givenargs):
392 args = getattr(fn, 'args', [])
392 args = getattr(fn, 'args', [])
393 if args:
393 if args:
394 cmd = ' '.join(map(util.shellquote, args))
394 cmd = ' '.join(map(util.shellquote, args))
395
395
396 nums = []
396 nums = []
397 def replacer(m):
397 def replacer(m):
398 num = int(m.group(1)) - 1
398 num = int(m.group(1)) - 1
399 nums.append(num)
399 nums.append(num)
400 if num < len(givenargs):
400 if num < len(givenargs):
401 return givenargs[num]
401 return givenargs[num]
402 raise util.Abort(_('too few arguments for command alias'))
402 raise util.Abort(_('too few arguments for command alias'))
403 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
403 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
404 givenargs = [x for i, x in enumerate(givenargs)
404 givenargs = [x for i, x in enumerate(givenargs)
405 if i not in nums]
405 if i not in nums]
406 args = shlex.split(cmd)
406 args = shlex.split(cmd)
407 return args + givenargs
407 return args + givenargs
408
408
409 def aliasinterpolate(name, args, cmd):
409 def aliasinterpolate(name, args, cmd):
410 '''interpolate args into cmd for shell aliases
410 '''interpolate args into cmd for shell aliases
411
411
412 This also handles $0, $@ and "$@".
412 This also handles $0, $@ and "$@".
413 '''
413 '''
414 # util.interpolate can't deal with "$@" (with quotes) because it's only
414 # util.interpolate can't deal with "$@" (with quotes) because it's only
415 # built to match prefix + patterns.
415 # built to match prefix + patterns.
416 replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args))
416 replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args))
417 replacemap['$0'] = name
417 replacemap['$0'] = name
418 replacemap['$$'] = '$'
418 replacemap['$$'] = '$'
419 replacemap['$@'] = ' '.join(args)
419 replacemap['$@'] = ' '.join(args)
420 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
420 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
421 # parameters, separated out into words. Emulate the same behavior here by
421 # parameters, separated out into words. Emulate the same behavior here by
422 # quoting the arguments individually. POSIX shells will then typically
422 # quoting the arguments individually. POSIX shells will then typically
423 # tokenize each argument into exactly one word.
423 # tokenize each argument into exactly one word.
424 replacemap['"$@"'] = ' '.join(util.shellquote(arg) for arg in args)
424 replacemap['"$@"'] = ' '.join(util.shellquote(arg) for arg in args)
425 # escape '\$' for regex
425 # escape '\$' for regex
426 regex = '|'.join(replacemap.keys()).replace('$', r'\$')
426 regex = '|'.join(replacemap.keys()).replace('$', r'\$')
427 r = re.compile(regex)
427 r = re.compile(regex)
428 return r.sub(lambda x: replacemap[x.group()], cmd)
428 return r.sub(lambda x: replacemap[x.group()], cmd)
429
429
430 class cmdalias(object):
430 class cmdalias(object):
431 def __init__(self, name, definition, cmdtable):
431 def __init__(self, name, definition, cmdtable):
432 self.name = self.cmd = name
432 self.name = self.cmd = name
433 self.cmdname = ''
433 self.cmdname = ''
434 self.definition = definition
434 self.definition = definition
435 self.fn = None
435 self.fn = None
436 self.args = []
436 self.args = []
437 self.opts = []
437 self.opts = []
438 self.help = ''
438 self.help = ''
439 self.norepo = True
439 self.norepo = True
440 self.optionalrepo = False
440 self.optionalrepo = False
441 self.badalias = None
441 self.badalias = None
442 self.unknowncmd = False
442 self.unknowncmd = False
443
443
444 try:
444 try:
445 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
445 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
446 for alias, e in cmdtable.iteritems():
446 for alias, e in cmdtable.iteritems():
447 if e is entry:
447 if e is entry:
448 self.cmd = alias
448 self.cmd = alias
449 break
449 break
450 self.shadows = True
450 self.shadows = True
451 except error.UnknownCommand:
451 except error.UnknownCommand:
452 self.shadows = False
452 self.shadows = False
453
453
454 if not self.definition:
454 if not self.definition:
455 self.badalias = _("no definition for alias '%s'") % self.name
455 self.badalias = _("no definition for alias '%s'") % self.name
456 return
456 return
457
457
458 if self.definition.startswith('!'):
458 if self.definition.startswith('!'):
459 self.shell = True
459 self.shell = True
460 def fn(ui, *args):
460 def fn(ui, *args):
461 env = {'HG_ARGS': ' '.join((self.name,) + args)}
461 env = {'HG_ARGS': ' '.join((self.name,) + args)}
462 def _checkvar(m):
462 def _checkvar(m):
463 if m.groups()[0] == '$':
463 if m.groups()[0] == '$':
464 return m.group()
464 return m.group()
465 elif int(m.groups()[0]) <= len(args):
465 elif int(m.groups()[0]) <= len(args):
466 return m.group()
466 return m.group()
467 else:
467 else:
468 ui.debug("No argument found for substitution "
468 ui.debug("No argument found for substitution "
469 "of %i variable in alias '%s' definition."
469 "of %i variable in alias '%s' definition."
470 % (int(m.groups()[0]), self.name))
470 % (int(m.groups()[0]), self.name))
471 return ''
471 return ''
472 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
472 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
473 cmd = aliasinterpolate(self.name, args, cmd)
473 cmd = aliasinterpolate(self.name, args, cmd)
474 return ui.system(cmd, environ=env)
474 return ui.system(cmd, environ=env)
475 self.fn = fn
475 self.fn = fn
476 return
476 return
477
477
478 try:
478 try:
479 args = shlex.split(self.definition)
479 args = shlex.split(self.definition)
480 except ValueError as inst:
480 except ValueError as inst:
481 self.badalias = (_("error in definition for alias '%s': %s")
481 self.badalias = (_("error in definition for alias '%s': %s")
482 % (self.name, inst))
482 % (self.name, inst))
483 return
483 return
484 self.cmdname = cmd = args.pop(0)
484 self.cmdname = cmd = args.pop(0)
485 args = map(util.expandpath, args)
485 args = map(util.expandpath, args)
486
486
487 for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"):
487 for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"):
488 if _earlygetopt([invalidarg], args):
488 if _earlygetopt([invalidarg], args):
489 self.badalias = (_("error in definition for alias '%s': %s may "
489 self.badalias = (_("error in definition for alias '%s': %s may "
490 "only be given on the command line")
490 "only be given on the command line")
491 % (self.name, invalidarg))
491 % (self.name, invalidarg))
492 return
492 return
493
493
494 try:
494 try:
495 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
495 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
496 if len(tableentry) > 2:
496 if len(tableentry) > 2:
497 self.fn, self.opts, self.help = tableentry
497 self.fn, self.opts, self.help = tableentry
498 else:
498 else:
499 self.fn, self.opts = tableentry
499 self.fn, self.opts = tableentry
500
500
501 self.args = aliasargs(self.fn, args)
501 self.args = aliasargs(self.fn, args)
502 if cmd not in commands.norepo.split(' '):
502 if cmd not in commands.norepo.split(' '):
503 self.norepo = False
503 self.norepo = False
504 if cmd in commands.optionalrepo.split(' '):
504 if cmd in commands.optionalrepo.split(' '):
505 self.optionalrepo = True
505 self.optionalrepo = True
506 if self.help.startswith("hg " + cmd):
506 if self.help.startswith("hg " + cmd):
507 # drop prefix in old-style help lines so hg shows the alias
507 # drop prefix in old-style help lines so hg shows the alias
508 self.help = self.help[4 + len(cmd):]
508 self.help = self.help[4 + len(cmd):]
509 self.__doc__ = self.fn.__doc__
509 self.__doc__ = self.fn.__doc__
510
510
511 except error.UnknownCommand:
511 except error.UnknownCommand:
512 self.badalias = (_("alias '%s' resolves to unknown command '%s'")
512 self.badalias = (_("alias '%s' resolves to unknown command '%s'")
513 % (self.name, cmd))
513 % (self.name, cmd))
514 self.unknowncmd = True
514 self.unknowncmd = True
515 except error.AmbiguousCommand:
515 except error.AmbiguousCommand:
516 self.badalias = (_("alias '%s' resolves to ambiguous command '%s'")
516 self.badalias = (_("alias '%s' resolves to ambiguous command '%s'")
517 % (self.name, cmd))
517 % (self.name, cmd))
518
518
519 def __call__(self, ui, *args, **opts):
519 def __call__(self, ui, *args, **opts):
520 if self.badalias:
520 if self.badalias:
521 hint = None
521 hint = None
522 if self.unknowncmd:
522 if self.unknowncmd:
523 try:
523 try:
524 # check if the command is in a disabled extension
524 # check if the command is in a disabled extension
525 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
525 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
526 hint = _("'%s' is provided by '%s' extension") % (cmd, ext)
526 hint = _("'%s' is provided by '%s' extension") % (cmd, ext)
527 except error.UnknownCommand:
527 except error.UnknownCommand:
528 pass
528 pass
529 raise util.Abort(self.badalias, hint=hint)
529 raise util.Abort(self.badalias, hint=hint)
530 if self.shadows:
530 if self.shadows:
531 ui.debug("alias '%s' shadows command '%s'\n" %
531 ui.debug("alias '%s' shadows command '%s'\n" %
532 (self.name, self.cmdname))
532 (self.name, self.cmdname))
533
533
534 if util.safehasattr(self, 'shell'):
534 if util.safehasattr(self, 'shell'):
535 return self.fn(ui, *args, **opts)
535 return self.fn(ui, *args, **opts)
536 else:
536 else:
537 try:
537 try:
538 return util.checksignature(self.fn)(ui, *args, **opts)
538 return util.checksignature(self.fn)(ui, *args, **opts)
539 except error.SignatureError:
539 except error.SignatureError:
540 args = ' '.join([self.cmdname] + self.args)
540 args = ' '.join([self.cmdname] + self.args)
541 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
541 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
542 raise
542 raise
543
543
544 def addaliases(ui, cmdtable):
544 def addaliases(ui, cmdtable):
545 # aliases are processed after extensions have been loaded, so they
545 # aliases are processed after extensions have been loaded, so they
546 # may use extension commands. Aliases can also use other alias definitions,
546 # may use extension commands. Aliases can also use other alias definitions,
547 # but only if they have been defined prior to the current definition.
547 # but only if they have been defined prior to the current definition.
548 for alias, definition in ui.configitems('alias'):
548 for alias, definition in ui.configitems('alias'):
549 aliasdef = cmdalias(alias, definition, cmdtable)
549 aliasdef = cmdalias(alias, definition, cmdtable)
550
550
551 try:
551 try:
552 olddef = cmdtable[aliasdef.cmd][0]
552 olddef = cmdtable[aliasdef.cmd][0]
553 if olddef.definition == aliasdef.definition:
553 if olddef.definition == aliasdef.definition:
554 continue
554 continue
555 except (KeyError, AttributeError):
555 except (KeyError, AttributeError):
556 # definition might not exist or it might not be a cmdalias
556 # definition might not exist or it might not be a cmdalias
557 pass
557 pass
558
558
559 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
559 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
560 if aliasdef.norepo:
560 if aliasdef.norepo:
561 commands.norepo += ' %s' % alias
561 commands.norepo += ' %s' % alias
562 if aliasdef.optionalrepo:
562 if aliasdef.optionalrepo:
563 commands.optionalrepo += ' %s' % alias
563 commands.optionalrepo += ' %s' % alias
564
564
565 def _parse(ui, args):
565 def _parse(ui, args):
566 options = {}
566 options = {}
567 cmdoptions = {}
567 cmdoptions = {}
568
568
569 try:
569 try:
570 args = fancyopts.fancyopts(args, commands.globalopts, options)
570 args = fancyopts.fancyopts(args, commands.globalopts, options)
571 except fancyopts.getopt.GetoptError as inst:
571 except fancyopts.getopt.GetoptError as inst:
572 raise error.CommandError(None, inst)
572 raise error.CommandError(None, inst)
573
573
574 if args:
574 if args:
575 cmd, args = args[0], args[1:]
575 cmd, args = args[0], args[1:]
576 aliases, entry = cmdutil.findcmd(cmd, commands.table,
576 aliases, entry = cmdutil.findcmd(cmd, commands.table,
577 ui.configbool("ui", "strict"))
577 ui.configbool("ui", "strict"))
578 cmd = aliases[0]
578 cmd = aliases[0]
579 args = aliasargs(entry[0], args)
579 args = aliasargs(entry[0], args)
580 defaults = ui.config("defaults", cmd)
580 defaults = ui.config("defaults", cmd)
581 if defaults:
581 if defaults:
582 args = map(util.expandpath, shlex.split(defaults)) + args
582 args = map(util.expandpath, shlex.split(defaults)) + args
583 c = list(entry[1])
583 c = list(entry[1])
584 else:
584 else:
585 cmd = None
585 cmd = None
586 c = []
586 c = []
587
587
588 # combine global options into local
588 # combine global options into local
589 for o in commands.globalopts:
589 for o in commands.globalopts:
590 c.append((o[0], o[1], options[o[1]], o[3]))
590 c.append((o[0], o[1], options[o[1]], o[3]))
591
591
592 try:
592 try:
593 args = fancyopts.fancyopts(args, c, cmdoptions, True)
593 args = fancyopts.fancyopts(args, c, cmdoptions, True)
594 except fancyopts.getopt.GetoptError as inst:
594 except fancyopts.getopt.GetoptError as inst:
595 raise error.CommandError(cmd, inst)
595 raise error.CommandError(cmd, inst)
596
596
597 # separate global options back out
597 # separate global options back out
598 for o in commands.globalopts:
598 for o in commands.globalopts:
599 n = o[1]
599 n = o[1]
600 options[n] = cmdoptions[n]
600 options[n] = cmdoptions[n]
601 del cmdoptions[n]
601 del cmdoptions[n]
602
602
603 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
603 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
604
604
605 def _parseconfig(ui, config):
605 def _parseconfig(ui, config):
606 """parse the --config options from the command line"""
606 """parse the --config options from the command line"""
607 configs = []
607 configs = []
608
608
609 for cfg in config:
609 for cfg in config:
610 try:
610 try:
611 name, value = cfg.split('=', 1)
611 name, value = cfg.split('=', 1)
612 section, name = name.split('.', 1)
612 section, name = name.split('.', 1)
613 if not section or not name:
613 if not section or not name:
614 raise IndexError
614 raise IndexError
615 ui.setconfig(section, name, value, '--config')
615 ui.setconfig(section, name, value, '--config')
616 configs.append((section, name, value))
616 configs.append((section, name, value))
617 except (IndexError, ValueError):
617 except (IndexError, ValueError):
618 raise util.Abort(_('malformed --config option: %r '
618 raise util.Abort(_('malformed --config option: %r '
619 '(use --config section.name=value)') % cfg)
619 '(use --config section.name=value)') % cfg)
620
620
621 return configs
621 return configs
622
622
623 def _earlygetopt(aliases, args):
623 def _earlygetopt(aliases, args):
624 """Return list of values for an option (or aliases).
624 """Return list of values for an option (or aliases).
625
625
626 The values are listed in the order they appear in args.
626 The values are listed in the order they appear in args.
627 The options and values are removed from args.
627 The options and values are removed from args.
628
628
629 >>> args = ['x', '--cwd', 'foo', 'y']
629 >>> args = ['x', '--cwd', 'foo', 'y']
630 >>> _earlygetopt(['--cwd'], args), args
630 >>> _earlygetopt(['--cwd'], args), args
631 (['foo'], ['x', 'y'])
631 (['foo'], ['x', 'y'])
632
632
633 >>> args = ['x', '--cwd=bar', 'y']
633 >>> args = ['x', '--cwd=bar', 'y']
634 >>> _earlygetopt(['--cwd'], args), args
634 >>> _earlygetopt(['--cwd'], args), args
635 (['bar'], ['x', 'y'])
635 (['bar'], ['x', 'y'])
636
636
637 >>> args = ['x', '-R', 'foo', 'y']
637 >>> args = ['x', '-R', 'foo', 'y']
638 >>> _earlygetopt(['-R'], args), args
638 >>> _earlygetopt(['-R'], args), args
639 (['foo'], ['x', 'y'])
639 (['foo'], ['x', 'y'])
640
640
641 >>> args = ['x', '-Rbar', 'y']
641 >>> args = ['x', '-Rbar', 'y']
642 >>> _earlygetopt(['-R'], args), args
642 >>> _earlygetopt(['-R'], args), args
643 (['bar'], ['x', 'y'])
643 (['bar'], ['x', 'y'])
644 """
644 """
645 try:
645 try:
646 argcount = args.index("--")
646 argcount = args.index("--")
647 except ValueError:
647 except ValueError:
648 argcount = len(args)
648 argcount = len(args)
649 shortopts = [opt for opt in aliases if len(opt) == 2]
649 shortopts = [opt for opt in aliases if len(opt) == 2]
650 values = []
650 values = []
651 pos = 0
651 pos = 0
652 while pos < argcount:
652 while pos < argcount:
653 fullarg = arg = args[pos]
653 fullarg = arg = args[pos]
654 equals = arg.find('=')
654 equals = arg.find('=')
655 if equals > -1:
655 if equals > -1:
656 arg = arg[:equals]
656 arg = arg[:equals]
657 if arg in aliases:
657 if arg in aliases:
658 del args[pos]
658 del args[pos]
659 if equals > -1:
659 if equals > -1:
660 values.append(fullarg[equals + 1:])
660 values.append(fullarg[equals + 1:])
661 argcount -= 1
661 argcount -= 1
662 else:
662 else:
663 if pos + 1 >= argcount:
663 if pos + 1 >= argcount:
664 # ignore and let getopt report an error if there is no value
664 # ignore and let getopt report an error if there is no value
665 break
665 break
666 values.append(args.pop(pos))
666 values.append(args.pop(pos))
667 argcount -= 2
667 argcount -= 2
668 elif arg[:2] in shortopts:
668 elif arg[:2] in shortopts:
669 # short option can have no following space, e.g. hg log -Rfoo
669 # short option can have no following space, e.g. hg log -Rfoo
670 values.append(args.pop(pos)[2:])
670 values.append(args.pop(pos)[2:])
671 argcount -= 1
671 argcount -= 1
672 else:
672 else:
673 pos += 1
673 pos += 1
674 return values
674 return values
675
675
676 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
676 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
677 # run pre-hook, and abort if it fails
677 # run pre-hook, and abort if it fails
678 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
678 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
679 pats=cmdpats, opts=cmdoptions)
679 pats=cmdpats, opts=cmdoptions)
680 ret = _runcommand(ui, options, cmd, d)
680 ret = _runcommand(ui, options, cmd, d)
681 # run post-hook, passing command result
681 # run post-hook, passing command result
682 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
682 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
683 result=ret, pats=cmdpats, opts=cmdoptions)
683 result=ret, pats=cmdpats, opts=cmdoptions)
684 return ret
684 return ret
685
685
686 def _getlocal(ui, rpath):
686 def _getlocal(ui, rpath):
687 """Return (path, local ui object) for the given target path.
687 """Return (path, local ui object) for the given target path.
688
688
689 Takes paths in [cwd]/.hg/hgrc into account."
689 Takes paths in [cwd]/.hg/hgrc into account."
690 """
690 """
691 try:
691 try:
692 wd = os.getcwd()
692 wd = os.getcwd()
693 except OSError as e:
693 except OSError as e:
694 raise util.Abort(_("error getting current working directory: %s") %
694 raise util.Abort(_("error getting current working directory: %s") %
695 e.strerror)
695 e.strerror)
696 path = cmdutil.findrepo(wd) or ""
696 path = cmdutil.findrepo(wd) or ""
697 if not path:
697 if not path:
698 lui = ui
698 lui = ui
699 else:
699 else:
700 lui = ui.copy()
700 lui = ui.copy()
701 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
701 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
702
702
703 if rpath and rpath[-1]:
703 if rpath and rpath[-1]:
704 path = lui.expandpath(rpath[-1])
704 path = lui.expandpath(rpath[-1])
705 lui = ui.copy()
705 lui = ui.copy()
706 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
706 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
707
707
708 return path, lui
708 return path, lui
709
709
710 def _checkshellalias(lui, ui, args, precheck=True):
710 def _checkshellalias(lui, ui, args, precheck=True):
711 """Return the function to run the shell alias, if it is required
711 """Return the function to run the shell alias, if it is required
712
712
713 'precheck' is whether this function is invoked before adding
713 'precheck' is whether this function is invoked before adding
714 aliases or not.
714 aliases or not.
715 """
715 """
716 options = {}
716 options = {}
717
717
718 try:
718 try:
719 args = fancyopts.fancyopts(args, commands.globalopts, options)
719 args = fancyopts.fancyopts(args, commands.globalopts, options)
720 except fancyopts.getopt.GetoptError:
720 except fancyopts.getopt.GetoptError:
721 return
721 return
722
722
723 if not args:
723 if not args:
724 return
724 return
725
725
726 if precheck:
726 if precheck:
727 strict = True
727 strict = True
728 norepo = commands.norepo
728 norepo = commands.norepo
729 optionalrepo = commands.optionalrepo
729 optionalrepo = commands.optionalrepo
730 def restorecommands():
730 def restorecommands():
731 commands.norepo = norepo
731 commands.norepo = norepo
732 commands.optionalrepo = optionalrepo
732 commands.optionalrepo = optionalrepo
733 cmdtable = commands.table.copy()
733 cmdtable = commands.table.copy()
734 addaliases(lui, cmdtable)
734 addaliases(lui, cmdtable)
735 else:
735 else:
736 strict = False
736 strict = False
737 def restorecommands():
737 def restorecommands():
738 pass
738 pass
739 cmdtable = commands.table
739 cmdtable = commands.table
740
740
741 cmd = args[0]
741 cmd = args[0]
742 try:
742 try:
743 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
743 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
744 except (error.AmbiguousCommand, error.UnknownCommand):
744 except (error.AmbiguousCommand, error.UnknownCommand):
745 restorecommands()
745 restorecommands()
746 return
746 return
747
747
748 cmd = aliases[0]
748 cmd = aliases[0]
749 fn = entry[0]
749 fn = entry[0]
750
750
751 if cmd and util.safehasattr(fn, 'shell'):
751 if cmd and util.safehasattr(fn, 'shell'):
752 d = lambda: fn(ui, *args[1:])
752 d = lambda: fn(ui, *args[1:])
753 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
753 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
754 [], {})
754 [], {})
755
755
756 restorecommands()
756 restorecommands()
757
757
758 _loaded = set()
758 _loaded = set()
759 def _dispatch(req):
759 def _dispatch(req):
760 args = req.args
760 args = req.args
761 ui = req.ui
761 ui = req.ui
762
762
763 # check for cwd
763 # check for cwd
764 cwd = _earlygetopt(['--cwd'], args)
764 cwd = _earlygetopt(['--cwd'], args)
765 if cwd:
765 if cwd:
766 os.chdir(cwd[-1])
766 os.chdir(cwd[-1])
767
767
768 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
768 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
769 path, lui = _getlocal(ui, rpath)
769 path, lui = _getlocal(ui, rpath)
770
770
771 # Now that we're operating in the right directory/repository with
771 # Now that we're operating in the right directory/repository with
772 # the right config settings, check for shell aliases
772 # the right config settings, check for shell aliases
773 shellaliasfn = _checkshellalias(lui, ui, args)
773 shellaliasfn = _checkshellalias(lui, ui, args)
774 if shellaliasfn:
774 if shellaliasfn:
775 return shellaliasfn()
775 return shellaliasfn()
776
776
777 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
777 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
778 # reposetup. Programs like TortoiseHg will call _dispatch several
778 # reposetup. Programs like TortoiseHg will call _dispatch several
779 # times so we keep track of configured extensions in _loaded.
779 # times so we keep track of configured extensions in _loaded.
780 extensions.loadall(lui)
780 extensions.loadall(lui)
781 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
781 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
782 # Propagate any changes to lui.__class__ by extensions
782 # Propagate any changes to lui.__class__ by extensions
783 ui.__class__ = lui.__class__
783 ui.__class__ = lui.__class__
784
784
785 # (uisetup and extsetup are handled in extensions.loadall)
785 # (uisetup and extsetup are handled in extensions.loadall)
786
786
787 for name, module in exts:
787 for name, module in exts:
788 cmdtable = getattr(module, 'cmdtable', {})
788 cmdtable = getattr(module, 'cmdtable', {})
789 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
789 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
790 if overrides:
790 if overrides:
791 ui.warn(_("extension '%s' overrides commands: %s\n")
791 ui.warn(_("extension '%s' overrides commands: %s\n")
792 % (name, " ".join(overrides)))
792 % (name, " ".join(overrides)))
793 commands.table.update(cmdtable)
793 commands.table.update(cmdtable)
794 _loaded.add(name)
794 _loaded.add(name)
795
795
796 # (reposetup is handled in hg.repository)
796 # (reposetup is handled in hg.repository)
797
797
798 addaliases(lui, commands.table)
798 addaliases(lui, commands.table)
799
799
800 if not lui.configbool("ui", "strict"):
800 if not lui.configbool("ui", "strict"):
801 # All aliases and commands are completely defined, now.
801 # All aliases and commands are completely defined, now.
802 # Check abbreviation/ambiguity of shell alias again, because shell
802 # Check abbreviation/ambiguity of shell alias again, because shell
803 # alias may cause failure of "_parse" (see issue4355)
803 # alias may cause failure of "_parse" (see issue4355)
804 shellaliasfn = _checkshellalias(lui, ui, args, precheck=False)
804 shellaliasfn = _checkshellalias(lui, ui, args, precheck=False)
805 if shellaliasfn:
805 if shellaliasfn:
806 return shellaliasfn()
806 return shellaliasfn()
807
807
808 # check for fallback encoding
808 # check for fallback encoding
809 fallback = lui.config('ui', 'fallbackencoding')
809 fallback = lui.config('ui', 'fallbackencoding')
810 if fallback:
810 if fallback:
811 encoding.fallbackencoding = fallback
811 encoding.fallbackencoding = fallback
812
812
813 fullargs = args
813 fullargs = args
814 cmd, func, args, options, cmdoptions = _parse(lui, args)
814 cmd, func, args, options, cmdoptions = _parse(lui, args)
815
815
816 if options["config"]:
816 if options["config"]:
817 raise util.Abort(_("option --config may not be abbreviated!"))
817 raise util.Abort(_("option --config may not be abbreviated!"))
818 if options["cwd"]:
818 if options["cwd"]:
819 raise util.Abort(_("option --cwd may not be abbreviated!"))
819 raise util.Abort(_("option --cwd may not be abbreviated!"))
820 if options["repository"]:
820 if options["repository"]:
821 raise util.Abort(_(
821 raise util.Abort(_(
822 "option -R has to be separated from other options (e.g. not -qR) "
822 "option -R has to be separated from other options (e.g. not -qR) "
823 "and --repository may only be abbreviated as --repo!"))
823 "and --repository may only be abbreviated as --repo!"))
824
824
825 if options["encoding"]:
825 if options["encoding"]:
826 encoding.encoding = options["encoding"]
826 encoding.encoding = options["encoding"]
827 if options["encodingmode"]:
827 if options["encodingmode"]:
828 encoding.encodingmode = options["encodingmode"]
828 encoding.encodingmode = options["encodingmode"]
829 if options["time"]:
829 if options["time"]:
830 def get_times():
830 def get_times():
831 t = os.times()
831 t = os.times()
832 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
832 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
833 t = (t[0], t[1], t[2], t[3], time.clock())
833 t = (t[0], t[1], t[2], t[3], time.clock())
834 return t
834 return t
835 s = get_times()
835 s = get_times()
836 def print_time():
836 def print_time():
837 t = get_times()
837 t = get_times()
838 ui.warn(_("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
838 ui.warn(_("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
839 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
839 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
840 atexit.register(print_time)
840 atexit.register(print_time)
841
841
842 uis = set([ui, lui])
842 uis = set([ui, lui])
843
843
844 if req.repo:
844 if req.repo:
845 uis.add(req.repo.ui)
845 uis.add(req.repo.ui)
846
846
847 if options['verbose'] or options['debug'] or options['quiet']:
847 if options['verbose'] or options['debug'] or options['quiet']:
848 for opt in ('verbose', 'debug', 'quiet'):
848 for opt in ('verbose', 'debug', 'quiet'):
849 val = str(bool(options[opt]))
849 val = str(bool(options[opt]))
850 for ui_ in uis:
850 for ui_ in uis:
851 ui_.setconfig('ui', opt, val, '--' + opt)
851 ui_.setconfig('ui', opt, val, '--' + opt)
852
852
853 if options['traceback']:
853 if options['traceback']:
854 for ui_ in uis:
854 for ui_ in uis:
855 ui_.setconfig('ui', 'traceback', 'on', '--traceback')
855 ui_.setconfig('ui', 'traceback', 'on', '--traceback')
856
856
857 if options['noninteractive']:
857 if options['noninteractive']:
858 for ui_ in uis:
858 for ui_ in uis:
859 ui_.setconfig('ui', 'interactive', 'off', '-y')
859 ui_.setconfig('ui', 'interactive', 'off', '-y')
860
860
861 if cmdoptions.get('insecure', False):
861 if cmdoptions.get('insecure', False):
862 for ui_ in uis:
862 for ui_ in uis:
863 ui_.setconfig('web', 'cacerts', '!', '--insecure')
863 ui_.setconfig('web', 'cacerts', '!', '--insecure')
864
864
865 if options['version']:
865 if options['version']:
866 return commands.version_(ui)
866 return commands.version_(ui)
867 if options['help']:
867 if options['help']:
868 return commands.help_(ui, cmd, command=True)
868 return commands.help_(ui, cmd, command=True)
869 elif not cmd:
869 elif not cmd:
870 return commands.help_(ui, 'shortlist')
870 return commands.help_(ui, 'shortlist')
871
871
872 repo = None
872 repo = None
873 cmdpats = args[:]
873 cmdpats = args[:]
874 if cmd not in commands.norepo.split():
874 if cmd not in commands.norepo.split():
875 # use the repo from the request only if we don't have -R
875 # use the repo from the request only if we don't have -R
876 if not rpath and not cwd:
876 if not rpath and not cwd:
877 repo = req.repo
877 repo = req.repo
878
878
879 if repo:
879 if repo:
880 # set the descriptors of the repo ui to those of ui
880 # set the descriptors of the repo ui to those of ui
881 repo.ui.fin = ui.fin
881 repo.ui.fin = ui.fin
882 repo.ui.fout = ui.fout
882 repo.ui.fout = ui.fout
883 repo.ui.ferr = ui.ferr
883 repo.ui.ferr = ui.ferr
884 else:
884 else:
885 try:
885 try:
886 repo = hg.repository(ui, path=path)
886 repo = hg.repository(ui, path=path)
887 if not repo.local():
887 if not repo.local():
888 raise util.Abort(_("repository '%s' is not local") % path)
888 raise util.Abort(_("repository '%s' is not local") % path)
889 repo.ui.setconfig("bundle", "mainreporoot", repo.root, 'repo')
889 repo.ui.setconfig("bundle", "mainreporoot", repo.root, 'repo')
890 except error.RequirementError:
890 except error.RequirementError:
891 raise
891 raise
892 except error.RepoError:
892 except error.RepoError:
893 if rpath and rpath[-1]: # invalid -R path
894 raise
893 if cmd not in commands.optionalrepo.split():
895 if cmd not in commands.optionalrepo.split():
894 if (cmd in commands.inferrepo.split() and
896 if (cmd in commands.inferrepo.split() and
895 args and not path): # try to infer -R from command args
897 args and not path): # try to infer -R from command args
896 repos = map(cmdutil.findrepo, args)
898 repos = map(cmdutil.findrepo, args)
897 guess = repos[0]
899 guess = repos[0]
898 if guess and repos.count(guess) == len(repos):
900 if guess and repos.count(guess) == len(repos):
899 req.args = ['--repository', guess] + fullargs
901 req.args = ['--repository', guess] + fullargs
900 return _dispatch(req)
902 return _dispatch(req)
901 if not path:
903 if not path:
902 raise error.RepoError(_("no repository found in '%s'"
904 raise error.RepoError(_("no repository found in '%s'"
903 " (.hg not found)")
905 " (.hg not found)")
904 % os.getcwd())
906 % os.getcwd())
905 raise
907 raise
906 if repo:
908 if repo:
907 ui = repo.ui
909 ui = repo.ui
908 if options['hidden']:
910 if options['hidden']:
909 repo = repo.unfiltered()
911 repo = repo.unfiltered()
910 args.insert(0, repo)
912 args.insert(0, repo)
911 elif rpath:
913 elif rpath:
912 ui.warn(_("warning: --repository ignored\n"))
914 ui.warn(_("warning: --repository ignored\n"))
913
915
914 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
916 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
915 ui.log("command", '%s\n', msg)
917 ui.log("command", '%s\n', msg)
916 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
918 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
917 try:
919 try:
918 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
920 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
919 cmdpats, cmdoptions)
921 cmdpats, cmdoptions)
920 finally:
922 finally:
921 if repo and repo != req.repo:
923 if repo and repo != req.repo:
922 repo.close()
924 repo.close()
923
925
924 def lsprofile(ui, func, fp):
926 def lsprofile(ui, func, fp):
925 format = ui.config('profiling', 'format', default='text')
927 format = ui.config('profiling', 'format', default='text')
926 field = ui.config('profiling', 'sort', default='inlinetime')
928 field = ui.config('profiling', 'sort', default='inlinetime')
927 limit = ui.configint('profiling', 'limit', default=30)
929 limit = ui.configint('profiling', 'limit', default=30)
928 climit = ui.configint('profiling', 'nested', default=0)
930 climit = ui.configint('profiling', 'nested', default=0)
929
931
930 if format not in ['text', 'kcachegrind']:
932 if format not in ['text', 'kcachegrind']:
931 ui.warn(_("unrecognized profiling format '%s'"
933 ui.warn(_("unrecognized profiling format '%s'"
932 " - Ignored\n") % format)
934 " - Ignored\n") % format)
933 format = 'text'
935 format = 'text'
934
936
935 try:
937 try:
936 from . import lsprof
938 from . import lsprof
937 except ImportError:
939 except ImportError:
938 raise util.Abort(_(
940 raise util.Abort(_(
939 'lsprof not available - install from '
941 'lsprof not available - install from '
940 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
942 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
941 p = lsprof.Profiler()
943 p = lsprof.Profiler()
942 p.enable(subcalls=True)
944 p.enable(subcalls=True)
943 try:
945 try:
944 return func()
946 return func()
945 finally:
947 finally:
946 p.disable()
948 p.disable()
947
949
948 if format == 'kcachegrind':
950 if format == 'kcachegrind':
949 from . import lsprofcalltree
951 from . import lsprofcalltree
950 calltree = lsprofcalltree.KCacheGrind(p)
952 calltree = lsprofcalltree.KCacheGrind(p)
951 calltree.output(fp)
953 calltree.output(fp)
952 else:
954 else:
953 # format == 'text'
955 # format == 'text'
954 stats = lsprof.Stats(p.getstats())
956 stats = lsprof.Stats(p.getstats())
955 stats.sort(field)
957 stats.sort(field)
956 stats.pprint(limit=limit, file=fp, climit=climit)
958 stats.pprint(limit=limit, file=fp, climit=climit)
957
959
958 def flameprofile(ui, func, fp):
960 def flameprofile(ui, func, fp):
959 try:
961 try:
960 from flamegraph import flamegraph
962 from flamegraph import flamegraph
961 except ImportError:
963 except ImportError:
962 raise util.Abort(_(
964 raise util.Abort(_(
963 'flamegraph not available - install from '
965 'flamegraph not available - install from '
964 'https://github.com/evanhempel/python-flamegraph'))
966 'https://github.com/evanhempel/python-flamegraph'))
965 # developer config: profiling.freq
967 # developer config: profiling.freq
966 freq = ui.configint('profiling', 'freq', default=1000)
968 freq = ui.configint('profiling', 'freq', default=1000)
967 filter_ = None
969 filter_ = None
968 collapse_recursion = True
970 collapse_recursion = True
969 thread = flamegraph.ProfileThread(fp, 1.0 / freq,
971 thread = flamegraph.ProfileThread(fp, 1.0 / freq,
970 filter_, collapse_recursion)
972 filter_, collapse_recursion)
971 start_time = time.clock()
973 start_time = time.clock()
972 try:
974 try:
973 thread.start()
975 thread.start()
974 func()
976 func()
975 finally:
977 finally:
976 thread.stop()
978 thread.stop()
977 thread.join()
979 thread.join()
978 print 'Collected %d stack frames (%d unique) in %2.2f seconds.' % (
980 print 'Collected %d stack frames (%d unique) in %2.2f seconds.' % (
979 time.clock() - start_time, thread.num_frames(),
981 time.clock() - start_time, thread.num_frames(),
980 thread.num_frames(unique=True))
982 thread.num_frames(unique=True))
981
983
982
984
983 def statprofile(ui, func, fp):
985 def statprofile(ui, func, fp):
984 try:
986 try:
985 import statprof
987 import statprof
986 except ImportError:
988 except ImportError:
987 raise util.Abort(_(
989 raise util.Abort(_(
988 'statprof not available - install using "easy_install statprof"'))
990 'statprof not available - install using "easy_install statprof"'))
989
991
990 freq = ui.configint('profiling', 'freq', default=1000)
992 freq = ui.configint('profiling', 'freq', default=1000)
991 if freq > 0:
993 if freq > 0:
992 statprof.reset(freq)
994 statprof.reset(freq)
993 else:
995 else:
994 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
996 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
995
997
996 statprof.start()
998 statprof.start()
997 try:
999 try:
998 return func()
1000 return func()
999 finally:
1001 finally:
1000 statprof.stop()
1002 statprof.stop()
1001 statprof.display(fp)
1003 statprof.display(fp)
1002
1004
1003 def _runcommand(ui, options, cmd, cmdfunc):
1005 def _runcommand(ui, options, cmd, cmdfunc):
1004 def checkargs():
1006 def checkargs():
1005 try:
1007 try:
1006 return cmdfunc()
1008 return cmdfunc()
1007 except error.SignatureError:
1009 except error.SignatureError:
1008 raise error.CommandError(cmd, _("invalid arguments"))
1010 raise error.CommandError(cmd, _("invalid arguments"))
1009
1011
1010 if options['profile']:
1012 if options['profile']:
1011 profiler = os.getenv('HGPROF')
1013 profiler = os.getenv('HGPROF')
1012 if profiler is None:
1014 if profiler is None:
1013 profiler = ui.config('profiling', 'type', default='ls')
1015 profiler = ui.config('profiling', 'type', default='ls')
1014 if profiler not in ('ls', 'stat', 'flame'):
1016 if profiler not in ('ls', 'stat', 'flame'):
1015 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
1017 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
1016 profiler = 'ls'
1018 profiler = 'ls'
1017
1019
1018 output = ui.config('profiling', 'output')
1020 output = ui.config('profiling', 'output')
1019
1021
1020 if output:
1022 if output:
1021 path = ui.expandpath(output)
1023 path = ui.expandpath(output)
1022 fp = open(path, 'wb')
1024 fp = open(path, 'wb')
1023 else:
1025 else:
1024 fp = sys.stderr
1026 fp = sys.stderr
1025
1027
1026 try:
1028 try:
1027 if profiler == 'ls':
1029 if profiler == 'ls':
1028 return lsprofile(ui, checkargs, fp)
1030 return lsprofile(ui, checkargs, fp)
1029 elif profiler == 'flame':
1031 elif profiler == 'flame':
1030 return flameprofile(ui, checkargs, fp)
1032 return flameprofile(ui, checkargs, fp)
1031 else:
1033 else:
1032 return statprofile(ui, checkargs, fp)
1034 return statprofile(ui, checkargs, fp)
1033 finally:
1035 finally:
1034 if output:
1036 if output:
1035 fp.close()
1037 fp.close()
1036 else:
1038 else:
1037 return checkargs()
1039 return checkargs()
@@ -1,1027 +1,1027 b''
1 Prepare repo a:
1 Prepare repo a:
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ hg add a
6 $ hg add a
7 $ hg commit -m test
7 $ hg commit -m test
8 $ echo first line > b
8 $ echo first line > b
9 $ hg add b
9 $ hg add b
10
10
11 Create a non-inlined filelog:
11 Create a non-inlined filelog:
12
12
13 $ $PYTHON -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
13 $ $PYTHON -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 > cat data1 >> b
15 > cat data1 >> b
16 > hg commit -m test
16 > hg commit -m test
17 > done
17 > done
18
18
19 List files in store/data (should show a 'b.d'):
19 List files in store/data (should show a 'b.d'):
20
20
21 $ for i in .hg/store/data/*; do
21 $ for i in .hg/store/data/*; do
22 > echo $i
22 > echo $i
23 > done
23 > done
24 .hg/store/data/a.i
24 .hg/store/data/a.i
25 .hg/store/data/b.d
25 .hg/store/data/b.d
26 .hg/store/data/b.i
26 .hg/store/data/b.i
27
27
28 Trigger branchcache creation:
28 Trigger branchcache creation:
29
29
30 $ hg branches
30 $ hg branches
31 default 10:a7949464abda
31 default 10:a7949464abda
32 $ ls .hg/cache
32 $ ls .hg/cache
33 branch2-served
33 branch2-served
34 rbc-names-v1
34 rbc-names-v1
35 rbc-revs-v1
35 rbc-revs-v1
36
36
37 Default operation:
37 Default operation:
38
38
39 $ hg clone . ../b
39 $ hg clone . ../b
40 updating to branch default
40 updating to branch default
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ cd ../b
42 $ cd ../b
43
43
44 Ensure branchcache got copied over:
44 Ensure branchcache got copied over:
45
45
46 $ ls .hg/cache
46 $ ls .hg/cache
47 branch2-served
47 branch2-served
48
48
49 $ cat a
49 $ cat a
50 a
50 a
51 $ hg verify
51 $ hg verify
52 checking changesets
52 checking changesets
53 checking manifests
53 checking manifests
54 crosschecking files in changesets and manifests
54 crosschecking files in changesets and manifests
55 checking files
55 checking files
56 2 files, 11 changesets, 11 total revisions
56 2 files, 11 changesets, 11 total revisions
57
57
58 Invalid dest '' must abort:
58 Invalid dest '' must abort:
59
59
60 $ hg clone . ''
60 $ hg clone . ''
61 abort: empty destination path is not valid
61 abort: empty destination path is not valid
62 [255]
62 [255]
63
63
64 No update, with debug option:
64 No update, with debug option:
65
65
66 #if hardlink
66 #if hardlink
67 $ hg --debug clone -U . ../c --config progress.debug=true
67 $ hg --debug clone -U . ../c --config progress.debug=true
68 linking: 1
68 linking: 1
69 linking: 2
69 linking: 2
70 linking: 3
70 linking: 3
71 linking: 4
71 linking: 4
72 linking: 5
72 linking: 5
73 linking: 6
73 linking: 6
74 linking: 7
74 linking: 7
75 linking: 8
75 linking: 8
76 linked 8 files
76 linked 8 files
77 #else
77 #else
78 $ hg --debug clone -U . ../c --config progress.debug=true
78 $ hg --debug clone -U . ../c --config progress.debug=true
79 linking: 1
79 linking: 1
80 copying: 2
80 copying: 2
81 copying: 3
81 copying: 3
82 copying: 4
82 copying: 4
83 copying: 5
83 copying: 5
84 copying: 6
84 copying: 6
85 copying: 7
85 copying: 7
86 copying: 8
86 copying: 8
87 copied 8 files
87 copied 8 files
88 #endif
88 #endif
89 $ cd ../c
89 $ cd ../c
90
90
91 Ensure branchcache got copied over:
91 Ensure branchcache got copied over:
92
92
93 $ ls .hg/cache
93 $ ls .hg/cache
94 branch2-served
94 branch2-served
95
95
96 $ cat a 2>/dev/null || echo "a not present"
96 $ cat a 2>/dev/null || echo "a not present"
97 a not present
97 a not present
98 $ hg verify
98 $ hg verify
99 checking changesets
99 checking changesets
100 checking manifests
100 checking manifests
101 crosschecking files in changesets and manifests
101 crosschecking files in changesets and manifests
102 checking files
102 checking files
103 2 files, 11 changesets, 11 total revisions
103 2 files, 11 changesets, 11 total revisions
104
104
105 Default destination:
105 Default destination:
106
106
107 $ mkdir ../d
107 $ mkdir ../d
108 $ cd ../d
108 $ cd ../d
109 $ hg clone ../a
109 $ hg clone ../a
110 destination directory: a
110 destination directory: a
111 updating to branch default
111 updating to branch default
112 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 $ cd a
113 $ cd a
114 $ hg cat a
114 $ hg cat a
115 a
115 a
116 $ cd ../..
116 $ cd ../..
117
117
118 Check that we drop the 'file:' from the path before writing the .hgrc:
118 Check that we drop the 'file:' from the path before writing the .hgrc:
119
119
120 $ hg clone file:a e
120 $ hg clone file:a e
121 updating to branch default
121 updating to branch default
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 $ grep 'file:' e/.hg/hgrc
123 $ grep 'file:' e/.hg/hgrc
124 [1]
124 [1]
125
125
126 Check that path aliases are expanded:
126 Check that path aliases are expanded:
127
127
128 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
128 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
129 $ hg -R f showconfig paths.default
129 $ hg -R f showconfig paths.default
130 $TESTTMP/a#0 (glob)
130 $TESTTMP/a#0 (glob)
131
131
132 Use --pull:
132 Use --pull:
133
133
134 $ hg clone --pull a g
134 $ hg clone --pull a g
135 requesting all changes
135 requesting all changes
136 adding changesets
136 adding changesets
137 adding manifests
137 adding manifests
138 adding file changes
138 adding file changes
139 added 11 changesets with 11 changes to 2 files
139 added 11 changesets with 11 changes to 2 files
140 updating to branch default
140 updating to branch default
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 $ hg -R g verify
142 $ hg -R g verify
143 checking changesets
143 checking changesets
144 checking manifests
144 checking manifests
145 crosschecking files in changesets and manifests
145 crosschecking files in changesets and manifests
146 checking files
146 checking files
147 2 files, 11 changesets, 11 total revisions
147 2 files, 11 changesets, 11 total revisions
148
148
149 Invalid dest '' with --pull must abort (issue2528):
149 Invalid dest '' with --pull must abort (issue2528):
150
150
151 $ hg clone --pull a ''
151 $ hg clone --pull a ''
152 abort: empty destination path is not valid
152 abort: empty destination path is not valid
153 [255]
153 [255]
154
154
155 Clone to '.':
155 Clone to '.':
156
156
157 $ mkdir h
157 $ mkdir h
158 $ cd h
158 $ cd h
159 $ hg clone ../a .
159 $ hg clone ../a .
160 updating to branch default
160 updating to branch default
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 $ cd ..
162 $ cd ..
163
163
164
164
165 *** Tests for option -u ***
165 *** Tests for option -u ***
166
166
167 Adding some more history to repo a:
167 Adding some more history to repo a:
168
168
169 $ cd a
169 $ cd a
170 $ hg tag ref1
170 $ hg tag ref1
171 $ echo the quick brown fox >a
171 $ echo the quick brown fox >a
172 $ hg ci -m "hacked default"
172 $ hg ci -m "hacked default"
173 $ hg up ref1
173 $ hg up ref1
174 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
175 $ hg branch stable
175 $ hg branch stable
176 marked working directory as branch stable
176 marked working directory as branch stable
177 (branches are permanent and global, did you want a bookmark?)
177 (branches are permanent and global, did you want a bookmark?)
178 $ echo some text >a
178 $ echo some text >a
179 $ hg ci -m "starting branch stable"
179 $ hg ci -m "starting branch stable"
180 $ hg tag ref2
180 $ hg tag ref2
181 $ echo some more text >a
181 $ echo some more text >a
182 $ hg ci -m "another change for branch stable"
182 $ hg ci -m "another change for branch stable"
183 $ hg up ref2
183 $ hg up ref2
184 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
184 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
185 $ hg parents
185 $ hg parents
186 changeset: 13:e8ece76546a6
186 changeset: 13:e8ece76546a6
187 branch: stable
187 branch: stable
188 tag: ref2
188 tag: ref2
189 parent: 10:a7949464abda
189 parent: 10:a7949464abda
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: starting branch stable
192 summary: starting branch stable
193
193
194
194
195 Repo a has two heads:
195 Repo a has two heads:
196
196
197 $ hg heads
197 $ hg heads
198 changeset: 15:0aae7cf88f0d
198 changeset: 15:0aae7cf88f0d
199 branch: stable
199 branch: stable
200 tag: tip
200 tag: tip
201 user: test
201 user: test
202 date: Thu Jan 01 00:00:00 1970 +0000
202 date: Thu Jan 01 00:00:00 1970 +0000
203 summary: another change for branch stable
203 summary: another change for branch stable
204
204
205 changeset: 12:f21241060d6a
205 changeset: 12:f21241060d6a
206 user: test
206 user: test
207 date: Thu Jan 01 00:00:00 1970 +0000
207 date: Thu Jan 01 00:00:00 1970 +0000
208 summary: hacked default
208 summary: hacked default
209
209
210
210
211 $ cd ..
211 $ cd ..
212
212
213
213
214 Testing --noupdate with --updaterev (must abort):
214 Testing --noupdate with --updaterev (must abort):
215
215
216 $ hg clone --noupdate --updaterev 1 a ua
216 $ hg clone --noupdate --updaterev 1 a ua
217 abort: cannot specify both --noupdate and --updaterev
217 abort: cannot specify both --noupdate and --updaterev
218 [255]
218 [255]
219
219
220
220
221 Testing clone -u:
221 Testing clone -u:
222
222
223 $ hg clone -u . a ua
223 $ hg clone -u . a ua
224 updating to branch stable
224 updating to branch stable
225 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
226
226
227 Repo ua has both heads:
227 Repo ua has both heads:
228
228
229 $ hg -R ua heads
229 $ hg -R ua heads
230 changeset: 15:0aae7cf88f0d
230 changeset: 15:0aae7cf88f0d
231 branch: stable
231 branch: stable
232 tag: tip
232 tag: tip
233 user: test
233 user: test
234 date: Thu Jan 01 00:00:00 1970 +0000
234 date: Thu Jan 01 00:00:00 1970 +0000
235 summary: another change for branch stable
235 summary: another change for branch stable
236
236
237 changeset: 12:f21241060d6a
237 changeset: 12:f21241060d6a
238 user: test
238 user: test
239 date: Thu Jan 01 00:00:00 1970 +0000
239 date: Thu Jan 01 00:00:00 1970 +0000
240 summary: hacked default
240 summary: hacked default
241
241
242
242
243 Same revision checked out in repo a and ua:
243 Same revision checked out in repo a and ua:
244
244
245 $ hg -R a parents --template "{node|short}\n"
245 $ hg -R a parents --template "{node|short}\n"
246 e8ece76546a6
246 e8ece76546a6
247 $ hg -R ua parents --template "{node|short}\n"
247 $ hg -R ua parents --template "{node|short}\n"
248 e8ece76546a6
248 e8ece76546a6
249
249
250 $ rm -r ua
250 $ rm -r ua
251
251
252
252
253 Testing clone --pull -u:
253 Testing clone --pull -u:
254
254
255 $ hg clone --pull -u . a ua
255 $ hg clone --pull -u . a ua
256 requesting all changes
256 requesting all changes
257 adding changesets
257 adding changesets
258 adding manifests
258 adding manifests
259 adding file changes
259 adding file changes
260 added 16 changesets with 16 changes to 3 files (+1 heads)
260 added 16 changesets with 16 changes to 3 files (+1 heads)
261 updating to branch stable
261 updating to branch stable
262 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
262 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
263
263
264 Repo ua has both heads:
264 Repo ua has both heads:
265
265
266 $ hg -R ua heads
266 $ hg -R ua heads
267 changeset: 15:0aae7cf88f0d
267 changeset: 15:0aae7cf88f0d
268 branch: stable
268 branch: stable
269 tag: tip
269 tag: tip
270 user: test
270 user: test
271 date: Thu Jan 01 00:00:00 1970 +0000
271 date: Thu Jan 01 00:00:00 1970 +0000
272 summary: another change for branch stable
272 summary: another change for branch stable
273
273
274 changeset: 12:f21241060d6a
274 changeset: 12:f21241060d6a
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
276 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: hacked default
277 summary: hacked default
278
278
279
279
280 Same revision checked out in repo a and ua:
280 Same revision checked out in repo a and ua:
281
281
282 $ hg -R a parents --template "{node|short}\n"
282 $ hg -R a parents --template "{node|short}\n"
283 e8ece76546a6
283 e8ece76546a6
284 $ hg -R ua parents --template "{node|short}\n"
284 $ hg -R ua parents --template "{node|short}\n"
285 e8ece76546a6
285 e8ece76546a6
286
286
287 $ rm -r ua
287 $ rm -r ua
288
288
289
289
290 Testing clone -u <branch>:
290 Testing clone -u <branch>:
291
291
292 $ hg clone -u stable a ua
292 $ hg clone -u stable a ua
293 updating to branch stable
293 updating to branch stable
294 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
295
295
296 Repo ua has both heads:
296 Repo ua has both heads:
297
297
298 $ hg -R ua heads
298 $ hg -R ua heads
299 changeset: 15:0aae7cf88f0d
299 changeset: 15:0aae7cf88f0d
300 branch: stable
300 branch: stable
301 tag: tip
301 tag: tip
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
304 summary: another change for branch stable
304 summary: another change for branch stable
305
305
306 changeset: 12:f21241060d6a
306 changeset: 12:f21241060d6a
307 user: test
307 user: test
308 date: Thu Jan 01 00:00:00 1970 +0000
308 date: Thu Jan 01 00:00:00 1970 +0000
309 summary: hacked default
309 summary: hacked default
310
310
311
311
312 Branch 'stable' is checked out:
312 Branch 'stable' is checked out:
313
313
314 $ hg -R ua parents
314 $ hg -R ua parents
315 changeset: 15:0aae7cf88f0d
315 changeset: 15:0aae7cf88f0d
316 branch: stable
316 branch: stable
317 tag: tip
317 tag: tip
318 user: test
318 user: test
319 date: Thu Jan 01 00:00:00 1970 +0000
319 date: Thu Jan 01 00:00:00 1970 +0000
320 summary: another change for branch stable
320 summary: another change for branch stable
321
321
322
322
323 $ rm -r ua
323 $ rm -r ua
324
324
325
325
326 Testing default checkout:
326 Testing default checkout:
327
327
328 $ hg clone a ua
328 $ hg clone a ua
329 updating to branch default
329 updating to branch default
330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
331
331
332 Repo ua has both heads:
332 Repo ua has both heads:
333
333
334 $ hg -R ua heads
334 $ hg -R ua heads
335 changeset: 15:0aae7cf88f0d
335 changeset: 15:0aae7cf88f0d
336 branch: stable
336 branch: stable
337 tag: tip
337 tag: tip
338 user: test
338 user: test
339 date: Thu Jan 01 00:00:00 1970 +0000
339 date: Thu Jan 01 00:00:00 1970 +0000
340 summary: another change for branch stable
340 summary: another change for branch stable
341
341
342 changeset: 12:f21241060d6a
342 changeset: 12:f21241060d6a
343 user: test
343 user: test
344 date: Thu Jan 01 00:00:00 1970 +0000
344 date: Thu Jan 01 00:00:00 1970 +0000
345 summary: hacked default
345 summary: hacked default
346
346
347
347
348 Branch 'default' is checked out:
348 Branch 'default' is checked out:
349
349
350 $ hg -R ua parents
350 $ hg -R ua parents
351 changeset: 12:f21241060d6a
351 changeset: 12:f21241060d6a
352 user: test
352 user: test
353 date: Thu Jan 01 00:00:00 1970 +0000
353 date: Thu Jan 01 00:00:00 1970 +0000
354 summary: hacked default
354 summary: hacked default
355
355
356 Test clone with a branch named "@" (issue3677)
356 Test clone with a branch named "@" (issue3677)
357
357
358 $ hg -R ua branch @
358 $ hg -R ua branch @
359 marked working directory as branch @
359 marked working directory as branch @
360 $ hg -R ua commit -m 'created branch @'
360 $ hg -R ua commit -m 'created branch @'
361 $ hg clone ua atbranch
361 $ hg clone ua atbranch
362 updating to branch default
362 updating to branch default
363 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 $ hg -R atbranch heads
364 $ hg -R atbranch heads
365 changeset: 16:798b6d97153e
365 changeset: 16:798b6d97153e
366 branch: @
366 branch: @
367 tag: tip
367 tag: tip
368 parent: 12:f21241060d6a
368 parent: 12:f21241060d6a
369 user: test
369 user: test
370 date: Thu Jan 01 00:00:00 1970 +0000
370 date: Thu Jan 01 00:00:00 1970 +0000
371 summary: created branch @
371 summary: created branch @
372
372
373 changeset: 15:0aae7cf88f0d
373 changeset: 15:0aae7cf88f0d
374 branch: stable
374 branch: stable
375 user: test
375 user: test
376 date: Thu Jan 01 00:00:00 1970 +0000
376 date: Thu Jan 01 00:00:00 1970 +0000
377 summary: another change for branch stable
377 summary: another change for branch stable
378
378
379 changeset: 12:f21241060d6a
379 changeset: 12:f21241060d6a
380 user: test
380 user: test
381 date: Thu Jan 01 00:00:00 1970 +0000
381 date: Thu Jan 01 00:00:00 1970 +0000
382 summary: hacked default
382 summary: hacked default
383
383
384 $ hg -R atbranch parents
384 $ hg -R atbranch parents
385 changeset: 12:f21241060d6a
385 changeset: 12:f21241060d6a
386 user: test
386 user: test
387 date: Thu Jan 01 00:00:00 1970 +0000
387 date: Thu Jan 01 00:00:00 1970 +0000
388 summary: hacked default
388 summary: hacked default
389
389
390
390
391 $ rm -r ua atbranch
391 $ rm -r ua atbranch
392
392
393
393
394 Testing #<branch>:
394 Testing #<branch>:
395
395
396 $ hg clone -u . a#stable ua
396 $ hg clone -u . a#stable ua
397 adding changesets
397 adding changesets
398 adding manifests
398 adding manifests
399 adding file changes
399 adding file changes
400 added 14 changesets with 14 changes to 3 files
400 added 14 changesets with 14 changes to 3 files
401 updating to branch stable
401 updating to branch stable
402 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
403
403
404 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
404 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
405
405
406 $ hg -R ua heads
406 $ hg -R ua heads
407 changeset: 13:0aae7cf88f0d
407 changeset: 13:0aae7cf88f0d
408 branch: stable
408 branch: stable
409 tag: tip
409 tag: tip
410 user: test
410 user: test
411 date: Thu Jan 01 00:00:00 1970 +0000
411 date: Thu Jan 01 00:00:00 1970 +0000
412 summary: another change for branch stable
412 summary: another change for branch stable
413
413
414 changeset: 10:a7949464abda
414 changeset: 10:a7949464abda
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
417 summary: test
417 summary: test
418
418
419
419
420 Same revision checked out in repo a and ua:
420 Same revision checked out in repo a and ua:
421
421
422 $ hg -R a parents --template "{node|short}\n"
422 $ hg -R a parents --template "{node|short}\n"
423 e8ece76546a6
423 e8ece76546a6
424 $ hg -R ua parents --template "{node|short}\n"
424 $ hg -R ua parents --template "{node|short}\n"
425 e8ece76546a6
425 e8ece76546a6
426
426
427 $ rm -r ua
427 $ rm -r ua
428
428
429
429
430 Testing -u -r <branch>:
430 Testing -u -r <branch>:
431
431
432 $ hg clone -u . -r stable a ua
432 $ hg clone -u . -r stable a ua
433 adding changesets
433 adding changesets
434 adding manifests
434 adding manifests
435 adding file changes
435 adding file changes
436 added 14 changesets with 14 changes to 3 files
436 added 14 changesets with 14 changes to 3 files
437 updating to branch stable
437 updating to branch stable
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
439
439
440 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
440 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
441
441
442 $ hg -R ua heads
442 $ hg -R ua heads
443 changeset: 13:0aae7cf88f0d
443 changeset: 13:0aae7cf88f0d
444 branch: stable
444 branch: stable
445 tag: tip
445 tag: tip
446 user: test
446 user: test
447 date: Thu Jan 01 00:00:00 1970 +0000
447 date: Thu Jan 01 00:00:00 1970 +0000
448 summary: another change for branch stable
448 summary: another change for branch stable
449
449
450 changeset: 10:a7949464abda
450 changeset: 10:a7949464abda
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: test
453 summary: test
454
454
455
455
456 Same revision checked out in repo a and ua:
456 Same revision checked out in repo a and ua:
457
457
458 $ hg -R a parents --template "{node|short}\n"
458 $ hg -R a parents --template "{node|short}\n"
459 e8ece76546a6
459 e8ece76546a6
460 $ hg -R ua parents --template "{node|short}\n"
460 $ hg -R ua parents --template "{node|short}\n"
461 e8ece76546a6
461 e8ece76546a6
462
462
463 $ rm -r ua
463 $ rm -r ua
464
464
465
465
466 Testing -r <branch>:
466 Testing -r <branch>:
467
467
468 $ hg clone -r stable a ua
468 $ hg clone -r stable a ua
469 adding changesets
469 adding changesets
470 adding manifests
470 adding manifests
471 adding file changes
471 adding file changes
472 added 14 changesets with 14 changes to 3 files
472 added 14 changesets with 14 changes to 3 files
473 updating to branch stable
473 updating to branch stable
474 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
474 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
475
475
476 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
476 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
477
477
478 $ hg -R ua heads
478 $ hg -R ua heads
479 changeset: 13:0aae7cf88f0d
479 changeset: 13:0aae7cf88f0d
480 branch: stable
480 branch: stable
481 tag: tip
481 tag: tip
482 user: test
482 user: test
483 date: Thu Jan 01 00:00:00 1970 +0000
483 date: Thu Jan 01 00:00:00 1970 +0000
484 summary: another change for branch stable
484 summary: another change for branch stable
485
485
486 changeset: 10:a7949464abda
486 changeset: 10:a7949464abda
487 user: test
487 user: test
488 date: Thu Jan 01 00:00:00 1970 +0000
488 date: Thu Jan 01 00:00:00 1970 +0000
489 summary: test
489 summary: test
490
490
491
491
492 Branch 'stable' is checked out:
492 Branch 'stable' is checked out:
493
493
494 $ hg -R ua parents
494 $ hg -R ua parents
495 changeset: 13:0aae7cf88f0d
495 changeset: 13:0aae7cf88f0d
496 branch: stable
496 branch: stable
497 tag: tip
497 tag: tip
498 user: test
498 user: test
499 date: Thu Jan 01 00:00:00 1970 +0000
499 date: Thu Jan 01 00:00:00 1970 +0000
500 summary: another change for branch stable
500 summary: another change for branch stable
501
501
502
502
503 $ rm -r ua
503 $ rm -r ua
504
504
505
505
506 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
506 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
507 iterable in addbranchrevs()
507 iterable in addbranchrevs()
508
508
509 $ cat <<EOF > simpleclone.py
509 $ cat <<EOF > simpleclone.py
510 > from mercurial import ui, hg
510 > from mercurial import ui, hg
511 > myui = ui.ui()
511 > myui = ui.ui()
512 > repo = hg.repository(myui, 'a')
512 > repo = hg.repository(myui, 'a')
513 > hg.clone(myui, {}, repo, dest="ua")
513 > hg.clone(myui, {}, repo, dest="ua")
514 > EOF
514 > EOF
515
515
516 $ python simpleclone.py
516 $ python simpleclone.py
517 updating to branch default
517 updating to branch default
518 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
518 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
519
519
520 $ rm -r ua
520 $ rm -r ua
521
521
522 $ cat <<EOF > branchclone.py
522 $ cat <<EOF > branchclone.py
523 > from mercurial import ui, hg, extensions
523 > from mercurial import ui, hg, extensions
524 > myui = ui.ui()
524 > myui = ui.ui()
525 > extensions.loadall(myui)
525 > extensions.loadall(myui)
526 > repo = hg.repository(myui, 'a')
526 > repo = hg.repository(myui, 'a')
527 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
527 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
528 > EOF
528 > EOF
529
529
530 $ python branchclone.py
530 $ python branchclone.py
531 adding changesets
531 adding changesets
532 adding manifests
532 adding manifests
533 adding file changes
533 adding file changes
534 added 14 changesets with 14 changes to 3 files
534 added 14 changesets with 14 changes to 3 files
535 updating to branch stable
535 updating to branch stable
536 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
536 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
537 $ rm -r ua
537 $ rm -r ua
538
538
539
539
540 Test clone with special '@' bookmark:
540 Test clone with special '@' bookmark:
541 $ cd a
541 $ cd a
542 $ hg bookmark -r a7949464abda @ # branch point of stable from default
542 $ hg bookmark -r a7949464abda @ # branch point of stable from default
543 $ hg clone . ../i
543 $ hg clone . ../i
544 updating to bookmark @
544 updating to bookmark @
545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
546 $ hg id -i ../i
546 $ hg id -i ../i
547 a7949464abda
547 a7949464abda
548 $ rm -r ../i
548 $ rm -r ../i
549
549
550 $ hg bookmark -f -r stable @
550 $ hg bookmark -f -r stable @
551 $ hg bookmarks
551 $ hg bookmarks
552 @ 15:0aae7cf88f0d
552 @ 15:0aae7cf88f0d
553 $ hg clone . ../i
553 $ hg clone . ../i
554 updating to bookmark @ on branch stable
554 updating to bookmark @ on branch stable
555 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
555 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 $ hg id -i ../i
556 $ hg id -i ../i
557 0aae7cf88f0d
557 0aae7cf88f0d
558 $ cd "$TESTTMP"
558 $ cd "$TESTTMP"
559
559
560
560
561 Testing failures:
561 Testing failures:
562
562
563 $ mkdir fail
563 $ mkdir fail
564 $ cd fail
564 $ cd fail
565
565
566 No local source
566 No local source
567
567
568 $ hg clone a b
568 $ hg clone a b
569 abort: repository a not found!
569 abort: repository a not found!
570 [255]
570 [255]
571
571
572 No remote source
572 No remote source
573
573
574 #if windows
574 #if windows
575 $ hg clone http://127.0.0.1:3121/a b
575 $ hg clone http://127.0.0.1:3121/a b
576 abort: error: * (glob)
576 abort: error: * (glob)
577 [255]
577 [255]
578 #else
578 #else
579 $ hg clone http://127.0.0.1:3121/a b
579 $ hg clone http://127.0.0.1:3121/a b
580 abort: error: *refused* (glob)
580 abort: error: *refused* (glob)
581 [255]
581 [255]
582 #endif
582 #endif
583 $ rm -rf b # work around bug with http clone
583 $ rm -rf b # work around bug with http clone
584
584
585
585
586 #if unix-permissions no-root
586 #if unix-permissions no-root
587
587
588 Inaccessible source
588 Inaccessible source
589
589
590 $ mkdir a
590 $ mkdir a
591 $ chmod 000 a
591 $ chmod 000 a
592 $ hg clone a b
592 $ hg clone a b
593 abort: repository a not found!
593 abort: repository a not found!
594 [255]
594 [255]
595
595
596 Inaccessible destination
596 Inaccessible destination
597
597
598 $ hg init b
598 $ hg init b
599 $ cd b
599 $ cd b
600 $ hg clone . ../a
600 $ hg clone . ../a
601 abort: Permission denied: '../a'
601 abort: Permission denied: '../a'
602 [255]
602 [255]
603 $ cd ..
603 $ cd ..
604 $ chmod 700 a
604 $ chmod 700 a
605 $ rm -r a b
605 $ rm -r a b
606
606
607 #endif
607 #endif
608
608
609
609
610 #if fifo
610 #if fifo
611
611
612 Source of wrong type
612 Source of wrong type
613
613
614 $ mkfifo a
614 $ mkfifo a
615 $ hg clone a b
615 $ hg clone a b
616 abort: repository a not found!
616 abort: repository a not found!
617 [255]
617 [255]
618 $ rm a
618 $ rm a
619
619
620 #endif
620 #endif
621
621
622 Default destination, same directory
622 Default destination, same directory
623
623
624 $ hg init q
624 $ hg init q
625 $ hg clone q
625 $ hg clone q
626 destination directory: q
626 destination directory: q
627 abort: destination 'q' is not empty
627 abort: destination 'q' is not empty
628 [255]
628 [255]
629
629
630 destination directory not empty
630 destination directory not empty
631
631
632 $ mkdir a
632 $ mkdir a
633 $ echo stuff > a/a
633 $ echo stuff > a/a
634 $ hg clone q a
634 $ hg clone q a
635 abort: destination 'a' is not empty
635 abort: destination 'a' is not empty
636 [255]
636 [255]
637
637
638
638
639 #if unix-permissions no-root
639 #if unix-permissions no-root
640
640
641 leave existing directory in place after clone failure
641 leave existing directory in place after clone failure
642
642
643 $ hg init c
643 $ hg init c
644 $ cd c
644 $ cd c
645 $ echo c > c
645 $ echo c > c
646 $ hg commit -A -m test
646 $ hg commit -A -m test
647 adding c
647 adding c
648 $ chmod -rx .hg/store/data
648 $ chmod -rx .hg/store/data
649 $ cd ..
649 $ cd ..
650 $ mkdir d
650 $ mkdir d
651 $ hg clone c d 2> err
651 $ hg clone c d 2> err
652 [255]
652 [255]
653 $ test -d d
653 $ test -d d
654 $ test -d d/.hg
654 $ test -d d/.hg
655 [1]
655 [1]
656
656
657 re-enable perm to allow deletion
657 re-enable perm to allow deletion
658
658
659 $ chmod +rx c/.hg/store/data
659 $ chmod +rx c/.hg/store/data
660
660
661 #endif
661 #endif
662
662
663 $ cd ..
663 $ cd ..
664
664
665 Test clone from the repository in (emulated) revlog format 0 (issue4203):
665 Test clone from the repository in (emulated) revlog format 0 (issue4203):
666
666
667 $ mkdir issue4203
667 $ mkdir issue4203
668 $ mkdir -p src/.hg
668 $ mkdir -p src/.hg
669 $ echo foo > src/foo
669 $ echo foo > src/foo
670 $ hg -R src add src/foo
670 $ hg -R src add src/foo
671 $ hg -R src commit -m '#0'
671 $ hg -R src commit -m '#0'
672 $ hg -R src log -q
672 $ hg -R src log -q
673 0:e1bab28bca43
673 0:e1bab28bca43
674 $ hg clone -U -q src dst
674 $ hg clone -U -q src dst
675 $ hg -R dst log -q
675 $ hg -R dst log -q
676 0:e1bab28bca43
676 0:e1bab28bca43
677
677
678 Create repositories to test auto sharing functionality
678 Create repositories to test auto sharing functionality
679
679
680 $ cat >> $HGRCPATH << EOF
680 $ cat >> $HGRCPATH << EOF
681 > [extensions]
681 > [extensions]
682 > share=
682 > share=
683 > EOF
683 > EOF
684
684
685 $ hg init empty
685 $ hg init empty
686 $ hg init source1a
686 $ hg init source1a
687 $ cd source1a
687 $ cd source1a
688 $ echo initial1 > foo
688 $ echo initial1 > foo
689 $ hg -q commit -A -m initial
689 $ hg -q commit -A -m initial
690 $ echo second > foo
690 $ echo second > foo
691 $ hg commit -m second
691 $ hg commit -m second
692 $ cd ..
692 $ cd ..
693
693
694 $ hg init filteredrev0
694 $ hg init filteredrev0
695 $ cd filteredrev0
695 $ cd filteredrev0
696 $ cat >> .hg/hgrc << EOF
696 $ cat >> .hg/hgrc << EOF
697 > [experimental]
697 > [experimental]
698 > evolution=createmarkers
698 > evolution=createmarkers
699 > EOF
699 > EOF
700 $ echo initial1 > foo
700 $ echo initial1 > foo
701 $ hg -q commit -A -m initial0
701 $ hg -q commit -A -m initial0
702 $ hg -q up -r null
702 $ hg -q up -r null
703 $ echo initial2 > foo
703 $ echo initial2 > foo
704 $ hg -q commit -A -m initial1
704 $ hg -q commit -A -m initial1
705 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
705 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
706 $ cd ..
706 $ cd ..
707
707
708 $ hg -q clone --pull source1a source1b
708 $ hg -q clone --pull source1a source1b
709 $ cd source1a
709 $ cd source1a
710 $ hg bookmark bookA
710 $ hg bookmark bookA
711 $ echo 1a > foo
711 $ echo 1a > foo
712 $ hg commit -m 1a
712 $ hg commit -m 1a
713 $ cd ../source1b
713 $ cd ../source1b
714 $ hg -q up -r 0
714 $ hg -q up -r 0
715 $ echo head1 > foo
715 $ echo head1 > foo
716 $ hg commit -m head1
716 $ hg commit -m head1
717 created new head
717 created new head
718 $ hg bookmark head1
718 $ hg bookmark head1
719 $ hg -q up -r 0
719 $ hg -q up -r 0
720 $ echo head2 > foo
720 $ echo head2 > foo
721 $ hg commit -m head2
721 $ hg commit -m head2
722 created new head
722 created new head
723 $ hg bookmark head2
723 $ hg bookmark head2
724 $ hg -q up -r 0
724 $ hg -q up -r 0
725 $ hg branch branch1
725 $ hg branch branch1
726 marked working directory as branch branch1
726 marked working directory as branch branch1
727 (branches are permanent and global, did you want a bookmark?)
727 (branches are permanent and global, did you want a bookmark?)
728 $ echo branch1 > foo
728 $ echo branch1 > foo
729 $ hg commit -m branch1
729 $ hg commit -m branch1
730 $ hg -q up -r 0
730 $ hg -q up -r 0
731 $ hg branch branch2
731 $ hg branch branch2
732 marked working directory as branch branch2
732 marked working directory as branch branch2
733 $ echo branch2 > foo
733 $ echo branch2 > foo
734 $ hg commit -m branch2
734 $ hg commit -m branch2
735 $ cd ..
735 $ cd ..
736 $ hg init source2
736 $ hg init source2
737 $ cd source2
737 $ cd source2
738 $ echo initial2 > foo
738 $ echo initial2 > foo
739 $ hg -q commit -A -m initial2
739 $ hg -q commit -A -m initial2
740 $ echo second > foo
740 $ echo second > foo
741 $ hg commit -m second
741 $ hg commit -m second
742 $ cd ..
742 $ cd ..
743
743
744 Clone with auto share from an empty repo should not result in share
744 Clone with auto share from an empty repo should not result in share
745
745
746 $ mkdir share
746 $ mkdir share
747 $ hg --config share.pool=share clone empty share-empty
747 $ hg --config share.pool=share clone empty share-empty
748 (not using pooled storage: remote appears to be empty)
748 (not using pooled storage: remote appears to be empty)
749 updating to branch default
749 updating to branch default
750 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
750 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
751 $ ls share
751 $ ls share
752 $ test -d share-empty/.hg/store
752 $ test -d share-empty/.hg/store
753 $ test -f share-empty/.hg/sharedpath
753 $ test -f share-empty/.hg/sharedpath
754 [1]
754 [1]
755
755
756 Clone with auto share from a repo with filtered revision 0 should not result in share
756 Clone with auto share from a repo with filtered revision 0 should not result in share
757
757
758 $ hg --config share.pool=share clone filteredrev0 share-filtered
758 $ hg --config share.pool=share clone filteredrev0 share-filtered
759 (not using pooled storage: unable to resolve identity of remote)
759 (not using pooled storage: unable to resolve identity of remote)
760 requesting all changes
760 requesting all changes
761 adding changesets
761 adding changesets
762 adding manifests
762 adding manifests
763 adding file changes
763 adding file changes
764 added 1 changesets with 1 changes to 1 files
764 added 1 changesets with 1 changes to 1 files
765 updating to branch default
765 updating to branch default
766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
767
767
768 Clone from repo with content should result in shared store being created
768 Clone from repo with content should result in shared store being created
769
769
770 $ hg --config share.pool=share clone source1a share-dest1a
770 $ hg --config share.pool=share clone source1a share-dest1a
771 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
771 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
772 requesting all changes
772 requesting all changes
773 adding changesets
773 adding changesets
774 adding manifests
774 adding manifests
775 adding file changes
775 adding file changes
776 added 3 changesets with 3 changes to 1 files
776 added 3 changesets with 3 changes to 1 files
777 updating working directory
777 updating working directory
778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
779 searching for changes
779 searching for changes
780 no changes found
780 no changes found
781 adding remote bookmark bookA
781 adding remote bookmark bookA
782
782
783 The shared repo should have been created
783 The shared repo should have been created
784
784
785 $ ls share
785 $ ls share
786 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
786 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
787
787
788 The destination should point to it
788 The destination should point to it
789
789
790 $ cat share-dest1a/.hg/sharedpath; echo
790 $ cat share-dest1a/.hg/sharedpath; echo
791 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
791 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
792
792
793 The destination should have bookmarks
793 The destination should have bookmarks
794
794
795 $ hg -R share-dest1a bookmarks
795 $ hg -R share-dest1a bookmarks
796 bookA 2:e5bfe23c0b47
796 bookA 2:e5bfe23c0b47
797
797
798 The default path should be the remote, not the share
798 The default path should be the remote, not the share
799
799
800 $ hg -R share-dest1a config paths.default
800 $ hg -R share-dest1a config paths.default
801 $TESTTMP/source1a (glob)
801 $TESTTMP/source1a (glob)
802
802
803 Clone with existing share dir should result in pull + share
803 Clone with existing share dir should result in pull + share
804
804
805 $ hg --config share.pool=share clone source1b share-dest1b
805 $ hg --config share.pool=share clone source1b share-dest1b
806 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
806 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
807 updating working directory
807 updating working directory
808 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
808 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
809 searching for changes
809 searching for changes
810 adding changesets
810 adding changesets
811 adding manifests
811 adding manifests
812 adding file changes
812 adding file changes
813 added 4 changesets with 4 changes to 1 files (+4 heads)
813 added 4 changesets with 4 changes to 1 files (+4 heads)
814 adding remote bookmark head1
814 adding remote bookmark head1
815 adding remote bookmark head2
815 adding remote bookmark head2
816
816
817 $ ls share
817 $ ls share
818 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
818 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
819
819
820 $ cat share-dest1b/.hg/sharedpath; echo
820 $ cat share-dest1b/.hg/sharedpath; echo
821 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
821 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
822
822
823 We only get bookmarks from the remote, not everything in the share
823 We only get bookmarks from the remote, not everything in the share
824
824
825 $ hg -R share-dest1b bookmarks
825 $ hg -R share-dest1b bookmarks
826 head1 3:4a8dc1ab4c13
826 head1 3:4a8dc1ab4c13
827 head2 4:99f71071f117
827 head2 4:99f71071f117
828
828
829 Default path should be source, not share.
829 Default path should be source, not share.
830
830
831 $ hg -R share-dest1b config paths.default
831 $ hg -R share-dest1b config paths.default
832 $TESTTMP/source1a (glob)
832 $TESTTMP/source1a (glob)
833
833
834 Clone from unrelated repo should result in new share
834 Clone from unrelated repo should result in new share
835
835
836 $ hg --config share.pool=share clone source2 share-dest2
836 $ hg --config share.pool=share clone source2 share-dest2
837 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
837 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
838 requesting all changes
838 requesting all changes
839 adding changesets
839 adding changesets
840 adding manifests
840 adding manifests
841 adding file changes
841 adding file changes
842 added 2 changesets with 2 changes to 1 files
842 added 2 changesets with 2 changes to 1 files
843 updating working directory
843 updating working directory
844 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
844 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
845 searching for changes
845 searching for changes
846 no changes found
846 no changes found
847
847
848 $ ls share
848 $ ls share
849 22aeff664783fd44c6d9b435618173c118c3448e
849 22aeff664783fd44c6d9b435618173c118c3448e
850 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
850 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
851
851
852 remote naming mode works as advertised
852 remote naming mode works as advertised
853
853
854 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
854 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
855 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
855 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
856 requesting all changes
856 requesting all changes
857 adding changesets
857 adding changesets
858 adding manifests
858 adding manifests
859 adding file changes
859 adding file changes
860 added 3 changesets with 3 changes to 1 files
860 added 3 changesets with 3 changes to 1 files
861 updating working directory
861 updating working directory
862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 searching for changes
863 searching for changes
864 no changes found
864 no changes found
865 adding remote bookmark bookA
865 adding remote bookmark bookA
866
866
867 $ ls shareremote
867 $ ls shareremote
868 195bb1fcdb595c14a6c13e0269129ed78f6debde
868 195bb1fcdb595c14a6c13e0269129ed78f6debde
869
869
870 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
870 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
871 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
871 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
872 requesting all changes
872 requesting all changes
873 adding changesets
873 adding changesets
874 adding manifests
874 adding manifests
875 adding file changes
875 adding file changes
876 added 6 changesets with 6 changes to 1 files (+4 heads)
876 added 6 changesets with 6 changes to 1 files (+4 heads)
877 updating working directory
877 updating working directory
878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 searching for changes
879 searching for changes
880 no changes found
880 no changes found
881 adding remote bookmark head1
881 adding remote bookmark head1
882 adding remote bookmark head2
882 adding remote bookmark head2
883
883
884 $ ls shareremote
884 $ ls shareremote
885 195bb1fcdb595c14a6c13e0269129ed78f6debde
885 195bb1fcdb595c14a6c13e0269129ed78f6debde
886 c0d4f83847ca2a873741feb7048a45085fd47c46
886 c0d4f83847ca2a873741feb7048a45085fd47c46
887
887
888 request to clone a single revision is respected in sharing mode
888 request to clone a single revision is respected in sharing mode
889
889
890 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
890 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
891 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
891 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
892 adding changesets
892 adding changesets
893 adding manifests
893 adding manifests
894 adding file changes
894 adding file changes
895 added 2 changesets with 2 changes to 1 files
895 added 2 changesets with 2 changes to 1 files
896 updating working directory
896 updating working directory
897 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
897 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
898 no changes found
898 no changes found
899 adding remote bookmark head1
899 adding remote bookmark head1
900
900
901 $ hg -R share-1arev log -G
901 $ hg -R share-1arev log -G
902 @ changeset: 1:4a8dc1ab4c13
902 @ changeset: 1:4a8dc1ab4c13
903 | bookmark: head1
903 | bookmark: head1
904 | tag: tip
904 | tag: tip
905 | user: test
905 | user: test
906 | date: Thu Jan 01 00:00:00 1970 +0000
906 | date: Thu Jan 01 00:00:00 1970 +0000
907 | summary: head1
907 | summary: head1
908 |
908 |
909 o changeset: 0:b5f04eac9d8f
909 o changeset: 0:b5f04eac9d8f
910 user: test
910 user: test
911 date: Thu Jan 01 00:00:00 1970 +0000
911 date: Thu Jan 01 00:00:00 1970 +0000
912 summary: initial
912 summary: initial
913
913
914
914
915 making another clone should only pull down requested rev
915 making another clone should only pull down requested rev
916
916
917 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
917 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
918 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
918 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
919 updating working directory
919 updating working directory
920 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
920 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
921 searching for changes
921 searching for changes
922 adding changesets
922 adding changesets
923 adding manifests
923 adding manifests
924 adding file changes
924 adding file changes
925 added 1 changesets with 1 changes to 1 files (+1 heads)
925 added 1 changesets with 1 changes to 1 files (+1 heads)
926 adding remote bookmark head1
926 adding remote bookmark head1
927 adding remote bookmark head2
927 adding remote bookmark head2
928
928
929 $ hg -R share-1brev log -G
929 $ hg -R share-1brev log -G
930 o changeset: 2:99f71071f117
930 o changeset: 2:99f71071f117
931 | bookmark: head2
931 | bookmark: head2
932 | tag: tip
932 | tag: tip
933 | parent: 0:b5f04eac9d8f
933 | parent: 0:b5f04eac9d8f
934 | user: test
934 | user: test
935 | date: Thu Jan 01 00:00:00 1970 +0000
935 | date: Thu Jan 01 00:00:00 1970 +0000
936 | summary: head2
936 | summary: head2
937 |
937 |
938 | @ changeset: 1:4a8dc1ab4c13
938 | @ changeset: 1:4a8dc1ab4c13
939 |/ bookmark: head1
939 |/ bookmark: head1
940 | user: test
940 | user: test
941 | date: Thu Jan 01 00:00:00 1970 +0000
941 | date: Thu Jan 01 00:00:00 1970 +0000
942 | summary: head1
942 | summary: head1
943 |
943 |
944 o changeset: 0:b5f04eac9d8f
944 o changeset: 0:b5f04eac9d8f
945 user: test
945 user: test
946 date: Thu Jan 01 00:00:00 1970 +0000
946 date: Thu Jan 01 00:00:00 1970 +0000
947 summary: initial
947 summary: initial
948
948
949
949
950 Request to clone a single branch is respected in sharing mode
950 Request to clone a single branch is respected in sharing mode
951
951
952 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
952 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
953 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
953 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
954 adding changesets
954 adding changesets
955 adding manifests
955 adding manifests
956 adding file changes
956 adding file changes
957 added 2 changesets with 2 changes to 1 files
957 added 2 changesets with 2 changes to 1 files
958 updating working directory
958 updating working directory
959 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
959 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
960 no changes found
960 no changes found
961
961
962 $ hg -R share-1bbranch1 log -G
962 $ hg -R share-1bbranch1 log -G
963 o changeset: 1:5f92a6c1a1b1
963 o changeset: 1:5f92a6c1a1b1
964 | branch: branch1
964 | branch: branch1
965 | tag: tip
965 | tag: tip
966 | user: test
966 | user: test
967 | date: Thu Jan 01 00:00:00 1970 +0000
967 | date: Thu Jan 01 00:00:00 1970 +0000
968 | summary: branch1
968 | summary: branch1
969 |
969 |
970 @ changeset: 0:b5f04eac9d8f
970 @ changeset: 0:b5f04eac9d8f
971 user: test
971 user: test
972 date: Thu Jan 01 00:00:00 1970 +0000
972 date: Thu Jan 01 00:00:00 1970 +0000
973 summary: initial
973 summary: initial
974
974
975
975
976 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
976 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
977 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
977 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
978 updating working directory
978 updating working directory
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
980 searching for changes
980 searching for changes
981 adding changesets
981 adding changesets
982 adding manifests
982 adding manifests
983 adding file changes
983 adding file changes
984 added 1 changesets with 1 changes to 1 files (+1 heads)
984 added 1 changesets with 1 changes to 1 files (+1 heads)
985
985
986 $ hg -R share-1bbranch2 log -G
986 $ hg -R share-1bbranch2 log -G
987 o changeset: 2:6bacf4683960
987 o changeset: 2:6bacf4683960
988 | branch: branch2
988 | branch: branch2
989 | tag: tip
989 | tag: tip
990 | parent: 0:b5f04eac9d8f
990 | parent: 0:b5f04eac9d8f
991 | user: test
991 | user: test
992 | date: Thu Jan 01 00:00:00 1970 +0000
992 | date: Thu Jan 01 00:00:00 1970 +0000
993 | summary: branch2
993 | summary: branch2
994 |
994 |
995 | o changeset: 1:5f92a6c1a1b1
995 | o changeset: 1:5f92a6c1a1b1
996 |/ branch: branch1
996 |/ branch: branch1
997 | user: test
997 | user: test
998 | date: Thu Jan 01 00:00:00 1970 +0000
998 | date: Thu Jan 01 00:00:00 1970 +0000
999 | summary: branch1
999 | summary: branch1
1000 |
1000 |
1001 @ changeset: 0:b5f04eac9d8f
1001 @ changeset: 0:b5f04eac9d8f
1002 user: test
1002 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1003 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: initial
1004 summary: initial
1005
1005
1006
1006
1007 -U is respected in share clone mode
1007 -U is respected in share clone mode
1008
1008
1009 $ hg --config share.pool=share clone -U source1a share-1anowc
1009 $ hg --config share.pool=share clone -U source1a share-1anowc
1010 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1010 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1011 searching for changes
1011 searching for changes
1012 no changes found
1012 no changes found
1013 adding remote bookmark bookA
1013 adding remote bookmark bookA
1014
1014
1015 $ ls share-1anowc
1015 $ ls share-1anowc
1016
1016
1017 Test that auto sharing doesn't cause failure of "hg clone local remote"
1017 Test that auto sharing doesn't cause failure of "hg clone local remote"
1018
1018
1019 $ cd $TESTTMP
1019 $ cd $TESTTMP
1020 $ hg -R a id -r 0
1020 $ hg -R a id -r 0
1021 acb14030fe0a
1021 acb14030fe0a
1022 $ hg id -R remote -r 0
1022 $ hg id -R remote -r 0
1023 abort: there is no Mercurial repository here (.hg not found)
1023 abort: repository remote not found!
1024 [255]
1024 [255]
1025 $ hg --config share.pool=share -q clone -e "python \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1025 $ hg --config share.pool=share -q clone -e "python \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1026 $ hg -R remote id -r 0
1026 $ hg -R remote id -r 0
1027 acb14030fe0a
1027 acb14030fe0a
@@ -1,649 +1,658 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 hgclient import readchannel, runcommand, check
16 >>> from hgclient import readchannel, runcommand, check
17 >>> @check
17 >>> @check
18 ... def hellomessage(server):
18 ... def hellomessage(server):
19 ... ch, data = readchannel(server)
19 ... ch, data = readchannel(server)
20 ... print '%c, %r' % (ch, data)
20 ... print '%c, %r' % (ch, data)
21 ... # run an arbitrary command to make sure the next thing the server
21 ... # run an arbitrary command to make sure the next thing the server
22 ... # sends isn't part of the hello message
22 ... # sends isn't part of the hello message
23 ... runcommand(server, ['id'])
23 ... runcommand(server, ['id'])
24 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
24 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
25 *** runcommand id
25 *** runcommand id
26 000000000000 tip
26 000000000000 tip
27
27
28 >>> from hgclient import check
28 >>> from hgclient import check
29 >>> @check
29 >>> @check
30 ... def unknowncommand(server):
30 ... def unknowncommand(server):
31 ... server.stdin.write('unknowncommand\n')
31 ... server.stdin.write('unknowncommand\n')
32 abort: unknown command unknowncommand
32 abort: unknown command unknowncommand
33
33
34 >>> from hgclient import readchannel, runcommand, check
34 >>> from hgclient import readchannel, runcommand, check
35 >>> @check
35 >>> @check
36 ... def checkruncommand(server):
36 ... def checkruncommand(server):
37 ... # hello block
37 ... # hello block
38 ... readchannel(server)
38 ... readchannel(server)
39 ...
39 ...
40 ... # no args
40 ... # no args
41 ... runcommand(server, [])
41 ... runcommand(server, [])
42 ...
42 ...
43 ... # global options
43 ... # global options
44 ... runcommand(server, ['id', '--quiet'])
44 ... runcommand(server, ['id', '--quiet'])
45 ...
45 ...
46 ... # make sure global options don't stick through requests
46 ... # make sure global options don't stick through requests
47 ... runcommand(server, ['id'])
47 ... runcommand(server, ['id'])
48 ...
48 ...
49 ... # --config
49 ... # --config
50 ... runcommand(server, ['id', '--config', 'ui.quiet=True'])
50 ... runcommand(server, ['id', '--config', 'ui.quiet=True'])
51 ...
51 ...
52 ... # make sure --config doesn't stick
52 ... # make sure --config doesn't stick
53 ... runcommand(server, ['id'])
53 ... runcommand(server, ['id'])
54 ...
54 ...
55 ... # negative return code should be masked
55 ... # negative return code should be masked
56 ... runcommand(server, ['id', '-runknown'])
56 ... runcommand(server, ['id', '-runknown'])
57 *** runcommand
57 *** runcommand
58 Mercurial Distributed SCM
58 Mercurial Distributed SCM
59
59
60 basic commands:
60 basic commands:
61
61
62 add add the specified files on the next commit
62 add add the specified files on the next commit
63 annotate show changeset information by line for each file
63 annotate show changeset information by line for each file
64 clone make a copy of an existing repository
64 clone make a copy of an existing repository
65 commit commit the specified files or all outstanding changes
65 commit commit the specified files or all outstanding changes
66 diff diff repository (or selected files)
66 diff diff repository (or selected files)
67 export dump the header and diffs for one or more changesets
67 export dump the header and diffs for one or more changesets
68 forget forget the specified files on the next commit
68 forget forget the specified files on the next commit
69 init create a new repository in the given directory
69 init create a new repository in the given directory
70 log show revision history of entire repository or files
70 log show revision history of entire repository or files
71 merge merge another revision into working directory
71 merge merge another revision into working directory
72 pull pull changes from the specified source
72 pull pull changes from the specified source
73 push push changes to the specified destination
73 push push changes to the specified destination
74 remove remove the specified files on the next commit
74 remove remove the specified files on the next commit
75 serve start stand-alone webserver
75 serve start stand-alone webserver
76 status show changed files in the working directory
76 status show changed files in the working directory
77 summary summarize working directory state
77 summary summarize working directory state
78 update update working directory (or switch revisions)
78 update update working directory (or switch revisions)
79
79
80 (use "hg help" for the full list of commands or "hg -v" for details)
80 (use "hg help" for the full list of commands or "hg -v" for details)
81 *** runcommand id --quiet
81 *** runcommand id --quiet
82 000000000000
82 000000000000
83 *** runcommand id
83 *** runcommand id
84 000000000000 tip
84 000000000000 tip
85 *** runcommand id --config ui.quiet=True
85 *** runcommand id --config ui.quiet=True
86 000000000000
86 000000000000
87 *** runcommand id
87 *** runcommand id
88 000000000000 tip
88 000000000000 tip
89 *** runcommand id -runknown
89 *** runcommand id -runknown
90 abort: unknown revision 'unknown'!
90 abort: unknown revision 'unknown'!
91 [255]
91 [255]
92
92
93 >>> from hgclient import readchannel, check
93 >>> from hgclient import readchannel, check
94 >>> @check
94 >>> @check
95 ... def inputeof(server):
95 ... def inputeof(server):
96 ... readchannel(server)
96 ... readchannel(server)
97 ... server.stdin.write('runcommand\n')
97 ... server.stdin.write('runcommand\n')
98 ... # close stdin while server is waiting for input
98 ... # close stdin while server is waiting for input
99 ... server.stdin.close()
99 ... server.stdin.close()
100 ...
100 ...
101 ... # server exits with 1 if the pipe closed while reading the command
101 ... # server exits with 1 if the pipe closed while reading the command
102 ... print 'server exit code =', server.wait()
102 ... print 'server exit code =', server.wait()
103 server exit code = 1
103 server exit code = 1
104
104
105 >>> import cStringIO
105 >>> import cStringIO
106 >>> from hgclient import readchannel, runcommand, check
106 >>> from hgclient import readchannel, runcommand, check
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=cStringIO.StringIO(patch))
126 ... runcommand(server, ['import', '-'], input=cStringIO.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 --cwd doesn't persist between requests:
138 check that --cwd doesn't persist between requests:
139
139
140 $ mkdir foo
140 $ mkdir foo
141 $ touch foo/bar
141 $ touch foo/bar
142 >>> from hgclient import readchannel, runcommand, check
142 >>> from hgclient import readchannel, runcommand, check
143 >>> @check
143 >>> @check
144 ... def cwd(server):
144 ... def cwd(server):
145 ... readchannel(server)
145 ... readchannel(server)
146 ... runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
146 ... runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
147 ... runcommand(server, ['st', 'foo/bar'])
147 ... runcommand(server, ['st', 'foo/bar'])
148 *** runcommand --cwd foo st bar
148 *** runcommand --cwd foo st bar
149 ? bar
149 ? bar
150 *** runcommand st foo/bar
150 *** runcommand st foo/bar
151 ? foo/bar
151 ? foo/bar
152
152
153 $ rm foo/bar
153 $ rm foo/bar
154
154
155
155
156 check that local configs for the cached repo aren't inherited when -R is used:
156 check that local configs for the cached repo aren't inherited when -R is used:
157
157
158 $ cat <<EOF >> .hg/hgrc
158 $ cat <<EOF >> .hg/hgrc
159 > [ui]
159 > [ui]
160 > foo = bar
160 > foo = bar
161 > EOF
161 > EOF
162
162
163 >>> from hgclient import readchannel, sep, runcommand, check
163 >>> from hgclient import readchannel, sep, runcommand, check
164 >>> @check
164 >>> @check
165 ... def localhgrc(server):
165 ... def localhgrc(server):
166 ... readchannel(server)
166 ... readchannel(server)
167 ...
167 ...
168 ... # the cached repo local hgrc contains ui.foo=bar, so showconfig should
168 ... # the cached repo local hgrc contains ui.foo=bar, so showconfig should
169 ... # show it
169 ... # show it
170 ... runcommand(server, ['showconfig'], outfilter=sep)
170 ... runcommand(server, ['showconfig'], outfilter=sep)
171 ...
171 ...
172 ... # but not for this repo
172 ... # but not for this repo
173 ... runcommand(server, ['init', 'foo'])
173 ... runcommand(server, ['init', 'foo'])
174 ... runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
174 ... runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
175 *** runcommand showconfig
175 *** runcommand showconfig
176 bundle.mainreporoot=$TESTTMP/repo
176 bundle.mainreporoot=$TESTTMP/repo
177 defaults.backout=-d "0 0"
177 defaults.backout=-d "0 0"
178 defaults.commit=-d "0 0"
178 defaults.commit=-d "0 0"
179 defaults.shelve=--date "0 0"
179 defaults.shelve=--date "0 0"
180 defaults.tag=-d "0 0"
180 defaults.tag=-d "0 0"
181 devel.all-warnings=true
181 devel.all-warnings=true
182 largefiles.usercache=$TESTTMP/.cache/largefiles
182 largefiles.usercache=$TESTTMP/.cache/largefiles
183 ui.slash=True
183 ui.slash=True
184 ui.interactive=False
184 ui.interactive=False
185 ui.mergemarkers=detailed
185 ui.mergemarkers=detailed
186 ui.foo=bar
186 ui.foo=bar
187 ui.nontty=true
187 ui.nontty=true
188 *** runcommand init foo
188 *** runcommand init foo
189 *** runcommand -R foo showconfig ui defaults
189 *** runcommand -R foo showconfig ui defaults
190 defaults.backout=-d "0 0"
190 defaults.backout=-d "0 0"
191 defaults.commit=-d "0 0"
191 defaults.commit=-d "0 0"
192 defaults.shelve=--date "0 0"
192 defaults.shelve=--date "0 0"
193 defaults.tag=-d "0 0"
193 defaults.tag=-d "0 0"
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.nontty=true
197 ui.nontty=true
198
198
199 $ rm -R foo
199 $ rm -R foo
200
200
201 #if windows
201 #if windows
202 $ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH"
202 $ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH"
203 #else
203 #else
204 $ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH"
204 $ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH"
205 #endif
205 #endif
206
206
207 $ cat <<EOF > hook.py
207 $ cat <<EOF > hook.py
208 > import sys
208 > import sys
209 > def hook(**args):
209 > def hook(**args):
210 > print 'hook talking'
210 > print 'hook talking'
211 > print 'now try to read something: %r' % sys.stdin.read()
211 > print 'now try to read something: %r' % sys.stdin.read()
212 > EOF
212 > EOF
213
213
214 >>> import cStringIO
214 >>> import cStringIO
215 >>> from hgclient import readchannel, runcommand, check
215 >>> from hgclient import readchannel, runcommand, check
216 >>> @check
216 >>> @check
217 ... def hookoutput(server):
217 ... def hookoutput(server):
218 ... readchannel(server)
218 ... readchannel(server)
219 ... runcommand(server, ['--config',
219 ... runcommand(server, ['--config',
220 ... 'hooks.pre-identify=python:hook.hook',
220 ... 'hooks.pre-identify=python:hook.hook',
221 ... 'id'],
221 ... 'id'],
222 ... input=cStringIO.StringIO('some input'))
222 ... input=cStringIO.StringIO('some input'))
223 *** runcommand --config hooks.pre-identify=python:hook.hook id
223 *** runcommand --config hooks.pre-identify=python:hook.hook id
224 hook talking
224 hook talking
225 now try to read something: 'some input'
225 now try to read something: 'some input'
226 eff892de26ec tip
226 eff892de26ec tip
227
227
228 $ rm hook.py*
228 $ rm hook.py*
229
229
230 $ echo a >> a
230 $ echo a >> a
231 >>> import os
231 >>> import os
232 >>> from hgclient import readchannel, runcommand, check
232 >>> from hgclient import readchannel, runcommand, check
233 >>> @check
233 >>> @check
234 ... def outsidechanges(server):
234 ... def outsidechanges(server):
235 ... readchannel(server)
235 ... readchannel(server)
236 ... runcommand(server, ['status'])
236 ... runcommand(server, ['status'])
237 ... os.system('hg ci -Am2')
237 ... os.system('hg ci -Am2')
238 ... runcommand(server, ['tip'])
238 ... runcommand(server, ['tip'])
239 ... runcommand(server, ['status'])
239 ... runcommand(server, ['status'])
240 *** runcommand status
240 *** runcommand status
241 M a
241 M a
242 *** runcommand tip
242 *** runcommand tip
243 changeset: 1:d3a0a68be6de
243 changeset: 1:d3a0a68be6de
244 tag: tip
244 tag: tip
245 user: test
245 user: test
246 date: Thu Jan 01 00:00:00 1970 +0000
246 date: Thu Jan 01 00:00:00 1970 +0000
247 summary: 2
247 summary: 2
248
248
249 *** runcommand status
249 *** runcommand status
250
250
251 >>> import os
251 >>> import os
252 >>> from hgclient import readchannel, runcommand, check
252 >>> from hgclient import readchannel, runcommand, check
253 >>> @check
253 >>> @check
254 ... def bookmarks(server):
254 ... def bookmarks(server):
255 ... readchannel(server)
255 ... readchannel(server)
256 ... runcommand(server, ['bookmarks'])
256 ... runcommand(server, ['bookmarks'])
257 ...
257 ...
258 ... # changes .hg/bookmarks
258 ... # changes .hg/bookmarks
259 ... os.system('hg bookmark -i bm1')
259 ... os.system('hg bookmark -i bm1')
260 ... os.system('hg bookmark -i bm2')
260 ... os.system('hg bookmark -i bm2')
261 ... runcommand(server, ['bookmarks'])
261 ... runcommand(server, ['bookmarks'])
262 ...
262 ...
263 ... # changes .hg/bookmarks.current
263 ... # changes .hg/bookmarks.current
264 ... os.system('hg upd bm1 -q')
264 ... os.system('hg upd bm1 -q')
265 ... runcommand(server, ['bookmarks'])
265 ... runcommand(server, ['bookmarks'])
266 ...
266 ...
267 ... runcommand(server, ['bookmarks', 'bm3'])
267 ... runcommand(server, ['bookmarks', 'bm3'])
268 ... f = open('a', 'ab')
268 ... f = open('a', 'ab')
269 ... f.write('a\n')
269 ... f.write('a\n')
270 ... f.close()
270 ... f.close()
271 ... runcommand(server, ['commit', '-Amm'])
271 ... runcommand(server, ['commit', '-Amm'])
272 ... runcommand(server, ['bookmarks'])
272 ... runcommand(server, ['bookmarks'])
273 *** runcommand bookmarks
273 *** runcommand bookmarks
274 no bookmarks set
274 no bookmarks set
275 *** runcommand bookmarks
275 *** runcommand bookmarks
276 bm1 1:d3a0a68be6de
276 bm1 1:d3a0a68be6de
277 bm2 1:d3a0a68be6de
277 bm2 1:d3a0a68be6de
278 *** runcommand bookmarks
278 *** runcommand bookmarks
279 * bm1 1:d3a0a68be6de
279 * bm1 1:d3a0a68be6de
280 bm2 1:d3a0a68be6de
280 bm2 1:d3a0a68be6de
281 *** runcommand bookmarks bm3
281 *** runcommand bookmarks bm3
282 *** runcommand commit -Amm
282 *** runcommand commit -Amm
283 *** runcommand bookmarks
283 *** runcommand bookmarks
284 bm1 1:d3a0a68be6de
284 bm1 1:d3a0a68be6de
285 bm2 1:d3a0a68be6de
285 bm2 1:d3a0a68be6de
286 * bm3 2:aef17e88f5f0
286 * bm3 2:aef17e88f5f0
287
287
288 >>> import os
288 >>> import os
289 >>> from hgclient import readchannel, runcommand, check
289 >>> from hgclient import readchannel, runcommand, check
290 >>> @check
290 >>> @check
291 ... def tagscache(server):
291 ... def tagscache(server):
292 ... readchannel(server)
292 ... readchannel(server)
293 ... runcommand(server, ['id', '-t', '-r', '0'])
293 ... runcommand(server, ['id', '-t', '-r', '0'])
294 ... os.system('hg tag -r 0 foo')
294 ... os.system('hg tag -r 0 foo')
295 ... runcommand(server, ['id', '-t', '-r', '0'])
295 ... runcommand(server, ['id', '-t', '-r', '0'])
296 *** runcommand id -t -r 0
296 *** runcommand id -t -r 0
297
297
298 *** runcommand id -t -r 0
298 *** runcommand id -t -r 0
299 foo
299 foo
300
300
301 >>> import os
301 >>> import os
302 >>> from hgclient import readchannel, runcommand, check
302 >>> from hgclient import readchannel, runcommand, check
303 >>> @check
303 >>> @check
304 ... def setphase(server):
304 ... def setphase(server):
305 ... readchannel(server)
305 ... readchannel(server)
306 ... runcommand(server, ['phase', '-r', '.'])
306 ... runcommand(server, ['phase', '-r', '.'])
307 ... os.system('hg phase -r . -p')
307 ... os.system('hg phase -r . -p')
308 ... runcommand(server, ['phase', '-r', '.'])
308 ... runcommand(server, ['phase', '-r', '.'])
309 *** runcommand phase -r .
309 *** runcommand phase -r .
310 3: draft
310 3: draft
311 *** runcommand phase -r .
311 *** runcommand phase -r .
312 3: public
312 3: public
313
313
314 $ echo a >> a
314 $ echo a >> a
315 >>> from hgclient import readchannel, runcommand, check
315 >>> from hgclient import readchannel, runcommand, check
316 >>> @check
316 >>> @check
317 ... def rollback(server):
317 ... def rollback(server):
318 ... readchannel(server)
318 ... readchannel(server)
319 ... runcommand(server, ['phase', '-r', '.', '-p'])
319 ... runcommand(server, ['phase', '-r', '.', '-p'])
320 ... runcommand(server, ['commit', '-Am.'])
320 ... runcommand(server, ['commit', '-Am.'])
321 ... runcommand(server, ['rollback'])
321 ... runcommand(server, ['rollback'])
322 ... runcommand(server, ['phase', '-r', '.'])
322 ... runcommand(server, ['phase', '-r', '.'])
323 *** runcommand phase -r . -p
323 *** runcommand phase -r . -p
324 no phases changed
324 no phases changed
325 [1]
325 [1]
326 *** runcommand commit -Am.
326 *** runcommand commit -Am.
327 *** runcommand rollback
327 *** runcommand rollback
328 repository tip rolled back to revision 3 (undo commit)
328 repository tip rolled back to revision 3 (undo commit)
329 working directory now based on revision 3
329 working directory now based on revision 3
330 *** runcommand phase -r .
330 *** runcommand phase -r .
331 3: public
331 3: public
332
332
333 >>> import os
333 >>> import os
334 >>> from hgclient import readchannel, runcommand, check
334 >>> from hgclient import readchannel, runcommand, check
335 >>> @check
335 >>> @check
336 ... def branch(server):
336 ... def branch(server):
337 ... readchannel(server)
337 ... readchannel(server)
338 ... runcommand(server, ['branch'])
338 ... runcommand(server, ['branch'])
339 ... os.system('hg branch foo')
339 ... os.system('hg branch foo')
340 ... runcommand(server, ['branch'])
340 ... runcommand(server, ['branch'])
341 ... os.system('hg branch default')
341 ... os.system('hg branch default')
342 *** runcommand branch
342 *** runcommand branch
343 default
343 default
344 marked working directory as branch foo
344 marked working directory as branch foo
345 (branches are permanent and global, did you want a bookmark?)
345 (branches are permanent and global, did you want a bookmark?)
346 *** runcommand branch
346 *** runcommand branch
347 foo
347 foo
348 marked working directory as branch default
348 marked working directory as branch default
349 (branches are permanent and global, did you want a bookmark?)
349 (branches are permanent and global, did you want a bookmark?)
350
350
351 $ touch .hgignore
351 $ touch .hgignore
352 >>> import os
352 >>> import os
353 >>> from hgclient import readchannel, runcommand, check
353 >>> from hgclient import readchannel, runcommand, check
354 >>> @check
354 >>> @check
355 ... def hgignore(server):
355 ... def hgignore(server):
356 ... readchannel(server)
356 ... readchannel(server)
357 ... runcommand(server, ['commit', '-Am.'])
357 ... runcommand(server, ['commit', '-Am.'])
358 ... f = open('ignored-file', 'ab')
358 ... f = open('ignored-file', 'ab')
359 ... f.write('')
359 ... f.write('')
360 ... f.close()
360 ... f.close()
361 ... f = open('.hgignore', 'ab')
361 ... f = open('.hgignore', 'ab')
362 ... f.write('ignored-file')
362 ... f.write('ignored-file')
363 ... f.close()
363 ... f.close()
364 ... runcommand(server, ['status', '-i', '-u'])
364 ... runcommand(server, ['status', '-i', '-u'])
365 *** runcommand commit -Am.
365 *** runcommand commit -Am.
366 adding .hgignore
366 adding .hgignore
367 *** runcommand status -i -u
367 *** runcommand status -i -u
368 I ignored-file
368 I ignored-file
369
369
370 >>> import os
370 >>> import os
371 >>> from hgclient import readchannel, sep, runcommand, check
371 >>> from hgclient import readchannel, sep, runcommand, check
372 >>> @check
372 >>> @check
373 ... def phasecacheafterstrip(server):
373 ... def phasecacheafterstrip(server):
374 ... readchannel(server)
374 ... readchannel(server)
375 ...
375 ...
376 ... # create new head, 5:731265503d86
376 ... # create new head, 5:731265503d86
377 ... runcommand(server, ['update', '-C', '0'])
377 ... runcommand(server, ['update', '-C', '0'])
378 ... f = open('a', 'ab')
378 ... f = open('a', 'ab')
379 ... f.write('a\n')
379 ... f.write('a\n')
380 ... f.close()
380 ... f.close()
381 ... runcommand(server, ['commit', '-Am.', 'a'])
381 ... runcommand(server, ['commit', '-Am.', 'a'])
382 ... runcommand(server, ['log', '-Gq'])
382 ... runcommand(server, ['log', '-Gq'])
383 ...
383 ...
384 ... # make it public; draft marker moves to 4:7966c8e3734d
384 ... # make it public; draft marker moves to 4:7966c8e3734d
385 ... runcommand(server, ['phase', '-p', '.'])
385 ... runcommand(server, ['phase', '-p', '.'])
386 ... # load _phasecache.phaseroots
386 ... # load _phasecache.phaseroots
387 ... runcommand(server, ['phase', '.'], outfilter=sep)
387 ... runcommand(server, ['phase', '.'], outfilter=sep)
388 ...
388 ...
389 ... # strip 1::4 outside server
389 ... # strip 1::4 outside server
390 ... os.system('hg -q --config extensions.mq= strip 1')
390 ... os.system('hg -q --config extensions.mq= strip 1')
391 ...
391 ...
392 ... # shouldn't raise "7966c8e3734d: no node!"
392 ... # shouldn't raise "7966c8e3734d: no node!"
393 ... runcommand(server, ['branches'])
393 ... runcommand(server, ['branches'])
394 *** runcommand update -C 0
394 *** runcommand update -C 0
395 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
395 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
396 (leaving bookmark bm3)
396 (leaving bookmark bm3)
397 *** runcommand commit -Am. a
397 *** runcommand commit -Am. a
398 created new head
398 created new head
399 *** runcommand log -Gq
399 *** runcommand log -Gq
400 @ 5:731265503d86
400 @ 5:731265503d86
401 |
401 |
402 | o 4:7966c8e3734d
402 | o 4:7966c8e3734d
403 | |
403 | |
404 | o 3:b9b85890c400
404 | o 3:b9b85890c400
405 | |
405 | |
406 | o 2:aef17e88f5f0
406 | o 2:aef17e88f5f0
407 | |
407 | |
408 | o 1:d3a0a68be6de
408 | o 1:d3a0a68be6de
409 |/
409 |/
410 o 0:eff892de26ec
410 o 0:eff892de26ec
411
411
412 *** runcommand phase -p .
412 *** runcommand phase -p .
413 *** runcommand phase .
413 *** runcommand phase .
414 5: public
414 5: public
415 *** runcommand branches
415 *** runcommand branches
416 default 1:731265503d86
416 default 1:731265503d86
417
417
418 $ cat >> .hg/hgrc << EOF
418 $ cat >> .hg/hgrc << EOF
419 > [experimental]
419 > [experimental]
420 > evolution=createmarkers
420 > evolution=createmarkers
421 > EOF
421 > EOF
422
422
423 >>> import os
423 >>> import os
424 >>> from hgclient import readchannel, runcommand, check
424 >>> from hgclient import readchannel, runcommand, check
425 >>> @check
425 >>> @check
426 ... def obsolete(server):
426 ... def obsolete(server):
427 ... readchannel(server)
427 ... readchannel(server)
428 ...
428 ...
429 ... runcommand(server, ['up', 'null'])
429 ... runcommand(server, ['up', 'null'])
430 ... runcommand(server, ['phase', '-df', 'tip'])
430 ... runcommand(server, ['phase', '-df', 'tip'])
431 ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
431 ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
432 ... if os.name == 'nt':
432 ... if os.name == 'nt':
433 ... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
433 ... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
434 ... os.system(cmd)
434 ... os.system(cmd)
435 ... runcommand(server, ['log', '--hidden'])
435 ... runcommand(server, ['log', '--hidden'])
436 ... runcommand(server, ['log'])
436 ... runcommand(server, ['log'])
437 *** runcommand up null
437 *** runcommand up null
438 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
438 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
439 *** runcommand phase -df tip
439 *** runcommand phase -df tip
440 *** runcommand log --hidden
440 *** runcommand log --hidden
441 changeset: 1:731265503d86
441 changeset: 1:731265503d86
442 tag: tip
442 tag: tip
443 user: test
443 user: test
444 date: Thu Jan 01 00:00:00 1970 +0000
444 date: Thu Jan 01 00:00:00 1970 +0000
445 summary: .
445 summary: .
446
446
447 changeset: 0:eff892de26ec
447 changeset: 0:eff892de26ec
448 bookmark: bm1
448 bookmark: bm1
449 bookmark: bm2
449 bookmark: bm2
450 bookmark: bm3
450 bookmark: bm3
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: 1
453 summary: 1
454
454
455 *** runcommand log
455 *** runcommand log
456 changeset: 0:eff892de26ec
456 changeset: 0:eff892de26ec
457 bookmark: bm1
457 bookmark: bm1
458 bookmark: bm2
458 bookmark: bm2
459 bookmark: bm3
459 bookmark: bm3
460 tag: tip
460 tag: tip
461 user: test
461 user: test
462 date: Thu Jan 01 00:00:00 1970 +0000
462 date: Thu Jan 01 00:00:00 1970 +0000
463 summary: 1
463 summary: 1
464
464
465
465
466 $ cat <<EOF >> .hg/hgrc
466 $ cat <<EOF >> .hg/hgrc
467 > [extensions]
467 > [extensions]
468 > mq =
468 > mq =
469 > EOF
469 > EOF
470
470
471 >>> import os
471 >>> import os
472 >>> from hgclient import readchannel, runcommand, check
472 >>> from hgclient import readchannel, runcommand, check
473 >>> @check
473 >>> @check
474 ... def mqoutsidechanges(server):
474 ... def mqoutsidechanges(server):
475 ... readchannel(server)
475 ... readchannel(server)
476 ...
476 ...
477 ... # load repo.mq
477 ... # load repo.mq
478 ... runcommand(server, ['qapplied'])
478 ... runcommand(server, ['qapplied'])
479 ... os.system('hg qnew 0.diff')
479 ... os.system('hg qnew 0.diff')
480 ... # repo.mq should be invalidated
480 ... # repo.mq should be invalidated
481 ... runcommand(server, ['qapplied'])
481 ... runcommand(server, ['qapplied'])
482 ...
482 ...
483 ... runcommand(server, ['qpop', '--all'])
483 ... runcommand(server, ['qpop', '--all'])
484 ... os.system('hg qqueue --create foo')
484 ... os.system('hg qqueue --create foo')
485 ... # repo.mq should be recreated to point to new queue
485 ... # repo.mq should be recreated to point to new queue
486 ... runcommand(server, ['qqueue', '--active'])
486 ... runcommand(server, ['qqueue', '--active'])
487 *** runcommand qapplied
487 *** runcommand qapplied
488 *** runcommand qapplied
488 *** runcommand qapplied
489 0.diff
489 0.diff
490 *** runcommand qpop --all
490 *** runcommand qpop --all
491 popping 0.diff
491 popping 0.diff
492 patch queue now empty
492 patch queue now empty
493 *** runcommand qqueue --active
493 *** runcommand qqueue --active
494 foo
494 foo
495
495
496 $ cat <<EOF > dbgui.py
496 $ cat <<EOF > dbgui.py
497 > import os, sys
497 > import os, sys
498 > from mercurial import cmdutil, commands
498 > from mercurial import cmdutil, commands
499 > cmdtable = {}
499 > cmdtable = {}
500 > command = cmdutil.command(cmdtable)
500 > command = cmdutil.command(cmdtable)
501 > @command("debuggetpass", norepo=True)
501 > @command("debuggetpass", norepo=True)
502 > def debuggetpass(ui):
502 > def debuggetpass(ui):
503 > ui.write("%s\\n" % ui.getpass())
503 > ui.write("%s\\n" % ui.getpass())
504 > @command("debugprompt", norepo=True)
504 > @command("debugprompt", norepo=True)
505 > def debugprompt(ui):
505 > def debugprompt(ui):
506 > ui.write("%s\\n" % ui.prompt("prompt:"))
506 > ui.write("%s\\n" % ui.prompt("prompt:"))
507 > @command("debugreadstdin", norepo=True)
507 > @command("debugreadstdin", norepo=True)
508 > def debugreadstdin(ui):
508 > def debugreadstdin(ui):
509 > ui.write("read: %r\n" % sys.stdin.read(1))
509 > ui.write("read: %r\n" % sys.stdin.read(1))
510 > @command("debugwritestdout", norepo=True)
510 > @command("debugwritestdout", norepo=True)
511 > def debugwritestdout(ui):
511 > def debugwritestdout(ui):
512 > os.write(1, "low-level stdout fd and\n")
512 > os.write(1, "low-level stdout fd and\n")
513 > sys.stdout.write("stdout should be redirected to /dev/null\n")
513 > sys.stdout.write("stdout should be redirected to /dev/null\n")
514 > sys.stdout.flush()
514 > sys.stdout.flush()
515 > EOF
515 > EOF
516 $ cat <<EOF >> .hg/hgrc
516 $ cat <<EOF >> .hg/hgrc
517 > [extensions]
517 > [extensions]
518 > dbgui = dbgui.py
518 > dbgui = dbgui.py
519 > EOF
519 > EOF
520
520
521 >>> import cStringIO
521 >>> import cStringIO
522 >>> from hgclient import readchannel, runcommand, check
522 >>> from hgclient import readchannel, runcommand, check
523 >>> @check
523 >>> @check
524 ... def getpass(server):
524 ... def getpass(server):
525 ... readchannel(server)
525 ... readchannel(server)
526 ... runcommand(server, ['debuggetpass', '--config',
526 ... runcommand(server, ['debuggetpass', '--config',
527 ... 'ui.interactive=True'],
527 ... 'ui.interactive=True'],
528 ... input=cStringIO.StringIO('1234\n'))
528 ... input=cStringIO.StringIO('1234\n'))
529 ... runcommand(server, ['debugprompt', '--config',
529 ... runcommand(server, ['debugprompt', '--config',
530 ... 'ui.interactive=True'],
530 ... 'ui.interactive=True'],
531 ... input=cStringIO.StringIO('5678\n'))
531 ... input=cStringIO.StringIO('5678\n'))
532 ... runcommand(server, ['debugreadstdin'])
532 ... runcommand(server, ['debugreadstdin'])
533 ... runcommand(server, ['debugwritestdout'])
533 ... runcommand(server, ['debugwritestdout'])
534 *** runcommand debuggetpass --config ui.interactive=True
534 *** runcommand debuggetpass --config ui.interactive=True
535 password: 1234
535 password: 1234
536 *** runcommand debugprompt --config ui.interactive=True
536 *** runcommand debugprompt --config ui.interactive=True
537 prompt: 5678
537 prompt: 5678
538 *** runcommand debugreadstdin
538 *** runcommand debugreadstdin
539 read: ''
539 read: ''
540 *** runcommand debugwritestdout
540 *** runcommand debugwritestdout
541
541
542
542
543 run commandserver in commandserver, which is silly but should work:
543 run commandserver in commandserver, which is silly but should work:
544
544
545 >>> import cStringIO
545 >>> import cStringIO
546 >>> from hgclient import readchannel, runcommand, check
546 >>> from hgclient import readchannel, runcommand, check
547 >>> @check
547 >>> @check
548 ... def nested(server):
548 ... def nested(server):
549 ... print '%c, %r' % readchannel(server)
549 ... print '%c, %r' % readchannel(server)
550 ... class nestedserver(object):
550 ... class nestedserver(object):
551 ... stdin = cStringIO.StringIO('getencoding\n')
551 ... stdin = cStringIO.StringIO('getencoding\n')
552 ... stdout = cStringIO.StringIO()
552 ... stdout = cStringIO.StringIO()
553 ... runcommand(server, ['serve', '--cmdserver', 'pipe'],
553 ... runcommand(server, ['serve', '--cmdserver', 'pipe'],
554 ... output=nestedserver.stdout, input=nestedserver.stdin)
554 ... output=nestedserver.stdout, input=nestedserver.stdin)
555 ... nestedserver.stdout.seek(0)
555 ... nestedserver.stdout.seek(0)
556 ... print '%c, %r' % readchannel(nestedserver) # hello
556 ... print '%c, %r' % readchannel(nestedserver) # hello
557 ... print '%c, %r' % readchannel(nestedserver) # getencoding
557 ... print '%c, %r' % readchannel(nestedserver) # getencoding
558 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
558 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
559 *** runcommand serve --cmdserver pipe
559 *** runcommand serve --cmdserver pipe
560 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
560 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
561 r, '*' (glob)
561 r, '*' (glob)
562
562
563
563
564 start without repository:
564 start without repository:
565
565
566 $ cd ..
566 $ cd ..
567
567
568 >>> from hgclient import readchannel, runcommand, check
568 >>> from hgclient import readchannel, runcommand, check
569 >>> @check
569 >>> @check
570 ... def hellomessage(server):
570 ... def hellomessage(server):
571 ... ch, data = readchannel(server)
571 ... ch, data = readchannel(server)
572 ... print '%c, %r' % (ch, data)
572 ... print '%c, %r' % (ch, data)
573 ... # run an arbitrary command to make sure the next thing the server
573 ... # run an arbitrary command to make sure the next thing the server
574 ... # sends isn't part of the hello message
574 ... # sends isn't part of the hello message
575 ... runcommand(server, ['id'])
575 ... runcommand(server, ['id'])
576 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
576 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
577 *** runcommand id
577 *** runcommand id
578 abort: there is no Mercurial repository here (.hg not found)
578 abort: there is no Mercurial repository here (.hg not found)
579 [255]
579 [255]
580
580
581 >>> from hgclient import readchannel, runcommand, check
581 >>> from hgclient import readchannel, runcommand, check
582 >>> @check
582 >>> @check
583 ... def startwithoutrepo(server):
583 ... def startwithoutrepo(server):
584 ... readchannel(server)
584 ... readchannel(server)
585 ... runcommand(server, ['init', 'repo2'])
585 ... runcommand(server, ['init', 'repo2'])
586 ... runcommand(server, ['id', '-R', 'repo2'])
586 ... runcommand(server, ['id', '-R', 'repo2'])
587 *** runcommand init repo2
587 *** runcommand init repo2
588 *** runcommand id -R repo2
588 *** runcommand id -R repo2
589 000000000000 tip
589 000000000000 tip
590
590
591
591
592 don't fall back to cwd if invalid -R path is specified (issue4805):
593
594 $ cd repo
595 $ hg serve --cmdserver pipe -R ../nonexistent
596 abort: repository ../nonexistent not found!
597 [255]
598 $ cd ..
599
600
592 unix domain socket:
601 unix domain socket:
593
602
594 $ cd repo
603 $ cd repo
595 $ hg update -q
604 $ hg update -q
596
605
597 #if unix-socket unix-permissions
606 #if unix-socket unix-permissions
598
607
599 >>> import cStringIO
608 >>> import cStringIO
600 >>> from hgclient import unixserver, readchannel, runcommand, check
609 >>> from hgclient import unixserver, readchannel, runcommand, check
601 >>> server = unixserver('.hg/server.sock', '.hg/server.log')
610 >>> server = unixserver('.hg/server.sock', '.hg/server.log')
602 >>> def hellomessage(conn):
611 >>> def hellomessage(conn):
603 ... ch, data = readchannel(conn)
612 ... ch, data = readchannel(conn)
604 ... print '%c, %r' % (ch, data)
613 ... print '%c, %r' % (ch, data)
605 ... runcommand(conn, ['id'])
614 ... runcommand(conn, ['id'])
606 >>> check(hellomessage, server.connect)
615 >>> check(hellomessage, server.connect)
607 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
616 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
608 *** runcommand id
617 *** runcommand id
609 eff892de26ec tip bm1/bm2/bm3
618 eff892de26ec tip bm1/bm2/bm3
610 >>> def unknowncommand(conn):
619 >>> def unknowncommand(conn):
611 ... readchannel(conn)
620 ... readchannel(conn)
612 ... conn.stdin.write('unknowncommand\n')
621 ... conn.stdin.write('unknowncommand\n')
613 >>> check(unknowncommand, server.connect) # error sent to server.log
622 >>> check(unknowncommand, server.connect) # error sent to server.log
614 >>> def serverinput(conn):
623 >>> def serverinput(conn):
615 ... readchannel(conn)
624 ... readchannel(conn)
616 ... patch = """
625 ... patch = """
617 ... # HG changeset patch
626 ... # HG changeset patch
618 ... # User test
627 ... # User test
619 ... # Date 0 0
628 ... # Date 0 0
620 ... 2
629 ... 2
621 ...
630 ...
622 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
631 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
623 ... --- a/a
632 ... --- a/a
624 ... +++ b/a
633 ... +++ b/a
625 ... @@ -1,1 +1,2 @@
634 ... @@ -1,1 +1,2 @@
626 ... 1
635 ... 1
627 ... +2
636 ... +2
628 ... """
637 ... """
629 ... runcommand(conn, ['import', '-'], input=cStringIO.StringIO(patch))
638 ... runcommand(conn, ['import', '-'], input=cStringIO.StringIO(patch))
630 ... runcommand(conn, ['log', '-rtip', '-q'])
639 ... runcommand(conn, ['log', '-rtip', '-q'])
631 >>> check(serverinput, server.connect)
640 >>> check(serverinput, server.connect)
632 *** runcommand import -
641 *** runcommand import -
633 applying patch from stdin
642 applying patch from stdin
634 *** runcommand log -rtip -q
643 *** runcommand log -rtip -q
635 2:1ed24be7e7a0
644 2:1ed24be7e7a0
636 >>> server.shutdown()
645 >>> server.shutdown()
637
646
638 $ cat .hg/server.log
647 $ cat .hg/server.log
639 listening at .hg/server.sock
648 listening at .hg/server.sock
640 abort: unknown command unknowncommand
649 abort: unknown command unknowncommand
641 killed!
650 killed!
642 #endif
651 #endif
643 #if no-unix-socket
652 #if no-unix-socket
644
653
645 $ hg serve --cmdserver unix -a .hg/server.sock
654 $ hg serve --cmdserver unix -a .hg/server.sock
646 abort: unsupported platform
655 abort: unsupported platform
647 [255]
656 [255]
648
657
649 #endif
658 #endif
@@ -1,512 +1,512 b''
1 This test is a duplicate of 'test-http.t' feel free to factor out
1 This test is a duplicate of 'test-http.t' feel free to factor out
2 parts that are not bundle1/bundle2 specific.
2 parts that are not bundle1/bundle2 specific.
3
3
4 $ cat << EOF >> $HGRCPATH
4 $ cat << EOF >> $HGRCPATH
5 > [experimental]
5 > [experimental]
6 > # This test is dedicated to interaction through old bundle
6 > # This test is dedicated to interaction through old bundle
7 > bundle2-exp = False
7 > bundle2-exp = False
8 > EOF
8 > EOF
9
9
10
10
11 This test tries to exercise the ssh functionality with a dummy script
11 This test tries to exercise the ssh functionality with a dummy script
12
12
13 creating 'remote' repo
13 creating 'remote' repo
14
14
15 $ hg init remote
15 $ hg init remote
16 $ cd remote
16 $ cd remote
17 $ echo this > foo
17 $ echo this > foo
18 $ echo this > fooO
18 $ echo this > fooO
19 $ hg ci -A -m "init" foo fooO
19 $ hg ci -A -m "init" foo fooO
20
20
21 insert a closed branch (issue4428)
21 insert a closed branch (issue4428)
22
22
23 $ hg up null
23 $ hg up null
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
25 $ hg branch closed
25 $ hg branch closed
26 marked working directory as branch closed
26 marked working directory as branch closed
27 (branches are permanent and global, did you want a bookmark?)
27 (branches are permanent and global, did you want a bookmark?)
28 $ hg ci -mc0
28 $ hg ci -mc0
29 $ hg ci --close-branch -mc1
29 $ hg ci --close-branch -mc1
30 $ hg up -q default
30 $ hg up -q default
31
31
32 configure for serving
32 configure for serving
33
33
34 $ cat <<EOF > .hg/hgrc
34 $ cat <<EOF > .hg/hgrc
35 > [server]
35 > [server]
36 > uncompressed = True
36 > uncompressed = True
37 >
37 >
38 > [hooks]
38 > [hooks]
39 > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
39 > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
40 > EOF
40 > EOF
41 $ cd ..
41 $ cd ..
42
42
43 repo not found error
43 repo not found error
44
44
45 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
45 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
46 remote: abort: there is no Mercurial repository here (.hg not found)!
46 remote: abort: repository nonexistent not found!
47 abort: no suitable response from remote hg!
47 abort: no suitable response from remote hg!
48 [255]
48 [255]
49
49
50 non-existent absolute path
50 non-existent absolute path
51
51
52 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
52 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
53 remote: abort: there is no Mercurial repository here (.hg not found)!
53 remote: abort: repository /$TESTTMP/nonexistent not found!
54 abort: no suitable response from remote hg!
54 abort: no suitable response from remote hg!
55 [255]
55 [255]
56
56
57 clone remote via stream
57 clone remote via stream
58
58
59 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
59 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
60 streaming all changes
60 streaming all changes
61 4 files to transfer, 615 bytes of data
61 4 files to transfer, 615 bytes of data
62 transferred 615 bytes in * seconds (*) (glob)
62 transferred 615 bytes in * seconds (*) (glob)
63 searching for changes
63 searching for changes
64 no changes found
64 no changes found
65 updating to branch default
65 updating to branch default
66 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 $ cd local-stream
67 $ cd local-stream
68 $ hg verify
68 $ hg verify
69 checking changesets
69 checking changesets
70 checking manifests
70 checking manifests
71 crosschecking files in changesets and manifests
71 crosschecking files in changesets and manifests
72 checking files
72 checking files
73 2 files, 3 changesets, 2 total revisions
73 2 files, 3 changesets, 2 total revisions
74 $ hg branches
74 $ hg branches
75 default 0:1160648e36ce
75 default 0:1160648e36ce
76 $ cd ..
76 $ cd ..
77
77
78 clone bookmarks via stream
78 clone bookmarks via stream
79
79
80 $ hg -R local-stream book mybook
80 $ hg -R local-stream book mybook
81 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
81 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
82 streaming all changes
82 streaming all changes
83 4 files to transfer, 615 bytes of data
83 4 files to transfer, 615 bytes of data
84 transferred 615 bytes in * seconds (*) (glob)
84 transferred 615 bytes in * seconds (*) (glob)
85 searching for changes
85 searching for changes
86 no changes found
86 no changes found
87 updating to branch default
87 updating to branch default
88 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 $ cd stream2
89 $ cd stream2
90 $ hg book
90 $ hg book
91 mybook 0:1160648e36ce
91 mybook 0:1160648e36ce
92 $ cd ..
92 $ cd ..
93 $ rm -rf local-stream stream2
93 $ rm -rf local-stream stream2
94
94
95 clone remote via pull
95 clone remote via pull
96
96
97 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
97 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
98 requesting all changes
98 requesting all changes
99 adding changesets
99 adding changesets
100 adding manifests
100 adding manifests
101 adding file changes
101 adding file changes
102 added 3 changesets with 2 changes to 2 files
102 added 3 changesets with 2 changes to 2 files
103 updating to branch default
103 updating to branch default
104 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105
105
106 verify
106 verify
107
107
108 $ cd local
108 $ cd local
109 $ hg verify
109 $ hg verify
110 checking changesets
110 checking changesets
111 checking manifests
111 checking manifests
112 crosschecking files in changesets and manifests
112 crosschecking files in changesets and manifests
113 checking files
113 checking files
114 2 files, 3 changesets, 2 total revisions
114 2 files, 3 changesets, 2 total revisions
115 $ echo '[hooks]' >> .hg/hgrc
115 $ echo '[hooks]' >> .hg/hgrc
116 $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
116 $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
117
117
118 empty default pull
118 empty default pull
119
119
120 $ hg paths
120 $ hg paths
121 default = ssh://user@dummy/remote
121 default = ssh://user@dummy/remote
122 $ hg pull -e "python \"$TESTDIR/dummyssh\""
122 $ hg pull -e "python \"$TESTDIR/dummyssh\""
123 pulling from ssh://user@dummy/remote
123 pulling from ssh://user@dummy/remote
124 searching for changes
124 searching for changes
125 no changes found
125 no changes found
126
126
127 pull from wrong ssh URL
127 pull from wrong ssh URL
128
128
129 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
129 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
130 pulling from ssh://user@dummy/doesnotexist
130 pulling from ssh://user@dummy/doesnotexist
131 remote: abort: there is no Mercurial repository here (.hg not found)!
131 remote: abort: repository doesnotexist not found!
132 abort: no suitable response from remote hg!
132 abort: no suitable response from remote hg!
133 [255]
133 [255]
134
134
135 local change
135 local change
136
136
137 $ echo bleah > foo
137 $ echo bleah > foo
138 $ hg ci -m "add"
138 $ hg ci -m "add"
139
139
140 updating rc
140 updating rc
141
141
142 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
142 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
143 $ echo "[ui]" >> .hg/hgrc
143 $ echo "[ui]" >> .hg/hgrc
144 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
144 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
145
145
146 find outgoing
146 find outgoing
147
147
148 $ hg out ssh://user@dummy/remote
148 $ hg out ssh://user@dummy/remote
149 comparing with ssh://user@dummy/remote
149 comparing with ssh://user@dummy/remote
150 searching for changes
150 searching for changes
151 changeset: 3:a28a9d1a809c
151 changeset: 3:a28a9d1a809c
152 tag: tip
152 tag: tip
153 parent: 0:1160648e36ce
153 parent: 0:1160648e36ce
154 user: test
154 user: test
155 date: Thu Jan 01 00:00:00 1970 +0000
155 date: Thu Jan 01 00:00:00 1970 +0000
156 summary: add
156 summary: add
157
157
158
158
159 find incoming on the remote side
159 find incoming on the remote side
160
160
161 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
161 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
162 comparing with ssh://user@dummy/local
162 comparing with ssh://user@dummy/local
163 searching for changes
163 searching for changes
164 changeset: 3:a28a9d1a809c
164 changeset: 3:a28a9d1a809c
165 tag: tip
165 tag: tip
166 parent: 0:1160648e36ce
166 parent: 0:1160648e36ce
167 user: test
167 user: test
168 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
169 summary: add
169 summary: add
170
170
171
171
172 find incoming on the remote side (using absolute path)
172 find incoming on the remote side (using absolute path)
173
173
174 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
174 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
175 comparing with ssh://user@dummy/$TESTTMP/local
175 comparing with ssh://user@dummy/$TESTTMP/local
176 searching for changes
176 searching for changes
177 changeset: 3:a28a9d1a809c
177 changeset: 3:a28a9d1a809c
178 tag: tip
178 tag: tip
179 parent: 0:1160648e36ce
179 parent: 0:1160648e36ce
180 user: test
180 user: test
181 date: Thu Jan 01 00:00:00 1970 +0000
181 date: Thu Jan 01 00:00:00 1970 +0000
182 summary: add
182 summary: add
183
183
184
184
185 push
185 push
186
186
187 $ hg push
187 $ hg push
188 pushing to ssh://user@dummy/remote
188 pushing to ssh://user@dummy/remote
189 searching for changes
189 searching for changes
190 remote: adding changesets
190 remote: adding changesets
191 remote: adding manifests
191 remote: adding manifests
192 remote: adding file changes
192 remote: adding file changes
193 remote: added 1 changesets with 1 changes to 1 files
193 remote: added 1 changesets with 1 changes to 1 files
194 $ cd ../remote
194 $ cd ../remote
195
195
196 check remote tip
196 check remote tip
197
197
198 $ hg tip
198 $ hg tip
199 changeset: 3:a28a9d1a809c
199 changeset: 3:a28a9d1a809c
200 tag: tip
200 tag: tip
201 parent: 0:1160648e36ce
201 parent: 0:1160648e36ce
202 user: test
202 user: test
203 date: Thu Jan 01 00:00:00 1970 +0000
203 date: Thu Jan 01 00:00:00 1970 +0000
204 summary: add
204 summary: add
205
205
206 $ hg verify
206 $ hg verify
207 checking changesets
207 checking changesets
208 checking manifests
208 checking manifests
209 crosschecking files in changesets and manifests
209 crosschecking files in changesets and manifests
210 checking files
210 checking files
211 2 files, 4 changesets, 3 total revisions
211 2 files, 4 changesets, 3 total revisions
212 $ hg cat -r tip foo
212 $ hg cat -r tip foo
213 bleah
213 bleah
214 $ echo z > z
214 $ echo z > z
215 $ hg ci -A -m z z
215 $ hg ci -A -m z z
216 created new head
216 created new head
217
217
218 test pushkeys and bookmarks
218 test pushkeys and bookmarks
219
219
220 $ cd ../local
220 $ cd ../local
221 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
221 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
222 bookmarks
222 bookmarks
223 namespaces
223 namespaces
224 phases
224 phases
225 $ hg book foo -r 0
225 $ hg book foo -r 0
226 $ hg out -B
226 $ hg out -B
227 comparing with ssh://user@dummy/remote
227 comparing with ssh://user@dummy/remote
228 searching for changed bookmarks
228 searching for changed bookmarks
229 foo 1160648e36ce
229 foo 1160648e36ce
230 $ hg push -B foo
230 $ hg push -B foo
231 pushing to ssh://user@dummy/remote
231 pushing to ssh://user@dummy/remote
232 searching for changes
232 searching for changes
233 no changes found
233 no changes found
234 exporting bookmark foo
234 exporting bookmark foo
235 [1]
235 [1]
236 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
236 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
237 foo 1160648e36cec0054048a7edc4110c6f84fde594
237 foo 1160648e36cec0054048a7edc4110c6f84fde594
238 $ hg book -f foo
238 $ hg book -f foo
239 $ hg push --traceback
239 $ hg push --traceback
240 pushing to ssh://user@dummy/remote
240 pushing to ssh://user@dummy/remote
241 searching for changes
241 searching for changes
242 no changes found
242 no changes found
243 updating bookmark foo
243 updating bookmark foo
244 [1]
244 [1]
245 $ hg book -d foo
245 $ hg book -d foo
246 $ hg in -B
246 $ hg in -B
247 comparing with ssh://user@dummy/remote
247 comparing with ssh://user@dummy/remote
248 searching for changed bookmarks
248 searching for changed bookmarks
249 foo a28a9d1a809c
249 foo a28a9d1a809c
250 $ hg book -f -r 0 foo
250 $ hg book -f -r 0 foo
251 $ hg pull -B foo
251 $ hg pull -B foo
252 pulling from ssh://user@dummy/remote
252 pulling from ssh://user@dummy/remote
253 no changes found
253 no changes found
254 updating bookmark foo
254 updating bookmark foo
255 $ hg book -d foo
255 $ hg book -d foo
256 $ hg push -B foo
256 $ hg push -B foo
257 pushing to ssh://user@dummy/remote
257 pushing to ssh://user@dummy/remote
258 searching for changes
258 searching for changes
259 no changes found
259 no changes found
260 deleting remote bookmark foo
260 deleting remote bookmark foo
261 [1]
261 [1]
262
262
263 a bad, evil hook that prints to stdout
263 a bad, evil hook that prints to stdout
264
264
265 $ cat <<EOF > $TESTTMP/badhook
265 $ cat <<EOF > $TESTTMP/badhook
266 > import sys
266 > import sys
267 > sys.stdout.write("KABOOM\n")
267 > sys.stdout.write("KABOOM\n")
268 > EOF
268 > EOF
269
269
270 $ echo '[hooks]' >> ../remote/.hg/hgrc
270 $ echo '[hooks]' >> ../remote/.hg/hgrc
271 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
271 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
272 $ echo r > r
272 $ echo r > r
273 $ hg ci -A -m z r
273 $ hg ci -A -m z r
274
274
275 push should succeed even though it has an unexpected response
275 push should succeed even though it has an unexpected response
276
276
277 $ hg push
277 $ hg push
278 pushing to ssh://user@dummy/remote
278 pushing to ssh://user@dummy/remote
279 searching for changes
279 searching for changes
280 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
280 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
281 remote: adding changesets
281 remote: adding changesets
282 remote: adding manifests
282 remote: adding manifests
283 remote: adding file changes
283 remote: adding file changes
284 remote: added 1 changesets with 1 changes to 1 files
284 remote: added 1 changesets with 1 changes to 1 files
285 remote: KABOOM
285 remote: KABOOM
286 $ hg -R ../remote heads
286 $ hg -R ../remote heads
287 changeset: 5:1383141674ec
287 changeset: 5:1383141674ec
288 tag: tip
288 tag: tip
289 parent: 3:a28a9d1a809c
289 parent: 3:a28a9d1a809c
290 user: test
290 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
291 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: z
292 summary: z
293
293
294 changeset: 4:6c0482d977a3
294 changeset: 4:6c0482d977a3
295 parent: 0:1160648e36ce
295 parent: 0:1160648e36ce
296 user: test
296 user: test
297 date: Thu Jan 01 00:00:00 1970 +0000
297 date: Thu Jan 01 00:00:00 1970 +0000
298 summary: z
298 summary: z
299
299
300
300
301 clone bookmarks
301 clone bookmarks
302
302
303 $ hg -R ../remote bookmark test
303 $ hg -R ../remote bookmark test
304 $ hg -R ../remote bookmarks
304 $ hg -R ../remote bookmarks
305 * test 4:6c0482d977a3
305 * test 4:6c0482d977a3
306 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
306 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
307 requesting all changes
307 requesting all changes
308 adding changesets
308 adding changesets
309 adding manifests
309 adding manifests
310 adding file changes
310 adding file changes
311 added 6 changesets with 5 changes to 4 files (+1 heads)
311 added 6 changesets with 5 changes to 4 files (+1 heads)
312 updating to branch default
312 updating to branch default
313 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
313 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 $ hg -R local-bookmarks bookmarks
314 $ hg -R local-bookmarks bookmarks
315 test 4:6c0482d977a3
315 test 4:6c0482d977a3
316
316
317 passwords in ssh urls are not supported
317 passwords in ssh urls are not supported
318 (we use a glob here because different Python versions give different
318 (we use a glob here because different Python versions give different
319 results here)
319 results here)
320
320
321 $ hg push ssh://user:erroneouspwd@dummy/remote
321 $ hg push ssh://user:erroneouspwd@dummy/remote
322 pushing to ssh://user:*@dummy/remote (glob)
322 pushing to ssh://user:*@dummy/remote (glob)
323 abort: password in URL not supported!
323 abort: password in URL not supported!
324 [255]
324 [255]
325
325
326 $ cd ..
326 $ cd ..
327
327
328 hide outer repo
328 hide outer repo
329 $ hg init
329 $ hg init
330
330
331 Test remote paths with spaces (issue2983):
331 Test remote paths with spaces (issue2983):
332
332
333 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
333 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
334 $ touch "$TESTTMP/a repo/test"
334 $ touch "$TESTTMP/a repo/test"
335 $ hg -R 'a repo' commit -A -m "test"
335 $ hg -R 'a repo' commit -A -m "test"
336 adding test
336 adding test
337 $ hg -R 'a repo' tag tag
337 $ hg -R 'a repo' tag tag
338 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
338 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
339 73649e48688a
339 73649e48688a
340
340
341 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
341 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
342 abort: unknown revision 'noNoNO'!
342 abort: unknown revision 'noNoNO'!
343 [255]
343 [255]
344
344
345 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
345 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
346
346
347 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
347 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
348 destination directory: a repo
348 destination directory: a repo
349 abort: destination 'a repo' is not empty
349 abort: destination 'a repo' is not empty
350 [255]
350 [255]
351
351
352 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
352 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
353 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
353 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
354 parameters:
354 parameters:
355
355
356 $ cat > ssh.sh << EOF
356 $ cat > ssh.sh << EOF
357 > userhost="\$1"
357 > userhost="\$1"
358 > SSH_ORIGINAL_COMMAND="\$2"
358 > SSH_ORIGINAL_COMMAND="\$2"
359 > export SSH_ORIGINAL_COMMAND
359 > export SSH_ORIGINAL_COMMAND
360 > PYTHONPATH="$PYTHONPATH"
360 > PYTHONPATH="$PYTHONPATH"
361 > export PYTHONPATH
361 > export PYTHONPATH
362 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
362 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
363 > EOF
363 > EOF
364
364
365 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
365 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
366 73649e48688a
366 73649e48688a
367
367
368 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
368 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
369 remote: Illegal repository "$TESTTMP/a'repo" (glob)
369 remote: Illegal repository "$TESTTMP/a'repo" (glob)
370 abort: no suitable response from remote hg!
370 abort: no suitable response from remote hg!
371 [255]
371 [255]
372
372
373 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
373 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
374 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
374 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
375 abort: no suitable response from remote hg!
375 abort: no suitable response from remote hg!
376 [255]
376 [255]
377
377
378 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
378 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
379 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
379 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
380 [255]
380 [255]
381
381
382 Test hg-ssh in read-only mode:
382 Test hg-ssh in read-only mode:
383
383
384 $ cat > ssh.sh << EOF
384 $ cat > ssh.sh << EOF
385 > userhost="\$1"
385 > userhost="\$1"
386 > SSH_ORIGINAL_COMMAND="\$2"
386 > SSH_ORIGINAL_COMMAND="\$2"
387 > export SSH_ORIGINAL_COMMAND
387 > export SSH_ORIGINAL_COMMAND
388 > PYTHONPATH="$PYTHONPATH"
388 > PYTHONPATH="$PYTHONPATH"
389 > export PYTHONPATH
389 > export PYTHONPATH
390 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
390 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
391 > EOF
391 > EOF
392
392
393 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
393 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
394 requesting all changes
394 requesting all changes
395 adding changesets
395 adding changesets
396 adding manifests
396 adding manifests
397 adding file changes
397 adding file changes
398 added 6 changesets with 5 changes to 4 files (+1 heads)
398 added 6 changesets with 5 changes to 4 files (+1 heads)
399 updating to branch default
399 updating to branch default
400 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
400 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
401
401
402 $ cd read-only-local
402 $ cd read-only-local
403 $ echo "baz" > bar
403 $ echo "baz" > bar
404 $ hg ci -A -m "unpushable commit" bar
404 $ hg ci -A -m "unpushable commit" bar
405 $ hg push --ssh "sh ../ssh.sh"
405 $ hg push --ssh "sh ../ssh.sh"
406 pushing to ssh://user@dummy/*/remote (glob)
406 pushing to ssh://user@dummy/*/remote (glob)
407 searching for changes
407 searching for changes
408 remote: Permission denied
408 remote: Permission denied
409 remote: abort: pretxnopen.hg-ssh hook failed
409 remote: abort: pretxnopen.hg-ssh hook failed
410 remote: Permission denied
410 remote: Permission denied
411 remote: pushkey-abort: prepushkey.hg-ssh hook failed
411 remote: pushkey-abort: prepushkey.hg-ssh hook failed
412 updating 6c0482d977a3 to public failed!
412 updating 6c0482d977a3 to public failed!
413 [1]
413 [1]
414
414
415 $ cd ..
415 $ cd ..
416
416
417 stderr from remote commands should be printed before stdout from local code (issue4336)
417 stderr from remote commands should be printed before stdout from local code (issue4336)
418
418
419 $ hg clone remote stderr-ordering
419 $ hg clone remote stderr-ordering
420 updating to branch default
420 updating to branch default
421 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
421 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 $ cd stderr-ordering
422 $ cd stderr-ordering
423 $ cat >> localwrite.py << EOF
423 $ cat >> localwrite.py << EOF
424 > from mercurial import exchange, extensions
424 > from mercurial import exchange, extensions
425 >
425 >
426 > def wrappedpush(orig, repo, *args, **kwargs):
426 > def wrappedpush(orig, repo, *args, **kwargs):
427 > res = orig(repo, *args, **kwargs)
427 > res = orig(repo, *args, **kwargs)
428 > repo.ui.write('local stdout\n')
428 > repo.ui.write('local stdout\n')
429 > return res
429 > return res
430 >
430 >
431 > def extsetup(ui):
431 > def extsetup(ui):
432 > extensions.wrapfunction(exchange, 'push', wrappedpush)
432 > extensions.wrapfunction(exchange, 'push', wrappedpush)
433 > EOF
433 > EOF
434
434
435 $ cat >> .hg/hgrc << EOF
435 $ cat >> .hg/hgrc << EOF
436 > [paths]
436 > [paths]
437 > default-push = ssh://user@dummy/remote
437 > default-push = ssh://user@dummy/remote
438 > [ui]
438 > [ui]
439 > ssh = python "$TESTDIR/dummyssh"
439 > ssh = python "$TESTDIR/dummyssh"
440 > [extensions]
440 > [extensions]
441 > localwrite = localwrite.py
441 > localwrite = localwrite.py
442 > EOF
442 > EOF
443
443
444 $ echo localwrite > foo
444 $ echo localwrite > foo
445 $ hg commit -m 'testing localwrite'
445 $ hg commit -m 'testing localwrite'
446 $ hg push
446 $ hg push
447 pushing to ssh://user@dummy/remote
447 pushing to ssh://user@dummy/remote
448 searching for changes
448 searching for changes
449 remote: adding changesets
449 remote: adding changesets
450 remote: adding manifests
450 remote: adding manifests
451 remote: adding file changes
451 remote: adding file changes
452 remote: added 1 changesets with 1 changes to 1 files
452 remote: added 1 changesets with 1 changes to 1 files
453 remote: KABOOM
453 remote: KABOOM
454 local stdout
454 local stdout
455
455
456 debug output
456 debug output
457
457
458 $ hg pull --debug ssh://user@dummy/remote
458 $ hg pull --debug ssh://user@dummy/remote
459 pulling from ssh://user@dummy/remote
459 pulling from ssh://user@dummy/remote
460 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
460 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
461 sending hello command
461 sending hello command
462 sending between command
462 sending between command
463 remote: 345
463 remote: 345
464 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
464 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
465 remote: 1
465 remote: 1
466 preparing listkeys for "bookmarks"
466 preparing listkeys for "bookmarks"
467 sending listkeys command
467 sending listkeys command
468 received listkey for "bookmarks": 45 bytes
468 received listkey for "bookmarks": 45 bytes
469 query 1; heads
469 query 1; heads
470 sending batch command
470 sending batch command
471 searching for changes
471 searching for changes
472 all remote heads known locally
472 all remote heads known locally
473 no changes found
473 no changes found
474 preparing listkeys for "phases"
474 preparing listkeys for "phases"
475 sending listkeys command
475 sending listkeys command
476 received listkey for "phases": 15 bytes
476 received listkey for "phases": 15 bytes
477 checking for updated bookmarks
477 checking for updated bookmarks
478
478
479 $ cd ..
479 $ cd ..
480
480
481 $ cat dummylog
481 $ cat dummylog
482 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
482 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
483 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
483 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
484 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
484 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
485 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
485 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
486 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
486 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
487 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
487 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
488 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
488 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
489 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
489 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
490 Got arguments 1:user@dummy 2:hg -R local serve --stdio
490 Got arguments 1:user@dummy 2:hg -R local serve --stdio
491 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
491 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
492 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
492 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
493 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
493 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
494 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
494 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
495 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
495 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
496 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
496 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
497 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
497 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
498 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
498 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
499 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
499 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
500 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
500 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
501 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
501 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
502 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
502 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
503 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
503 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
504 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
504 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
505 Got arguments 1:user@dummy 2:hg init 'a repo'
505 Got arguments 1:user@dummy 2:hg init 'a repo'
506 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
506 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
507 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
507 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
508 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
508 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
509 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
509 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
510 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
510 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
511 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
511 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
512 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
512 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
@@ -1,503 +1,503 b''
1
1
2 This test tries to exercise the ssh functionality with a dummy script
2 This test tries to exercise the ssh functionality with a dummy script
3
3
4 creating 'remote' repo
4 creating 'remote' repo
5
5
6 $ hg init remote
6 $ hg init remote
7 $ cd remote
7 $ cd remote
8 $ echo this > foo
8 $ echo this > foo
9 $ echo this > fooO
9 $ echo this > fooO
10 $ hg ci -A -m "init" foo fooO
10 $ hg ci -A -m "init" foo fooO
11
11
12 insert a closed branch (issue4428)
12 insert a closed branch (issue4428)
13
13
14 $ hg up null
14 $ hg up null
15 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
15 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 $ hg branch closed
16 $ hg branch closed
17 marked working directory as branch closed
17 marked working directory as branch closed
18 (branches are permanent and global, did you want a bookmark?)
18 (branches are permanent and global, did you want a bookmark?)
19 $ hg ci -mc0
19 $ hg ci -mc0
20 $ hg ci --close-branch -mc1
20 $ hg ci --close-branch -mc1
21 $ hg up -q default
21 $ hg up -q default
22
22
23 configure for serving
23 configure for serving
24
24
25 $ cat <<EOF > .hg/hgrc
25 $ cat <<EOF > .hg/hgrc
26 > [server]
26 > [server]
27 > uncompressed = True
27 > uncompressed = True
28 >
28 >
29 > [hooks]
29 > [hooks]
30 > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
30 > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
31 > EOF
31 > EOF
32 $ cd ..
32 $ cd ..
33
33
34 repo not found error
34 repo not found error
35
35
36 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
36 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
37 remote: abort: there is no Mercurial repository here (.hg not found)!
37 remote: abort: repository nonexistent not found!
38 abort: no suitable response from remote hg!
38 abort: no suitable response from remote hg!
39 [255]
39 [255]
40
40
41 non-existent absolute path
41 non-existent absolute path
42
42
43 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
43 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
44 remote: abort: there is no Mercurial repository here (.hg not found)!
44 remote: abort: repository $TESTTMP/nonexistent not found!
45 abort: no suitable response from remote hg!
45 abort: no suitable response from remote hg!
46 [255]
46 [255]
47
47
48 clone remote via stream
48 clone remote via stream
49
49
50 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
50 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
51 streaming all changes
51 streaming all changes
52 4 files to transfer, 615 bytes of data
52 4 files to transfer, 615 bytes of data
53 transferred 615 bytes in * seconds (*) (glob)
53 transferred 615 bytes in * seconds (*) (glob)
54 searching for changes
54 searching for changes
55 no changes found
55 no changes found
56 updating to branch default
56 updating to branch default
57 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 $ cd local-stream
58 $ cd local-stream
59 $ hg verify
59 $ hg verify
60 checking changesets
60 checking changesets
61 checking manifests
61 checking manifests
62 crosschecking files in changesets and manifests
62 crosschecking files in changesets and manifests
63 checking files
63 checking files
64 2 files, 3 changesets, 2 total revisions
64 2 files, 3 changesets, 2 total revisions
65 $ hg branches
65 $ hg branches
66 default 0:1160648e36ce
66 default 0:1160648e36ce
67 $ cd ..
67 $ cd ..
68
68
69 clone bookmarks via stream
69 clone bookmarks via stream
70
70
71 $ hg -R local-stream book mybook
71 $ hg -R local-stream book mybook
72 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
72 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/local-stream stream2
73 streaming all changes
73 streaming all changes
74 4 files to transfer, 615 bytes of data
74 4 files to transfer, 615 bytes of data
75 transferred 615 bytes in * seconds (*) (glob)
75 transferred 615 bytes in * seconds (*) (glob)
76 searching for changes
76 searching for changes
77 no changes found
77 no changes found
78 updating to branch default
78 updating to branch default
79 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 $ cd stream2
80 $ cd stream2
81 $ hg book
81 $ hg book
82 mybook 0:1160648e36ce
82 mybook 0:1160648e36ce
83 $ cd ..
83 $ cd ..
84 $ rm -rf local-stream stream2
84 $ rm -rf local-stream stream2
85
85
86 clone remote via pull
86 clone remote via pull
87
87
88 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
88 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
89 requesting all changes
89 requesting all changes
90 adding changesets
90 adding changesets
91 adding manifests
91 adding manifests
92 adding file changes
92 adding file changes
93 added 3 changesets with 2 changes to 2 files
93 added 3 changesets with 2 changes to 2 files
94 updating to branch default
94 updating to branch default
95 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
95 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
96
96
97 verify
97 verify
98
98
99 $ cd local
99 $ cd local
100 $ hg verify
100 $ hg verify
101 checking changesets
101 checking changesets
102 checking manifests
102 checking manifests
103 crosschecking files in changesets and manifests
103 crosschecking files in changesets and manifests
104 checking files
104 checking files
105 2 files, 3 changesets, 2 total revisions
105 2 files, 3 changesets, 2 total revisions
106 $ echo '[hooks]' >> .hg/hgrc
106 $ echo '[hooks]' >> .hg/hgrc
107 $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
107 $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
108
108
109 empty default pull
109 empty default pull
110
110
111 $ hg paths
111 $ hg paths
112 default = ssh://user@dummy/remote
112 default = ssh://user@dummy/remote
113 $ hg pull -e "python \"$TESTDIR/dummyssh\""
113 $ hg pull -e "python \"$TESTDIR/dummyssh\""
114 pulling from ssh://user@dummy/remote
114 pulling from ssh://user@dummy/remote
115 searching for changes
115 searching for changes
116 no changes found
116 no changes found
117
117
118 pull from wrong ssh URL
118 pull from wrong ssh URL
119
119
120 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
120 $ hg pull -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
121 pulling from ssh://user@dummy/doesnotexist
121 pulling from ssh://user@dummy/doesnotexist
122 remote: abort: there is no Mercurial repository here (.hg not found)!
122 remote: abort: repository doesnotexist not found!
123 abort: no suitable response from remote hg!
123 abort: no suitable response from remote hg!
124 [255]
124 [255]
125
125
126 local change
126 local change
127
127
128 $ echo bleah > foo
128 $ echo bleah > foo
129 $ hg ci -m "add"
129 $ hg ci -m "add"
130
130
131 updating rc
131 updating rc
132
132
133 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
133 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
134 $ echo "[ui]" >> .hg/hgrc
134 $ echo "[ui]" >> .hg/hgrc
135 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
135 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
136
136
137 find outgoing
137 find outgoing
138
138
139 $ hg out ssh://user@dummy/remote
139 $ hg out ssh://user@dummy/remote
140 comparing with ssh://user@dummy/remote
140 comparing with ssh://user@dummy/remote
141 searching for changes
141 searching for changes
142 changeset: 3:a28a9d1a809c
142 changeset: 3:a28a9d1a809c
143 tag: tip
143 tag: tip
144 parent: 0:1160648e36ce
144 parent: 0:1160648e36ce
145 user: test
145 user: test
146 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
147 summary: add
147 summary: add
148
148
149
149
150 find incoming on the remote side
150 find incoming on the remote side
151
151
152 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
152 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
153 comparing with ssh://user@dummy/local
153 comparing with ssh://user@dummy/local
154 searching for changes
154 searching for changes
155 changeset: 3:a28a9d1a809c
155 changeset: 3:a28a9d1a809c
156 tag: tip
156 tag: tip
157 parent: 0:1160648e36ce
157 parent: 0:1160648e36ce
158 user: test
158 user: test
159 date: Thu Jan 01 00:00:00 1970 +0000
159 date: Thu Jan 01 00:00:00 1970 +0000
160 summary: add
160 summary: add
161
161
162
162
163 find incoming on the remote side (using absolute path)
163 find incoming on the remote side (using absolute path)
164
164
165 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
165 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
166 comparing with ssh://user@dummy/$TESTTMP/local
166 comparing with ssh://user@dummy/$TESTTMP/local
167 searching for changes
167 searching for changes
168 changeset: 3:a28a9d1a809c
168 changeset: 3:a28a9d1a809c
169 tag: tip
169 tag: tip
170 parent: 0:1160648e36ce
170 parent: 0:1160648e36ce
171 user: test
171 user: test
172 date: Thu Jan 01 00:00:00 1970 +0000
172 date: Thu Jan 01 00:00:00 1970 +0000
173 summary: add
173 summary: add
174
174
175
175
176 push
176 push
177
177
178 $ hg push
178 $ hg push
179 pushing to ssh://user@dummy/remote
179 pushing to ssh://user@dummy/remote
180 searching for changes
180 searching for changes
181 remote: adding changesets
181 remote: adding changesets
182 remote: adding manifests
182 remote: adding manifests
183 remote: adding file changes
183 remote: adding file changes
184 remote: added 1 changesets with 1 changes to 1 files
184 remote: added 1 changesets with 1 changes to 1 files
185 $ cd ../remote
185 $ cd ../remote
186
186
187 check remote tip
187 check remote tip
188
188
189 $ hg tip
189 $ hg tip
190 changeset: 3:a28a9d1a809c
190 changeset: 3:a28a9d1a809c
191 tag: tip
191 tag: tip
192 parent: 0:1160648e36ce
192 parent: 0:1160648e36ce
193 user: test
193 user: test
194 date: Thu Jan 01 00:00:00 1970 +0000
194 date: Thu Jan 01 00:00:00 1970 +0000
195 summary: add
195 summary: add
196
196
197 $ hg verify
197 $ hg verify
198 checking changesets
198 checking changesets
199 checking manifests
199 checking manifests
200 crosschecking files in changesets and manifests
200 crosschecking files in changesets and manifests
201 checking files
201 checking files
202 2 files, 4 changesets, 3 total revisions
202 2 files, 4 changesets, 3 total revisions
203 $ hg cat -r tip foo
203 $ hg cat -r tip foo
204 bleah
204 bleah
205 $ echo z > z
205 $ echo z > z
206 $ hg ci -A -m z z
206 $ hg ci -A -m z z
207 created new head
207 created new head
208
208
209 test pushkeys and bookmarks
209 test pushkeys and bookmarks
210
210
211 $ cd ../local
211 $ cd ../local
212 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
212 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
213 bookmarks
213 bookmarks
214 namespaces
214 namespaces
215 phases
215 phases
216 $ hg book foo -r 0
216 $ hg book foo -r 0
217 $ hg out -B
217 $ hg out -B
218 comparing with ssh://user@dummy/remote
218 comparing with ssh://user@dummy/remote
219 searching for changed bookmarks
219 searching for changed bookmarks
220 foo 1160648e36ce
220 foo 1160648e36ce
221 $ hg push -B foo
221 $ hg push -B foo
222 pushing to ssh://user@dummy/remote
222 pushing to ssh://user@dummy/remote
223 searching for changes
223 searching for changes
224 no changes found
224 no changes found
225 exporting bookmark foo
225 exporting bookmark foo
226 [1]
226 [1]
227 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
227 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
228 foo 1160648e36cec0054048a7edc4110c6f84fde594
228 foo 1160648e36cec0054048a7edc4110c6f84fde594
229 $ hg book -f foo
229 $ hg book -f foo
230 $ hg push --traceback
230 $ hg push --traceback
231 pushing to ssh://user@dummy/remote
231 pushing to ssh://user@dummy/remote
232 searching for changes
232 searching for changes
233 no changes found
233 no changes found
234 updating bookmark foo
234 updating bookmark foo
235 [1]
235 [1]
236 $ hg book -d foo
236 $ hg book -d foo
237 $ hg in -B
237 $ hg in -B
238 comparing with ssh://user@dummy/remote
238 comparing with ssh://user@dummy/remote
239 searching for changed bookmarks
239 searching for changed bookmarks
240 foo a28a9d1a809c
240 foo a28a9d1a809c
241 $ hg book -f -r 0 foo
241 $ hg book -f -r 0 foo
242 $ hg pull -B foo
242 $ hg pull -B foo
243 pulling from ssh://user@dummy/remote
243 pulling from ssh://user@dummy/remote
244 no changes found
244 no changes found
245 updating bookmark foo
245 updating bookmark foo
246 $ hg book -d foo
246 $ hg book -d foo
247 $ hg push -B foo
247 $ hg push -B foo
248 pushing to ssh://user@dummy/remote
248 pushing to ssh://user@dummy/remote
249 searching for changes
249 searching for changes
250 no changes found
250 no changes found
251 deleting remote bookmark foo
251 deleting remote bookmark foo
252 [1]
252 [1]
253
253
254 a bad, evil hook that prints to stdout
254 a bad, evil hook that prints to stdout
255
255
256 $ cat <<EOF > $TESTTMP/badhook
256 $ cat <<EOF > $TESTTMP/badhook
257 > import sys
257 > import sys
258 > sys.stdout.write("KABOOM\n")
258 > sys.stdout.write("KABOOM\n")
259 > EOF
259 > EOF
260
260
261 $ echo '[hooks]' >> ../remote/.hg/hgrc
261 $ echo '[hooks]' >> ../remote/.hg/hgrc
262 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
262 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
263 $ echo r > r
263 $ echo r > r
264 $ hg ci -A -m z r
264 $ hg ci -A -m z r
265
265
266 push should succeed even though it has an unexpected response
266 push should succeed even though it has an unexpected response
267
267
268 $ hg push
268 $ hg push
269 pushing to ssh://user@dummy/remote
269 pushing to ssh://user@dummy/remote
270 searching for changes
270 searching for changes
271 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
271 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
272 remote: adding changesets
272 remote: adding changesets
273 remote: adding manifests
273 remote: adding manifests
274 remote: adding file changes
274 remote: adding file changes
275 remote: added 1 changesets with 1 changes to 1 files
275 remote: added 1 changesets with 1 changes to 1 files
276 remote: KABOOM
276 remote: KABOOM
277 $ hg -R ../remote heads
277 $ hg -R ../remote heads
278 changeset: 5:1383141674ec
278 changeset: 5:1383141674ec
279 tag: tip
279 tag: tip
280 parent: 3:a28a9d1a809c
280 parent: 3:a28a9d1a809c
281 user: test
281 user: test
282 date: Thu Jan 01 00:00:00 1970 +0000
282 date: Thu Jan 01 00:00:00 1970 +0000
283 summary: z
283 summary: z
284
284
285 changeset: 4:6c0482d977a3
285 changeset: 4:6c0482d977a3
286 parent: 0:1160648e36ce
286 parent: 0:1160648e36ce
287 user: test
287 user: test
288 date: Thu Jan 01 00:00:00 1970 +0000
288 date: Thu Jan 01 00:00:00 1970 +0000
289 summary: z
289 summary: z
290
290
291
291
292 clone bookmarks
292 clone bookmarks
293
293
294 $ hg -R ../remote bookmark test
294 $ hg -R ../remote bookmark test
295 $ hg -R ../remote bookmarks
295 $ hg -R ../remote bookmarks
296 * test 4:6c0482d977a3
296 * test 4:6c0482d977a3
297 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
297 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
298 requesting all changes
298 requesting all changes
299 adding changesets
299 adding changesets
300 adding manifests
300 adding manifests
301 adding file changes
301 adding file changes
302 added 6 changesets with 5 changes to 4 files (+1 heads)
302 added 6 changesets with 5 changes to 4 files (+1 heads)
303 updating to branch default
303 updating to branch default
304 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 $ hg -R local-bookmarks bookmarks
305 $ hg -R local-bookmarks bookmarks
306 test 4:6c0482d977a3
306 test 4:6c0482d977a3
307
307
308 passwords in ssh urls are not supported
308 passwords in ssh urls are not supported
309 (we use a glob here because different Python versions give different
309 (we use a glob here because different Python versions give different
310 results here)
310 results here)
311
311
312 $ hg push ssh://user:erroneouspwd@dummy/remote
312 $ hg push ssh://user:erroneouspwd@dummy/remote
313 pushing to ssh://user:*@dummy/remote (glob)
313 pushing to ssh://user:*@dummy/remote (glob)
314 abort: password in URL not supported!
314 abort: password in URL not supported!
315 [255]
315 [255]
316
316
317 $ cd ..
317 $ cd ..
318
318
319 hide outer repo
319 hide outer repo
320 $ hg init
320 $ hg init
321
321
322 Test remote paths with spaces (issue2983):
322 Test remote paths with spaces (issue2983):
323
323
324 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
324 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
325 $ touch "$TESTTMP/a repo/test"
325 $ touch "$TESTTMP/a repo/test"
326 $ hg -R 'a repo' commit -A -m "test"
326 $ hg -R 'a repo' commit -A -m "test"
327 adding test
327 adding test
328 $ hg -R 'a repo' tag tag
328 $ hg -R 'a repo' tag tag
329 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
329 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
330 73649e48688a
330 73649e48688a
331
331
332 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
332 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
333 abort: unknown revision 'noNoNO'!
333 abort: unknown revision 'noNoNO'!
334 [255]
334 [255]
335
335
336 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
336 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
337
337
338 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
338 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
339 destination directory: a repo
339 destination directory: a repo
340 abort: destination 'a repo' is not empty
340 abort: destination 'a repo' is not empty
341 [255]
341 [255]
342
342
343 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
343 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
344 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
344 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
345 parameters:
345 parameters:
346
346
347 $ cat > ssh.sh << EOF
347 $ cat > ssh.sh << EOF
348 > userhost="\$1"
348 > userhost="\$1"
349 > SSH_ORIGINAL_COMMAND="\$2"
349 > SSH_ORIGINAL_COMMAND="\$2"
350 > export SSH_ORIGINAL_COMMAND
350 > export SSH_ORIGINAL_COMMAND
351 > PYTHONPATH="$PYTHONPATH"
351 > PYTHONPATH="$PYTHONPATH"
352 > export PYTHONPATH
352 > export PYTHONPATH
353 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
353 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
354 > EOF
354 > EOF
355
355
356 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
356 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
357 73649e48688a
357 73649e48688a
358
358
359 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
359 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
360 remote: Illegal repository "$TESTTMP/a'repo" (glob)
360 remote: Illegal repository "$TESTTMP/a'repo" (glob)
361 abort: no suitable response from remote hg!
361 abort: no suitable response from remote hg!
362 [255]
362 [255]
363
363
364 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
364 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
365 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
365 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
366 abort: no suitable response from remote hg!
366 abort: no suitable response from remote hg!
367 [255]
367 [255]
368
368
369 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
369 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
370 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
370 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
371 [255]
371 [255]
372
372
373 Test hg-ssh in read-only mode:
373 Test hg-ssh in read-only mode:
374
374
375 $ cat > ssh.sh << EOF
375 $ cat > ssh.sh << EOF
376 > userhost="\$1"
376 > userhost="\$1"
377 > SSH_ORIGINAL_COMMAND="\$2"
377 > SSH_ORIGINAL_COMMAND="\$2"
378 > export SSH_ORIGINAL_COMMAND
378 > export SSH_ORIGINAL_COMMAND
379 > PYTHONPATH="$PYTHONPATH"
379 > PYTHONPATH="$PYTHONPATH"
380 > export PYTHONPATH
380 > export PYTHONPATH
381 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
381 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
382 > EOF
382 > EOF
383
383
384 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
384 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
385 requesting all changes
385 requesting all changes
386 adding changesets
386 adding changesets
387 adding manifests
387 adding manifests
388 adding file changes
388 adding file changes
389 added 6 changesets with 5 changes to 4 files (+1 heads)
389 added 6 changesets with 5 changes to 4 files (+1 heads)
390 updating to branch default
390 updating to branch default
391 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
391 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
392
392
393 $ cd read-only-local
393 $ cd read-only-local
394 $ echo "baz" > bar
394 $ echo "baz" > bar
395 $ hg ci -A -m "unpushable commit" bar
395 $ hg ci -A -m "unpushable commit" bar
396 $ hg push --ssh "sh ../ssh.sh"
396 $ hg push --ssh "sh ../ssh.sh"
397 pushing to ssh://user@dummy/*/remote (glob)
397 pushing to ssh://user@dummy/*/remote (glob)
398 searching for changes
398 searching for changes
399 remote: Permission denied
399 remote: Permission denied
400 abort: pretxnopen.hg-ssh hook failed
400 abort: pretxnopen.hg-ssh hook failed
401 [255]
401 [255]
402
402
403 $ cd ..
403 $ cd ..
404
404
405 stderr from remote commands should be printed before stdout from local code (issue4336)
405 stderr from remote commands should be printed before stdout from local code (issue4336)
406
406
407 $ hg clone remote stderr-ordering
407 $ hg clone remote stderr-ordering
408 updating to branch default
408 updating to branch default
409 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
410 $ cd stderr-ordering
410 $ cd stderr-ordering
411 $ cat >> localwrite.py << EOF
411 $ cat >> localwrite.py << EOF
412 > from mercurial import exchange, extensions
412 > from mercurial import exchange, extensions
413 >
413 >
414 > def wrappedpush(orig, repo, *args, **kwargs):
414 > def wrappedpush(orig, repo, *args, **kwargs):
415 > res = orig(repo, *args, **kwargs)
415 > res = orig(repo, *args, **kwargs)
416 > repo.ui.write('local stdout\n')
416 > repo.ui.write('local stdout\n')
417 > return res
417 > return res
418 >
418 >
419 > def extsetup(ui):
419 > def extsetup(ui):
420 > extensions.wrapfunction(exchange, 'push', wrappedpush)
420 > extensions.wrapfunction(exchange, 'push', wrappedpush)
421 > EOF
421 > EOF
422
422
423 $ cat >> .hg/hgrc << EOF
423 $ cat >> .hg/hgrc << EOF
424 > [paths]
424 > [paths]
425 > default-push = ssh://user@dummy/remote
425 > default-push = ssh://user@dummy/remote
426 > [ui]
426 > [ui]
427 > ssh = python "$TESTDIR/dummyssh"
427 > ssh = python "$TESTDIR/dummyssh"
428 > [extensions]
428 > [extensions]
429 > localwrite = localwrite.py
429 > localwrite = localwrite.py
430 > EOF
430 > EOF
431
431
432 $ echo localwrite > foo
432 $ echo localwrite > foo
433 $ hg commit -m 'testing localwrite'
433 $ hg commit -m 'testing localwrite'
434 $ hg push
434 $ hg push
435 pushing to ssh://user@dummy/remote
435 pushing to ssh://user@dummy/remote
436 searching for changes
436 searching for changes
437 remote: adding changesets
437 remote: adding changesets
438 remote: adding manifests
438 remote: adding manifests
439 remote: adding file changes
439 remote: adding file changes
440 remote: added 1 changesets with 1 changes to 1 files
440 remote: added 1 changesets with 1 changes to 1 files
441 remote: KABOOM
441 remote: KABOOM
442 local stdout
442 local stdout
443
443
444 debug output
444 debug output
445
445
446 $ hg pull --debug ssh://user@dummy/remote
446 $ hg pull --debug ssh://user@dummy/remote
447 pulling from ssh://user@dummy/remote
447 pulling from ssh://user@dummy/remote
448 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
448 running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
449 sending hello command
449 sending hello command
450 sending between command
450 sending between command
451 remote: 345
451 remote: 345
452 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
452 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
453 remote: 1
453 remote: 1
454 query 1; heads
454 query 1; heads
455 sending batch command
455 sending batch command
456 searching for changes
456 searching for changes
457 all remote heads known locally
457 all remote heads known locally
458 no changes found
458 no changes found
459 sending getbundle command
459 sending getbundle command
460 bundle2-input-bundle: with-transaction
460 bundle2-input-bundle: with-transaction
461 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
461 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
462 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
462 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
463 bundle2-input-part: total payload size 45
463 bundle2-input-part: total payload size 45
464 bundle2-input-bundle: 1 parts total
464 bundle2-input-bundle: 1 parts total
465 checking for updated bookmarks
465 checking for updated bookmarks
466 preparing listkeys for "phases"
466 preparing listkeys for "phases"
467 sending listkeys command
467 sending listkeys command
468 received listkey for "phases": 15 bytes
468 received listkey for "phases": 15 bytes
469
469
470 $ cd ..
470 $ cd ..
471
471
472 $ cat dummylog
472 $ cat dummylog
473 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
473 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
474 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
474 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
475 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
475 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
476 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
476 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio
477 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
477 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
478 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
478 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
479 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
479 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
480 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
480 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
481 Got arguments 1:user@dummy 2:hg -R local serve --stdio
481 Got arguments 1:user@dummy 2:hg -R local serve --stdio
482 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
482 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
483 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
483 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
484 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
484 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
485 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
485 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
486 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
486 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
487 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
487 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
488 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
488 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
489 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
489 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
490 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
490 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
491 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
491 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
492 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
492 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
493 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
493 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
494 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
494 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
495 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
495 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
496 Got arguments 1:user@dummy 2:hg init 'a repo'
496 Got arguments 1:user@dummy 2:hg init 'a repo'
497 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
497 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
498 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
498 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
499 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
499 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
500 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
500 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
501 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
501 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
502 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
502 changegroup-in-remote hook: HG_BUNDLE2=1 HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:ssh:127.0.0.1 (glob)
503 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
503 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
General Comments 0
You need to be logged in to leave comments. Login now