##// END OF EJS Templates
debugcommands: support for sending "batch" requests...
Gregory Szorc -
r36548:097ad107 default
parent child Browse files
Show More
@@ -1,2772 +1,2811 b''
1 # debugcommands.py - command processing for debug* commands
1 # debugcommands.py - command processing for debug* commands
2 #
2 #
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import codecs
10 import codecs
11 import collections
11 import collections
12 import difflib
12 import difflib
13 import errno
13 import errno
14 import operator
14 import operator
15 import os
15 import os
16 import random
16 import random
17 import socket
17 import socket
18 import ssl
18 import ssl
19 import string
19 import string
20 import subprocess
20 import subprocess
21 import sys
21 import sys
22 import tempfile
22 import tempfile
23 import time
23 import time
24
24
25 from .i18n import _
25 from .i18n import _
26 from .node import (
26 from .node import (
27 bin,
27 bin,
28 hex,
28 hex,
29 nullhex,
29 nullhex,
30 nullid,
30 nullid,
31 nullrev,
31 nullrev,
32 short,
32 short,
33 )
33 )
34 from . import (
34 from . import (
35 bundle2,
35 bundle2,
36 changegroup,
36 changegroup,
37 cmdutil,
37 cmdutil,
38 color,
38 color,
39 context,
39 context,
40 dagparser,
40 dagparser,
41 dagutil,
41 dagutil,
42 encoding,
42 encoding,
43 error,
43 error,
44 exchange,
44 exchange,
45 extensions,
45 extensions,
46 filemerge,
46 filemerge,
47 fileset,
47 fileset,
48 formatter,
48 formatter,
49 hg,
49 hg,
50 localrepo,
50 localrepo,
51 lock as lockmod,
51 lock as lockmod,
52 logcmdutil,
52 logcmdutil,
53 merge as mergemod,
53 merge as mergemod,
54 obsolete,
54 obsolete,
55 obsutil,
55 obsutil,
56 phases,
56 phases,
57 policy,
57 policy,
58 pvec,
58 pvec,
59 pycompat,
59 pycompat,
60 registrar,
60 registrar,
61 repair,
61 repair,
62 revlog,
62 revlog,
63 revset,
63 revset,
64 revsetlang,
64 revsetlang,
65 scmutil,
65 scmutil,
66 setdiscovery,
66 setdiscovery,
67 simplemerge,
67 simplemerge,
68 smartset,
68 smartset,
69 sshpeer,
69 sshpeer,
70 sslutil,
70 sslutil,
71 streamclone,
71 streamclone,
72 templater,
72 templater,
73 treediscovery,
73 treediscovery,
74 upgrade,
74 upgrade,
75 url as urlmod,
75 url as urlmod,
76 util,
76 util,
77 vfs as vfsmod,
77 vfs as vfsmod,
78 wireprotoserver,
78 wireprotoserver,
79 )
79 )
80
80
81 release = lockmod.release
81 release = lockmod.release
82
82
83 command = registrar.command()
83 command = registrar.command()
84
84
85 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
85 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
86 def debugancestor(ui, repo, *args):
86 def debugancestor(ui, repo, *args):
87 """find the ancestor revision of two revisions in a given index"""
87 """find the ancestor revision of two revisions in a given index"""
88 if len(args) == 3:
88 if len(args) == 3:
89 index, rev1, rev2 = args
89 index, rev1, rev2 = args
90 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
90 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
91 lookup = r.lookup
91 lookup = r.lookup
92 elif len(args) == 2:
92 elif len(args) == 2:
93 if not repo:
93 if not repo:
94 raise error.Abort(_('there is no Mercurial repository here '
94 raise error.Abort(_('there is no Mercurial repository here '
95 '(.hg not found)'))
95 '(.hg not found)'))
96 rev1, rev2 = args
96 rev1, rev2 = args
97 r = repo.changelog
97 r = repo.changelog
98 lookup = repo.lookup
98 lookup = repo.lookup
99 else:
99 else:
100 raise error.Abort(_('either two or three arguments required'))
100 raise error.Abort(_('either two or three arguments required'))
101 a = r.ancestor(lookup(rev1), lookup(rev2))
101 a = r.ancestor(lookup(rev1), lookup(rev2))
102 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
102 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
103
103
104 @command('debugapplystreamclonebundle', [], 'FILE')
104 @command('debugapplystreamclonebundle', [], 'FILE')
105 def debugapplystreamclonebundle(ui, repo, fname):
105 def debugapplystreamclonebundle(ui, repo, fname):
106 """apply a stream clone bundle file"""
106 """apply a stream clone bundle file"""
107 f = hg.openpath(ui, fname)
107 f = hg.openpath(ui, fname)
108 gen = exchange.readbundle(ui, f, fname)
108 gen = exchange.readbundle(ui, f, fname)
109 gen.apply(repo)
109 gen.apply(repo)
110
110
111 @command('debugbuilddag',
111 @command('debugbuilddag',
112 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
112 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
113 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
113 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
114 ('n', 'new-file', None, _('add new file at each rev'))],
114 ('n', 'new-file', None, _('add new file at each rev'))],
115 _('[OPTION]... [TEXT]'))
115 _('[OPTION]... [TEXT]'))
116 def debugbuilddag(ui, repo, text=None,
116 def debugbuilddag(ui, repo, text=None,
117 mergeable_file=False,
117 mergeable_file=False,
118 overwritten_file=False,
118 overwritten_file=False,
119 new_file=False):
119 new_file=False):
120 """builds a repo with a given DAG from scratch in the current empty repo
120 """builds a repo with a given DAG from scratch in the current empty repo
121
121
122 The description of the DAG is read from stdin if not given on the
122 The description of the DAG is read from stdin if not given on the
123 command line.
123 command line.
124
124
125 Elements:
125 Elements:
126
126
127 - "+n" is a linear run of n nodes based on the current default parent
127 - "+n" is a linear run of n nodes based on the current default parent
128 - "." is a single node based on the current default parent
128 - "." is a single node based on the current default parent
129 - "$" resets the default parent to null (implied at the start);
129 - "$" resets the default parent to null (implied at the start);
130 otherwise the default parent is always the last node created
130 otherwise the default parent is always the last node created
131 - "<p" sets the default parent to the backref p
131 - "<p" sets the default parent to the backref p
132 - "*p" is a fork at parent p, which is a backref
132 - "*p" is a fork at parent p, which is a backref
133 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
133 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
134 - "/p2" is a merge of the preceding node and p2
134 - "/p2" is a merge of the preceding node and p2
135 - ":tag" defines a local tag for the preceding node
135 - ":tag" defines a local tag for the preceding node
136 - "@branch" sets the named branch for subsequent nodes
136 - "@branch" sets the named branch for subsequent nodes
137 - "#...\\n" is a comment up to the end of the line
137 - "#...\\n" is a comment up to the end of the line
138
138
139 Whitespace between the above elements is ignored.
139 Whitespace between the above elements is ignored.
140
140
141 A backref is either
141 A backref is either
142
142
143 - a number n, which references the node curr-n, where curr is the current
143 - a number n, which references the node curr-n, where curr is the current
144 node, or
144 node, or
145 - the name of a local tag you placed earlier using ":tag", or
145 - the name of a local tag you placed earlier using ":tag", or
146 - empty to denote the default parent.
146 - empty to denote the default parent.
147
147
148 All string valued-elements are either strictly alphanumeric, or must
148 All string valued-elements are either strictly alphanumeric, or must
149 be enclosed in double quotes ("..."), with "\\" as escape character.
149 be enclosed in double quotes ("..."), with "\\" as escape character.
150 """
150 """
151
151
152 if text is None:
152 if text is None:
153 ui.status(_("reading DAG from stdin\n"))
153 ui.status(_("reading DAG from stdin\n"))
154 text = ui.fin.read()
154 text = ui.fin.read()
155
155
156 cl = repo.changelog
156 cl = repo.changelog
157 if len(cl) > 0:
157 if len(cl) > 0:
158 raise error.Abort(_('repository is not empty'))
158 raise error.Abort(_('repository is not empty'))
159
159
160 # determine number of revs in DAG
160 # determine number of revs in DAG
161 total = 0
161 total = 0
162 for type, data in dagparser.parsedag(text):
162 for type, data in dagparser.parsedag(text):
163 if type == 'n':
163 if type == 'n':
164 total += 1
164 total += 1
165
165
166 if mergeable_file:
166 if mergeable_file:
167 linesperrev = 2
167 linesperrev = 2
168 # make a file with k lines per rev
168 # make a file with k lines per rev
169 initialmergedlines = ['%d' % i for i in xrange(0, total * linesperrev)]
169 initialmergedlines = ['%d' % i for i in xrange(0, total * linesperrev)]
170 initialmergedlines.append("")
170 initialmergedlines.append("")
171
171
172 tags = []
172 tags = []
173
173
174 wlock = lock = tr = None
174 wlock = lock = tr = None
175 try:
175 try:
176 wlock = repo.wlock()
176 wlock = repo.wlock()
177 lock = repo.lock()
177 lock = repo.lock()
178 tr = repo.transaction("builddag")
178 tr = repo.transaction("builddag")
179
179
180 at = -1
180 at = -1
181 atbranch = 'default'
181 atbranch = 'default'
182 nodeids = []
182 nodeids = []
183 id = 0
183 id = 0
184 ui.progress(_('building'), id, unit=_('revisions'), total=total)
184 ui.progress(_('building'), id, unit=_('revisions'), total=total)
185 for type, data in dagparser.parsedag(text):
185 for type, data in dagparser.parsedag(text):
186 if type == 'n':
186 if type == 'n':
187 ui.note(('node %s\n' % pycompat.bytestr(data)))
187 ui.note(('node %s\n' % pycompat.bytestr(data)))
188 id, ps = data
188 id, ps = data
189
189
190 files = []
190 files = []
191 filecontent = {}
191 filecontent = {}
192
192
193 p2 = None
193 p2 = None
194 if mergeable_file:
194 if mergeable_file:
195 fn = "mf"
195 fn = "mf"
196 p1 = repo[ps[0]]
196 p1 = repo[ps[0]]
197 if len(ps) > 1:
197 if len(ps) > 1:
198 p2 = repo[ps[1]]
198 p2 = repo[ps[1]]
199 pa = p1.ancestor(p2)
199 pa = p1.ancestor(p2)
200 base, local, other = [x[fn].data() for x in (pa, p1,
200 base, local, other = [x[fn].data() for x in (pa, p1,
201 p2)]
201 p2)]
202 m3 = simplemerge.Merge3Text(base, local, other)
202 m3 = simplemerge.Merge3Text(base, local, other)
203 ml = [l.strip() for l in m3.merge_lines()]
203 ml = [l.strip() for l in m3.merge_lines()]
204 ml.append("")
204 ml.append("")
205 elif at > 0:
205 elif at > 0:
206 ml = p1[fn].data().split("\n")
206 ml = p1[fn].data().split("\n")
207 else:
207 else:
208 ml = initialmergedlines
208 ml = initialmergedlines
209 ml[id * linesperrev] += " r%i" % id
209 ml[id * linesperrev] += " r%i" % id
210 mergedtext = "\n".join(ml)
210 mergedtext = "\n".join(ml)
211 files.append(fn)
211 files.append(fn)
212 filecontent[fn] = mergedtext
212 filecontent[fn] = mergedtext
213
213
214 if overwritten_file:
214 if overwritten_file:
215 fn = "of"
215 fn = "of"
216 files.append(fn)
216 files.append(fn)
217 filecontent[fn] = "r%i\n" % id
217 filecontent[fn] = "r%i\n" % id
218
218
219 if new_file:
219 if new_file:
220 fn = "nf%i" % id
220 fn = "nf%i" % id
221 files.append(fn)
221 files.append(fn)
222 filecontent[fn] = "r%i\n" % id
222 filecontent[fn] = "r%i\n" % id
223 if len(ps) > 1:
223 if len(ps) > 1:
224 if not p2:
224 if not p2:
225 p2 = repo[ps[1]]
225 p2 = repo[ps[1]]
226 for fn in p2:
226 for fn in p2:
227 if fn.startswith("nf"):
227 if fn.startswith("nf"):
228 files.append(fn)
228 files.append(fn)
229 filecontent[fn] = p2[fn].data()
229 filecontent[fn] = p2[fn].data()
230
230
231 def fctxfn(repo, cx, path):
231 def fctxfn(repo, cx, path):
232 if path in filecontent:
232 if path in filecontent:
233 return context.memfilectx(repo, cx, path,
233 return context.memfilectx(repo, cx, path,
234 filecontent[path])
234 filecontent[path])
235 return None
235 return None
236
236
237 if len(ps) == 0 or ps[0] < 0:
237 if len(ps) == 0 or ps[0] < 0:
238 pars = [None, None]
238 pars = [None, None]
239 elif len(ps) == 1:
239 elif len(ps) == 1:
240 pars = [nodeids[ps[0]], None]
240 pars = [nodeids[ps[0]], None]
241 else:
241 else:
242 pars = [nodeids[p] for p in ps]
242 pars = [nodeids[p] for p in ps]
243 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
243 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
244 date=(id, 0),
244 date=(id, 0),
245 user="debugbuilddag",
245 user="debugbuilddag",
246 extra={'branch': atbranch})
246 extra={'branch': atbranch})
247 nodeid = repo.commitctx(cx)
247 nodeid = repo.commitctx(cx)
248 nodeids.append(nodeid)
248 nodeids.append(nodeid)
249 at = id
249 at = id
250 elif type == 'l':
250 elif type == 'l':
251 id, name = data
251 id, name = data
252 ui.note(('tag %s\n' % name))
252 ui.note(('tag %s\n' % name))
253 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
253 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
254 elif type == 'a':
254 elif type == 'a':
255 ui.note(('branch %s\n' % data))
255 ui.note(('branch %s\n' % data))
256 atbranch = data
256 atbranch = data
257 ui.progress(_('building'), id, unit=_('revisions'), total=total)
257 ui.progress(_('building'), id, unit=_('revisions'), total=total)
258 tr.close()
258 tr.close()
259
259
260 if tags:
260 if tags:
261 repo.vfs.write("localtags", "".join(tags))
261 repo.vfs.write("localtags", "".join(tags))
262 finally:
262 finally:
263 ui.progress(_('building'), None)
263 ui.progress(_('building'), None)
264 release(tr, lock, wlock)
264 release(tr, lock, wlock)
265
265
266 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
266 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
267 indent_string = ' ' * indent
267 indent_string = ' ' * indent
268 if all:
268 if all:
269 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
269 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
270 % indent_string)
270 % indent_string)
271
271
272 def showchunks(named):
272 def showchunks(named):
273 ui.write("\n%s%s\n" % (indent_string, named))
273 ui.write("\n%s%s\n" % (indent_string, named))
274 for deltadata in gen.deltaiter():
274 for deltadata in gen.deltaiter():
275 node, p1, p2, cs, deltabase, delta, flags = deltadata
275 node, p1, p2, cs, deltabase, delta, flags = deltadata
276 ui.write("%s%s %s %s %s %s %d\n" %
276 ui.write("%s%s %s %s %s %s %d\n" %
277 (indent_string, hex(node), hex(p1), hex(p2),
277 (indent_string, hex(node), hex(p1), hex(p2),
278 hex(cs), hex(deltabase), len(delta)))
278 hex(cs), hex(deltabase), len(delta)))
279
279
280 chunkdata = gen.changelogheader()
280 chunkdata = gen.changelogheader()
281 showchunks("changelog")
281 showchunks("changelog")
282 chunkdata = gen.manifestheader()
282 chunkdata = gen.manifestheader()
283 showchunks("manifest")
283 showchunks("manifest")
284 for chunkdata in iter(gen.filelogheader, {}):
284 for chunkdata in iter(gen.filelogheader, {}):
285 fname = chunkdata['filename']
285 fname = chunkdata['filename']
286 showchunks(fname)
286 showchunks(fname)
287 else:
287 else:
288 if isinstance(gen, bundle2.unbundle20):
288 if isinstance(gen, bundle2.unbundle20):
289 raise error.Abort(_('use debugbundle2 for this file'))
289 raise error.Abort(_('use debugbundle2 for this file'))
290 chunkdata = gen.changelogheader()
290 chunkdata = gen.changelogheader()
291 for deltadata in gen.deltaiter():
291 for deltadata in gen.deltaiter():
292 node, p1, p2, cs, deltabase, delta, flags = deltadata
292 node, p1, p2, cs, deltabase, delta, flags = deltadata
293 ui.write("%s%s\n" % (indent_string, hex(node)))
293 ui.write("%s%s\n" % (indent_string, hex(node)))
294
294
295 def _debugobsmarkers(ui, part, indent=0, **opts):
295 def _debugobsmarkers(ui, part, indent=0, **opts):
296 """display version and markers contained in 'data'"""
296 """display version and markers contained in 'data'"""
297 opts = pycompat.byteskwargs(opts)
297 opts = pycompat.byteskwargs(opts)
298 data = part.read()
298 data = part.read()
299 indent_string = ' ' * indent
299 indent_string = ' ' * indent
300 try:
300 try:
301 version, markers = obsolete._readmarkers(data)
301 version, markers = obsolete._readmarkers(data)
302 except error.UnknownVersion as exc:
302 except error.UnknownVersion as exc:
303 msg = "%sunsupported version: %s (%d bytes)\n"
303 msg = "%sunsupported version: %s (%d bytes)\n"
304 msg %= indent_string, exc.version, len(data)
304 msg %= indent_string, exc.version, len(data)
305 ui.write(msg)
305 ui.write(msg)
306 else:
306 else:
307 msg = "%sversion: %d (%d bytes)\n"
307 msg = "%sversion: %d (%d bytes)\n"
308 msg %= indent_string, version, len(data)
308 msg %= indent_string, version, len(data)
309 ui.write(msg)
309 ui.write(msg)
310 fm = ui.formatter('debugobsolete', opts)
310 fm = ui.formatter('debugobsolete', opts)
311 for rawmarker in sorted(markers):
311 for rawmarker in sorted(markers):
312 m = obsutil.marker(None, rawmarker)
312 m = obsutil.marker(None, rawmarker)
313 fm.startitem()
313 fm.startitem()
314 fm.plain(indent_string)
314 fm.plain(indent_string)
315 cmdutil.showmarker(fm, m)
315 cmdutil.showmarker(fm, m)
316 fm.end()
316 fm.end()
317
317
318 def _debugphaseheads(ui, data, indent=0):
318 def _debugphaseheads(ui, data, indent=0):
319 """display version and markers contained in 'data'"""
319 """display version and markers contained in 'data'"""
320 indent_string = ' ' * indent
320 indent_string = ' ' * indent
321 headsbyphase = phases.binarydecode(data)
321 headsbyphase = phases.binarydecode(data)
322 for phase in phases.allphases:
322 for phase in phases.allphases:
323 for head in headsbyphase[phase]:
323 for head in headsbyphase[phase]:
324 ui.write(indent_string)
324 ui.write(indent_string)
325 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
325 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
326
326
327 def _quasirepr(thing):
327 def _quasirepr(thing):
328 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
328 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
329 return '{%s}' % (
329 return '{%s}' % (
330 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
330 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
331 return pycompat.bytestr(repr(thing))
331 return pycompat.bytestr(repr(thing))
332
332
333 def _debugbundle2(ui, gen, all=None, **opts):
333 def _debugbundle2(ui, gen, all=None, **opts):
334 """lists the contents of a bundle2"""
334 """lists the contents of a bundle2"""
335 if not isinstance(gen, bundle2.unbundle20):
335 if not isinstance(gen, bundle2.unbundle20):
336 raise error.Abort(_('not a bundle2 file'))
336 raise error.Abort(_('not a bundle2 file'))
337 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
337 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
338 parttypes = opts.get(r'part_type', [])
338 parttypes = opts.get(r'part_type', [])
339 for part in gen.iterparts():
339 for part in gen.iterparts():
340 if parttypes and part.type not in parttypes:
340 if parttypes and part.type not in parttypes:
341 continue
341 continue
342 ui.write('%s -- %s\n' % (part.type, _quasirepr(part.params)))
342 ui.write('%s -- %s\n' % (part.type, _quasirepr(part.params)))
343 if part.type == 'changegroup':
343 if part.type == 'changegroup':
344 version = part.params.get('version', '01')
344 version = part.params.get('version', '01')
345 cg = changegroup.getunbundler(version, part, 'UN')
345 cg = changegroup.getunbundler(version, part, 'UN')
346 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
346 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
347 if part.type == 'obsmarkers':
347 if part.type == 'obsmarkers':
348 _debugobsmarkers(ui, part, indent=4, **opts)
348 _debugobsmarkers(ui, part, indent=4, **opts)
349 if part.type == 'phase-heads':
349 if part.type == 'phase-heads':
350 _debugphaseheads(ui, part, indent=4)
350 _debugphaseheads(ui, part, indent=4)
351
351
352 @command('debugbundle',
352 @command('debugbundle',
353 [('a', 'all', None, _('show all details')),
353 [('a', 'all', None, _('show all details')),
354 ('', 'part-type', [], _('show only the named part type')),
354 ('', 'part-type', [], _('show only the named part type')),
355 ('', 'spec', None, _('print the bundlespec of the bundle'))],
355 ('', 'spec', None, _('print the bundlespec of the bundle'))],
356 _('FILE'),
356 _('FILE'),
357 norepo=True)
357 norepo=True)
358 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
358 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
359 """lists the contents of a bundle"""
359 """lists the contents of a bundle"""
360 with hg.openpath(ui, bundlepath) as f:
360 with hg.openpath(ui, bundlepath) as f:
361 if spec:
361 if spec:
362 spec = exchange.getbundlespec(ui, f)
362 spec = exchange.getbundlespec(ui, f)
363 ui.write('%s\n' % spec)
363 ui.write('%s\n' % spec)
364 return
364 return
365
365
366 gen = exchange.readbundle(ui, f, bundlepath)
366 gen = exchange.readbundle(ui, f, bundlepath)
367 if isinstance(gen, bundle2.unbundle20):
367 if isinstance(gen, bundle2.unbundle20):
368 return _debugbundle2(ui, gen, all=all, **opts)
368 return _debugbundle2(ui, gen, all=all, **opts)
369 _debugchangegroup(ui, gen, all=all, **opts)
369 _debugchangegroup(ui, gen, all=all, **opts)
370
370
371 @command('debugcapabilities',
371 @command('debugcapabilities',
372 [], _('PATH'),
372 [], _('PATH'),
373 norepo=True)
373 norepo=True)
374 def debugcapabilities(ui, path, **opts):
374 def debugcapabilities(ui, path, **opts):
375 """lists the capabilities of a remote peer"""
375 """lists the capabilities of a remote peer"""
376 opts = pycompat.byteskwargs(opts)
376 opts = pycompat.byteskwargs(opts)
377 peer = hg.peer(ui, opts, path)
377 peer = hg.peer(ui, opts, path)
378 caps = peer.capabilities()
378 caps = peer.capabilities()
379 ui.write(('Main capabilities:\n'))
379 ui.write(('Main capabilities:\n'))
380 for c in sorted(caps):
380 for c in sorted(caps):
381 ui.write((' %s\n') % c)
381 ui.write((' %s\n') % c)
382 b2caps = bundle2.bundle2caps(peer)
382 b2caps = bundle2.bundle2caps(peer)
383 if b2caps:
383 if b2caps:
384 ui.write(('Bundle2 capabilities:\n'))
384 ui.write(('Bundle2 capabilities:\n'))
385 for key, values in sorted(b2caps.iteritems()):
385 for key, values in sorted(b2caps.iteritems()):
386 ui.write((' %s\n') % key)
386 ui.write((' %s\n') % key)
387 for v in values:
387 for v in values:
388 ui.write((' %s\n') % v)
388 ui.write((' %s\n') % v)
389
389
390 @command('debugcheckstate', [], '')
390 @command('debugcheckstate', [], '')
391 def debugcheckstate(ui, repo):
391 def debugcheckstate(ui, repo):
392 """validate the correctness of the current dirstate"""
392 """validate the correctness of the current dirstate"""
393 parent1, parent2 = repo.dirstate.parents()
393 parent1, parent2 = repo.dirstate.parents()
394 m1 = repo[parent1].manifest()
394 m1 = repo[parent1].manifest()
395 m2 = repo[parent2].manifest()
395 m2 = repo[parent2].manifest()
396 errors = 0
396 errors = 0
397 for f in repo.dirstate:
397 for f in repo.dirstate:
398 state = repo.dirstate[f]
398 state = repo.dirstate[f]
399 if state in "nr" and f not in m1:
399 if state in "nr" and f not in m1:
400 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
400 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
401 errors += 1
401 errors += 1
402 if state in "a" and f in m1:
402 if state in "a" and f in m1:
403 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
403 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
404 errors += 1
404 errors += 1
405 if state in "m" and f not in m1 and f not in m2:
405 if state in "m" and f not in m1 and f not in m2:
406 ui.warn(_("%s in state %s, but not in either manifest\n") %
406 ui.warn(_("%s in state %s, but not in either manifest\n") %
407 (f, state))
407 (f, state))
408 errors += 1
408 errors += 1
409 for f in m1:
409 for f in m1:
410 state = repo.dirstate[f]
410 state = repo.dirstate[f]
411 if state not in "nrm":
411 if state not in "nrm":
412 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
412 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
413 errors += 1
413 errors += 1
414 if errors:
414 if errors:
415 error = _(".hg/dirstate inconsistent with current parent's manifest")
415 error = _(".hg/dirstate inconsistent with current parent's manifest")
416 raise error.Abort(error)
416 raise error.Abort(error)
417
417
418 @command('debugcolor',
418 @command('debugcolor',
419 [('', 'style', None, _('show all configured styles'))],
419 [('', 'style', None, _('show all configured styles'))],
420 'hg debugcolor')
420 'hg debugcolor')
421 def debugcolor(ui, repo, **opts):
421 def debugcolor(ui, repo, **opts):
422 """show available color, effects or style"""
422 """show available color, effects or style"""
423 ui.write(('color mode: %s\n') % ui._colormode)
423 ui.write(('color mode: %s\n') % ui._colormode)
424 if opts.get(r'style'):
424 if opts.get(r'style'):
425 return _debugdisplaystyle(ui)
425 return _debugdisplaystyle(ui)
426 else:
426 else:
427 return _debugdisplaycolor(ui)
427 return _debugdisplaycolor(ui)
428
428
429 def _debugdisplaycolor(ui):
429 def _debugdisplaycolor(ui):
430 ui = ui.copy()
430 ui = ui.copy()
431 ui._styles.clear()
431 ui._styles.clear()
432 for effect in color._activeeffects(ui).keys():
432 for effect in color._activeeffects(ui).keys():
433 ui._styles[effect] = effect
433 ui._styles[effect] = effect
434 if ui._terminfoparams:
434 if ui._terminfoparams:
435 for k, v in ui.configitems('color'):
435 for k, v in ui.configitems('color'):
436 if k.startswith('color.'):
436 if k.startswith('color.'):
437 ui._styles[k] = k[6:]
437 ui._styles[k] = k[6:]
438 elif k.startswith('terminfo.'):
438 elif k.startswith('terminfo.'):
439 ui._styles[k] = k[9:]
439 ui._styles[k] = k[9:]
440 ui.write(_('available colors:\n'))
440 ui.write(_('available colors:\n'))
441 # sort label with a '_' after the other to group '_background' entry.
441 # sort label with a '_' after the other to group '_background' entry.
442 items = sorted(ui._styles.items(),
442 items = sorted(ui._styles.items(),
443 key=lambda i: ('_' in i[0], i[0], i[1]))
443 key=lambda i: ('_' in i[0], i[0], i[1]))
444 for colorname, label in items:
444 for colorname, label in items:
445 ui.write(('%s\n') % colorname, label=label)
445 ui.write(('%s\n') % colorname, label=label)
446
446
447 def _debugdisplaystyle(ui):
447 def _debugdisplaystyle(ui):
448 ui.write(_('available style:\n'))
448 ui.write(_('available style:\n'))
449 width = max(len(s) for s in ui._styles)
449 width = max(len(s) for s in ui._styles)
450 for label, effects in sorted(ui._styles.items()):
450 for label, effects in sorted(ui._styles.items()):
451 ui.write('%s' % label, label=label)
451 ui.write('%s' % label, label=label)
452 if effects:
452 if effects:
453 # 50
453 # 50
454 ui.write(': ')
454 ui.write(': ')
455 ui.write(' ' * (max(0, width - len(label))))
455 ui.write(' ' * (max(0, width - len(label))))
456 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
456 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
457 ui.write('\n')
457 ui.write('\n')
458
458
459 @command('debugcreatestreamclonebundle', [], 'FILE')
459 @command('debugcreatestreamclonebundle', [], 'FILE')
460 def debugcreatestreamclonebundle(ui, repo, fname):
460 def debugcreatestreamclonebundle(ui, repo, fname):
461 """create a stream clone bundle file
461 """create a stream clone bundle file
462
462
463 Stream bundles are special bundles that are essentially archives of
463 Stream bundles are special bundles that are essentially archives of
464 revlog files. They are commonly used for cloning very quickly.
464 revlog files. They are commonly used for cloning very quickly.
465 """
465 """
466 # TODO we may want to turn this into an abort when this functionality
466 # TODO we may want to turn this into an abort when this functionality
467 # is moved into `hg bundle`.
467 # is moved into `hg bundle`.
468 if phases.hassecret(repo):
468 if phases.hassecret(repo):
469 ui.warn(_('(warning: stream clone bundle will contain secret '
469 ui.warn(_('(warning: stream clone bundle will contain secret '
470 'revisions)\n'))
470 'revisions)\n'))
471
471
472 requirements, gen = streamclone.generatebundlev1(repo)
472 requirements, gen = streamclone.generatebundlev1(repo)
473 changegroup.writechunks(ui, gen, fname)
473 changegroup.writechunks(ui, gen, fname)
474
474
475 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
475 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
476
476
477 @command('debugdag',
477 @command('debugdag',
478 [('t', 'tags', None, _('use tags as labels')),
478 [('t', 'tags', None, _('use tags as labels')),
479 ('b', 'branches', None, _('annotate with branch names')),
479 ('b', 'branches', None, _('annotate with branch names')),
480 ('', 'dots', None, _('use dots for runs')),
480 ('', 'dots', None, _('use dots for runs')),
481 ('s', 'spaces', None, _('separate elements by spaces'))],
481 ('s', 'spaces', None, _('separate elements by spaces'))],
482 _('[OPTION]... [FILE [REV]...]'),
482 _('[OPTION]... [FILE [REV]...]'),
483 optionalrepo=True)
483 optionalrepo=True)
484 def debugdag(ui, repo, file_=None, *revs, **opts):
484 def debugdag(ui, repo, file_=None, *revs, **opts):
485 """format the changelog or an index DAG as a concise textual description
485 """format the changelog or an index DAG as a concise textual description
486
486
487 If you pass a revlog index, the revlog's DAG is emitted. If you list
487 If you pass a revlog index, the revlog's DAG is emitted. If you list
488 revision numbers, they get labeled in the output as rN.
488 revision numbers, they get labeled in the output as rN.
489
489
490 Otherwise, the changelog DAG of the current repo is emitted.
490 Otherwise, the changelog DAG of the current repo is emitted.
491 """
491 """
492 spaces = opts.get(r'spaces')
492 spaces = opts.get(r'spaces')
493 dots = opts.get(r'dots')
493 dots = opts.get(r'dots')
494 if file_:
494 if file_:
495 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
495 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
496 file_)
496 file_)
497 revs = set((int(r) for r in revs))
497 revs = set((int(r) for r in revs))
498 def events():
498 def events():
499 for r in rlog:
499 for r in rlog:
500 yield 'n', (r, list(p for p in rlog.parentrevs(r)
500 yield 'n', (r, list(p for p in rlog.parentrevs(r)
501 if p != -1))
501 if p != -1))
502 if r in revs:
502 if r in revs:
503 yield 'l', (r, "r%i" % r)
503 yield 'l', (r, "r%i" % r)
504 elif repo:
504 elif repo:
505 cl = repo.changelog
505 cl = repo.changelog
506 tags = opts.get(r'tags')
506 tags = opts.get(r'tags')
507 branches = opts.get(r'branches')
507 branches = opts.get(r'branches')
508 if tags:
508 if tags:
509 labels = {}
509 labels = {}
510 for l, n in repo.tags().items():
510 for l, n in repo.tags().items():
511 labels.setdefault(cl.rev(n), []).append(l)
511 labels.setdefault(cl.rev(n), []).append(l)
512 def events():
512 def events():
513 b = "default"
513 b = "default"
514 for r in cl:
514 for r in cl:
515 if branches:
515 if branches:
516 newb = cl.read(cl.node(r))[5]['branch']
516 newb = cl.read(cl.node(r))[5]['branch']
517 if newb != b:
517 if newb != b:
518 yield 'a', newb
518 yield 'a', newb
519 b = newb
519 b = newb
520 yield 'n', (r, list(p for p in cl.parentrevs(r)
520 yield 'n', (r, list(p for p in cl.parentrevs(r)
521 if p != -1))
521 if p != -1))
522 if tags:
522 if tags:
523 ls = labels.get(r)
523 ls = labels.get(r)
524 if ls:
524 if ls:
525 for l in ls:
525 for l in ls:
526 yield 'l', (r, l)
526 yield 'l', (r, l)
527 else:
527 else:
528 raise error.Abort(_('need repo for changelog dag'))
528 raise error.Abort(_('need repo for changelog dag'))
529
529
530 for line in dagparser.dagtextlines(events(),
530 for line in dagparser.dagtextlines(events(),
531 addspaces=spaces,
531 addspaces=spaces,
532 wraplabels=True,
532 wraplabels=True,
533 wrapannotations=True,
533 wrapannotations=True,
534 wrapnonlinear=dots,
534 wrapnonlinear=dots,
535 usedots=dots,
535 usedots=dots,
536 maxlinewidth=70):
536 maxlinewidth=70):
537 ui.write(line)
537 ui.write(line)
538 ui.write("\n")
538 ui.write("\n")
539
539
540 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
540 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
541 def debugdata(ui, repo, file_, rev=None, **opts):
541 def debugdata(ui, repo, file_, rev=None, **opts):
542 """dump the contents of a data file revision"""
542 """dump the contents of a data file revision"""
543 opts = pycompat.byteskwargs(opts)
543 opts = pycompat.byteskwargs(opts)
544 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
544 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
545 if rev is not None:
545 if rev is not None:
546 raise error.CommandError('debugdata', _('invalid arguments'))
546 raise error.CommandError('debugdata', _('invalid arguments'))
547 file_, rev = None, file_
547 file_, rev = None, file_
548 elif rev is None:
548 elif rev is None:
549 raise error.CommandError('debugdata', _('invalid arguments'))
549 raise error.CommandError('debugdata', _('invalid arguments'))
550 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
550 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
551 try:
551 try:
552 ui.write(r.revision(r.lookup(rev), raw=True))
552 ui.write(r.revision(r.lookup(rev), raw=True))
553 except KeyError:
553 except KeyError:
554 raise error.Abort(_('invalid revision identifier %s') % rev)
554 raise error.Abort(_('invalid revision identifier %s') % rev)
555
555
556 @command('debugdate',
556 @command('debugdate',
557 [('e', 'extended', None, _('try extended date formats'))],
557 [('e', 'extended', None, _('try extended date formats'))],
558 _('[-e] DATE [RANGE]'),
558 _('[-e] DATE [RANGE]'),
559 norepo=True, optionalrepo=True)
559 norepo=True, optionalrepo=True)
560 def debugdate(ui, date, range=None, **opts):
560 def debugdate(ui, date, range=None, **opts):
561 """parse and display a date"""
561 """parse and display a date"""
562 if opts[r"extended"]:
562 if opts[r"extended"]:
563 d = util.parsedate(date, util.extendeddateformats)
563 d = util.parsedate(date, util.extendeddateformats)
564 else:
564 else:
565 d = util.parsedate(date)
565 d = util.parsedate(date)
566 ui.write(("internal: %d %d\n") % d)
566 ui.write(("internal: %d %d\n") % d)
567 ui.write(("standard: %s\n") % util.datestr(d))
567 ui.write(("standard: %s\n") % util.datestr(d))
568 if range:
568 if range:
569 m = util.matchdate(range)
569 m = util.matchdate(range)
570 ui.write(("match: %s\n") % m(d[0]))
570 ui.write(("match: %s\n") % m(d[0]))
571
571
572 @command('debugdeltachain',
572 @command('debugdeltachain',
573 cmdutil.debugrevlogopts + cmdutil.formatteropts,
573 cmdutil.debugrevlogopts + cmdutil.formatteropts,
574 _('-c|-m|FILE'),
574 _('-c|-m|FILE'),
575 optionalrepo=True)
575 optionalrepo=True)
576 def debugdeltachain(ui, repo, file_=None, **opts):
576 def debugdeltachain(ui, repo, file_=None, **opts):
577 """dump information about delta chains in a revlog
577 """dump information about delta chains in a revlog
578
578
579 Output can be templatized. Available template keywords are:
579 Output can be templatized. Available template keywords are:
580
580
581 :``rev``: revision number
581 :``rev``: revision number
582 :``chainid``: delta chain identifier (numbered by unique base)
582 :``chainid``: delta chain identifier (numbered by unique base)
583 :``chainlen``: delta chain length to this revision
583 :``chainlen``: delta chain length to this revision
584 :``prevrev``: previous revision in delta chain
584 :``prevrev``: previous revision in delta chain
585 :``deltatype``: role of delta / how it was computed
585 :``deltatype``: role of delta / how it was computed
586 :``compsize``: compressed size of revision
586 :``compsize``: compressed size of revision
587 :``uncompsize``: uncompressed size of revision
587 :``uncompsize``: uncompressed size of revision
588 :``chainsize``: total size of compressed revisions in chain
588 :``chainsize``: total size of compressed revisions in chain
589 :``chainratio``: total chain size divided by uncompressed revision size
589 :``chainratio``: total chain size divided by uncompressed revision size
590 (new delta chains typically start at ratio 2.00)
590 (new delta chains typically start at ratio 2.00)
591 :``lindist``: linear distance from base revision in delta chain to end
591 :``lindist``: linear distance from base revision in delta chain to end
592 of this revision
592 of this revision
593 :``extradist``: total size of revisions not part of this delta chain from
593 :``extradist``: total size of revisions not part of this delta chain from
594 base of delta chain to end of this revision; a measurement
594 base of delta chain to end of this revision; a measurement
595 of how much extra data we need to read/seek across to read
595 of how much extra data we need to read/seek across to read
596 the delta chain for this revision
596 the delta chain for this revision
597 :``extraratio``: extradist divided by chainsize; another representation of
597 :``extraratio``: extradist divided by chainsize; another representation of
598 how much unrelated data is needed to load this delta chain
598 how much unrelated data is needed to load this delta chain
599
599
600 If the repository is configured to use the sparse read, additional keywords
600 If the repository is configured to use the sparse read, additional keywords
601 are available:
601 are available:
602
602
603 :``readsize``: total size of data read from the disk for a revision
603 :``readsize``: total size of data read from the disk for a revision
604 (sum of the sizes of all the blocks)
604 (sum of the sizes of all the blocks)
605 :``largestblock``: size of the largest block of data read from the disk
605 :``largestblock``: size of the largest block of data read from the disk
606 :``readdensity``: density of useful bytes in the data read from the disk
606 :``readdensity``: density of useful bytes in the data read from the disk
607 :``srchunks``: in how many data hunks the whole revision would be read
607 :``srchunks``: in how many data hunks the whole revision would be read
608
608
609 The sparse read can be enabled with experimental.sparse-read = True
609 The sparse read can be enabled with experimental.sparse-read = True
610 """
610 """
611 opts = pycompat.byteskwargs(opts)
611 opts = pycompat.byteskwargs(opts)
612 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
612 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
613 index = r.index
613 index = r.index
614 generaldelta = r.version & revlog.FLAG_GENERALDELTA
614 generaldelta = r.version & revlog.FLAG_GENERALDELTA
615 withsparseread = getattr(r, '_withsparseread', False)
615 withsparseread = getattr(r, '_withsparseread', False)
616
616
617 def revinfo(rev):
617 def revinfo(rev):
618 e = index[rev]
618 e = index[rev]
619 compsize = e[1]
619 compsize = e[1]
620 uncompsize = e[2]
620 uncompsize = e[2]
621 chainsize = 0
621 chainsize = 0
622
622
623 if generaldelta:
623 if generaldelta:
624 if e[3] == e[5]:
624 if e[3] == e[5]:
625 deltatype = 'p1'
625 deltatype = 'p1'
626 elif e[3] == e[6]:
626 elif e[3] == e[6]:
627 deltatype = 'p2'
627 deltatype = 'p2'
628 elif e[3] == rev - 1:
628 elif e[3] == rev - 1:
629 deltatype = 'prev'
629 deltatype = 'prev'
630 elif e[3] == rev:
630 elif e[3] == rev:
631 deltatype = 'base'
631 deltatype = 'base'
632 else:
632 else:
633 deltatype = 'other'
633 deltatype = 'other'
634 else:
634 else:
635 if e[3] == rev:
635 if e[3] == rev:
636 deltatype = 'base'
636 deltatype = 'base'
637 else:
637 else:
638 deltatype = 'prev'
638 deltatype = 'prev'
639
639
640 chain = r._deltachain(rev)[0]
640 chain = r._deltachain(rev)[0]
641 for iterrev in chain:
641 for iterrev in chain:
642 e = index[iterrev]
642 e = index[iterrev]
643 chainsize += e[1]
643 chainsize += e[1]
644
644
645 return compsize, uncompsize, deltatype, chain, chainsize
645 return compsize, uncompsize, deltatype, chain, chainsize
646
646
647 fm = ui.formatter('debugdeltachain', opts)
647 fm = ui.formatter('debugdeltachain', opts)
648
648
649 fm.plain(' rev chain# chainlen prev delta '
649 fm.plain(' rev chain# chainlen prev delta '
650 'size rawsize chainsize ratio lindist extradist '
650 'size rawsize chainsize ratio lindist extradist '
651 'extraratio')
651 'extraratio')
652 if withsparseread:
652 if withsparseread:
653 fm.plain(' readsize largestblk rddensity srchunks')
653 fm.plain(' readsize largestblk rddensity srchunks')
654 fm.plain('\n')
654 fm.plain('\n')
655
655
656 chainbases = {}
656 chainbases = {}
657 for rev in r:
657 for rev in r:
658 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
658 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
659 chainbase = chain[0]
659 chainbase = chain[0]
660 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
660 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
661 start = r.start
661 start = r.start
662 length = r.length
662 length = r.length
663 basestart = start(chainbase)
663 basestart = start(chainbase)
664 revstart = start(rev)
664 revstart = start(rev)
665 lineardist = revstart + comp - basestart
665 lineardist = revstart + comp - basestart
666 extradist = lineardist - chainsize
666 extradist = lineardist - chainsize
667 try:
667 try:
668 prevrev = chain[-2]
668 prevrev = chain[-2]
669 except IndexError:
669 except IndexError:
670 prevrev = -1
670 prevrev = -1
671
671
672 chainratio = float(chainsize) / float(uncomp)
672 chainratio = float(chainsize) / float(uncomp)
673 extraratio = float(extradist) / float(chainsize)
673 extraratio = float(extradist) / float(chainsize)
674
674
675 fm.startitem()
675 fm.startitem()
676 fm.write('rev chainid chainlen prevrev deltatype compsize '
676 fm.write('rev chainid chainlen prevrev deltatype compsize '
677 'uncompsize chainsize chainratio lindist extradist '
677 'uncompsize chainsize chainratio lindist extradist '
678 'extraratio',
678 'extraratio',
679 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
679 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
680 rev, chainid, len(chain), prevrev, deltatype, comp,
680 rev, chainid, len(chain), prevrev, deltatype, comp,
681 uncomp, chainsize, chainratio, lineardist, extradist,
681 uncomp, chainsize, chainratio, lineardist, extradist,
682 extraratio,
682 extraratio,
683 rev=rev, chainid=chainid, chainlen=len(chain),
683 rev=rev, chainid=chainid, chainlen=len(chain),
684 prevrev=prevrev, deltatype=deltatype, compsize=comp,
684 prevrev=prevrev, deltatype=deltatype, compsize=comp,
685 uncompsize=uncomp, chainsize=chainsize,
685 uncompsize=uncomp, chainsize=chainsize,
686 chainratio=chainratio, lindist=lineardist,
686 chainratio=chainratio, lindist=lineardist,
687 extradist=extradist, extraratio=extraratio)
687 extradist=extradist, extraratio=extraratio)
688 if withsparseread:
688 if withsparseread:
689 readsize = 0
689 readsize = 0
690 largestblock = 0
690 largestblock = 0
691 srchunks = 0
691 srchunks = 0
692
692
693 for revschunk in revlog._slicechunk(r, chain):
693 for revschunk in revlog._slicechunk(r, chain):
694 srchunks += 1
694 srchunks += 1
695 blkend = start(revschunk[-1]) + length(revschunk[-1])
695 blkend = start(revschunk[-1]) + length(revschunk[-1])
696 blksize = blkend - start(revschunk[0])
696 blksize = blkend - start(revschunk[0])
697
697
698 readsize += blksize
698 readsize += blksize
699 if largestblock < blksize:
699 if largestblock < blksize:
700 largestblock = blksize
700 largestblock = blksize
701
701
702 readdensity = float(chainsize) / float(readsize)
702 readdensity = float(chainsize) / float(readsize)
703
703
704 fm.write('readsize largestblock readdensity srchunks',
704 fm.write('readsize largestblock readdensity srchunks',
705 ' %10d %10d %9.5f %8d',
705 ' %10d %10d %9.5f %8d',
706 readsize, largestblock, readdensity, srchunks,
706 readsize, largestblock, readdensity, srchunks,
707 readsize=readsize, largestblock=largestblock,
707 readsize=readsize, largestblock=largestblock,
708 readdensity=readdensity, srchunks=srchunks)
708 readdensity=readdensity, srchunks=srchunks)
709
709
710 fm.plain('\n')
710 fm.plain('\n')
711
711
712 fm.end()
712 fm.end()
713
713
714 @command('debugdirstate|debugstate',
714 @command('debugdirstate|debugstate',
715 [('', 'nodates', None, _('do not display the saved mtime')),
715 [('', 'nodates', None, _('do not display the saved mtime')),
716 ('', 'datesort', None, _('sort by saved mtime'))],
716 ('', 'datesort', None, _('sort by saved mtime'))],
717 _('[OPTION]...'))
717 _('[OPTION]...'))
718 def debugstate(ui, repo, **opts):
718 def debugstate(ui, repo, **opts):
719 """show the contents of the current dirstate"""
719 """show the contents of the current dirstate"""
720
720
721 nodates = opts.get(r'nodates')
721 nodates = opts.get(r'nodates')
722 datesort = opts.get(r'datesort')
722 datesort = opts.get(r'datesort')
723
723
724 timestr = ""
724 timestr = ""
725 if datesort:
725 if datesort:
726 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
726 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
727 else:
727 else:
728 keyfunc = None # sort by filename
728 keyfunc = None # sort by filename
729 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
729 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
730 if ent[3] == -1:
730 if ent[3] == -1:
731 timestr = 'unset '
731 timestr = 'unset '
732 elif nodates:
732 elif nodates:
733 timestr = 'set '
733 timestr = 'set '
734 else:
734 else:
735 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
735 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
736 time.localtime(ent[3]))
736 time.localtime(ent[3]))
737 timestr = encoding.strtolocal(timestr)
737 timestr = encoding.strtolocal(timestr)
738 if ent[1] & 0o20000:
738 if ent[1] & 0o20000:
739 mode = 'lnk'
739 mode = 'lnk'
740 else:
740 else:
741 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
741 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
742 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
742 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
743 for f in repo.dirstate.copies():
743 for f in repo.dirstate.copies():
744 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
744 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
745
745
746 @command('debugdiscovery',
746 @command('debugdiscovery',
747 [('', 'old', None, _('use old-style discovery')),
747 [('', 'old', None, _('use old-style discovery')),
748 ('', 'nonheads', None,
748 ('', 'nonheads', None,
749 _('use old-style discovery with non-heads included')),
749 _('use old-style discovery with non-heads included')),
750 ('', 'rev', [], 'restrict discovery to this set of revs'),
750 ('', 'rev', [], 'restrict discovery to this set of revs'),
751 ] + cmdutil.remoteopts,
751 ] + cmdutil.remoteopts,
752 _('[--rev REV] [OTHER]'))
752 _('[--rev REV] [OTHER]'))
753 def debugdiscovery(ui, repo, remoteurl="default", **opts):
753 def debugdiscovery(ui, repo, remoteurl="default", **opts):
754 """runs the changeset discovery protocol in isolation"""
754 """runs the changeset discovery protocol in isolation"""
755 opts = pycompat.byteskwargs(opts)
755 opts = pycompat.byteskwargs(opts)
756 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
756 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
757 remote = hg.peer(repo, opts, remoteurl)
757 remote = hg.peer(repo, opts, remoteurl)
758 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
758 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
759
759
760 # make sure tests are repeatable
760 # make sure tests are repeatable
761 random.seed(12323)
761 random.seed(12323)
762
762
763 def doit(pushedrevs, remoteheads, remote=remote):
763 def doit(pushedrevs, remoteheads, remote=remote):
764 if opts.get('old'):
764 if opts.get('old'):
765 if not util.safehasattr(remote, 'branches'):
765 if not util.safehasattr(remote, 'branches'):
766 # enable in-client legacy support
766 # enable in-client legacy support
767 remote = localrepo.locallegacypeer(remote.local())
767 remote = localrepo.locallegacypeer(remote.local())
768 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
768 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
769 force=True)
769 force=True)
770 common = set(common)
770 common = set(common)
771 if not opts.get('nonheads'):
771 if not opts.get('nonheads'):
772 ui.write(("unpruned common: %s\n") %
772 ui.write(("unpruned common: %s\n") %
773 " ".join(sorted(short(n) for n in common)))
773 " ".join(sorted(short(n) for n in common)))
774 dag = dagutil.revlogdag(repo.changelog)
774 dag = dagutil.revlogdag(repo.changelog)
775 all = dag.ancestorset(dag.internalizeall(common))
775 all = dag.ancestorset(dag.internalizeall(common))
776 common = dag.externalizeall(dag.headsetofconnecteds(all))
776 common = dag.externalizeall(dag.headsetofconnecteds(all))
777 else:
777 else:
778 nodes = None
778 nodes = None
779 if pushedrevs:
779 if pushedrevs:
780 revs = scmutil.revrange(repo, pushedrevs)
780 revs = scmutil.revrange(repo, pushedrevs)
781 nodes = [repo[r].node() for r in revs]
781 nodes = [repo[r].node() for r in revs]
782 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
782 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
783 ancestorsof=nodes)
783 ancestorsof=nodes)
784 common = set(common)
784 common = set(common)
785 rheads = set(hds)
785 rheads = set(hds)
786 lheads = set(repo.heads())
786 lheads = set(repo.heads())
787 ui.write(("common heads: %s\n") %
787 ui.write(("common heads: %s\n") %
788 " ".join(sorted(short(n) for n in common)))
788 " ".join(sorted(short(n) for n in common)))
789 if lheads <= common:
789 if lheads <= common:
790 ui.write(("local is subset\n"))
790 ui.write(("local is subset\n"))
791 elif rheads <= common:
791 elif rheads <= common:
792 ui.write(("remote is subset\n"))
792 ui.write(("remote is subset\n"))
793
793
794 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
794 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
795 localrevs = opts['rev']
795 localrevs = opts['rev']
796 doit(localrevs, remoterevs)
796 doit(localrevs, remoterevs)
797
797
798 _chunksize = 4 << 10
798 _chunksize = 4 << 10
799
799
800 @command('debugdownload',
800 @command('debugdownload',
801 [
801 [
802 ('o', 'output', '', _('path')),
802 ('o', 'output', '', _('path')),
803 ],
803 ],
804 optionalrepo=True)
804 optionalrepo=True)
805 def debugdownload(ui, repo, url, output=None, **opts):
805 def debugdownload(ui, repo, url, output=None, **opts):
806 """download a resource using Mercurial logic and config
806 """download a resource using Mercurial logic and config
807 """
807 """
808 fh = urlmod.open(ui, url, output)
808 fh = urlmod.open(ui, url, output)
809
809
810 dest = ui
810 dest = ui
811 if output:
811 if output:
812 dest = open(output, "wb", _chunksize)
812 dest = open(output, "wb", _chunksize)
813 try:
813 try:
814 data = fh.read(_chunksize)
814 data = fh.read(_chunksize)
815 while data:
815 while data:
816 dest.write(data)
816 dest.write(data)
817 data = fh.read(_chunksize)
817 data = fh.read(_chunksize)
818 finally:
818 finally:
819 if output:
819 if output:
820 dest.close()
820 dest.close()
821
821
822 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
822 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
823 def debugextensions(ui, **opts):
823 def debugextensions(ui, **opts):
824 '''show information about active extensions'''
824 '''show information about active extensions'''
825 opts = pycompat.byteskwargs(opts)
825 opts = pycompat.byteskwargs(opts)
826 exts = extensions.extensions(ui)
826 exts = extensions.extensions(ui)
827 hgver = util.version()
827 hgver = util.version()
828 fm = ui.formatter('debugextensions', opts)
828 fm = ui.formatter('debugextensions', opts)
829 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
829 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
830 isinternal = extensions.ismoduleinternal(extmod)
830 isinternal = extensions.ismoduleinternal(extmod)
831 extsource = pycompat.fsencode(extmod.__file__)
831 extsource = pycompat.fsencode(extmod.__file__)
832 if isinternal:
832 if isinternal:
833 exttestedwith = [] # never expose magic string to users
833 exttestedwith = [] # never expose magic string to users
834 else:
834 else:
835 exttestedwith = getattr(extmod, 'testedwith', '').split()
835 exttestedwith = getattr(extmod, 'testedwith', '').split()
836 extbuglink = getattr(extmod, 'buglink', None)
836 extbuglink = getattr(extmod, 'buglink', None)
837
837
838 fm.startitem()
838 fm.startitem()
839
839
840 if ui.quiet or ui.verbose:
840 if ui.quiet or ui.verbose:
841 fm.write('name', '%s\n', extname)
841 fm.write('name', '%s\n', extname)
842 else:
842 else:
843 fm.write('name', '%s', extname)
843 fm.write('name', '%s', extname)
844 if isinternal or hgver in exttestedwith:
844 if isinternal or hgver in exttestedwith:
845 fm.plain('\n')
845 fm.plain('\n')
846 elif not exttestedwith:
846 elif not exttestedwith:
847 fm.plain(_(' (untested!)\n'))
847 fm.plain(_(' (untested!)\n'))
848 else:
848 else:
849 lasttestedversion = exttestedwith[-1]
849 lasttestedversion = exttestedwith[-1]
850 fm.plain(' (%s!)\n' % lasttestedversion)
850 fm.plain(' (%s!)\n' % lasttestedversion)
851
851
852 fm.condwrite(ui.verbose and extsource, 'source',
852 fm.condwrite(ui.verbose and extsource, 'source',
853 _(' location: %s\n'), extsource or "")
853 _(' location: %s\n'), extsource or "")
854
854
855 if ui.verbose:
855 if ui.verbose:
856 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
856 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
857 fm.data(bundled=isinternal)
857 fm.data(bundled=isinternal)
858
858
859 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
859 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
860 _(' tested with: %s\n'),
860 _(' tested with: %s\n'),
861 fm.formatlist(exttestedwith, name='ver'))
861 fm.formatlist(exttestedwith, name='ver'))
862
862
863 fm.condwrite(ui.verbose and extbuglink, 'buglink',
863 fm.condwrite(ui.verbose and extbuglink, 'buglink',
864 _(' bug reporting: %s\n'), extbuglink or "")
864 _(' bug reporting: %s\n'), extbuglink or "")
865
865
866 fm.end()
866 fm.end()
867
867
868 @command('debugfileset',
868 @command('debugfileset',
869 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
869 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
870 _('[-r REV] FILESPEC'))
870 _('[-r REV] FILESPEC'))
871 def debugfileset(ui, repo, expr, **opts):
871 def debugfileset(ui, repo, expr, **opts):
872 '''parse and apply a fileset specification'''
872 '''parse and apply a fileset specification'''
873 ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
873 ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
874 if ui.verbose:
874 if ui.verbose:
875 tree = fileset.parse(expr)
875 tree = fileset.parse(expr)
876 ui.note(fileset.prettyformat(tree), "\n")
876 ui.note(fileset.prettyformat(tree), "\n")
877
877
878 for f in ctx.getfileset(expr):
878 for f in ctx.getfileset(expr):
879 ui.write("%s\n" % f)
879 ui.write("%s\n" % f)
880
880
881 @command('debugformat',
881 @command('debugformat',
882 [] + cmdutil.formatteropts,
882 [] + cmdutil.formatteropts,
883 _(''))
883 _(''))
884 def debugformat(ui, repo, **opts):
884 def debugformat(ui, repo, **opts):
885 """display format information about the current repository
885 """display format information about the current repository
886
886
887 Use --verbose to get extra information about current config value and
887 Use --verbose to get extra information about current config value and
888 Mercurial default."""
888 Mercurial default."""
889 opts = pycompat.byteskwargs(opts)
889 opts = pycompat.byteskwargs(opts)
890 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
890 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
891 maxvariantlength = max(len('format-variant'), maxvariantlength)
891 maxvariantlength = max(len('format-variant'), maxvariantlength)
892
892
893 def makeformatname(name):
893 def makeformatname(name):
894 return '%s:' + (' ' * (maxvariantlength - len(name)))
894 return '%s:' + (' ' * (maxvariantlength - len(name)))
895
895
896 fm = ui.formatter('debugformat', opts)
896 fm = ui.formatter('debugformat', opts)
897 if fm.isplain():
897 if fm.isplain():
898 def formatvalue(value):
898 def formatvalue(value):
899 if util.safehasattr(value, 'startswith'):
899 if util.safehasattr(value, 'startswith'):
900 return value
900 return value
901 if value:
901 if value:
902 return 'yes'
902 return 'yes'
903 else:
903 else:
904 return 'no'
904 return 'no'
905 else:
905 else:
906 formatvalue = pycompat.identity
906 formatvalue = pycompat.identity
907
907
908 fm.plain('format-variant')
908 fm.plain('format-variant')
909 fm.plain(' ' * (maxvariantlength - len('format-variant')))
909 fm.plain(' ' * (maxvariantlength - len('format-variant')))
910 fm.plain(' repo')
910 fm.plain(' repo')
911 if ui.verbose:
911 if ui.verbose:
912 fm.plain(' config default')
912 fm.plain(' config default')
913 fm.plain('\n')
913 fm.plain('\n')
914 for fv in upgrade.allformatvariant:
914 for fv in upgrade.allformatvariant:
915 fm.startitem()
915 fm.startitem()
916 repovalue = fv.fromrepo(repo)
916 repovalue = fv.fromrepo(repo)
917 configvalue = fv.fromconfig(repo)
917 configvalue = fv.fromconfig(repo)
918
918
919 if repovalue != configvalue:
919 if repovalue != configvalue:
920 namelabel = 'formatvariant.name.mismatchconfig'
920 namelabel = 'formatvariant.name.mismatchconfig'
921 repolabel = 'formatvariant.repo.mismatchconfig'
921 repolabel = 'formatvariant.repo.mismatchconfig'
922 elif repovalue != fv.default:
922 elif repovalue != fv.default:
923 namelabel = 'formatvariant.name.mismatchdefault'
923 namelabel = 'formatvariant.name.mismatchdefault'
924 repolabel = 'formatvariant.repo.mismatchdefault'
924 repolabel = 'formatvariant.repo.mismatchdefault'
925 else:
925 else:
926 namelabel = 'formatvariant.name.uptodate'
926 namelabel = 'formatvariant.name.uptodate'
927 repolabel = 'formatvariant.repo.uptodate'
927 repolabel = 'formatvariant.repo.uptodate'
928
928
929 fm.write('name', makeformatname(fv.name), fv.name,
929 fm.write('name', makeformatname(fv.name), fv.name,
930 label=namelabel)
930 label=namelabel)
931 fm.write('repo', ' %3s', formatvalue(repovalue),
931 fm.write('repo', ' %3s', formatvalue(repovalue),
932 label=repolabel)
932 label=repolabel)
933 if fv.default != configvalue:
933 if fv.default != configvalue:
934 configlabel = 'formatvariant.config.special'
934 configlabel = 'formatvariant.config.special'
935 else:
935 else:
936 configlabel = 'formatvariant.config.default'
936 configlabel = 'formatvariant.config.default'
937 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
937 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
938 label=configlabel)
938 label=configlabel)
939 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
939 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
940 label='formatvariant.default')
940 label='formatvariant.default')
941 fm.plain('\n')
941 fm.plain('\n')
942 fm.end()
942 fm.end()
943
943
944 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
944 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
945 def debugfsinfo(ui, path="."):
945 def debugfsinfo(ui, path="."):
946 """show information detected about current filesystem"""
946 """show information detected about current filesystem"""
947 ui.write(('path: %s\n') % path)
947 ui.write(('path: %s\n') % path)
948 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
948 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
949 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
949 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
950 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
950 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
951 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
951 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
952 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
952 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
953 casesensitive = '(unknown)'
953 casesensitive = '(unknown)'
954 try:
954 try:
955 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
955 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
956 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
956 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
957 except OSError:
957 except OSError:
958 pass
958 pass
959 ui.write(('case-sensitive: %s\n') % casesensitive)
959 ui.write(('case-sensitive: %s\n') % casesensitive)
960
960
961 @command('debuggetbundle',
961 @command('debuggetbundle',
962 [('H', 'head', [], _('id of head node'), _('ID')),
962 [('H', 'head', [], _('id of head node'), _('ID')),
963 ('C', 'common', [], _('id of common node'), _('ID')),
963 ('C', 'common', [], _('id of common node'), _('ID')),
964 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
964 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
965 _('REPO FILE [-H|-C ID]...'),
965 _('REPO FILE [-H|-C ID]...'),
966 norepo=True)
966 norepo=True)
967 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
967 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
968 """retrieves a bundle from a repo
968 """retrieves a bundle from a repo
969
969
970 Every ID must be a full-length hex node id string. Saves the bundle to the
970 Every ID must be a full-length hex node id string. Saves the bundle to the
971 given file.
971 given file.
972 """
972 """
973 opts = pycompat.byteskwargs(opts)
973 opts = pycompat.byteskwargs(opts)
974 repo = hg.peer(ui, opts, repopath)
974 repo = hg.peer(ui, opts, repopath)
975 if not repo.capable('getbundle'):
975 if not repo.capable('getbundle'):
976 raise error.Abort("getbundle() not supported by target repository")
976 raise error.Abort("getbundle() not supported by target repository")
977 args = {}
977 args = {}
978 if common:
978 if common:
979 args[r'common'] = [bin(s) for s in common]
979 args[r'common'] = [bin(s) for s in common]
980 if head:
980 if head:
981 args[r'heads'] = [bin(s) for s in head]
981 args[r'heads'] = [bin(s) for s in head]
982 # TODO: get desired bundlecaps from command line.
982 # TODO: get desired bundlecaps from command line.
983 args[r'bundlecaps'] = None
983 args[r'bundlecaps'] = None
984 bundle = repo.getbundle('debug', **args)
984 bundle = repo.getbundle('debug', **args)
985
985
986 bundletype = opts.get('type', 'bzip2').lower()
986 bundletype = opts.get('type', 'bzip2').lower()
987 btypes = {'none': 'HG10UN',
987 btypes = {'none': 'HG10UN',
988 'bzip2': 'HG10BZ',
988 'bzip2': 'HG10BZ',
989 'gzip': 'HG10GZ',
989 'gzip': 'HG10GZ',
990 'bundle2': 'HG20'}
990 'bundle2': 'HG20'}
991 bundletype = btypes.get(bundletype)
991 bundletype = btypes.get(bundletype)
992 if bundletype not in bundle2.bundletypes:
992 if bundletype not in bundle2.bundletypes:
993 raise error.Abort(_('unknown bundle type specified with --type'))
993 raise error.Abort(_('unknown bundle type specified with --type'))
994 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
994 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
995
995
996 @command('debugignore', [], '[FILE]')
996 @command('debugignore', [], '[FILE]')
997 def debugignore(ui, repo, *files, **opts):
997 def debugignore(ui, repo, *files, **opts):
998 """display the combined ignore pattern and information about ignored files
998 """display the combined ignore pattern and information about ignored files
999
999
1000 With no argument display the combined ignore pattern.
1000 With no argument display the combined ignore pattern.
1001
1001
1002 Given space separated file names, shows if the given file is ignored and
1002 Given space separated file names, shows if the given file is ignored and
1003 if so, show the ignore rule (file and line number) that matched it.
1003 if so, show the ignore rule (file and line number) that matched it.
1004 """
1004 """
1005 ignore = repo.dirstate._ignore
1005 ignore = repo.dirstate._ignore
1006 if not files:
1006 if not files:
1007 # Show all the patterns
1007 # Show all the patterns
1008 ui.write("%s\n" % repr(ignore))
1008 ui.write("%s\n" % repr(ignore))
1009 else:
1009 else:
1010 m = scmutil.match(repo[None], pats=files)
1010 m = scmutil.match(repo[None], pats=files)
1011 for f in m.files():
1011 for f in m.files():
1012 nf = util.normpath(f)
1012 nf = util.normpath(f)
1013 ignored = None
1013 ignored = None
1014 ignoredata = None
1014 ignoredata = None
1015 if nf != '.':
1015 if nf != '.':
1016 if ignore(nf):
1016 if ignore(nf):
1017 ignored = nf
1017 ignored = nf
1018 ignoredata = repo.dirstate._ignorefileandline(nf)
1018 ignoredata = repo.dirstate._ignorefileandline(nf)
1019 else:
1019 else:
1020 for p in util.finddirs(nf):
1020 for p in util.finddirs(nf):
1021 if ignore(p):
1021 if ignore(p):
1022 ignored = p
1022 ignored = p
1023 ignoredata = repo.dirstate._ignorefileandline(p)
1023 ignoredata = repo.dirstate._ignorefileandline(p)
1024 break
1024 break
1025 if ignored:
1025 if ignored:
1026 if ignored == nf:
1026 if ignored == nf:
1027 ui.write(_("%s is ignored\n") % m.uipath(f))
1027 ui.write(_("%s is ignored\n") % m.uipath(f))
1028 else:
1028 else:
1029 ui.write(_("%s is ignored because of "
1029 ui.write(_("%s is ignored because of "
1030 "containing folder %s\n")
1030 "containing folder %s\n")
1031 % (m.uipath(f), ignored))
1031 % (m.uipath(f), ignored))
1032 ignorefile, lineno, line = ignoredata
1032 ignorefile, lineno, line = ignoredata
1033 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1033 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1034 % (ignorefile, lineno, line))
1034 % (ignorefile, lineno, line))
1035 else:
1035 else:
1036 ui.write(_("%s is not ignored\n") % m.uipath(f))
1036 ui.write(_("%s is not ignored\n") % m.uipath(f))
1037
1037
1038 @command('debugindex', cmdutil.debugrevlogopts +
1038 @command('debugindex', cmdutil.debugrevlogopts +
1039 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1039 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1040 _('[-f FORMAT] -c|-m|FILE'),
1040 _('[-f FORMAT] -c|-m|FILE'),
1041 optionalrepo=True)
1041 optionalrepo=True)
1042 def debugindex(ui, repo, file_=None, **opts):
1042 def debugindex(ui, repo, file_=None, **opts):
1043 """dump the contents of an index file"""
1043 """dump the contents of an index file"""
1044 opts = pycompat.byteskwargs(opts)
1044 opts = pycompat.byteskwargs(opts)
1045 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1045 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1046 format = opts.get('format', 0)
1046 format = opts.get('format', 0)
1047 if format not in (0, 1):
1047 if format not in (0, 1):
1048 raise error.Abort(_("unknown format %d") % format)
1048 raise error.Abort(_("unknown format %d") % format)
1049
1049
1050 generaldelta = r.version & revlog.FLAG_GENERALDELTA
1050 generaldelta = r.version & revlog.FLAG_GENERALDELTA
1051 if generaldelta:
1051 if generaldelta:
1052 basehdr = ' delta'
1052 basehdr = ' delta'
1053 else:
1053 else:
1054 basehdr = ' base'
1054 basehdr = ' base'
1055
1055
1056 if ui.debugflag:
1056 if ui.debugflag:
1057 shortfn = hex
1057 shortfn = hex
1058 else:
1058 else:
1059 shortfn = short
1059 shortfn = short
1060
1060
1061 # There might not be anything in r, so have a sane default
1061 # There might not be anything in r, so have a sane default
1062 idlen = 12
1062 idlen = 12
1063 for i in r:
1063 for i in r:
1064 idlen = len(shortfn(r.node(i)))
1064 idlen = len(shortfn(r.node(i)))
1065 break
1065 break
1066
1066
1067 if format == 0:
1067 if format == 0:
1068 ui.write((" rev offset length " + basehdr + " linkrev"
1068 ui.write((" rev offset length " + basehdr + " linkrev"
1069 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
1069 " %s %s p2\n") % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
1070 elif format == 1:
1070 elif format == 1:
1071 ui.write((" rev flag offset length"
1071 ui.write((" rev flag offset length"
1072 " size " + basehdr + " link p1 p2"
1072 " size " + basehdr + " link p1 p2"
1073 " %s\n") % "nodeid".rjust(idlen))
1073 " %s\n") % "nodeid".rjust(idlen))
1074
1074
1075 for i in r:
1075 for i in r:
1076 node = r.node(i)
1076 node = r.node(i)
1077 if generaldelta:
1077 if generaldelta:
1078 base = r.deltaparent(i)
1078 base = r.deltaparent(i)
1079 else:
1079 else:
1080 base = r.chainbase(i)
1080 base = r.chainbase(i)
1081 if format == 0:
1081 if format == 0:
1082 try:
1082 try:
1083 pp = r.parents(node)
1083 pp = r.parents(node)
1084 except Exception:
1084 except Exception:
1085 pp = [nullid, nullid]
1085 pp = [nullid, nullid]
1086 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1086 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1087 i, r.start(i), r.length(i), base, r.linkrev(i),
1087 i, r.start(i), r.length(i), base, r.linkrev(i),
1088 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1088 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1089 elif format == 1:
1089 elif format == 1:
1090 pr = r.parentrevs(i)
1090 pr = r.parentrevs(i)
1091 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1091 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1092 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1092 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1093 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
1093 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
1094
1094
1095 @command('debugindexdot', cmdutil.debugrevlogopts,
1095 @command('debugindexdot', cmdutil.debugrevlogopts,
1096 _('-c|-m|FILE'), optionalrepo=True)
1096 _('-c|-m|FILE'), optionalrepo=True)
1097 def debugindexdot(ui, repo, file_=None, **opts):
1097 def debugindexdot(ui, repo, file_=None, **opts):
1098 """dump an index DAG as a graphviz dot file"""
1098 """dump an index DAG as a graphviz dot file"""
1099 opts = pycompat.byteskwargs(opts)
1099 opts = pycompat.byteskwargs(opts)
1100 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1100 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1101 ui.write(("digraph G {\n"))
1101 ui.write(("digraph G {\n"))
1102 for i in r:
1102 for i in r:
1103 node = r.node(i)
1103 node = r.node(i)
1104 pp = r.parents(node)
1104 pp = r.parents(node)
1105 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1105 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1106 if pp[1] != nullid:
1106 if pp[1] != nullid:
1107 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1107 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1108 ui.write("}\n")
1108 ui.write("}\n")
1109
1109
1110 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1110 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1111 def debuginstall(ui, **opts):
1111 def debuginstall(ui, **opts):
1112 '''test Mercurial installation
1112 '''test Mercurial installation
1113
1113
1114 Returns 0 on success.
1114 Returns 0 on success.
1115 '''
1115 '''
1116 opts = pycompat.byteskwargs(opts)
1116 opts = pycompat.byteskwargs(opts)
1117
1117
1118 def writetemp(contents):
1118 def writetemp(contents):
1119 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1119 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1120 f = os.fdopen(fd, pycompat.sysstr("wb"))
1120 f = os.fdopen(fd, pycompat.sysstr("wb"))
1121 f.write(contents)
1121 f.write(contents)
1122 f.close()
1122 f.close()
1123 return name
1123 return name
1124
1124
1125 problems = 0
1125 problems = 0
1126
1126
1127 fm = ui.formatter('debuginstall', opts)
1127 fm = ui.formatter('debuginstall', opts)
1128 fm.startitem()
1128 fm.startitem()
1129
1129
1130 # encoding
1130 # encoding
1131 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1131 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1132 err = None
1132 err = None
1133 try:
1133 try:
1134 codecs.lookup(pycompat.sysstr(encoding.encoding))
1134 codecs.lookup(pycompat.sysstr(encoding.encoding))
1135 except LookupError as inst:
1135 except LookupError as inst:
1136 err = util.forcebytestr(inst)
1136 err = util.forcebytestr(inst)
1137 problems += 1
1137 problems += 1
1138 fm.condwrite(err, 'encodingerror', _(" %s\n"
1138 fm.condwrite(err, 'encodingerror', _(" %s\n"
1139 " (check that your locale is properly set)\n"), err)
1139 " (check that your locale is properly set)\n"), err)
1140
1140
1141 # Python
1141 # Python
1142 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1142 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1143 pycompat.sysexecutable)
1143 pycompat.sysexecutable)
1144 fm.write('pythonver', _("checking Python version (%s)\n"),
1144 fm.write('pythonver', _("checking Python version (%s)\n"),
1145 ("%d.%d.%d" % sys.version_info[:3]))
1145 ("%d.%d.%d" % sys.version_info[:3]))
1146 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1146 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1147 os.path.dirname(pycompat.fsencode(os.__file__)))
1147 os.path.dirname(pycompat.fsencode(os.__file__)))
1148
1148
1149 security = set(sslutil.supportedprotocols)
1149 security = set(sslutil.supportedprotocols)
1150 if sslutil.hassni:
1150 if sslutil.hassni:
1151 security.add('sni')
1151 security.add('sni')
1152
1152
1153 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1153 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1154 fm.formatlist(sorted(security), name='protocol',
1154 fm.formatlist(sorted(security), name='protocol',
1155 fmt='%s', sep=','))
1155 fmt='%s', sep=','))
1156
1156
1157 # These are warnings, not errors. So don't increment problem count. This
1157 # These are warnings, not errors. So don't increment problem count. This
1158 # may change in the future.
1158 # may change in the future.
1159 if 'tls1.2' not in security:
1159 if 'tls1.2' not in security:
1160 fm.plain(_(' TLS 1.2 not supported by Python install; '
1160 fm.plain(_(' TLS 1.2 not supported by Python install; '
1161 'network connections lack modern security\n'))
1161 'network connections lack modern security\n'))
1162 if 'sni' not in security:
1162 if 'sni' not in security:
1163 fm.plain(_(' SNI not supported by Python install; may have '
1163 fm.plain(_(' SNI not supported by Python install; may have '
1164 'connectivity issues with some servers\n'))
1164 'connectivity issues with some servers\n'))
1165
1165
1166 # TODO print CA cert info
1166 # TODO print CA cert info
1167
1167
1168 # hg version
1168 # hg version
1169 hgver = util.version()
1169 hgver = util.version()
1170 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1170 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1171 hgver.split('+')[0])
1171 hgver.split('+')[0])
1172 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1172 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1173 '+'.join(hgver.split('+')[1:]))
1173 '+'.join(hgver.split('+')[1:]))
1174
1174
1175 # compiled modules
1175 # compiled modules
1176 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1176 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1177 policy.policy)
1177 policy.policy)
1178 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1178 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1179 os.path.dirname(pycompat.fsencode(__file__)))
1179 os.path.dirname(pycompat.fsencode(__file__)))
1180
1180
1181 if policy.policy in ('c', 'allow'):
1181 if policy.policy in ('c', 'allow'):
1182 err = None
1182 err = None
1183 try:
1183 try:
1184 from .cext import (
1184 from .cext import (
1185 base85,
1185 base85,
1186 bdiff,
1186 bdiff,
1187 mpatch,
1187 mpatch,
1188 osutil,
1188 osutil,
1189 )
1189 )
1190 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1190 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1191 except Exception as inst:
1191 except Exception as inst:
1192 err = util.forcebytestr(inst)
1192 err = util.forcebytestr(inst)
1193 problems += 1
1193 problems += 1
1194 fm.condwrite(err, 'extensionserror', " %s\n", err)
1194 fm.condwrite(err, 'extensionserror', " %s\n", err)
1195
1195
1196 compengines = util.compengines._engines.values()
1196 compengines = util.compengines._engines.values()
1197 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1197 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1198 fm.formatlist(sorted(e.name() for e in compengines),
1198 fm.formatlist(sorted(e.name() for e in compengines),
1199 name='compengine', fmt='%s', sep=', '))
1199 name='compengine', fmt='%s', sep=', '))
1200 fm.write('compenginesavail', _('checking available compression engines '
1200 fm.write('compenginesavail', _('checking available compression engines '
1201 '(%s)\n'),
1201 '(%s)\n'),
1202 fm.formatlist(sorted(e.name() for e in compengines
1202 fm.formatlist(sorted(e.name() for e in compengines
1203 if e.available()),
1203 if e.available()),
1204 name='compengine', fmt='%s', sep=', '))
1204 name='compengine', fmt='%s', sep=', '))
1205 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1205 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1206 fm.write('compenginesserver', _('checking available compression engines '
1206 fm.write('compenginesserver', _('checking available compression engines '
1207 'for wire protocol (%s)\n'),
1207 'for wire protocol (%s)\n'),
1208 fm.formatlist([e.name() for e in wirecompengines
1208 fm.formatlist([e.name() for e in wirecompengines
1209 if e.wireprotosupport()],
1209 if e.wireprotosupport()],
1210 name='compengine', fmt='%s', sep=', '))
1210 name='compengine', fmt='%s', sep=', '))
1211 re2 = 'missing'
1211 re2 = 'missing'
1212 if util._re2:
1212 if util._re2:
1213 re2 = 'available'
1213 re2 = 'available'
1214 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1214 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1215 fm.data(re2=bool(util._re2))
1215 fm.data(re2=bool(util._re2))
1216
1216
1217 # templates
1217 # templates
1218 p = templater.templatepaths()
1218 p = templater.templatepaths()
1219 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1219 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1220 fm.condwrite(not p, '', _(" no template directories found\n"))
1220 fm.condwrite(not p, '', _(" no template directories found\n"))
1221 if p:
1221 if p:
1222 m = templater.templatepath("map-cmdline.default")
1222 m = templater.templatepath("map-cmdline.default")
1223 if m:
1223 if m:
1224 # template found, check if it is working
1224 # template found, check if it is working
1225 err = None
1225 err = None
1226 try:
1226 try:
1227 templater.templater.frommapfile(m)
1227 templater.templater.frommapfile(m)
1228 except Exception as inst:
1228 except Exception as inst:
1229 err = util.forcebytestr(inst)
1229 err = util.forcebytestr(inst)
1230 p = None
1230 p = None
1231 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1231 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1232 else:
1232 else:
1233 p = None
1233 p = None
1234 fm.condwrite(p, 'defaulttemplate',
1234 fm.condwrite(p, 'defaulttemplate',
1235 _("checking default template (%s)\n"), m)
1235 _("checking default template (%s)\n"), m)
1236 fm.condwrite(not m, 'defaulttemplatenotfound',
1236 fm.condwrite(not m, 'defaulttemplatenotfound',
1237 _(" template '%s' not found\n"), "default")
1237 _(" template '%s' not found\n"), "default")
1238 if not p:
1238 if not p:
1239 problems += 1
1239 problems += 1
1240 fm.condwrite(not p, '',
1240 fm.condwrite(not p, '',
1241 _(" (templates seem to have been installed incorrectly)\n"))
1241 _(" (templates seem to have been installed incorrectly)\n"))
1242
1242
1243 # editor
1243 # editor
1244 editor = ui.geteditor()
1244 editor = ui.geteditor()
1245 editor = util.expandpath(editor)
1245 editor = util.expandpath(editor)
1246 editorbin = util.shellsplit(editor)[0]
1246 editorbin = util.shellsplit(editor)[0]
1247 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1247 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1248 cmdpath = util.findexe(editorbin)
1248 cmdpath = util.findexe(editorbin)
1249 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1249 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1250 _(" No commit editor set and can't find %s in PATH\n"
1250 _(" No commit editor set and can't find %s in PATH\n"
1251 " (specify a commit editor in your configuration"
1251 " (specify a commit editor in your configuration"
1252 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1252 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1253 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1253 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1254 _(" Can't find editor '%s' in PATH\n"
1254 _(" Can't find editor '%s' in PATH\n"
1255 " (specify a commit editor in your configuration"
1255 " (specify a commit editor in your configuration"
1256 " file)\n"), not cmdpath and editorbin)
1256 " file)\n"), not cmdpath and editorbin)
1257 if not cmdpath and editor != 'vi':
1257 if not cmdpath and editor != 'vi':
1258 problems += 1
1258 problems += 1
1259
1259
1260 # check username
1260 # check username
1261 username = None
1261 username = None
1262 err = None
1262 err = None
1263 try:
1263 try:
1264 username = ui.username()
1264 username = ui.username()
1265 except error.Abort as e:
1265 except error.Abort as e:
1266 err = util.forcebytestr(e)
1266 err = util.forcebytestr(e)
1267 problems += 1
1267 problems += 1
1268
1268
1269 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1269 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1270 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1270 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1271 " (specify a username in your configuration file)\n"), err)
1271 " (specify a username in your configuration file)\n"), err)
1272
1272
1273 fm.condwrite(not problems, '',
1273 fm.condwrite(not problems, '',
1274 _("no problems detected\n"))
1274 _("no problems detected\n"))
1275 if not problems:
1275 if not problems:
1276 fm.data(problems=problems)
1276 fm.data(problems=problems)
1277 fm.condwrite(problems, 'problems',
1277 fm.condwrite(problems, 'problems',
1278 _("%d problems detected,"
1278 _("%d problems detected,"
1279 " please check your install!\n"), problems)
1279 " please check your install!\n"), problems)
1280 fm.end()
1280 fm.end()
1281
1281
1282 return problems
1282 return problems
1283
1283
1284 @command('debugknown', [], _('REPO ID...'), norepo=True)
1284 @command('debugknown', [], _('REPO ID...'), norepo=True)
1285 def debugknown(ui, repopath, *ids, **opts):
1285 def debugknown(ui, repopath, *ids, **opts):
1286 """test whether node ids are known to a repo
1286 """test whether node ids are known to a repo
1287
1287
1288 Every ID must be a full-length hex node id string. Returns a list of 0s
1288 Every ID must be a full-length hex node id string. Returns a list of 0s
1289 and 1s indicating unknown/known.
1289 and 1s indicating unknown/known.
1290 """
1290 """
1291 opts = pycompat.byteskwargs(opts)
1291 opts = pycompat.byteskwargs(opts)
1292 repo = hg.peer(ui, opts, repopath)
1292 repo = hg.peer(ui, opts, repopath)
1293 if not repo.capable('known'):
1293 if not repo.capable('known'):
1294 raise error.Abort("known() not supported by target repository")
1294 raise error.Abort("known() not supported by target repository")
1295 flags = repo.known([bin(s) for s in ids])
1295 flags = repo.known([bin(s) for s in ids])
1296 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1296 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1297
1297
1298 @command('debuglabelcomplete', [], _('LABEL...'))
1298 @command('debuglabelcomplete', [], _('LABEL...'))
1299 def debuglabelcomplete(ui, repo, *args):
1299 def debuglabelcomplete(ui, repo, *args):
1300 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1300 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1301 debugnamecomplete(ui, repo, *args)
1301 debugnamecomplete(ui, repo, *args)
1302
1302
1303 @command('debuglocks',
1303 @command('debuglocks',
1304 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1304 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1305 ('W', 'force-wlock', None,
1305 ('W', 'force-wlock', None,
1306 _('free the working state lock (DANGEROUS)')),
1306 _('free the working state lock (DANGEROUS)')),
1307 ('s', 'set-lock', None, _('set the store lock until stopped')),
1307 ('s', 'set-lock', None, _('set the store lock until stopped')),
1308 ('S', 'set-wlock', None,
1308 ('S', 'set-wlock', None,
1309 _('set the working state lock until stopped'))],
1309 _('set the working state lock until stopped'))],
1310 _('[OPTION]...'))
1310 _('[OPTION]...'))
1311 def debuglocks(ui, repo, **opts):
1311 def debuglocks(ui, repo, **opts):
1312 """show or modify state of locks
1312 """show or modify state of locks
1313
1313
1314 By default, this command will show which locks are held. This
1314 By default, this command will show which locks are held. This
1315 includes the user and process holding the lock, the amount of time
1315 includes the user and process holding the lock, the amount of time
1316 the lock has been held, and the machine name where the process is
1316 the lock has been held, and the machine name where the process is
1317 running if it's not local.
1317 running if it's not local.
1318
1318
1319 Locks protect the integrity of Mercurial's data, so should be
1319 Locks protect the integrity of Mercurial's data, so should be
1320 treated with care. System crashes or other interruptions may cause
1320 treated with care. System crashes or other interruptions may cause
1321 locks to not be properly released, though Mercurial will usually
1321 locks to not be properly released, though Mercurial will usually
1322 detect and remove such stale locks automatically.
1322 detect and remove such stale locks automatically.
1323
1323
1324 However, detecting stale locks may not always be possible (for
1324 However, detecting stale locks may not always be possible (for
1325 instance, on a shared filesystem). Removing locks may also be
1325 instance, on a shared filesystem). Removing locks may also be
1326 blocked by filesystem permissions.
1326 blocked by filesystem permissions.
1327
1327
1328 Setting a lock will prevent other commands from changing the data.
1328 Setting a lock will prevent other commands from changing the data.
1329 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1329 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1330 The set locks are removed when the command exits.
1330 The set locks are removed when the command exits.
1331
1331
1332 Returns 0 if no locks are held.
1332 Returns 0 if no locks are held.
1333
1333
1334 """
1334 """
1335
1335
1336 if opts.get(r'force_lock'):
1336 if opts.get(r'force_lock'):
1337 repo.svfs.unlink('lock')
1337 repo.svfs.unlink('lock')
1338 if opts.get(r'force_wlock'):
1338 if opts.get(r'force_wlock'):
1339 repo.vfs.unlink('wlock')
1339 repo.vfs.unlink('wlock')
1340 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1340 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1341 return 0
1341 return 0
1342
1342
1343 locks = []
1343 locks = []
1344 try:
1344 try:
1345 if opts.get(r'set_wlock'):
1345 if opts.get(r'set_wlock'):
1346 try:
1346 try:
1347 locks.append(repo.wlock(False))
1347 locks.append(repo.wlock(False))
1348 except error.LockHeld:
1348 except error.LockHeld:
1349 raise error.Abort(_('wlock is already held'))
1349 raise error.Abort(_('wlock is already held'))
1350 if opts.get(r'set_lock'):
1350 if opts.get(r'set_lock'):
1351 try:
1351 try:
1352 locks.append(repo.lock(False))
1352 locks.append(repo.lock(False))
1353 except error.LockHeld:
1353 except error.LockHeld:
1354 raise error.Abort(_('lock is already held'))
1354 raise error.Abort(_('lock is already held'))
1355 if len(locks):
1355 if len(locks):
1356 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1356 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1357 return 0
1357 return 0
1358 finally:
1358 finally:
1359 release(*locks)
1359 release(*locks)
1360
1360
1361 now = time.time()
1361 now = time.time()
1362 held = 0
1362 held = 0
1363
1363
1364 def report(vfs, name, method):
1364 def report(vfs, name, method):
1365 # this causes stale locks to get reaped for more accurate reporting
1365 # this causes stale locks to get reaped for more accurate reporting
1366 try:
1366 try:
1367 l = method(False)
1367 l = method(False)
1368 except error.LockHeld:
1368 except error.LockHeld:
1369 l = None
1369 l = None
1370
1370
1371 if l:
1371 if l:
1372 l.release()
1372 l.release()
1373 else:
1373 else:
1374 try:
1374 try:
1375 stat = vfs.lstat(name)
1375 stat = vfs.lstat(name)
1376 age = now - stat.st_mtime
1376 age = now - stat.st_mtime
1377 user = util.username(stat.st_uid)
1377 user = util.username(stat.st_uid)
1378 locker = vfs.readlock(name)
1378 locker = vfs.readlock(name)
1379 if ":" in locker:
1379 if ":" in locker:
1380 host, pid = locker.split(':')
1380 host, pid = locker.split(':')
1381 if host == socket.gethostname():
1381 if host == socket.gethostname():
1382 locker = 'user %s, process %s' % (user, pid)
1382 locker = 'user %s, process %s' % (user, pid)
1383 else:
1383 else:
1384 locker = 'user %s, process %s, host %s' \
1384 locker = 'user %s, process %s, host %s' \
1385 % (user, pid, host)
1385 % (user, pid, host)
1386 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1386 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1387 return 1
1387 return 1
1388 except OSError as e:
1388 except OSError as e:
1389 if e.errno != errno.ENOENT:
1389 if e.errno != errno.ENOENT:
1390 raise
1390 raise
1391
1391
1392 ui.write(("%-6s free\n") % (name + ":"))
1392 ui.write(("%-6s free\n") % (name + ":"))
1393 return 0
1393 return 0
1394
1394
1395 held += report(repo.svfs, "lock", repo.lock)
1395 held += report(repo.svfs, "lock", repo.lock)
1396 held += report(repo.vfs, "wlock", repo.wlock)
1396 held += report(repo.vfs, "wlock", repo.wlock)
1397
1397
1398 return held
1398 return held
1399
1399
1400 @command('debugmergestate', [], '')
1400 @command('debugmergestate', [], '')
1401 def debugmergestate(ui, repo, *args):
1401 def debugmergestate(ui, repo, *args):
1402 """print merge state
1402 """print merge state
1403
1403
1404 Use --verbose to print out information about whether v1 or v2 merge state
1404 Use --verbose to print out information about whether v1 or v2 merge state
1405 was chosen."""
1405 was chosen."""
1406 def _hashornull(h):
1406 def _hashornull(h):
1407 if h == nullhex:
1407 if h == nullhex:
1408 return 'null'
1408 return 'null'
1409 else:
1409 else:
1410 return h
1410 return h
1411
1411
1412 def printrecords(version):
1412 def printrecords(version):
1413 ui.write(('* version %d records\n') % version)
1413 ui.write(('* version %d records\n') % version)
1414 if version == 1:
1414 if version == 1:
1415 records = v1records
1415 records = v1records
1416 else:
1416 else:
1417 records = v2records
1417 records = v2records
1418
1418
1419 for rtype, record in records:
1419 for rtype, record in records:
1420 # pretty print some record types
1420 # pretty print some record types
1421 if rtype == 'L':
1421 if rtype == 'L':
1422 ui.write(('local: %s\n') % record)
1422 ui.write(('local: %s\n') % record)
1423 elif rtype == 'O':
1423 elif rtype == 'O':
1424 ui.write(('other: %s\n') % record)
1424 ui.write(('other: %s\n') % record)
1425 elif rtype == 'm':
1425 elif rtype == 'm':
1426 driver, mdstate = record.split('\0', 1)
1426 driver, mdstate = record.split('\0', 1)
1427 ui.write(('merge driver: %s (state "%s")\n')
1427 ui.write(('merge driver: %s (state "%s")\n')
1428 % (driver, mdstate))
1428 % (driver, mdstate))
1429 elif rtype in 'FDC':
1429 elif rtype in 'FDC':
1430 r = record.split('\0')
1430 r = record.split('\0')
1431 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1431 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1432 if version == 1:
1432 if version == 1:
1433 onode = 'not stored in v1 format'
1433 onode = 'not stored in v1 format'
1434 flags = r[7]
1434 flags = r[7]
1435 else:
1435 else:
1436 onode, flags = r[7:9]
1436 onode, flags = r[7:9]
1437 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1437 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1438 % (f, rtype, state, _hashornull(hash)))
1438 % (f, rtype, state, _hashornull(hash)))
1439 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1439 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1440 ui.write((' ancestor path: %s (node %s)\n')
1440 ui.write((' ancestor path: %s (node %s)\n')
1441 % (afile, _hashornull(anode)))
1441 % (afile, _hashornull(anode)))
1442 ui.write((' other path: %s (node %s)\n')
1442 ui.write((' other path: %s (node %s)\n')
1443 % (ofile, _hashornull(onode)))
1443 % (ofile, _hashornull(onode)))
1444 elif rtype == 'f':
1444 elif rtype == 'f':
1445 filename, rawextras = record.split('\0', 1)
1445 filename, rawextras = record.split('\0', 1)
1446 extras = rawextras.split('\0')
1446 extras = rawextras.split('\0')
1447 i = 0
1447 i = 0
1448 extrastrings = []
1448 extrastrings = []
1449 while i < len(extras):
1449 while i < len(extras):
1450 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1450 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1451 i += 2
1451 i += 2
1452
1452
1453 ui.write(('file extras: %s (%s)\n')
1453 ui.write(('file extras: %s (%s)\n')
1454 % (filename, ', '.join(extrastrings)))
1454 % (filename, ', '.join(extrastrings)))
1455 elif rtype == 'l':
1455 elif rtype == 'l':
1456 labels = record.split('\0', 2)
1456 labels = record.split('\0', 2)
1457 labels = [l for l in labels if len(l) > 0]
1457 labels = [l for l in labels if len(l) > 0]
1458 ui.write(('labels:\n'))
1458 ui.write(('labels:\n'))
1459 ui.write((' local: %s\n' % labels[0]))
1459 ui.write((' local: %s\n' % labels[0]))
1460 ui.write((' other: %s\n' % labels[1]))
1460 ui.write((' other: %s\n' % labels[1]))
1461 if len(labels) > 2:
1461 if len(labels) > 2:
1462 ui.write((' base: %s\n' % labels[2]))
1462 ui.write((' base: %s\n' % labels[2]))
1463 else:
1463 else:
1464 ui.write(('unrecognized entry: %s\t%s\n')
1464 ui.write(('unrecognized entry: %s\t%s\n')
1465 % (rtype, record.replace('\0', '\t')))
1465 % (rtype, record.replace('\0', '\t')))
1466
1466
1467 # Avoid mergestate.read() since it may raise an exception for unsupported
1467 # Avoid mergestate.read() since it may raise an exception for unsupported
1468 # merge state records. We shouldn't be doing this, but this is OK since this
1468 # merge state records. We shouldn't be doing this, but this is OK since this
1469 # command is pretty low-level.
1469 # command is pretty low-level.
1470 ms = mergemod.mergestate(repo)
1470 ms = mergemod.mergestate(repo)
1471
1471
1472 # sort so that reasonable information is on top
1472 # sort so that reasonable information is on top
1473 v1records = ms._readrecordsv1()
1473 v1records = ms._readrecordsv1()
1474 v2records = ms._readrecordsv2()
1474 v2records = ms._readrecordsv2()
1475 order = 'LOml'
1475 order = 'LOml'
1476 def key(r):
1476 def key(r):
1477 idx = order.find(r[0])
1477 idx = order.find(r[0])
1478 if idx == -1:
1478 if idx == -1:
1479 return (1, r[1])
1479 return (1, r[1])
1480 else:
1480 else:
1481 return (0, idx)
1481 return (0, idx)
1482 v1records.sort(key=key)
1482 v1records.sort(key=key)
1483 v2records.sort(key=key)
1483 v2records.sort(key=key)
1484
1484
1485 if not v1records and not v2records:
1485 if not v1records and not v2records:
1486 ui.write(('no merge state found\n'))
1486 ui.write(('no merge state found\n'))
1487 elif not v2records:
1487 elif not v2records:
1488 ui.note(('no version 2 merge state\n'))
1488 ui.note(('no version 2 merge state\n'))
1489 printrecords(1)
1489 printrecords(1)
1490 elif ms._v1v2match(v1records, v2records):
1490 elif ms._v1v2match(v1records, v2records):
1491 ui.note(('v1 and v2 states match: using v2\n'))
1491 ui.note(('v1 and v2 states match: using v2\n'))
1492 printrecords(2)
1492 printrecords(2)
1493 else:
1493 else:
1494 ui.note(('v1 and v2 states mismatch: using v1\n'))
1494 ui.note(('v1 and v2 states mismatch: using v1\n'))
1495 printrecords(1)
1495 printrecords(1)
1496 if ui.verbose:
1496 if ui.verbose:
1497 printrecords(2)
1497 printrecords(2)
1498
1498
1499 @command('debugnamecomplete', [], _('NAME...'))
1499 @command('debugnamecomplete', [], _('NAME...'))
1500 def debugnamecomplete(ui, repo, *args):
1500 def debugnamecomplete(ui, repo, *args):
1501 '''complete "names" - tags, open branch names, bookmark names'''
1501 '''complete "names" - tags, open branch names, bookmark names'''
1502
1502
1503 names = set()
1503 names = set()
1504 # since we previously only listed open branches, we will handle that
1504 # since we previously only listed open branches, we will handle that
1505 # specially (after this for loop)
1505 # specially (after this for loop)
1506 for name, ns in repo.names.iteritems():
1506 for name, ns in repo.names.iteritems():
1507 if name != 'branches':
1507 if name != 'branches':
1508 names.update(ns.listnames(repo))
1508 names.update(ns.listnames(repo))
1509 names.update(tag for (tag, heads, tip, closed)
1509 names.update(tag for (tag, heads, tip, closed)
1510 in repo.branchmap().iterbranches() if not closed)
1510 in repo.branchmap().iterbranches() if not closed)
1511 completions = set()
1511 completions = set()
1512 if not args:
1512 if not args:
1513 args = ['']
1513 args = ['']
1514 for a in args:
1514 for a in args:
1515 completions.update(n for n in names if n.startswith(a))
1515 completions.update(n for n in names if n.startswith(a))
1516 ui.write('\n'.join(sorted(completions)))
1516 ui.write('\n'.join(sorted(completions)))
1517 ui.write('\n')
1517 ui.write('\n')
1518
1518
1519 @command('debugobsolete',
1519 @command('debugobsolete',
1520 [('', 'flags', 0, _('markers flag')),
1520 [('', 'flags', 0, _('markers flag')),
1521 ('', 'record-parents', False,
1521 ('', 'record-parents', False,
1522 _('record parent information for the precursor')),
1522 _('record parent information for the precursor')),
1523 ('r', 'rev', [], _('display markers relevant to REV')),
1523 ('r', 'rev', [], _('display markers relevant to REV')),
1524 ('', 'exclusive', False, _('restrict display to markers only '
1524 ('', 'exclusive', False, _('restrict display to markers only '
1525 'relevant to REV')),
1525 'relevant to REV')),
1526 ('', 'index', False, _('display index of the marker')),
1526 ('', 'index', False, _('display index of the marker')),
1527 ('', 'delete', [], _('delete markers specified by indices')),
1527 ('', 'delete', [], _('delete markers specified by indices')),
1528 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1528 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1529 _('[OBSOLETED [REPLACEMENT ...]]'))
1529 _('[OBSOLETED [REPLACEMENT ...]]'))
1530 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1530 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1531 """create arbitrary obsolete marker
1531 """create arbitrary obsolete marker
1532
1532
1533 With no arguments, displays the list of obsolescence markers."""
1533 With no arguments, displays the list of obsolescence markers."""
1534
1534
1535 opts = pycompat.byteskwargs(opts)
1535 opts = pycompat.byteskwargs(opts)
1536
1536
1537 def parsenodeid(s):
1537 def parsenodeid(s):
1538 try:
1538 try:
1539 # We do not use revsingle/revrange functions here to accept
1539 # We do not use revsingle/revrange functions here to accept
1540 # arbitrary node identifiers, possibly not present in the
1540 # arbitrary node identifiers, possibly not present in the
1541 # local repository.
1541 # local repository.
1542 n = bin(s)
1542 n = bin(s)
1543 if len(n) != len(nullid):
1543 if len(n) != len(nullid):
1544 raise TypeError()
1544 raise TypeError()
1545 return n
1545 return n
1546 except TypeError:
1546 except TypeError:
1547 raise error.Abort('changeset references must be full hexadecimal '
1547 raise error.Abort('changeset references must be full hexadecimal '
1548 'node identifiers')
1548 'node identifiers')
1549
1549
1550 if opts.get('delete'):
1550 if opts.get('delete'):
1551 indices = []
1551 indices = []
1552 for v in opts.get('delete'):
1552 for v in opts.get('delete'):
1553 try:
1553 try:
1554 indices.append(int(v))
1554 indices.append(int(v))
1555 except ValueError:
1555 except ValueError:
1556 raise error.Abort(_('invalid index value: %r') % v,
1556 raise error.Abort(_('invalid index value: %r') % v,
1557 hint=_('use integers for indices'))
1557 hint=_('use integers for indices'))
1558
1558
1559 if repo.currenttransaction():
1559 if repo.currenttransaction():
1560 raise error.Abort(_('cannot delete obsmarkers in the middle '
1560 raise error.Abort(_('cannot delete obsmarkers in the middle '
1561 'of transaction.'))
1561 'of transaction.'))
1562
1562
1563 with repo.lock():
1563 with repo.lock():
1564 n = repair.deleteobsmarkers(repo.obsstore, indices)
1564 n = repair.deleteobsmarkers(repo.obsstore, indices)
1565 ui.write(_('deleted %i obsolescence markers\n') % n)
1565 ui.write(_('deleted %i obsolescence markers\n') % n)
1566
1566
1567 return
1567 return
1568
1568
1569 if precursor is not None:
1569 if precursor is not None:
1570 if opts['rev']:
1570 if opts['rev']:
1571 raise error.Abort('cannot select revision when creating marker')
1571 raise error.Abort('cannot select revision when creating marker')
1572 metadata = {}
1572 metadata = {}
1573 metadata['user'] = opts['user'] or ui.username()
1573 metadata['user'] = opts['user'] or ui.username()
1574 succs = tuple(parsenodeid(succ) for succ in successors)
1574 succs = tuple(parsenodeid(succ) for succ in successors)
1575 l = repo.lock()
1575 l = repo.lock()
1576 try:
1576 try:
1577 tr = repo.transaction('debugobsolete')
1577 tr = repo.transaction('debugobsolete')
1578 try:
1578 try:
1579 date = opts.get('date')
1579 date = opts.get('date')
1580 if date:
1580 if date:
1581 date = util.parsedate(date)
1581 date = util.parsedate(date)
1582 else:
1582 else:
1583 date = None
1583 date = None
1584 prec = parsenodeid(precursor)
1584 prec = parsenodeid(precursor)
1585 parents = None
1585 parents = None
1586 if opts['record_parents']:
1586 if opts['record_parents']:
1587 if prec not in repo.unfiltered():
1587 if prec not in repo.unfiltered():
1588 raise error.Abort('cannot used --record-parents on '
1588 raise error.Abort('cannot used --record-parents on '
1589 'unknown changesets')
1589 'unknown changesets')
1590 parents = repo.unfiltered()[prec].parents()
1590 parents = repo.unfiltered()[prec].parents()
1591 parents = tuple(p.node() for p in parents)
1591 parents = tuple(p.node() for p in parents)
1592 repo.obsstore.create(tr, prec, succs, opts['flags'],
1592 repo.obsstore.create(tr, prec, succs, opts['flags'],
1593 parents=parents, date=date,
1593 parents=parents, date=date,
1594 metadata=metadata, ui=ui)
1594 metadata=metadata, ui=ui)
1595 tr.close()
1595 tr.close()
1596 except ValueError as exc:
1596 except ValueError as exc:
1597 raise error.Abort(_('bad obsmarker input: %s') %
1597 raise error.Abort(_('bad obsmarker input: %s') %
1598 pycompat.bytestr(exc))
1598 pycompat.bytestr(exc))
1599 finally:
1599 finally:
1600 tr.release()
1600 tr.release()
1601 finally:
1601 finally:
1602 l.release()
1602 l.release()
1603 else:
1603 else:
1604 if opts['rev']:
1604 if opts['rev']:
1605 revs = scmutil.revrange(repo, opts['rev'])
1605 revs = scmutil.revrange(repo, opts['rev'])
1606 nodes = [repo[r].node() for r in revs]
1606 nodes = [repo[r].node() for r in revs]
1607 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1607 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1608 exclusive=opts['exclusive']))
1608 exclusive=opts['exclusive']))
1609 markers.sort(key=lambda x: x._data)
1609 markers.sort(key=lambda x: x._data)
1610 else:
1610 else:
1611 markers = obsutil.getmarkers(repo)
1611 markers = obsutil.getmarkers(repo)
1612
1612
1613 markerstoiter = markers
1613 markerstoiter = markers
1614 isrelevant = lambda m: True
1614 isrelevant = lambda m: True
1615 if opts.get('rev') and opts.get('index'):
1615 if opts.get('rev') and opts.get('index'):
1616 markerstoiter = obsutil.getmarkers(repo)
1616 markerstoiter = obsutil.getmarkers(repo)
1617 markerset = set(markers)
1617 markerset = set(markers)
1618 isrelevant = lambda m: m in markerset
1618 isrelevant = lambda m: m in markerset
1619
1619
1620 fm = ui.formatter('debugobsolete', opts)
1620 fm = ui.formatter('debugobsolete', opts)
1621 for i, m in enumerate(markerstoiter):
1621 for i, m in enumerate(markerstoiter):
1622 if not isrelevant(m):
1622 if not isrelevant(m):
1623 # marker can be irrelevant when we're iterating over a set
1623 # marker can be irrelevant when we're iterating over a set
1624 # of markers (markerstoiter) which is bigger than the set
1624 # of markers (markerstoiter) which is bigger than the set
1625 # of markers we want to display (markers)
1625 # of markers we want to display (markers)
1626 # this can happen if both --index and --rev options are
1626 # this can happen if both --index and --rev options are
1627 # provided and thus we need to iterate over all of the markers
1627 # provided and thus we need to iterate over all of the markers
1628 # to get the correct indices, but only display the ones that
1628 # to get the correct indices, but only display the ones that
1629 # are relevant to --rev value
1629 # are relevant to --rev value
1630 continue
1630 continue
1631 fm.startitem()
1631 fm.startitem()
1632 ind = i if opts.get('index') else None
1632 ind = i if opts.get('index') else None
1633 cmdutil.showmarker(fm, m, index=ind)
1633 cmdutil.showmarker(fm, m, index=ind)
1634 fm.end()
1634 fm.end()
1635
1635
1636 @command('debugpathcomplete',
1636 @command('debugpathcomplete',
1637 [('f', 'full', None, _('complete an entire path')),
1637 [('f', 'full', None, _('complete an entire path')),
1638 ('n', 'normal', None, _('show only normal files')),
1638 ('n', 'normal', None, _('show only normal files')),
1639 ('a', 'added', None, _('show only added files')),
1639 ('a', 'added', None, _('show only added files')),
1640 ('r', 'removed', None, _('show only removed files'))],
1640 ('r', 'removed', None, _('show only removed files'))],
1641 _('FILESPEC...'))
1641 _('FILESPEC...'))
1642 def debugpathcomplete(ui, repo, *specs, **opts):
1642 def debugpathcomplete(ui, repo, *specs, **opts):
1643 '''complete part or all of a tracked path
1643 '''complete part or all of a tracked path
1644
1644
1645 This command supports shells that offer path name completion. It
1645 This command supports shells that offer path name completion. It
1646 currently completes only files already known to the dirstate.
1646 currently completes only files already known to the dirstate.
1647
1647
1648 Completion extends only to the next path segment unless
1648 Completion extends only to the next path segment unless
1649 --full is specified, in which case entire paths are used.'''
1649 --full is specified, in which case entire paths are used.'''
1650
1650
1651 def complete(path, acceptable):
1651 def complete(path, acceptable):
1652 dirstate = repo.dirstate
1652 dirstate = repo.dirstate
1653 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1653 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1654 rootdir = repo.root + pycompat.ossep
1654 rootdir = repo.root + pycompat.ossep
1655 if spec != repo.root and not spec.startswith(rootdir):
1655 if spec != repo.root and not spec.startswith(rootdir):
1656 return [], []
1656 return [], []
1657 if os.path.isdir(spec):
1657 if os.path.isdir(spec):
1658 spec += '/'
1658 spec += '/'
1659 spec = spec[len(rootdir):]
1659 spec = spec[len(rootdir):]
1660 fixpaths = pycompat.ossep != '/'
1660 fixpaths = pycompat.ossep != '/'
1661 if fixpaths:
1661 if fixpaths:
1662 spec = spec.replace(pycompat.ossep, '/')
1662 spec = spec.replace(pycompat.ossep, '/')
1663 speclen = len(spec)
1663 speclen = len(spec)
1664 fullpaths = opts[r'full']
1664 fullpaths = opts[r'full']
1665 files, dirs = set(), set()
1665 files, dirs = set(), set()
1666 adddir, addfile = dirs.add, files.add
1666 adddir, addfile = dirs.add, files.add
1667 for f, st in dirstate.iteritems():
1667 for f, st in dirstate.iteritems():
1668 if f.startswith(spec) and st[0] in acceptable:
1668 if f.startswith(spec) and st[0] in acceptable:
1669 if fixpaths:
1669 if fixpaths:
1670 f = f.replace('/', pycompat.ossep)
1670 f = f.replace('/', pycompat.ossep)
1671 if fullpaths:
1671 if fullpaths:
1672 addfile(f)
1672 addfile(f)
1673 continue
1673 continue
1674 s = f.find(pycompat.ossep, speclen)
1674 s = f.find(pycompat.ossep, speclen)
1675 if s >= 0:
1675 if s >= 0:
1676 adddir(f[:s])
1676 adddir(f[:s])
1677 else:
1677 else:
1678 addfile(f)
1678 addfile(f)
1679 return files, dirs
1679 return files, dirs
1680
1680
1681 acceptable = ''
1681 acceptable = ''
1682 if opts[r'normal']:
1682 if opts[r'normal']:
1683 acceptable += 'nm'
1683 acceptable += 'nm'
1684 if opts[r'added']:
1684 if opts[r'added']:
1685 acceptable += 'a'
1685 acceptable += 'a'
1686 if opts[r'removed']:
1686 if opts[r'removed']:
1687 acceptable += 'r'
1687 acceptable += 'r'
1688 cwd = repo.getcwd()
1688 cwd = repo.getcwd()
1689 if not specs:
1689 if not specs:
1690 specs = ['.']
1690 specs = ['.']
1691
1691
1692 files, dirs = set(), set()
1692 files, dirs = set(), set()
1693 for spec in specs:
1693 for spec in specs:
1694 f, d = complete(spec, acceptable or 'nmar')
1694 f, d = complete(spec, acceptable or 'nmar')
1695 files.update(f)
1695 files.update(f)
1696 dirs.update(d)
1696 dirs.update(d)
1697 files.update(dirs)
1697 files.update(dirs)
1698 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1698 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1699 ui.write('\n')
1699 ui.write('\n')
1700
1700
1701 @command('debugpeer', [], _('PATH'), norepo=True)
1701 @command('debugpeer', [], _('PATH'), norepo=True)
1702 def debugpeer(ui, path):
1702 def debugpeer(ui, path):
1703 """establish a connection to a peer repository"""
1703 """establish a connection to a peer repository"""
1704 # Always enable peer request logging. Requires --debug to display
1704 # Always enable peer request logging. Requires --debug to display
1705 # though.
1705 # though.
1706 overrides = {
1706 overrides = {
1707 ('devel', 'debug.peer-request'): True,
1707 ('devel', 'debug.peer-request'): True,
1708 }
1708 }
1709
1709
1710 with ui.configoverride(overrides):
1710 with ui.configoverride(overrides):
1711 peer = hg.peer(ui, {}, path)
1711 peer = hg.peer(ui, {}, path)
1712
1712
1713 local = peer.local() is not None
1713 local = peer.local() is not None
1714 canpush = peer.canpush()
1714 canpush = peer.canpush()
1715
1715
1716 ui.write(_('url: %s\n') % peer.url())
1716 ui.write(_('url: %s\n') % peer.url())
1717 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1717 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1718 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1718 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1719
1719
1720 @command('debugpickmergetool',
1720 @command('debugpickmergetool',
1721 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1721 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1722 ('', 'changedelete', None, _('emulate merging change and delete')),
1722 ('', 'changedelete', None, _('emulate merging change and delete')),
1723 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1723 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1724 _('[PATTERN]...'),
1724 _('[PATTERN]...'),
1725 inferrepo=True)
1725 inferrepo=True)
1726 def debugpickmergetool(ui, repo, *pats, **opts):
1726 def debugpickmergetool(ui, repo, *pats, **opts):
1727 """examine which merge tool is chosen for specified file
1727 """examine which merge tool is chosen for specified file
1728
1728
1729 As described in :hg:`help merge-tools`, Mercurial examines
1729 As described in :hg:`help merge-tools`, Mercurial examines
1730 configurations below in this order to decide which merge tool is
1730 configurations below in this order to decide which merge tool is
1731 chosen for specified file.
1731 chosen for specified file.
1732
1732
1733 1. ``--tool`` option
1733 1. ``--tool`` option
1734 2. ``HGMERGE`` environment variable
1734 2. ``HGMERGE`` environment variable
1735 3. configurations in ``merge-patterns`` section
1735 3. configurations in ``merge-patterns`` section
1736 4. configuration of ``ui.merge``
1736 4. configuration of ``ui.merge``
1737 5. configurations in ``merge-tools`` section
1737 5. configurations in ``merge-tools`` section
1738 6. ``hgmerge`` tool (for historical reason only)
1738 6. ``hgmerge`` tool (for historical reason only)
1739 7. default tool for fallback (``:merge`` or ``:prompt``)
1739 7. default tool for fallback (``:merge`` or ``:prompt``)
1740
1740
1741 This command writes out examination result in the style below::
1741 This command writes out examination result in the style below::
1742
1742
1743 FILE = MERGETOOL
1743 FILE = MERGETOOL
1744
1744
1745 By default, all files known in the first parent context of the
1745 By default, all files known in the first parent context of the
1746 working directory are examined. Use file patterns and/or -I/-X
1746 working directory are examined. Use file patterns and/or -I/-X
1747 options to limit target files. -r/--rev is also useful to examine
1747 options to limit target files. -r/--rev is also useful to examine
1748 files in another context without actual updating to it.
1748 files in another context without actual updating to it.
1749
1749
1750 With --debug, this command shows warning messages while matching
1750 With --debug, this command shows warning messages while matching
1751 against ``merge-patterns`` and so on, too. It is recommended to
1751 against ``merge-patterns`` and so on, too. It is recommended to
1752 use this option with explicit file patterns and/or -I/-X options,
1752 use this option with explicit file patterns and/or -I/-X options,
1753 because this option increases amount of output per file according
1753 because this option increases amount of output per file according
1754 to configurations in hgrc.
1754 to configurations in hgrc.
1755
1755
1756 With -v/--verbose, this command shows configurations below at
1756 With -v/--verbose, this command shows configurations below at
1757 first (only if specified).
1757 first (only if specified).
1758
1758
1759 - ``--tool`` option
1759 - ``--tool`` option
1760 - ``HGMERGE`` environment variable
1760 - ``HGMERGE`` environment variable
1761 - configuration of ``ui.merge``
1761 - configuration of ``ui.merge``
1762
1762
1763 If merge tool is chosen before matching against
1763 If merge tool is chosen before matching against
1764 ``merge-patterns``, this command can't show any helpful
1764 ``merge-patterns``, this command can't show any helpful
1765 information, even with --debug. In such case, information above is
1765 information, even with --debug. In such case, information above is
1766 useful to know why a merge tool is chosen.
1766 useful to know why a merge tool is chosen.
1767 """
1767 """
1768 opts = pycompat.byteskwargs(opts)
1768 opts = pycompat.byteskwargs(opts)
1769 overrides = {}
1769 overrides = {}
1770 if opts['tool']:
1770 if opts['tool']:
1771 overrides[('ui', 'forcemerge')] = opts['tool']
1771 overrides[('ui', 'forcemerge')] = opts['tool']
1772 ui.note(('with --tool %r\n') % (opts['tool']))
1772 ui.note(('with --tool %r\n') % (opts['tool']))
1773
1773
1774 with ui.configoverride(overrides, 'debugmergepatterns'):
1774 with ui.configoverride(overrides, 'debugmergepatterns'):
1775 hgmerge = encoding.environ.get("HGMERGE")
1775 hgmerge = encoding.environ.get("HGMERGE")
1776 if hgmerge is not None:
1776 if hgmerge is not None:
1777 ui.note(('with HGMERGE=%r\n') % (hgmerge))
1777 ui.note(('with HGMERGE=%r\n') % (hgmerge))
1778 uimerge = ui.config("ui", "merge")
1778 uimerge = ui.config("ui", "merge")
1779 if uimerge:
1779 if uimerge:
1780 ui.note(('with ui.merge=%r\n') % (uimerge))
1780 ui.note(('with ui.merge=%r\n') % (uimerge))
1781
1781
1782 ctx = scmutil.revsingle(repo, opts.get('rev'))
1782 ctx = scmutil.revsingle(repo, opts.get('rev'))
1783 m = scmutil.match(ctx, pats, opts)
1783 m = scmutil.match(ctx, pats, opts)
1784 changedelete = opts['changedelete']
1784 changedelete = opts['changedelete']
1785 for path in ctx.walk(m):
1785 for path in ctx.walk(m):
1786 fctx = ctx[path]
1786 fctx = ctx[path]
1787 try:
1787 try:
1788 if not ui.debugflag:
1788 if not ui.debugflag:
1789 ui.pushbuffer(error=True)
1789 ui.pushbuffer(error=True)
1790 tool, toolpath = filemerge._picktool(repo, ui, path,
1790 tool, toolpath = filemerge._picktool(repo, ui, path,
1791 fctx.isbinary(),
1791 fctx.isbinary(),
1792 'l' in fctx.flags(),
1792 'l' in fctx.flags(),
1793 changedelete)
1793 changedelete)
1794 finally:
1794 finally:
1795 if not ui.debugflag:
1795 if not ui.debugflag:
1796 ui.popbuffer()
1796 ui.popbuffer()
1797 ui.write(('%s = %s\n') % (path, tool))
1797 ui.write(('%s = %s\n') % (path, tool))
1798
1798
1799 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1799 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1800 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1800 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1801 '''access the pushkey key/value protocol
1801 '''access the pushkey key/value protocol
1802
1802
1803 With two args, list the keys in the given namespace.
1803 With two args, list the keys in the given namespace.
1804
1804
1805 With five args, set a key to new if it currently is set to old.
1805 With five args, set a key to new if it currently is set to old.
1806 Reports success or failure.
1806 Reports success or failure.
1807 '''
1807 '''
1808
1808
1809 target = hg.peer(ui, {}, repopath)
1809 target = hg.peer(ui, {}, repopath)
1810 if keyinfo:
1810 if keyinfo:
1811 key, old, new = keyinfo
1811 key, old, new = keyinfo
1812 r = target.pushkey(namespace, key, old, new)
1812 r = target.pushkey(namespace, key, old, new)
1813 ui.status(str(r) + '\n')
1813 ui.status(str(r) + '\n')
1814 return not r
1814 return not r
1815 else:
1815 else:
1816 for k, v in sorted(target.listkeys(namespace).iteritems()):
1816 for k, v in sorted(target.listkeys(namespace).iteritems()):
1817 ui.write("%s\t%s\n" % (util.escapestr(k),
1817 ui.write("%s\t%s\n" % (util.escapestr(k),
1818 util.escapestr(v)))
1818 util.escapestr(v)))
1819
1819
1820 @command('debugpvec', [], _('A B'))
1820 @command('debugpvec', [], _('A B'))
1821 def debugpvec(ui, repo, a, b=None):
1821 def debugpvec(ui, repo, a, b=None):
1822 ca = scmutil.revsingle(repo, a)
1822 ca = scmutil.revsingle(repo, a)
1823 cb = scmutil.revsingle(repo, b)
1823 cb = scmutil.revsingle(repo, b)
1824 pa = pvec.ctxpvec(ca)
1824 pa = pvec.ctxpvec(ca)
1825 pb = pvec.ctxpvec(cb)
1825 pb = pvec.ctxpvec(cb)
1826 if pa == pb:
1826 if pa == pb:
1827 rel = "="
1827 rel = "="
1828 elif pa > pb:
1828 elif pa > pb:
1829 rel = ">"
1829 rel = ">"
1830 elif pa < pb:
1830 elif pa < pb:
1831 rel = "<"
1831 rel = "<"
1832 elif pa | pb:
1832 elif pa | pb:
1833 rel = "|"
1833 rel = "|"
1834 ui.write(_("a: %s\n") % pa)
1834 ui.write(_("a: %s\n") % pa)
1835 ui.write(_("b: %s\n") % pb)
1835 ui.write(_("b: %s\n") % pb)
1836 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1836 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1837 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1837 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1838 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1838 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1839 pa.distance(pb), rel))
1839 pa.distance(pb), rel))
1840
1840
1841 @command('debugrebuilddirstate|debugrebuildstate',
1841 @command('debugrebuilddirstate|debugrebuildstate',
1842 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1842 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1843 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1843 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1844 'the working copy parent')),
1844 'the working copy parent')),
1845 ],
1845 ],
1846 _('[-r REV]'))
1846 _('[-r REV]'))
1847 def debugrebuilddirstate(ui, repo, rev, **opts):
1847 def debugrebuilddirstate(ui, repo, rev, **opts):
1848 """rebuild the dirstate as it would look like for the given revision
1848 """rebuild the dirstate as it would look like for the given revision
1849
1849
1850 If no revision is specified the first current parent will be used.
1850 If no revision is specified the first current parent will be used.
1851
1851
1852 The dirstate will be set to the files of the given revision.
1852 The dirstate will be set to the files of the given revision.
1853 The actual working directory content or existing dirstate
1853 The actual working directory content or existing dirstate
1854 information such as adds or removes is not considered.
1854 information such as adds or removes is not considered.
1855
1855
1856 ``minimal`` will only rebuild the dirstate status for files that claim to be
1856 ``minimal`` will only rebuild the dirstate status for files that claim to be
1857 tracked but are not in the parent manifest, or that exist in the parent
1857 tracked but are not in the parent manifest, or that exist in the parent
1858 manifest but are not in the dirstate. It will not change adds, removes, or
1858 manifest but are not in the dirstate. It will not change adds, removes, or
1859 modified files that are in the working copy parent.
1859 modified files that are in the working copy parent.
1860
1860
1861 One use of this command is to make the next :hg:`status` invocation
1861 One use of this command is to make the next :hg:`status` invocation
1862 check the actual file content.
1862 check the actual file content.
1863 """
1863 """
1864 ctx = scmutil.revsingle(repo, rev)
1864 ctx = scmutil.revsingle(repo, rev)
1865 with repo.wlock():
1865 with repo.wlock():
1866 dirstate = repo.dirstate
1866 dirstate = repo.dirstate
1867 changedfiles = None
1867 changedfiles = None
1868 # See command doc for what minimal does.
1868 # See command doc for what minimal does.
1869 if opts.get(r'minimal'):
1869 if opts.get(r'minimal'):
1870 manifestfiles = set(ctx.manifest().keys())
1870 manifestfiles = set(ctx.manifest().keys())
1871 dirstatefiles = set(dirstate)
1871 dirstatefiles = set(dirstate)
1872 manifestonly = manifestfiles - dirstatefiles
1872 manifestonly = manifestfiles - dirstatefiles
1873 dsonly = dirstatefiles - manifestfiles
1873 dsonly = dirstatefiles - manifestfiles
1874 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1874 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1875 changedfiles = manifestonly | dsnotadded
1875 changedfiles = manifestonly | dsnotadded
1876
1876
1877 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1877 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1878
1878
1879 @command('debugrebuildfncache', [], '')
1879 @command('debugrebuildfncache', [], '')
1880 def debugrebuildfncache(ui, repo):
1880 def debugrebuildfncache(ui, repo):
1881 """rebuild the fncache file"""
1881 """rebuild the fncache file"""
1882 repair.rebuildfncache(ui, repo)
1882 repair.rebuildfncache(ui, repo)
1883
1883
1884 @command('debugrename',
1884 @command('debugrename',
1885 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1885 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1886 _('[-r REV] FILE'))
1886 _('[-r REV] FILE'))
1887 def debugrename(ui, repo, file1, *pats, **opts):
1887 def debugrename(ui, repo, file1, *pats, **opts):
1888 """dump rename information"""
1888 """dump rename information"""
1889
1889
1890 opts = pycompat.byteskwargs(opts)
1890 opts = pycompat.byteskwargs(opts)
1891 ctx = scmutil.revsingle(repo, opts.get('rev'))
1891 ctx = scmutil.revsingle(repo, opts.get('rev'))
1892 m = scmutil.match(ctx, (file1,) + pats, opts)
1892 m = scmutil.match(ctx, (file1,) + pats, opts)
1893 for abs in ctx.walk(m):
1893 for abs in ctx.walk(m):
1894 fctx = ctx[abs]
1894 fctx = ctx[abs]
1895 o = fctx.filelog().renamed(fctx.filenode())
1895 o = fctx.filelog().renamed(fctx.filenode())
1896 rel = m.rel(abs)
1896 rel = m.rel(abs)
1897 if o:
1897 if o:
1898 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1898 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1899 else:
1899 else:
1900 ui.write(_("%s not renamed\n") % rel)
1900 ui.write(_("%s not renamed\n") % rel)
1901
1901
1902 @command('debugrevlog', cmdutil.debugrevlogopts +
1902 @command('debugrevlog', cmdutil.debugrevlogopts +
1903 [('d', 'dump', False, _('dump index data'))],
1903 [('d', 'dump', False, _('dump index data'))],
1904 _('-c|-m|FILE'),
1904 _('-c|-m|FILE'),
1905 optionalrepo=True)
1905 optionalrepo=True)
1906 def debugrevlog(ui, repo, file_=None, **opts):
1906 def debugrevlog(ui, repo, file_=None, **opts):
1907 """show data and statistics about a revlog"""
1907 """show data and statistics about a revlog"""
1908 opts = pycompat.byteskwargs(opts)
1908 opts = pycompat.byteskwargs(opts)
1909 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1909 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1910
1910
1911 if opts.get("dump"):
1911 if opts.get("dump"):
1912 numrevs = len(r)
1912 numrevs = len(r)
1913 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1913 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1914 " rawsize totalsize compression heads chainlen\n"))
1914 " rawsize totalsize compression heads chainlen\n"))
1915 ts = 0
1915 ts = 0
1916 heads = set()
1916 heads = set()
1917
1917
1918 for rev in xrange(numrevs):
1918 for rev in xrange(numrevs):
1919 dbase = r.deltaparent(rev)
1919 dbase = r.deltaparent(rev)
1920 if dbase == -1:
1920 if dbase == -1:
1921 dbase = rev
1921 dbase = rev
1922 cbase = r.chainbase(rev)
1922 cbase = r.chainbase(rev)
1923 clen = r.chainlen(rev)
1923 clen = r.chainlen(rev)
1924 p1, p2 = r.parentrevs(rev)
1924 p1, p2 = r.parentrevs(rev)
1925 rs = r.rawsize(rev)
1925 rs = r.rawsize(rev)
1926 ts = ts + rs
1926 ts = ts + rs
1927 heads -= set(r.parentrevs(rev))
1927 heads -= set(r.parentrevs(rev))
1928 heads.add(rev)
1928 heads.add(rev)
1929 try:
1929 try:
1930 compression = ts / r.end(rev)
1930 compression = ts / r.end(rev)
1931 except ZeroDivisionError:
1931 except ZeroDivisionError:
1932 compression = 0
1932 compression = 0
1933 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1933 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1934 "%11d %5d %8d\n" %
1934 "%11d %5d %8d\n" %
1935 (rev, p1, p2, r.start(rev), r.end(rev),
1935 (rev, p1, p2, r.start(rev), r.end(rev),
1936 r.start(dbase), r.start(cbase),
1936 r.start(dbase), r.start(cbase),
1937 r.start(p1), r.start(p2),
1937 r.start(p1), r.start(p2),
1938 rs, ts, compression, len(heads), clen))
1938 rs, ts, compression, len(heads), clen))
1939 return 0
1939 return 0
1940
1940
1941 v = r.version
1941 v = r.version
1942 format = v & 0xFFFF
1942 format = v & 0xFFFF
1943 flags = []
1943 flags = []
1944 gdelta = False
1944 gdelta = False
1945 if v & revlog.FLAG_INLINE_DATA:
1945 if v & revlog.FLAG_INLINE_DATA:
1946 flags.append('inline')
1946 flags.append('inline')
1947 if v & revlog.FLAG_GENERALDELTA:
1947 if v & revlog.FLAG_GENERALDELTA:
1948 gdelta = True
1948 gdelta = True
1949 flags.append('generaldelta')
1949 flags.append('generaldelta')
1950 if not flags:
1950 if not flags:
1951 flags = ['(none)']
1951 flags = ['(none)']
1952
1952
1953 nummerges = 0
1953 nummerges = 0
1954 numfull = 0
1954 numfull = 0
1955 numprev = 0
1955 numprev = 0
1956 nump1 = 0
1956 nump1 = 0
1957 nump2 = 0
1957 nump2 = 0
1958 numother = 0
1958 numother = 0
1959 nump1prev = 0
1959 nump1prev = 0
1960 nump2prev = 0
1960 nump2prev = 0
1961 chainlengths = []
1961 chainlengths = []
1962 chainbases = []
1962 chainbases = []
1963 chainspans = []
1963 chainspans = []
1964
1964
1965 datasize = [None, 0, 0]
1965 datasize = [None, 0, 0]
1966 fullsize = [None, 0, 0]
1966 fullsize = [None, 0, 0]
1967 deltasize = [None, 0, 0]
1967 deltasize = [None, 0, 0]
1968 chunktypecounts = {}
1968 chunktypecounts = {}
1969 chunktypesizes = {}
1969 chunktypesizes = {}
1970
1970
1971 def addsize(size, l):
1971 def addsize(size, l):
1972 if l[0] is None or size < l[0]:
1972 if l[0] is None or size < l[0]:
1973 l[0] = size
1973 l[0] = size
1974 if size > l[1]:
1974 if size > l[1]:
1975 l[1] = size
1975 l[1] = size
1976 l[2] += size
1976 l[2] += size
1977
1977
1978 numrevs = len(r)
1978 numrevs = len(r)
1979 for rev in xrange(numrevs):
1979 for rev in xrange(numrevs):
1980 p1, p2 = r.parentrevs(rev)
1980 p1, p2 = r.parentrevs(rev)
1981 delta = r.deltaparent(rev)
1981 delta = r.deltaparent(rev)
1982 if format > 0:
1982 if format > 0:
1983 addsize(r.rawsize(rev), datasize)
1983 addsize(r.rawsize(rev), datasize)
1984 if p2 != nullrev:
1984 if p2 != nullrev:
1985 nummerges += 1
1985 nummerges += 1
1986 size = r.length(rev)
1986 size = r.length(rev)
1987 if delta == nullrev:
1987 if delta == nullrev:
1988 chainlengths.append(0)
1988 chainlengths.append(0)
1989 chainbases.append(r.start(rev))
1989 chainbases.append(r.start(rev))
1990 chainspans.append(size)
1990 chainspans.append(size)
1991 numfull += 1
1991 numfull += 1
1992 addsize(size, fullsize)
1992 addsize(size, fullsize)
1993 else:
1993 else:
1994 chainlengths.append(chainlengths[delta] + 1)
1994 chainlengths.append(chainlengths[delta] + 1)
1995 baseaddr = chainbases[delta]
1995 baseaddr = chainbases[delta]
1996 revaddr = r.start(rev)
1996 revaddr = r.start(rev)
1997 chainbases.append(baseaddr)
1997 chainbases.append(baseaddr)
1998 chainspans.append((revaddr - baseaddr) + size)
1998 chainspans.append((revaddr - baseaddr) + size)
1999 addsize(size, deltasize)
1999 addsize(size, deltasize)
2000 if delta == rev - 1:
2000 if delta == rev - 1:
2001 numprev += 1
2001 numprev += 1
2002 if delta == p1:
2002 if delta == p1:
2003 nump1prev += 1
2003 nump1prev += 1
2004 elif delta == p2:
2004 elif delta == p2:
2005 nump2prev += 1
2005 nump2prev += 1
2006 elif delta == p1:
2006 elif delta == p1:
2007 nump1 += 1
2007 nump1 += 1
2008 elif delta == p2:
2008 elif delta == p2:
2009 nump2 += 1
2009 nump2 += 1
2010 elif delta != nullrev:
2010 elif delta != nullrev:
2011 numother += 1
2011 numother += 1
2012
2012
2013 # Obtain data on the raw chunks in the revlog.
2013 # Obtain data on the raw chunks in the revlog.
2014 segment = r._getsegmentforrevs(rev, rev)[1]
2014 segment = r._getsegmentforrevs(rev, rev)[1]
2015 if segment:
2015 if segment:
2016 chunktype = bytes(segment[0:1])
2016 chunktype = bytes(segment[0:1])
2017 else:
2017 else:
2018 chunktype = 'empty'
2018 chunktype = 'empty'
2019
2019
2020 if chunktype not in chunktypecounts:
2020 if chunktype not in chunktypecounts:
2021 chunktypecounts[chunktype] = 0
2021 chunktypecounts[chunktype] = 0
2022 chunktypesizes[chunktype] = 0
2022 chunktypesizes[chunktype] = 0
2023
2023
2024 chunktypecounts[chunktype] += 1
2024 chunktypecounts[chunktype] += 1
2025 chunktypesizes[chunktype] += size
2025 chunktypesizes[chunktype] += size
2026
2026
2027 # Adjust size min value for empty cases
2027 # Adjust size min value for empty cases
2028 for size in (datasize, fullsize, deltasize):
2028 for size in (datasize, fullsize, deltasize):
2029 if size[0] is None:
2029 if size[0] is None:
2030 size[0] = 0
2030 size[0] = 0
2031
2031
2032 numdeltas = numrevs - numfull
2032 numdeltas = numrevs - numfull
2033 numoprev = numprev - nump1prev - nump2prev
2033 numoprev = numprev - nump1prev - nump2prev
2034 totalrawsize = datasize[2]
2034 totalrawsize = datasize[2]
2035 datasize[2] /= numrevs
2035 datasize[2] /= numrevs
2036 fulltotal = fullsize[2]
2036 fulltotal = fullsize[2]
2037 fullsize[2] /= numfull
2037 fullsize[2] /= numfull
2038 deltatotal = deltasize[2]
2038 deltatotal = deltasize[2]
2039 if numrevs - numfull > 0:
2039 if numrevs - numfull > 0:
2040 deltasize[2] /= numrevs - numfull
2040 deltasize[2] /= numrevs - numfull
2041 totalsize = fulltotal + deltatotal
2041 totalsize = fulltotal + deltatotal
2042 avgchainlen = sum(chainlengths) / numrevs
2042 avgchainlen = sum(chainlengths) / numrevs
2043 maxchainlen = max(chainlengths)
2043 maxchainlen = max(chainlengths)
2044 maxchainspan = max(chainspans)
2044 maxchainspan = max(chainspans)
2045 compratio = 1
2045 compratio = 1
2046 if totalsize:
2046 if totalsize:
2047 compratio = totalrawsize / totalsize
2047 compratio = totalrawsize / totalsize
2048
2048
2049 basedfmtstr = '%%%dd\n'
2049 basedfmtstr = '%%%dd\n'
2050 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2050 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2051
2051
2052 def dfmtstr(max):
2052 def dfmtstr(max):
2053 return basedfmtstr % len(str(max))
2053 return basedfmtstr % len(str(max))
2054 def pcfmtstr(max, padding=0):
2054 def pcfmtstr(max, padding=0):
2055 return basepcfmtstr % (len(str(max)), ' ' * padding)
2055 return basepcfmtstr % (len(str(max)), ' ' * padding)
2056
2056
2057 def pcfmt(value, total):
2057 def pcfmt(value, total):
2058 if total:
2058 if total:
2059 return (value, 100 * float(value) / total)
2059 return (value, 100 * float(value) / total)
2060 else:
2060 else:
2061 return value, 100.0
2061 return value, 100.0
2062
2062
2063 ui.write(('format : %d\n') % format)
2063 ui.write(('format : %d\n') % format)
2064 ui.write(('flags : %s\n') % ', '.join(flags))
2064 ui.write(('flags : %s\n') % ', '.join(flags))
2065
2065
2066 ui.write('\n')
2066 ui.write('\n')
2067 fmt = pcfmtstr(totalsize)
2067 fmt = pcfmtstr(totalsize)
2068 fmt2 = dfmtstr(totalsize)
2068 fmt2 = dfmtstr(totalsize)
2069 ui.write(('revisions : ') + fmt2 % numrevs)
2069 ui.write(('revisions : ') + fmt2 % numrevs)
2070 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2070 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2071 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2071 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2072 ui.write(('revisions : ') + fmt2 % numrevs)
2072 ui.write(('revisions : ') + fmt2 % numrevs)
2073 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2073 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2074 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2074 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2075 ui.write(('revision size : ') + fmt2 % totalsize)
2075 ui.write(('revision size : ') + fmt2 % totalsize)
2076 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2076 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2077 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2077 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2078
2078
2079 def fmtchunktype(chunktype):
2079 def fmtchunktype(chunktype):
2080 if chunktype == 'empty':
2080 if chunktype == 'empty':
2081 return ' %s : ' % chunktype
2081 return ' %s : ' % chunktype
2082 elif chunktype in pycompat.bytestr(string.ascii_letters):
2082 elif chunktype in pycompat.bytestr(string.ascii_letters):
2083 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2083 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2084 else:
2084 else:
2085 return ' 0x%s : ' % hex(chunktype)
2085 return ' 0x%s : ' % hex(chunktype)
2086
2086
2087 ui.write('\n')
2087 ui.write('\n')
2088 ui.write(('chunks : ') + fmt2 % numrevs)
2088 ui.write(('chunks : ') + fmt2 % numrevs)
2089 for chunktype in sorted(chunktypecounts):
2089 for chunktype in sorted(chunktypecounts):
2090 ui.write(fmtchunktype(chunktype))
2090 ui.write(fmtchunktype(chunktype))
2091 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2091 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2092 ui.write(('chunks size : ') + fmt2 % totalsize)
2092 ui.write(('chunks size : ') + fmt2 % totalsize)
2093 for chunktype in sorted(chunktypecounts):
2093 for chunktype in sorted(chunktypecounts):
2094 ui.write(fmtchunktype(chunktype))
2094 ui.write(fmtchunktype(chunktype))
2095 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2095 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2096
2096
2097 ui.write('\n')
2097 ui.write('\n')
2098 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2098 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2099 ui.write(('avg chain length : ') + fmt % avgchainlen)
2099 ui.write(('avg chain length : ') + fmt % avgchainlen)
2100 ui.write(('max chain length : ') + fmt % maxchainlen)
2100 ui.write(('max chain length : ') + fmt % maxchainlen)
2101 ui.write(('max chain reach : ') + fmt % maxchainspan)
2101 ui.write(('max chain reach : ') + fmt % maxchainspan)
2102 ui.write(('compression ratio : ') + fmt % compratio)
2102 ui.write(('compression ratio : ') + fmt % compratio)
2103
2103
2104 if format > 0:
2104 if format > 0:
2105 ui.write('\n')
2105 ui.write('\n')
2106 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2106 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2107 % tuple(datasize))
2107 % tuple(datasize))
2108 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2108 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2109 % tuple(fullsize))
2109 % tuple(fullsize))
2110 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2110 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2111 % tuple(deltasize))
2111 % tuple(deltasize))
2112
2112
2113 if numdeltas > 0:
2113 if numdeltas > 0:
2114 ui.write('\n')
2114 ui.write('\n')
2115 fmt = pcfmtstr(numdeltas)
2115 fmt = pcfmtstr(numdeltas)
2116 fmt2 = pcfmtstr(numdeltas, 4)
2116 fmt2 = pcfmtstr(numdeltas, 4)
2117 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2117 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2118 if numprev > 0:
2118 if numprev > 0:
2119 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2119 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2120 numprev))
2120 numprev))
2121 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2121 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2122 numprev))
2122 numprev))
2123 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2123 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2124 numprev))
2124 numprev))
2125 if gdelta:
2125 if gdelta:
2126 ui.write(('deltas against p1 : ')
2126 ui.write(('deltas against p1 : ')
2127 + fmt % pcfmt(nump1, numdeltas))
2127 + fmt % pcfmt(nump1, numdeltas))
2128 ui.write(('deltas against p2 : ')
2128 ui.write(('deltas against p2 : ')
2129 + fmt % pcfmt(nump2, numdeltas))
2129 + fmt % pcfmt(nump2, numdeltas))
2130 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2130 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2131 numdeltas))
2131 numdeltas))
2132
2132
2133 @command('debugrevspec',
2133 @command('debugrevspec',
2134 [('', 'optimize', None,
2134 [('', 'optimize', None,
2135 _('print parsed tree after optimizing (DEPRECATED)')),
2135 _('print parsed tree after optimizing (DEPRECATED)')),
2136 ('', 'show-revs', True, _('print list of result revisions (default)')),
2136 ('', 'show-revs', True, _('print list of result revisions (default)')),
2137 ('s', 'show-set', None, _('print internal representation of result set')),
2137 ('s', 'show-set', None, _('print internal representation of result set')),
2138 ('p', 'show-stage', [],
2138 ('p', 'show-stage', [],
2139 _('print parsed tree at the given stage'), _('NAME')),
2139 _('print parsed tree at the given stage'), _('NAME')),
2140 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2140 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2141 ('', 'verify-optimized', False, _('verify optimized result')),
2141 ('', 'verify-optimized', False, _('verify optimized result')),
2142 ],
2142 ],
2143 ('REVSPEC'))
2143 ('REVSPEC'))
2144 def debugrevspec(ui, repo, expr, **opts):
2144 def debugrevspec(ui, repo, expr, **opts):
2145 """parse and apply a revision specification
2145 """parse and apply a revision specification
2146
2146
2147 Use -p/--show-stage option to print the parsed tree at the given stages.
2147 Use -p/--show-stage option to print the parsed tree at the given stages.
2148 Use -p all to print tree at every stage.
2148 Use -p all to print tree at every stage.
2149
2149
2150 Use --no-show-revs option with -s or -p to print only the set
2150 Use --no-show-revs option with -s or -p to print only the set
2151 representation or the parsed tree respectively.
2151 representation or the parsed tree respectively.
2152
2152
2153 Use --verify-optimized to compare the optimized result with the unoptimized
2153 Use --verify-optimized to compare the optimized result with the unoptimized
2154 one. Returns 1 if the optimized result differs.
2154 one. Returns 1 if the optimized result differs.
2155 """
2155 """
2156 opts = pycompat.byteskwargs(opts)
2156 opts = pycompat.byteskwargs(opts)
2157 aliases = ui.configitems('revsetalias')
2157 aliases = ui.configitems('revsetalias')
2158 stages = [
2158 stages = [
2159 ('parsed', lambda tree: tree),
2159 ('parsed', lambda tree: tree),
2160 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2160 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2161 ui.warn)),
2161 ui.warn)),
2162 ('concatenated', revsetlang.foldconcat),
2162 ('concatenated', revsetlang.foldconcat),
2163 ('analyzed', revsetlang.analyze),
2163 ('analyzed', revsetlang.analyze),
2164 ('optimized', revsetlang.optimize),
2164 ('optimized', revsetlang.optimize),
2165 ]
2165 ]
2166 if opts['no_optimized']:
2166 if opts['no_optimized']:
2167 stages = stages[:-1]
2167 stages = stages[:-1]
2168 if opts['verify_optimized'] and opts['no_optimized']:
2168 if opts['verify_optimized'] and opts['no_optimized']:
2169 raise error.Abort(_('cannot use --verify-optimized with '
2169 raise error.Abort(_('cannot use --verify-optimized with '
2170 '--no-optimized'))
2170 '--no-optimized'))
2171 stagenames = set(n for n, f in stages)
2171 stagenames = set(n for n, f in stages)
2172
2172
2173 showalways = set()
2173 showalways = set()
2174 showchanged = set()
2174 showchanged = set()
2175 if ui.verbose and not opts['show_stage']:
2175 if ui.verbose and not opts['show_stage']:
2176 # show parsed tree by --verbose (deprecated)
2176 # show parsed tree by --verbose (deprecated)
2177 showalways.add('parsed')
2177 showalways.add('parsed')
2178 showchanged.update(['expanded', 'concatenated'])
2178 showchanged.update(['expanded', 'concatenated'])
2179 if opts['optimize']:
2179 if opts['optimize']:
2180 showalways.add('optimized')
2180 showalways.add('optimized')
2181 if opts['show_stage'] and opts['optimize']:
2181 if opts['show_stage'] and opts['optimize']:
2182 raise error.Abort(_('cannot use --optimize with --show-stage'))
2182 raise error.Abort(_('cannot use --optimize with --show-stage'))
2183 if opts['show_stage'] == ['all']:
2183 if opts['show_stage'] == ['all']:
2184 showalways.update(stagenames)
2184 showalways.update(stagenames)
2185 else:
2185 else:
2186 for n in opts['show_stage']:
2186 for n in opts['show_stage']:
2187 if n not in stagenames:
2187 if n not in stagenames:
2188 raise error.Abort(_('invalid stage name: %s') % n)
2188 raise error.Abort(_('invalid stage name: %s') % n)
2189 showalways.update(opts['show_stage'])
2189 showalways.update(opts['show_stage'])
2190
2190
2191 treebystage = {}
2191 treebystage = {}
2192 printedtree = None
2192 printedtree = None
2193 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2193 tree = revsetlang.parse(expr, lookup=repo.__contains__)
2194 for n, f in stages:
2194 for n, f in stages:
2195 treebystage[n] = tree = f(tree)
2195 treebystage[n] = tree = f(tree)
2196 if n in showalways or (n in showchanged and tree != printedtree):
2196 if n in showalways or (n in showchanged and tree != printedtree):
2197 if opts['show_stage'] or n != 'parsed':
2197 if opts['show_stage'] or n != 'parsed':
2198 ui.write(("* %s:\n") % n)
2198 ui.write(("* %s:\n") % n)
2199 ui.write(revsetlang.prettyformat(tree), "\n")
2199 ui.write(revsetlang.prettyformat(tree), "\n")
2200 printedtree = tree
2200 printedtree = tree
2201
2201
2202 if opts['verify_optimized']:
2202 if opts['verify_optimized']:
2203 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2203 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2204 brevs = revset.makematcher(treebystage['optimized'])(repo)
2204 brevs = revset.makematcher(treebystage['optimized'])(repo)
2205 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2205 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2206 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2206 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2207 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2207 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2208 arevs = list(arevs)
2208 arevs = list(arevs)
2209 brevs = list(brevs)
2209 brevs = list(brevs)
2210 if arevs == brevs:
2210 if arevs == brevs:
2211 return 0
2211 return 0
2212 ui.write(('--- analyzed\n'), label='diff.file_a')
2212 ui.write(('--- analyzed\n'), label='diff.file_a')
2213 ui.write(('+++ optimized\n'), label='diff.file_b')
2213 ui.write(('+++ optimized\n'), label='diff.file_b')
2214 sm = difflib.SequenceMatcher(None, arevs, brevs)
2214 sm = difflib.SequenceMatcher(None, arevs, brevs)
2215 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2215 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2216 if tag in ('delete', 'replace'):
2216 if tag in ('delete', 'replace'):
2217 for c in arevs[alo:ahi]:
2217 for c in arevs[alo:ahi]:
2218 ui.write('-%s\n' % c, label='diff.deleted')
2218 ui.write('-%s\n' % c, label='diff.deleted')
2219 if tag in ('insert', 'replace'):
2219 if tag in ('insert', 'replace'):
2220 for c in brevs[blo:bhi]:
2220 for c in brevs[blo:bhi]:
2221 ui.write('+%s\n' % c, label='diff.inserted')
2221 ui.write('+%s\n' % c, label='diff.inserted')
2222 if tag == 'equal':
2222 if tag == 'equal':
2223 for c in arevs[alo:ahi]:
2223 for c in arevs[alo:ahi]:
2224 ui.write(' %s\n' % c)
2224 ui.write(' %s\n' % c)
2225 return 1
2225 return 1
2226
2226
2227 func = revset.makematcher(tree)
2227 func = revset.makematcher(tree)
2228 revs = func(repo)
2228 revs = func(repo)
2229 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2229 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2230 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2230 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2231 if not opts['show_revs']:
2231 if not opts['show_revs']:
2232 return
2232 return
2233 for c in revs:
2233 for c in revs:
2234 ui.write("%d\n" % c)
2234 ui.write("%d\n" % c)
2235
2235
2236 @command('debugserve', [
2236 @command('debugserve', [
2237 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2237 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2238 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2238 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2239 ('', 'logiofile', '', _('file to log server I/O to')),
2239 ('', 'logiofile', '', _('file to log server I/O to')),
2240 ], '')
2240 ], '')
2241 def debugserve(ui, repo, **opts):
2241 def debugserve(ui, repo, **opts):
2242 """run a server with advanced settings
2242 """run a server with advanced settings
2243
2243
2244 This command is similar to :hg:`serve`. It exists partially as a
2244 This command is similar to :hg:`serve`. It exists partially as a
2245 workaround to the fact that ``hg serve --stdio`` must have specific
2245 workaround to the fact that ``hg serve --stdio`` must have specific
2246 arguments for security reasons.
2246 arguments for security reasons.
2247 """
2247 """
2248 opts = pycompat.byteskwargs(opts)
2248 opts = pycompat.byteskwargs(opts)
2249
2249
2250 if not opts['sshstdio']:
2250 if not opts['sshstdio']:
2251 raise error.Abort(_('only --sshstdio is currently supported'))
2251 raise error.Abort(_('only --sshstdio is currently supported'))
2252
2252
2253 logfh = None
2253 logfh = None
2254
2254
2255 if opts['logiofd'] and opts['logiofile']:
2255 if opts['logiofd'] and opts['logiofile']:
2256 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2256 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2257
2257
2258 if opts['logiofd']:
2258 if opts['logiofd']:
2259 # Line buffered because output is line based.
2259 # Line buffered because output is line based.
2260 logfh = os.fdopen(int(opts['logiofd']), 'ab', 1)
2260 logfh = os.fdopen(int(opts['logiofd']), 'ab', 1)
2261 elif opts['logiofile']:
2261 elif opts['logiofile']:
2262 logfh = open(opts['logiofile'], 'ab', 1)
2262 logfh = open(opts['logiofile'], 'ab', 1)
2263
2263
2264 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2264 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2265 s.serve_forever()
2265 s.serve_forever()
2266
2266
2267 @command('debugsetparents', [], _('REV1 [REV2]'))
2267 @command('debugsetparents', [], _('REV1 [REV2]'))
2268 def debugsetparents(ui, repo, rev1, rev2=None):
2268 def debugsetparents(ui, repo, rev1, rev2=None):
2269 """manually set the parents of the current working directory
2269 """manually set the parents of the current working directory
2270
2270
2271 This is useful for writing repository conversion tools, but should
2271 This is useful for writing repository conversion tools, but should
2272 be used with care. For example, neither the working directory nor the
2272 be used with care. For example, neither the working directory nor the
2273 dirstate is updated, so file status may be incorrect after running this
2273 dirstate is updated, so file status may be incorrect after running this
2274 command.
2274 command.
2275
2275
2276 Returns 0 on success.
2276 Returns 0 on success.
2277 """
2277 """
2278
2278
2279 r1 = scmutil.revsingle(repo, rev1).node()
2279 r1 = scmutil.revsingle(repo, rev1).node()
2280 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2280 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2281
2281
2282 with repo.wlock():
2282 with repo.wlock():
2283 repo.setparents(r1, r2)
2283 repo.setparents(r1, r2)
2284
2284
2285 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2285 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2286 def debugssl(ui, repo, source=None, **opts):
2286 def debugssl(ui, repo, source=None, **opts):
2287 '''test a secure connection to a server
2287 '''test a secure connection to a server
2288
2288
2289 This builds the certificate chain for the server on Windows, installing the
2289 This builds the certificate chain for the server on Windows, installing the
2290 missing intermediates and trusted root via Windows Update if necessary. It
2290 missing intermediates and trusted root via Windows Update if necessary. It
2291 does nothing on other platforms.
2291 does nothing on other platforms.
2292
2292
2293 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2293 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2294 that server is used. See :hg:`help urls` for more information.
2294 that server is used. See :hg:`help urls` for more information.
2295
2295
2296 If the update succeeds, retry the original operation. Otherwise, the cause
2296 If the update succeeds, retry the original operation. Otherwise, the cause
2297 of the SSL error is likely another issue.
2297 of the SSL error is likely another issue.
2298 '''
2298 '''
2299 if not pycompat.iswindows:
2299 if not pycompat.iswindows:
2300 raise error.Abort(_('certificate chain building is only possible on '
2300 raise error.Abort(_('certificate chain building is only possible on '
2301 'Windows'))
2301 'Windows'))
2302
2302
2303 if not source:
2303 if not source:
2304 if not repo:
2304 if not repo:
2305 raise error.Abort(_("there is no Mercurial repository here, and no "
2305 raise error.Abort(_("there is no Mercurial repository here, and no "
2306 "server specified"))
2306 "server specified"))
2307 source = "default"
2307 source = "default"
2308
2308
2309 source, branches = hg.parseurl(ui.expandpath(source))
2309 source, branches = hg.parseurl(ui.expandpath(source))
2310 url = util.url(source)
2310 url = util.url(source)
2311 addr = None
2311 addr = None
2312
2312
2313 defaultport = {'https': 443, 'ssh': 22}
2313 defaultport = {'https': 443, 'ssh': 22}
2314 if url.scheme in defaultport:
2314 if url.scheme in defaultport:
2315 try:
2315 try:
2316 addr = (url.host, int(url.port or defaultport[url.scheme]))
2316 addr = (url.host, int(url.port or defaultport[url.scheme]))
2317 except ValueError:
2317 except ValueError:
2318 raise error.Abort(_("malformed port number in URL"))
2318 raise error.Abort(_("malformed port number in URL"))
2319 else:
2319 else:
2320 raise error.Abort(_("only https and ssh connections are supported"))
2320 raise error.Abort(_("only https and ssh connections are supported"))
2321
2321
2322 from . import win32
2322 from . import win32
2323
2323
2324 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2324 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2325 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2325 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2326
2326
2327 try:
2327 try:
2328 s.connect(addr)
2328 s.connect(addr)
2329 cert = s.getpeercert(True)
2329 cert = s.getpeercert(True)
2330
2330
2331 ui.status(_('checking the certificate chain for %s\n') % url.host)
2331 ui.status(_('checking the certificate chain for %s\n') % url.host)
2332
2332
2333 complete = win32.checkcertificatechain(cert, build=False)
2333 complete = win32.checkcertificatechain(cert, build=False)
2334
2334
2335 if not complete:
2335 if not complete:
2336 ui.status(_('certificate chain is incomplete, updating... '))
2336 ui.status(_('certificate chain is incomplete, updating... '))
2337
2337
2338 if not win32.checkcertificatechain(cert):
2338 if not win32.checkcertificatechain(cert):
2339 ui.status(_('failed.\n'))
2339 ui.status(_('failed.\n'))
2340 else:
2340 else:
2341 ui.status(_('done.\n'))
2341 ui.status(_('done.\n'))
2342 else:
2342 else:
2343 ui.status(_('full certificate chain is available\n'))
2343 ui.status(_('full certificate chain is available\n'))
2344 finally:
2344 finally:
2345 s.close()
2345 s.close()
2346
2346
2347 @command('debugsub',
2347 @command('debugsub',
2348 [('r', 'rev', '',
2348 [('r', 'rev', '',
2349 _('revision to check'), _('REV'))],
2349 _('revision to check'), _('REV'))],
2350 _('[-r REV] [REV]'))
2350 _('[-r REV] [REV]'))
2351 def debugsub(ui, repo, rev=None):
2351 def debugsub(ui, repo, rev=None):
2352 ctx = scmutil.revsingle(repo, rev, None)
2352 ctx = scmutil.revsingle(repo, rev, None)
2353 for k, v in sorted(ctx.substate.items()):
2353 for k, v in sorted(ctx.substate.items()):
2354 ui.write(('path %s\n') % k)
2354 ui.write(('path %s\n') % k)
2355 ui.write((' source %s\n') % v[0])
2355 ui.write((' source %s\n') % v[0])
2356 ui.write((' revision %s\n') % v[1])
2356 ui.write((' revision %s\n') % v[1])
2357
2357
2358 @command('debugsuccessorssets',
2358 @command('debugsuccessorssets',
2359 [('', 'closest', False, _('return closest successors sets only'))],
2359 [('', 'closest', False, _('return closest successors sets only'))],
2360 _('[REV]'))
2360 _('[REV]'))
2361 def debugsuccessorssets(ui, repo, *revs, **opts):
2361 def debugsuccessorssets(ui, repo, *revs, **opts):
2362 """show set of successors for revision
2362 """show set of successors for revision
2363
2363
2364 A successors set of changeset A is a consistent group of revisions that
2364 A successors set of changeset A is a consistent group of revisions that
2365 succeed A. It contains non-obsolete changesets only unless closests
2365 succeed A. It contains non-obsolete changesets only unless closests
2366 successors set is set.
2366 successors set is set.
2367
2367
2368 In most cases a changeset A has a single successors set containing a single
2368 In most cases a changeset A has a single successors set containing a single
2369 successor (changeset A replaced by A').
2369 successor (changeset A replaced by A').
2370
2370
2371 A changeset that is made obsolete with no successors are called "pruned".
2371 A changeset that is made obsolete with no successors are called "pruned".
2372 Such changesets have no successors sets at all.
2372 Such changesets have no successors sets at all.
2373
2373
2374 A changeset that has been "split" will have a successors set containing
2374 A changeset that has been "split" will have a successors set containing
2375 more than one successor.
2375 more than one successor.
2376
2376
2377 A changeset that has been rewritten in multiple different ways is called
2377 A changeset that has been rewritten in multiple different ways is called
2378 "divergent". Such changesets have multiple successor sets (each of which
2378 "divergent". Such changesets have multiple successor sets (each of which
2379 may also be split, i.e. have multiple successors).
2379 may also be split, i.e. have multiple successors).
2380
2380
2381 Results are displayed as follows::
2381 Results are displayed as follows::
2382
2382
2383 <rev1>
2383 <rev1>
2384 <successors-1A>
2384 <successors-1A>
2385 <rev2>
2385 <rev2>
2386 <successors-2A>
2386 <successors-2A>
2387 <successors-2B1> <successors-2B2> <successors-2B3>
2387 <successors-2B1> <successors-2B2> <successors-2B3>
2388
2388
2389 Here rev2 has two possible (i.e. divergent) successors sets. The first
2389 Here rev2 has two possible (i.e. divergent) successors sets. The first
2390 holds one element, whereas the second holds three (i.e. the changeset has
2390 holds one element, whereas the second holds three (i.e. the changeset has
2391 been split).
2391 been split).
2392 """
2392 """
2393 # passed to successorssets caching computation from one call to another
2393 # passed to successorssets caching computation from one call to another
2394 cache = {}
2394 cache = {}
2395 ctx2str = bytes
2395 ctx2str = bytes
2396 node2str = short
2396 node2str = short
2397 for rev in scmutil.revrange(repo, revs):
2397 for rev in scmutil.revrange(repo, revs):
2398 ctx = repo[rev]
2398 ctx = repo[rev]
2399 ui.write('%s\n'% ctx2str(ctx))
2399 ui.write('%s\n'% ctx2str(ctx))
2400 for succsset in obsutil.successorssets(repo, ctx.node(),
2400 for succsset in obsutil.successorssets(repo, ctx.node(),
2401 closest=opts[r'closest'],
2401 closest=opts[r'closest'],
2402 cache=cache):
2402 cache=cache):
2403 if succsset:
2403 if succsset:
2404 ui.write(' ')
2404 ui.write(' ')
2405 ui.write(node2str(succsset[0]))
2405 ui.write(node2str(succsset[0]))
2406 for node in succsset[1:]:
2406 for node in succsset[1:]:
2407 ui.write(' ')
2407 ui.write(' ')
2408 ui.write(node2str(node))
2408 ui.write(node2str(node))
2409 ui.write('\n')
2409 ui.write('\n')
2410
2410
2411 @command('debugtemplate',
2411 @command('debugtemplate',
2412 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2412 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2413 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2413 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2414 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2414 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2415 optionalrepo=True)
2415 optionalrepo=True)
2416 def debugtemplate(ui, repo, tmpl, **opts):
2416 def debugtemplate(ui, repo, tmpl, **opts):
2417 """parse and apply a template
2417 """parse and apply a template
2418
2418
2419 If -r/--rev is given, the template is processed as a log template and
2419 If -r/--rev is given, the template is processed as a log template and
2420 applied to the given changesets. Otherwise, it is processed as a generic
2420 applied to the given changesets. Otherwise, it is processed as a generic
2421 template.
2421 template.
2422
2422
2423 Use --verbose to print the parsed tree.
2423 Use --verbose to print the parsed tree.
2424 """
2424 """
2425 revs = None
2425 revs = None
2426 if opts[r'rev']:
2426 if opts[r'rev']:
2427 if repo is None:
2427 if repo is None:
2428 raise error.RepoError(_('there is no Mercurial repository here '
2428 raise error.RepoError(_('there is no Mercurial repository here '
2429 '(.hg not found)'))
2429 '(.hg not found)'))
2430 revs = scmutil.revrange(repo, opts[r'rev'])
2430 revs = scmutil.revrange(repo, opts[r'rev'])
2431
2431
2432 props = {}
2432 props = {}
2433 for d in opts[r'define']:
2433 for d in opts[r'define']:
2434 try:
2434 try:
2435 k, v = (e.strip() for e in d.split('=', 1))
2435 k, v = (e.strip() for e in d.split('=', 1))
2436 if not k or k == 'ui':
2436 if not k or k == 'ui':
2437 raise ValueError
2437 raise ValueError
2438 props[k] = v
2438 props[k] = v
2439 except ValueError:
2439 except ValueError:
2440 raise error.Abort(_('malformed keyword definition: %s') % d)
2440 raise error.Abort(_('malformed keyword definition: %s') % d)
2441
2441
2442 if ui.verbose:
2442 if ui.verbose:
2443 aliases = ui.configitems('templatealias')
2443 aliases = ui.configitems('templatealias')
2444 tree = templater.parse(tmpl)
2444 tree = templater.parse(tmpl)
2445 ui.note(templater.prettyformat(tree), '\n')
2445 ui.note(templater.prettyformat(tree), '\n')
2446 newtree = templater.expandaliases(tree, aliases)
2446 newtree = templater.expandaliases(tree, aliases)
2447 if newtree != tree:
2447 if newtree != tree:
2448 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2448 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2449
2449
2450 if revs is None:
2450 if revs is None:
2451 tres = formatter.templateresources(ui, repo)
2451 tres = formatter.templateresources(ui, repo)
2452 t = formatter.maketemplater(ui, tmpl, resources=tres)
2452 t = formatter.maketemplater(ui, tmpl, resources=tres)
2453 ui.write(t.render(props))
2453 ui.write(t.render(props))
2454 else:
2454 else:
2455 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2455 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2456 for r in revs:
2456 for r in revs:
2457 displayer.show(repo[r], **pycompat.strkwargs(props))
2457 displayer.show(repo[r], **pycompat.strkwargs(props))
2458 displayer.close()
2458 displayer.close()
2459
2459
2460 @command('debugupdatecaches', [])
2460 @command('debugupdatecaches', [])
2461 def debugupdatecaches(ui, repo, *pats, **opts):
2461 def debugupdatecaches(ui, repo, *pats, **opts):
2462 """warm all known caches in the repository"""
2462 """warm all known caches in the repository"""
2463 with repo.wlock(), repo.lock():
2463 with repo.wlock(), repo.lock():
2464 repo.updatecaches()
2464 repo.updatecaches()
2465
2465
2466 @command('debugupgraderepo', [
2466 @command('debugupgraderepo', [
2467 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2467 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2468 ('', 'run', False, _('performs an upgrade')),
2468 ('', 'run', False, _('performs an upgrade')),
2469 ])
2469 ])
2470 def debugupgraderepo(ui, repo, run=False, optimize=None):
2470 def debugupgraderepo(ui, repo, run=False, optimize=None):
2471 """upgrade a repository to use different features
2471 """upgrade a repository to use different features
2472
2472
2473 If no arguments are specified, the repository is evaluated for upgrade
2473 If no arguments are specified, the repository is evaluated for upgrade
2474 and a list of problems and potential optimizations is printed.
2474 and a list of problems and potential optimizations is printed.
2475
2475
2476 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2476 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2477 can be influenced via additional arguments. More details will be provided
2477 can be influenced via additional arguments. More details will be provided
2478 by the command output when run without ``--run``.
2478 by the command output when run without ``--run``.
2479
2479
2480 During the upgrade, the repository will be locked and no writes will be
2480 During the upgrade, the repository will be locked and no writes will be
2481 allowed.
2481 allowed.
2482
2482
2483 At the end of the upgrade, the repository may not be readable while new
2483 At the end of the upgrade, the repository may not be readable while new
2484 repository data is swapped in. This window will be as long as it takes to
2484 repository data is swapped in. This window will be as long as it takes to
2485 rename some directories inside the ``.hg`` directory. On most machines, this
2485 rename some directories inside the ``.hg`` directory. On most machines, this
2486 should complete almost instantaneously and the chances of a consumer being
2486 should complete almost instantaneously and the chances of a consumer being
2487 unable to access the repository should be low.
2487 unable to access the repository should be low.
2488 """
2488 """
2489 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2489 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2490
2490
2491 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2491 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2492 inferrepo=True)
2492 inferrepo=True)
2493 def debugwalk(ui, repo, *pats, **opts):
2493 def debugwalk(ui, repo, *pats, **opts):
2494 """show how files match on given patterns"""
2494 """show how files match on given patterns"""
2495 opts = pycompat.byteskwargs(opts)
2495 opts = pycompat.byteskwargs(opts)
2496 m = scmutil.match(repo[None], pats, opts)
2496 m = scmutil.match(repo[None], pats, opts)
2497 ui.write(('matcher: %r\n' % m))
2497 ui.write(('matcher: %r\n' % m))
2498 items = list(repo[None].walk(m))
2498 items = list(repo[None].walk(m))
2499 if not items:
2499 if not items:
2500 return
2500 return
2501 f = lambda fn: fn
2501 f = lambda fn: fn
2502 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2502 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2503 f = lambda fn: util.normpath(fn)
2503 f = lambda fn: util.normpath(fn)
2504 fmt = 'f %%-%ds %%-%ds %%s' % (
2504 fmt = 'f %%-%ds %%-%ds %%s' % (
2505 max([len(abs) for abs in items]),
2505 max([len(abs) for abs in items]),
2506 max([len(m.rel(abs)) for abs in items]))
2506 max([len(m.rel(abs)) for abs in items]))
2507 for abs in items:
2507 for abs in items:
2508 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2508 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2509 ui.write("%s\n" % line.rstrip())
2509 ui.write("%s\n" % line.rstrip())
2510
2510
2511 @command('debugwireargs',
2511 @command('debugwireargs',
2512 [('', 'three', '', 'three'),
2512 [('', 'three', '', 'three'),
2513 ('', 'four', '', 'four'),
2513 ('', 'four', '', 'four'),
2514 ('', 'five', '', 'five'),
2514 ('', 'five', '', 'five'),
2515 ] + cmdutil.remoteopts,
2515 ] + cmdutil.remoteopts,
2516 _('REPO [OPTIONS]... [ONE [TWO]]'),
2516 _('REPO [OPTIONS]... [ONE [TWO]]'),
2517 norepo=True)
2517 norepo=True)
2518 def debugwireargs(ui, repopath, *vals, **opts):
2518 def debugwireargs(ui, repopath, *vals, **opts):
2519 opts = pycompat.byteskwargs(opts)
2519 opts = pycompat.byteskwargs(opts)
2520 repo = hg.peer(ui, opts, repopath)
2520 repo = hg.peer(ui, opts, repopath)
2521 for opt in cmdutil.remoteopts:
2521 for opt in cmdutil.remoteopts:
2522 del opts[opt[1]]
2522 del opts[opt[1]]
2523 args = {}
2523 args = {}
2524 for k, v in opts.iteritems():
2524 for k, v in opts.iteritems():
2525 if v:
2525 if v:
2526 args[k] = v
2526 args[k] = v
2527 args = pycompat.strkwargs(args)
2527 args = pycompat.strkwargs(args)
2528 # run twice to check that we don't mess up the stream for the next command
2528 # run twice to check that we don't mess up the stream for the next command
2529 res1 = repo.debugwireargs(*vals, **args)
2529 res1 = repo.debugwireargs(*vals, **args)
2530 res2 = repo.debugwireargs(*vals, **args)
2530 res2 = repo.debugwireargs(*vals, **args)
2531 ui.write("%s\n" % res1)
2531 ui.write("%s\n" % res1)
2532 if res1 != res2:
2532 if res1 != res2:
2533 ui.warn("%s\n" % res2)
2533 ui.warn("%s\n" % res2)
2534
2534
2535 def _parsewirelangblocks(fh):
2535 def _parsewirelangblocks(fh):
2536 activeaction = None
2536 activeaction = None
2537 blocklines = []
2537 blocklines = []
2538
2538
2539 for line in fh:
2539 for line in fh:
2540 line = line.rstrip()
2540 line = line.rstrip()
2541 if not line:
2541 if not line:
2542 continue
2542 continue
2543
2543
2544 if line.startswith(b'#'):
2544 if line.startswith(b'#'):
2545 continue
2545 continue
2546
2546
2547 if not line.startswith(' '):
2547 if not line.startswith(' '):
2548 # New block. Flush previous one.
2548 # New block. Flush previous one.
2549 if activeaction:
2549 if activeaction:
2550 yield activeaction, blocklines
2550 yield activeaction, blocklines
2551
2551
2552 activeaction = line
2552 activeaction = line
2553 blocklines = []
2553 blocklines = []
2554 continue
2554 continue
2555
2555
2556 # Else we start with an indent.
2556 # Else we start with an indent.
2557
2557
2558 if not activeaction:
2558 if not activeaction:
2559 raise error.Abort(_('indented line outside of block'))
2559 raise error.Abort(_('indented line outside of block'))
2560
2560
2561 blocklines.append(line)
2561 blocklines.append(line)
2562
2562
2563 # Flush last block.
2563 # Flush last block.
2564 if activeaction:
2564 if activeaction:
2565 yield activeaction, blocklines
2565 yield activeaction, blocklines
2566
2566
2567 @command('debugwireproto',
2567 @command('debugwireproto',
2568 [
2568 [
2569 ('', 'localssh', False, _('start an SSH server for this repo')),
2569 ('', 'localssh', False, _('start an SSH server for this repo')),
2570 ('', 'peer', '', _('construct a specific version of the peer')),
2570 ('', 'peer', '', _('construct a specific version of the peer')),
2571 ] + cmdutil.remoteopts,
2571 ] + cmdutil.remoteopts,
2572 _('[REPO]'),
2572 _('[REPO]'),
2573 optionalrepo=True)
2573 optionalrepo=True)
2574 def debugwireproto(ui, repo, **opts):
2574 def debugwireproto(ui, repo, **opts):
2575 """send wire protocol commands to a server
2575 """send wire protocol commands to a server
2576
2576
2577 This command can be used to issue wire protocol commands to remote
2577 This command can be used to issue wire protocol commands to remote
2578 peers and to debug the raw data being exchanged.
2578 peers and to debug the raw data being exchanged.
2579
2579
2580 ``--localssh`` will start an SSH server against the current repository
2580 ``--localssh`` will start an SSH server against the current repository
2581 and connect to that. By default, the connection will perform a handshake
2581 and connect to that. By default, the connection will perform a handshake
2582 and establish an appropriate peer instance.
2582 and establish an appropriate peer instance.
2583
2583
2584 ``--peer`` can be used to bypass the handshake protocol and construct a
2584 ``--peer`` can be used to bypass the handshake protocol and construct a
2585 peer instance using the specified class type. Valid values are ``raw``,
2585 peer instance using the specified class type. Valid values are ``raw``,
2586 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2586 ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending raw data
2587 payloads and don't support higher-level command actions.
2587 payloads and don't support higher-level command actions.
2588
2588
2589 Commands are issued via a mini language which is specified via stdin.
2589 Commands are issued via a mini language which is specified via stdin.
2590 The language consists of individual actions to perform. An action is
2590 The language consists of individual actions to perform. An action is
2591 defined by a block. A block is defined as a line with no leading
2591 defined by a block. A block is defined as a line with no leading
2592 space followed by 0 or more lines with leading space. Blocks are
2592 space followed by 0 or more lines with leading space. Blocks are
2593 effectively a high-level command with additional metadata.
2593 effectively a high-level command with additional metadata.
2594
2594
2595 Lines beginning with ``#`` are ignored.
2595 Lines beginning with ``#`` are ignored.
2596
2596
2597 The following sections denote available actions.
2597 The following sections denote available actions.
2598
2598
2599 raw
2599 raw
2600 ---
2600 ---
2601
2601
2602 Send raw data to the server.
2602 Send raw data to the server.
2603
2603
2604 The block payload contains the raw data to send as one atomic send
2604 The block payload contains the raw data to send as one atomic send
2605 operation. The data may not actually be delivered in a single system
2605 operation. The data may not actually be delivered in a single system
2606 call: it depends on the abilities of the transport being used.
2606 call: it depends on the abilities of the transport being used.
2607
2607
2608 Each line in the block is de-indented and concatenated. Then, that
2608 Each line in the block is de-indented and concatenated. Then, that
2609 value is evaluated as a Python b'' literal. This allows the use of
2609 value is evaluated as a Python b'' literal. This allows the use of
2610 backslash escaping, etc.
2610 backslash escaping, etc.
2611
2611
2612 raw+
2612 raw+
2613 ----
2613 ----
2614
2614
2615 Behaves like ``raw`` except flushes output afterwards.
2615 Behaves like ``raw`` except flushes output afterwards.
2616
2616
2617 command <X>
2617 command <X>
2618 -----------
2618 -----------
2619
2619
2620 Send a request to run a named command, whose name follows the ``command``
2620 Send a request to run a named command, whose name follows the ``command``
2621 string.
2621 string.
2622
2622
2623 Arguments to the command are defined as lines in this block. The format of
2623 Arguments to the command are defined as lines in this block. The format of
2624 each line is ``<key> <value>``. e.g.::
2624 each line is ``<key> <value>``. e.g.::
2625
2625
2626 command listkeys
2626 command listkeys
2627 namespace bookmarks
2627 namespace bookmarks
2628
2628
2629 Values are interpreted as Python b'' literals. This allows encoding
2629 Values are interpreted as Python b'' literals. This allows encoding
2630 special byte sequences via backslash escaping.
2630 special byte sequences via backslash escaping.
2631
2631
2632 batchbegin
2633 ----------
2634
2635 Instruct the peer to begin a batched send.
2636
2637 All ``command`` blocks are queued for execution until the next
2638 ``batchsubmit`` block.
2639
2640 batchsubmit
2641 -----------
2642
2643 Submit previously queued ``command`` blocks as a batch request.
2644
2645 This action MUST be paired with a ``batchbegin`` action.
2646
2632 close
2647 close
2633 -----
2648 -----
2634
2649
2635 Close the connection to the server.
2650 Close the connection to the server.
2636
2651
2637 flush
2652 flush
2638 -----
2653 -----
2639
2654
2640 Flush data written to the server.
2655 Flush data written to the server.
2641
2656
2642 readavailable
2657 readavailable
2643 -------------
2658 -------------
2644
2659
2645 Read all available data from the server.
2660 Read all available data from the server.
2646
2661
2647 If the connection to the server encompasses multiple pipes, we poll both
2662 If the connection to the server encompasses multiple pipes, we poll both
2648 pipes and read available data.
2663 pipes and read available data.
2649
2664
2650 readline
2665 readline
2651 --------
2666 --------
2652
2667
2653 Read a line of output from the server. If there are multiple output
2668 Read a line of output from the server. If there are multiple output
2654 pipes, reads only the main pipe.
2669 pipes, reads only the main pipe.
2655 """
2670 """
2656 opts = pycompat.byteskwargs(opts)
2671 opts = pycompat.byteskwargs(opts)
2657
2672
2658 if opts['localssh'] and not repo:
2673 if opts['localssh'] and not repo:
2659 raise error.Abort(_('--localssh requires a repository'))
2674 raise error.Abort(_('--localssh requires a repository'))
2660
2675
2661 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2676 if opts['peer'] and opts['peer'] not in ('raw', 'ssh1', 'ssh2'):
2662 raise error.Abort(_('invalid value for --peer'),
2677 raise error.Abort(_('invalid value for --peer'),
2663 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2678 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2664
2679
2665 if ui.interactive():
2680 if ui.interactive():
2666 ui.write(_('(waiting for commands on stdin)\n'))
2681 ui.write(_('(waiting for commands on stdin)\n'))
2667
2682
2668 blocks = list(_parsewirelangblocks(ui.fin))
2683 blocks = list(_parsewirelangblocks(ui.fin))
2669
2684
2670 proc = None
2685 proc = None
2671
2686
2672 if opts['localssh']:
2687 if opts['localssh']:
2673 # We start the SSH server in its own process so there is process
2688 # We start the SSH server in its own process so there is process
2674 # separation. This prevents a whole class of potential bugs around
2689 # separation. This prevents a whole class of potential bugs around
2675 # shared state from interfering with server operation.
2690 # shared state from interfering with server operation.
2676 args = util.hgcmd() + [
2691 args = util.hgcmd() + [
2677 '-R', repo.root,
2692 '-R', repo.root,
2678 'debugserve', '--sshstdio',
2693 'debugserve', '--sshstdio',
2679 ]
2694 ]
2680 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2695 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2681 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2696 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2682 bufsize=0)
2697 bufsize=0)
2683
2698
2684 stdin = proc.stdin
2699 stdin = proc.stdin
2685 stdout = proc.stdout
2700 stdout = proc.stdout
2686 stderr = proc.stderr
2701 stderr = proc.stderr
2687
2702
2688 # We turn the pipes into observers so we can log I/O.
2703 # We turn the pipes into observers so we can log I/O.
2689 if ui.verbose or opts['peer'] == 'raw':
2704 if ui.verbose or opts['peer'] == 'raw':
2690 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2705 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2691 logdata=True)
2706 logdata=True)
2692 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2707 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2693 logdata=True)
2708 logdata=True)
2694 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2709 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2695 logdata=True)
2710 logdata=True)
2696
2711
2697 # --localssh also implies the peer connection settings.
2712 # --localssh also implies the peer connection settings.
2698
2713
2699 url = 'ssh://localserver'
2714 url = 'ssh://localserver'
2700
2715
2701 if opts['peer'] == 'ssh1':
2716 if opts['peer'] == 'ssh1':
2702 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2717 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2703 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2718 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2704 None)
2719 None)
2705 elif opts['peer'] == 'ssh2':
2720 elif opts['peer'] == 'ssh2':
2706 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2721 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2707 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2722 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2708 None)
2723 None)
2709 elif opts['peer'] == 'raw':
2724 elif opts['peer'] == 'raw':
2710 ui.write(_('using raw connection to peer\n'))
2725 ui.write(_('using raw connection to peer\n'))
2711 peer = None
2726 peer = None
2712 else:
2727 else:
2713 ui.write(_('creating ssh peer from handshake results\n'))
2728 ui.write(_('creating ssh peer from handshake results\n'))
2714 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr)
2729 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr)
2715
2730
2716 else:
2731 else:
2717 raise error.Abort(_('only --localssh is currently supported'))
2732 raise error.Abort(_('only --localssh is currently supported'))
2718
2733
2734 batchedcommands = None
2735
2719 # Now perform actions based on the parsed wire language instructions.
2736 # Now perform actions based on the parsed wire language instructions.
2720 for action, lines in blocks:
2737 for action, lines in blocks:
2721 if action in ('raw', 'raw+'):
2738 if action in ('raw', 'raw+'):
2722 # Concatenate the data together.
2739 # Concatenate the data together.
2723 data = ''.join(l.lstrip() for l in lines)
2740 data = ''.join(l.lstrip() for l in lines)
2724 data = util.unescapestr(data)
2741 data = util.unescapestr(data)
2725 stdin.write(data)
2742 stdin.write(data)
2726
2743
2727 if action == 'raw+':
2744 if action == 'raw+':
2728 stdin.flush()
2745 stdin.flush()
2729 elif action == 'flush':
2746 elif action == 'flush':
2730 stdin.flush()
2747 stdin.flush()
2731 elif action.startswith('command'):
2748 elif action.startswith('command'):
2732 if not peer:
2749 if not peer:
2733 raise error.Abort(_('cannot send commands unless peer instance '
2750 raise error.Abort(_('cannot send commands unless peer instance '
2734 'is available'))
2751 'is available'))
2735
2752
2736 command = action.split(' ', 1)[1]
2753 command = action.split(' ', 1)[1]
2737
2754
2738 args = {}
2755 args = {}
2739 for line in lines:
2756 for line in lines:
2740 # We need to allow empty values.
2757 # We need to allow empty values.
2741 fields = line.lstrip().split(' ', 1)
2758 fields = line.lstrip().split(' ', 1)
2742 if len(fields) == 1:
2759 if len(fields) == 1:
2743 key = fields[0]
2760 key = fields[0]
2744 value = ''
2761 value = ''
2745 else:
2762 else:
2746 key, value = fields
2763 key, value = fields
2747
2764
2748 args[key] = util.unescapestr(value)
2765 args[key] = util.unescapestr(value)
2749
2766
2767 if batchedcommands is not None:
2768 batchedcommands.append((command, args))
2769 continue
2770
2750 ui.status(_('sending %s command\n') % command)
2771 ui.status(_('sending %s command\n') % command)
2751 res = peer._call(command, **args)
2772 res = peer._call(command, **args)
2752 ui.status(_('response: %s\n') % util.escapedata(res))
2773 ui.status(_('response: %s\n') % util.escapedata(res))
2753
2774
2775 elif action == 'batchbegin':
2776 if batchedcommands is not None:
2777 raise error.Abort(_('nested batchbegin not allowed'))
2778
2779 batchedcommands = []
2780 elif action == 'batchsubmit':
2781 # There is a batching API we could go through. But it would be
2782 # difficult to normalize requests into function calls. It is easier
2783 # to bypass this layer and normalize to commands + args.
2784 ui.status(_('sending batch with %d sub-commands\n') %
2785 len(batchedcommands))
2786 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
2787 ui.status(_('response #%d: %s\n') % (i, util.escapedata(chunk)))
2788
2789 batchedcommands = None
2754 elif action == 'close':
2790 elif action == 'close':
2755 peer.close()
2791 peer.close()
2756 elif action == 'readavailable':
2792 elif action == 'readavailable':
2757 fds = util.poll([stdout.fileno(), stderr.fileno()])
2793 fds = util.poll([stdout.fileno(), stderr.fileno()])
2758
2794
2759 if stdout.fileno() in fds:
2795 if stdout.fileno() in fds:
2760 util.readpipe(stdout)
2796 util.readpipe(stdout)
2761 if stderr.fileno() in fds:
2797 if stderr.fileno() in fds:
2762 util.readpipe(stderr)
2798 util.readpipe(stderr)
2763 elif action == 'readline':
2799 elif action == 'readline':
2764 stdout.readline()
2800 stdout.readline()
2765 else:
2801 else:
2766 raise error.Abort(_('unknown action: %s') % action)
2802 raise error.Abort(_('unknown action: %s') % action)
2767
2803
2804 if batchedcommands is not None:
2805 raise error.Abort(_('unclosed "batchbegin" request'))
2806
2768 if peer:
2807 if peer:
2769 peer.close()
2808 peer.close()
2770
2809
2771 if proc:
2810 if proc:
2772 proc.kill()
2811 proc.kill()
@@ -1,1832 +1,1934 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
67 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
87 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
96 capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
104 o> 384\n
104 o> 384\n
105 o> write(384) -> None:
105 o> write(384) -> None:
106 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
106 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
107 384
107 384
108 capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
108 capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
115 capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
119 o> 384\n
119 o> 384\n
120 o> write(384) -> None:
120 o> write(384) -> None:
121 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
121 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
148 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
149 i> write(98) -> None:
149 i> write(98) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
186 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
242 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
243 i> write(98) -> None:
243 i> write(98) -> None:
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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
299 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
314 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
361 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
362 i> write(98) -> None:
362 i> write(98) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
386 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
441 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
442 i> write(98) -> None:
442 i> write(98) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
488 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
489 i> write(98) -> None:
489 i> write(98) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
533 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
534 i> write(98) -> None:
534 i> write(98) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
603 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
685 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
686 i> write(98) -> None:
686 i> write(98) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
719 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
720 i> write(98) -> None:
720 i> write(98) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
762 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
763 i> write(98) -> None:
763 i> write(98) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
792 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
793 i> write(105) -> None:
793 i> write(105) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
833 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
882 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
938 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
957 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
998 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1012 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1029 remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1097 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1098 i> write(6) -> None:
1098 i> write(6) -> None:
1099 i> hello\n
1099 i> hello\n
1100 o> readline() -> 4:
1100 o> readline() -> 4:
1101 o> 384\n
1101 o> 384\n
1102 o> readline() -> 384:
1102 o> readline() -> 384:
1103 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1103 o> capabilities: lookup changegroupsubset 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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1135 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1136 i> write(45) -> None:
1136 i> write(45) -> None:
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) -> None:
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) -> None:
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) -> None:
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) -> None:
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) -> None:
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 changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1207 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1208 i> write(98) -> None:
1208 i> write(98) -> None:
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) -> None:
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) -> None:
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) -> None:
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 $ cd ..
1276 $ cd ..
1277
1277
1278 Test listkeys for listing namespaces
1278 Test listkeys for listing namespaces
1279
1279
1280 $ hg init empty
1280 $ hg init empty
1281 $ cd empty
1281 $ cd empty
1282 $ debugwireproto << EOF
1282 $ debugwireproto << EOF
1283 > command listkeys
1283 > command listkeys
1284 > namespace namespaces
1284 > namespace namespaces
1285 > EOF
1285 > EOF
1286 testing ssh1
1286 testing ssh1
1287 creating ssh peer from handshake results
1287 creating ssh peer from handshake results
1288 i> write(104) -> None:
1288 i> write(104) -> None:
1289 i> hello\n
1289 i> hello\n
1290 i> between\n
1290 i> between\n
1291 i> pairs 81\n
1291 i> pairs 81\n
1292 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1292 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1293 i> flush() -> None
1293 i> flush() -> None
1294 o> readline() -> 4:
1294 o> readline() -> 4:
1295 o> 384\n
1295 o> 384\n
1296 o> readline() -> 384:
1296 o> readline() -> 384:
1297 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1297 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1298 o> readline() -> 2:
1298 o> readline() -> 2:
1299 o> 1\n
1299 o> 1\n
1300 o> readline() -> 1:
1300 o> readline() -> 1:
1301 o> \n
1301 o> \n
1302 sending listkeys command
1302 sending listkeys command
1303 i> write(9) -> None:
1303 i> write(9) -> None:
1304 i> listkeys\n
1304 i> listkeys\n
1305 i> write(13) -> None:
1305 i> write(13) -> None:
1306 i> namespace 10\n
1306 i> namespace 10\n
1307 i> write(10) -> None: namespaces
1307 i> write(10) -> None: namespaces
1308 i> flush() -> None
1308 i> flush() -> None
1309 o> bufferedreadline() -> 3:
1309 o> bufferedreadline() -> 3:
1310 o> 30\n
1310 o> 30\n
1311 o> bufferedread(30) -> 30:
1311 o> bufferedread(30) -> 30:
1312 o> bookmarks \n
1312 o> bookmarks \n
1313 o> namespaces \n
1313 o> namespaces \n
1314 o> phases
1314 o> phases
1315 response: bookmarks \nnamespaces \nphases
1315 response: bookmarks \nnamespaces \nphases
1316
1316
1317 testing ssh2
1317 testing ssh2
1318 creating ssh peer from handshake results
1318 creating ssh peer from handshake results
1319 i> write(171) -> None:
1319 i> write(171) -> None:
1320 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1320 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1321 i> hello\n
1321 i> hello\n
1322 i> between\n
1322 i> between\n
1323 i> pairs 81\n
1323 i> pairs 81\n
1324 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1324 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1325 i> flush() -> None
1325 i> flush() -> None
1326 o> readline() -> 62:
1326 o> readline() -> 62:
1327 o> upgraded * exp-ssh-v2-0001\n (glob)
1327 o> upgraded * exp-ssh-v2-0001\n (glob)
1328 o> readline() -> 4:
1328 o> readline() -> 4:
1329 o> 383\n
1329 o> 383\n
1330 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1330 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1331 o> read(1) -> 1:
1331 o> read(1) -> 1:
1332 o> \n
1332 o> \n
1333 sending listkeys command
1333 sending listkeys command
1334 i> write(9) -> None:
1334 i> write(9) -> None:
1335 i> listkeys\n
1335 i> listkeys\n
1336 i> write(13) -> None:
1336 i> write(13) -> None:
1337 i> namespace 10\n
1337 i> namespace 10\n
1338 i> write(10) -> None: namespaces
1338 i> write(10) -> None: namespaces
1339 i> flush() -> None
1339 i> flush() -> None
1340 o> bufferedreadline() -> 3:
1340 o> bufferedreadline() -> 3:
1341 o> 30\n
1341 o> 30\n
1342 o> bufferedread(30) -> 30:
1342 o> bufferedread(30) -> 30:
1343 o> bookmarks \n
1343 o> bookmarks \n
1344 o> namespaces \n
1344 o> namespaces \n
1345 o> phases
1345 o> phases
1346 response: bookmarks \nnamespaces \nphases
1346 response: bookmarks \nnamespaces \nphases
1347
1347
1348 $ cd ..
1348 $ cd ..
1349
1349
1350 Test listkeys for bookmarks
1350 Test listkeys for bookmarks
1351
1351
1352 $ hg init bookmarkrepo
1352 $ hg init bookmarkrepo
1353 $ cd bookmarkrepo
1353 $ cd bookmarkrepo
1354 $ echo 0 > foo
1354 $ echo 0 > foo
1355 $ hg add foo
1355 $ hg add foo
1356 $ hg -q commit -m initial
1356 $ hg -q commit -m initial
1357 $ echo 1 > foo
1357 $ echo 1 > foo
1358 $ hg commit -m second
1358 $ hg commit -m second
1359
1359
1360 With no bookmarks set
1360 With no bookmarks set
1361
1361
1362 $ debugwireproto << EOF
1362 $ debugwireproto << EOF
1363 > command listkeys
1363 > command listkeys
1364 > namespace bookmarks
1364 > namespace bookmarks
1365 > EOF
1365 > EOF
1366 testing ssh1
1366 testing ssh1
1367 creating ssh peer from handshake results
1367 creating ssh peer from handshake results
1368 i> write(104) -> None:
1368 i> write(104) -> None:
1369 i> hello\n
1369 i> hello\n
1370 i> between\n
1370 i> between\n
1371 i> pairs 81\n
1371 i> pairs 81\n
1372 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1372 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1373 i> flush() -> None
1373 i> flush() -> None
1374 o> readline() -> 4:
1374 o> readline() -> 4:
1375 o> 384\n
1375 o> 384\n
1376 o> readline() -> 384:
1376 o> readline() -> 384:
1377 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1377 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1378 o> readline() -> 2:
1378 o> readline() -> 2:
1379 o> 1\n
1379 o> 1\n
1380 o> readline() -> 1:
1380 o> readline() -> 1:
1381 o> \n
1381 o> \n
1382 sending listkeys command
1382 sending listkeys command
1383 i> write(9) -> None:
1383 i> write(9) -> None:
1384 i> listkeys\n
1384 i> listkeys\n
1385 i> write(12) -> None:
1385 i> write(12) -> None:
1386 i> namespace 9\n
1386 i> namespace 9\n
1387 i> write(9) -> None: bookmarks
1387 i> write(9) -> None: bookmarks
1388 i> flush() -> None
1388 i> flush() -> None
1389 o> bufferedreadline() -> 2:
1389 o> bufferedreadline() -> 2:
1390 o> 0\n
1390 o> 0\n
1391 response:
1391 response:
1392
1392
1393 testing ssh2
1393 testing ssh2
1394 creating ssh peer from handshake results
1394 creating ssh peer from handshake results
1395 i> write(171) -> None:
1395 i> write(171) -> None:
1396 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1396 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1397 i> hello\n
1397 i> hello\n
1398 i> between\n
1398 i> between\n
1399 i> pairs 81\n
1399 i> pairs 81\n
1400 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1400 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1401 i> flush() -> None
1401 i> flush() -> None
1402 o> readline() -> 62:
1402 o> readline() -> 62:
1403 o> upgraded * exp-ssh-v2-0001\n (glob)
1403 o> upgraded * exp-ssh-v2-0001\n (glob)
1404 o> readline() -> 4:
1404 o> readline() -> 4:
1405 o> 383\n
1405 o> 383\n
1406 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1406 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1407 o> read(1) -> 1:
1407 o> read(1) -> 1:
1408 o> \n
1408 o> \n
1409 sending listkeys command
1409 sending listkeys command
1410 i> write(9) -> None:
1410 i> write(9) -> None:
1411 i> listkeys\n
1411 i> listkeys\n
1412 i> write(12) -> None:
1412 i> write(12) -> None:
1413 i> namespace 9\n
1413 i> namespace 9\n
1414 i> write(9) -> None: bookmarks
1414 i> write(9) -> None: 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 With a single bookmark set
1420 With a single bookmark set
1421
1421
1422 $ hg book -r 0 bookA
1422 $ hg book -r 0 bookA
1423 $ debugwireproto << EOF
1423 $ debugwireproto << EOF
1424 > command listkeys
1424 > command listkeys
1425 > namespace bookmarks
1425 > namespace bookmarks
1426 > EOF
1426 > EOF
1427 testing ssh1
1427 testing ssh1
1428 creating ssh peer from handshake results
1428 creating ssh peer from handshake results
1429 i> write(104) -> None:
1429 i> write(104) -> None:
1430 i> hello\n
1430 i> hello\n
1431 i> between\n
1431 i> between\n
1432 i> pairs 81\n
1432 i> pairs 81\n
1433 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1433 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1434 i> flush() -> None
1434 i> flush() -> None
1435 o> readline() -> 4:
1435 o> readline() -> 4:
1436 o> 384\n
1436 o> 384\n
1437 o> readline() -> 384:
1437 o> readline() -> 384:
1438 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1438 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1439 o> readline() -> 2:
1439 o> readline() -> 2:
1440 o> 1\n
1440 o> 1\n
1441 o> readline() -> 1:
1441 o> readline() -> 1:
1442 o> \n
1442 o> \n
1443 sending listkeys command
1443 sending listkeys command
1444 i> write(9) -> None:
1444 i> write(9) -> None:
1445 i> listkeys\n
1445 i> listkeys\n
1446 i> write(12) -> None:
1446 i> write(12) -> None:
1447 i> namespace 9\n
1447 i> namespace 9\n
1448 i> write(9) -> None: bookmarks
1448 i> write(9) -> None: bookmarks
1449 i> flush() -> None
1449 i> flush() -> None
1450 o> bufferedreadline() -> 3:
1450 o> bufferedreadline() -> 3:
1451 o> 46\n
1451 o> 46\n
1452 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1452 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1453 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1453 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1454
1454
1455 testing ssh2
1455 testing ssh2
1456 creating ssh peer from handshake results
1456 creating ssh peer from handshake results
1457 i> write(171) -> None:
1457 i> write(171) -> None:
1458 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1458 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1459 i> hello\n
1459 i> hello\n
1460 i> between\n
1460 i> between\n
1461 i> pairs 81\n
1461 i> pairs 81\n
1462 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1462 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1463 i> flush() -> None
1463 i> flush() -> None
1464 o> readline() -> 62:
1464 o> readline() -> 62:
1465 o> upgraded * exp-ssh-v2-0001\n (glob)
1465 o> upgraded * exp-ssh-v2-0001\n (glob)
1466 o> readline() -> 4:
1466 o> readline() -> 4:
1467 o> 383\n
1467 o> 383\n
1468 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1468 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1469 o> read(1) -> 1:
1469 o> read(1) -> 1:
1470 o> \n
1470 o> \n
1471 sending listkeys command
1471 sending listkeys command
1472 i> write(9) -> None:
1472 i> write(9) -> None:
1473 i> listkeys\n
1473 i> listkeys\n
1474 i> write(12) -> None:
1474 i> write(12) -> None:
1475 i> namespace 9\n
1475 i> namespace 9\n
1476 i> write(9) -> None: bookmarks
1476 i> write(9) -> None: bookmarks
1477 i> flush() -> None
1477 i> flush() -> None
1478 o> bufferedreadline() -> 3:
1478 o> bufferedreadline() -> 3:
1479 o> 46\n
1479 o> 46\n
1480 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1480 o> bufferedread(46) -> 46: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1481 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1481 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f
1482
1482
1483 With multiple bookmarks set
1483 With multiple bookmarks set
1484
1484
1485 $ hg book -r 1 bookB
1485 $ hg book -r 1 bookB
1486 $ debugwireproto << EOF
1486 $ debugwireproto << EOF
1487 > command listkeys
1487 > command listkeys
1488 > namespace bookmarks
1488 > namespace bookmarks
1489 > EOF
1489 > EOF
1490 testing ssh1
1490 testing ssh1
1491 creating ssh peer from handshake results
1491 creating ssh peer from handshake results
1492 i> write(104) -> None:
1492 i> write(104) -> None:
1493 i> hello\n
1493 i> hello\n
1494 i> between\n
1494 i> between\n
1495 i> pairs 81\n
1495 i> pairs 81\n
1496 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1496 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1497 i> flush() -> None
1497 i> flush() -> None
1498 o> readline() -> 4:
1498 o> readline() -> 4:
1499 o> 384\n
1499 o> 384\n
1500 o> readline() -> 384:
1500 o> readline() -> 384:
1501 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1501 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1502 o> readline() -> 2:
1502 o> readline() -> 2:
1503 o> 1\n
1503 o> 1\n
1504 o> readline() -> 1:
1504 o> readline() -> 1:
1505 o> \n
1505 o> \n
1506 sending listkeys command
1506 sending listkeys command
1507 i> write(9) -> None:
1507 i> write(9) -> None:
1508 i> listkeys\n
1508 i> listkeys\n
1509 i> write(12) -> None:
1509 i> write(12) -> None:
1510 i> namespace 9\n
1510 i> namespace 9\n
1511 i> write(9) -> None: bookmarks
1511 i> write(9) -> None: bookmarks
1512 i> flush() -> None
1512 i> flush() -> None
1513 o> bufferedreadline() -> 3:
1513 o> bufferedreadline() -> 3:
1514 o> 93\n
1514 o> 93\n
1515 o> bufferedread(93) -> 93:
1515 o> bufferedread(93) -> 93:
1516 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1516 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1517 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1517 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1518 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1518 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1519
1519
1520 testing ssh2
1520 testing ssh2
1521 creating ssh peer from handshake results
1521 creating ssh peer from handshake results
1522 i> write(171) -> None:
1522 i> write(171) -> None:
1523 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1523 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1524 i> hello\n
1524 i> hello\n
1525 i> between\n
1525 i> between\n
1526 i> pairs 81\n
1526 i> pairs 81\n
1527 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1527 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1528 i> flush() -> None
1528 i> flush() -> None
1529 o> readline() -> 62:
1529 o> readline() -> 62:
1530 o> upgraded * exp-ssh-v2-0001\n (glob)
1530 o> upgraded * exp-ssh-v2-0001\n (glob)
1531 o> readline() -> 4:
1531 o> readline() -> 4:
1532 o> 383\n
1532 o> 383\n
1533 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1533 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1534 o> read(1) -> 1:
1534 o> read(1) -> 1:
1535 o> \n
1535 o> \n
1536 sending listkeys command
1536 sending listkeys command
1537 i> write(9) -> None:
1537 i> write(9) -> None:
1538 i> listkeys\n
1538 i> listkeys\n
1539 i> write(12) -> None:
1539 i> write(12) -> None:
1540 i> namespace 9\n
1540 i> namespace 9\n
1541 i> write(9) -> None: bookmarks
1541 i> write(9) -> None: bookmarks
1542 i> flush() -> None
1542 i> flush() -> None
1543 o> bufferedreadline() -> 3:
1543 o> bufferedreadline() -> 3:
1544 o> 93\n
1544 o> 93\n
1545 o> bufferedread(93) -> 93:
1545 o> bufferedread(93) -> 93:
1546 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1546 o> bookA 68986213bd4485ea51533535e3fc9e78007a711f\n
1547 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1547 o> bookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1548 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1548 response: bookA 68986213bd4485ea51533535e3fc9e78007a711f\nbookB 1880f3755e2e52e3199e0ee5638128b08642f34d
1549
1549
1550 $ cd ..
1550 $ cd ..
1551
1551
1552 Test listkeys for phases
1552 Test listkeys for phases
1553
1553
1554 $ hg init phasesrepo
1554 $ hg init phasesrepo
1555 $ cd phasesrepo
1555 $ cd phasesrepo
1556
1556
1557 Phases on empty repo
1557 Phases on empty repo
1558
1558
1559 $ debugwireproto << EOF
1559 $ debugwireproto << EOF
1560 > command listkeys
1560 > command listkeys
1561 > namespace phases
1561 > namespace phases
1562 > EOF
1562 > EOF
1563 testing ssh1
1563 testing ssh1
1564 creating ssh peer from handshake results
1564 creating ssh peer from handshake results
1565 i> write(104) -> None:
1565 i> write(104) -> None:
1566 i> hello\n
1566 i> hello\n
1567 i> between\n
1567 i> between\n
1568 i> pairs 81\n
1568 i> pairs 81\n
1569 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1569 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1570 i> flush() -> None
1570 i> flush() -> None
1571 o> readline() -> 4:
1571 o> readline() -> 4:
1572 o> 384\n
1572 o> 384\n
1573 o> readline() -> 384:
1573 o> readline() -> 384:
1574 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1574 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1575 o> readline() -> 2:
1575 o> readline() -> 2:
1576 o> 1\n
1576 o> 1\n
1577 o> readline() -> 1:
1577 o> readline() -> 1:
1578 o> \n
1578 o> \n
1579 sending listkeys command
1579 sending listkeys command
1580 i> write(9) -> None:
1580 i> write(9) -> None:
1581 i> listkeys\n
1581 i> listkeys\n
1582 i> write(12) -> None:
1582 i> write(12) -> None:
1583 i> namespace 6\n
1583 i> namespace 6\n
1584 i> write(6) -> None: phases
1584 i> write(6) -> None: phases
1585 i> flush() -> None
1585 i> flush() -> None
1586 o> bufferedreadline() -> 3:
1586 o> bufferedreadline() -> 3:
1587 o> 15\n
1587 o> 15\n
1588 o> bufferedread(15) -> 15: publishing True
1588 o> bufferedread(15) -> 15: publishing True
1589 response: publishing True
1589 response: publishing True
1590
1590
1591 testing ssh2
1591 testing ssh2
1592 creating ssh peer from handshake results
1592 creating ssh peer from handshake results
1593 i> write(171) -> None:
1593 i> write(171) -> None:
1594 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1594 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1595 i> hello\n
1595 i> hello\n
1596 i> between\n
1596 i> between\n
1597 i> pairs 81\n
1597 i> pairs 81\n
1598 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1598 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1599 i> flush() -> None
1599 i> flush() -> None
1600 o> readline() -> 62:
1600 o> readline() -> 62:
1601 o> upgraded * exp-ssh-v2-0001\n (glob)
1601 o> upgraded * exp-ssh-v2-0001\n (glob)
1602 o> readline() -> 4:
1602 o> readline() -> 4:
1603 o> 383\n
1603 o> 383\n
1604 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1604 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1605 o> read(1) -> 1:
1605 o> read(1) -> 1:
1606 o> \n
1606 o> \n
1607 sending listkeys command
1607 sending listkeys command
1608 i> write(9) -> None:
1608 i> write(9) -> None:
1609 i> listkeys\n
1609 i> listkeys\n
1610 i> write(12) -> None:
1610 i> write(12) -> None:
1611 i> namespace 6\n
1611 i> namespace 6\n
1612 i> write(6) -> None: phases
1612 i> write(6) -> None: phases
1613 i> flush() -> None
1613 i> flush() -> None
1614 o> bufferedreadline() -> 3:
1614 o> bufferedreadline() -> 3:
1615 o> 15\n
1615 o> 15\n
1616 o> bufferedread(15) -> 15: publishing True
1616 o> bufferedread(15) -> 15: publishing True
1617 response: publishing True
1617 response: publishing True
1618
1618
1619 Create some commits
1619 Create some commits
1620
1620
1621 $ echo 0 > foo
1621 $ echo 0 > foo
1622 $ hg add foo
1622 $ hg add foo
1623 $ hg -q commit -m initial
1623 $ hg -q commit -m initial
1624 $ hg phase --public
1624 $ hg phase --public
1625 $ echo 1 > foo
1625 $ echo 1 > foo
1626 $ hg commit -m 'head 1 commit 1'
1626 $ hg commit -m 'head 1 commit 1'
1627 $ echo 2 > foo
1627 $ echo 2 > foo
1628 $ hg commit -m 'head 1 commit 2'
1628 $ hg commit -m 'head 1 commit 2'
1629 $ hg -q up 0
1629 $ hg -q up 0
1630 $ echo 1a > foo
1630 $ echo 1a > foo
1631 $ hg commit -m 'head 2 commit 1'
1631 $ hg commit -m 'head 2 commit 1'
1632 created new head
1632 created new head
1633 $ echo 2a > foo
1633 $ echo 2a > foo
1634 $ hg commit -m 'head 2 commit 2'
1634 $ hg commit -m 'head 2 commit 2'
1635
1635
1636 Two draft heads
1636 Two draft heads
1637
1637
1638 $ debugwireproto << EOF
1638 $ debugwireproto << EOF
1639 > command listkeys
1639 > command listkeys
1640 > namespace phases
1640 > namespace phases
1641 > EOF
1641 > EOF
1642 testing ssh1
1642 testing ssh1
1643 creating ssh peer from handshake results
1643 creating ssh peer from handshake results
1644 i> write(104) -> None:
1644 i> write(104) -> None:
1645 i> hello\n
1645 i> hello\n
1646 i> between\n
1646 i> between\n
1647 i> pairs 81\n
1647 i> pairs 81\n
1648 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1648 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1649 i> flush() -> None
1649 i> flush() -> None
1650 o> readline() -> 4:
1650 o> readline() -> 4:
1651 o> 384\n
1651 o> 384\n
1652 o> readline() -> 384:
1652 o> readline() -> 384:
1653 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1653 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1654 o> readline() -> 2:
1654 o> readline() -> 2:
1655 o> 1\n
1655 o> 1\n
1656 o> readline() -> 1:
1656 o> readline() -> 1:
1657 o> \n
1657 o> \n
1658 sending listkeys command
1658 sending listkeys command
1659 i> write(9) -> None:
1659 i> write(9) -> None:
1660 i> listkeys\n
1660 i> listkeys\n
1661 i> write(12) -> None:
1661 i> write(12) -> None:
1662 i> namespace 6\n
1662 i> namespace 6\n
1663 i> write(6) -> None: phases
1663 i> write(6) -> None: phases
1664 i> flush() -> None
1664 i> flush() -> None
1665 o> bufferedreadline() -> 4:
1665 o> bufferedreadline() -> 4:
1666 o> 101\n
1666 o> 101\n
1667 o> bufferedread(101) -> 101:
1667 o> bufferedread(101) -> 101:
1668 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1668 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1669 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1669 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1670 o> publishing True
1670 o> publishing True
1671 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1671 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1672
1672
1673 testing ssh2
1673 testing ssh2
1674 creating ssh peer from handshake results
1674 creating ssh peer from handshake results
1675 i> write(171) -> None:
1675 i> write(171) -> None:
1676 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1676 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1677 i> hello\n
1677 i> hello\n
1678 i> between\n
1678 i> between\n
1679 i> pairs 81\n
1679 i> pairs 81\n
1680 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1680 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1681 i> flush() -> None
1681 i> flush() -> None
1682 o> readline() -> 62:
1682 o> readline() -> 62:
1683 o> upgraded * exp-ssh-v2-0001\n (glob)
1683 o> upgraded * exp-ssh-v2-0001\n (glob)
1684 o> readline() -> 4:
1684 o> readline() -> 4:
1685 o> 383\n
1685 o> 383\n
1686 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1686 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1687 o> read(1) -> 1:
1687 o> read(1) -> 1:
1688 o> \n
1688 o> \n
1689 sending listkeys command
1689 sending listkeys command
1690 i> write(9) -> None:
1690 i> write(9) -> None:
1691 i> listkeys\n
1691 i> listkeys\n
1692 i> write(12) -> None:
1692 i> write(12) -> None:
1693 i> namespace 6\n
1693 i> namespace 6\n
1694 i> write(6) -> None: phases
1694 i> write(6) -> None: phases
1695 i> flush() -> None
1695 i> flush() -> None
1696 o> bufferedreadline() -> 4:
1696 o> bufferedreadline() -> 4:
1697 o> 101\n
1697 o> 101\n
1698 o> bufferedread(101) -> 101:
1698 o> bufferedread(101) -> 101:
1699 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1699 o> 20b8a89289d80036e6c4e87c2083e3bea1586637 1\n
1700 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1700 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1701 o> publishing True
1701 o> publishing True
1702 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1702 response: 20b8a89289d80036e6c4e87c2083e3bea1586637 1\nc4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1703
1703
1704 Single draft head
1704 Single draft head
1705
1705
1706 $ hg phase --public -r 2
1706 $ hg phase --public -r 2
1707 $ debugwireproto << EOF
1707 $ debugwireproto << EOF
1708 > command listkeys
1708 > command listkeys
1709 > namespace phases
1709 > namespace phases
1710 > EOF
1710 > EOF
1711 testing ssh1
1711 testing ssh1
1712 creating ssh peer from handshake results
1712 creating ssh peer from handshake results
1713 i> write(104) -> None:
1713 i> write(104) -> None:
1714 i> hello\n
1714 i> hello\n
1715 i> between\n
1715 i> between\n
1716 i> pairs 81\n
1716 i> pairs 81\n
1717 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1717 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1718 i> flush() -> None
1718 i> flush() -> None
1719 o> readline() -> 4:
1719 o> readline() -> 4:
1720 o> 384\n
1720 o> 384\n
1721 o> readline() -> 384:
1721 o> readline() -> 384:
1722 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1722 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1723 o> readline() -> 2:
1723 o> readline() -> 2:
1724 o> 1\n
1724 o> 1\n
1725 o> readline() -> 1:
1725 o> readline() -> 1:
1726 o> \n
1726 o> \n
1727 sending listkeys command
1727 sending listkeys command
1728 i> write(9) -> None:
1728 i> write(9) -> None:
1729 i> listkeys\n
1729 i> listkeys\n
1730 i> write(12) -> None:
1730 i> write(12) -> None:
1731 i> namespace 6\n
1731 i> namespace 6\n
1732 i> write(6) -> None: phases
1732 i> write(6) -> None: phases
1733 i> flush() -> None
1733 i> flush() -> None
1734 o> bufferedreadline() -> 3:
1734 o> bufferedreadline() -> 3:
1735 o> 58\n
1735 o> 58\n
1736 o> bufferedread(58) -> 58:
1736 o> bufferedread(58) -> 58:
1737 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1737 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1738 o> publishing True
1738 o> publishing True
1739 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1739 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1740
1740
1741 testing ssh2
1741 testing ssh2
1742 creating ssh peer from handshake results
1742 creating ssh peer from handshake results
1743 i> write(171) -> None:
1743 i> write(171) -> None:
1744 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1744 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1745 i> hello\n
1745 i> hello\n
1746 i> between\n
1746 i> between\n
1747 i> pairs 81\n
1747 i> pairs 81\n
1748 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1748 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1749 i> flush() -> None
1749 i> flush() -> None
1750 o> readline() -> 62:
1750 o> readline() -> 62:
1751 o> upgraded * exp-ssh-v2-0001\n (glob)
1751 o> upgraded * exp-ssh-v2-0001\n (glob)
1752 o> readline() -> 4:
1752 o> readline() -> 4:
1753 o> 383\n
1753 o> 383\n
1754 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1754 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1755 o> read(1) -> 1:
1755 o> read(1) -> 1:
1756 o> \n
1756 o> \n
1757 sending listkeys command
1757 sending listkeys command
1758 i> write(9) -> None:
1758 i> write(9) -> None:
1759 i> listkeys\n
1759 i> listkeys\n
1760 i> write(12) -> None:
1760 i> write(12) -> None:
1761 i> namespace 6\n
1761 i> namespace 6\n
1762 i> write(6) -> None: phases
1762 i> write(6) -> None: phases
1763 i> flush() -> None
1763 i> flush() -> None
1764 o> bufferedreadline() -> 3:
1764 o> bufferedreadline() -> 3:
1765 o> 58\n
1765 o> 58\n
1766 o> bufferedread(58) -> 58:
1766 o> bufferedread(58) -> 58:
1767 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1767 o> c4750011d906c18ea2f0527419cbc1a544435150 1\n
1768 o> publishing True
1768 o> publishing True
1769 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1769 response: c4750011d906c18ea2f0527419cbc1a544435150 1\npublishing True
1770
1770
1771 All public heads
1771 All public heads
1772
1772
1773 $ hg phase --public -r 4
1773 $ hg phase --public -r 4
1774 $ debugwireproto << EOF
1774 $ debugwireproto << EOF
1775 > command listkeys
1775 > command listkeys
1776 > namespace phases
1776 > namespace phases
1777 > EOF
1777 > EOF
1778 testing ssh1
1778 testing ssh1
1779 creating ssh peer from handshake results
1779 creating ssh peer from handshake results
1780 i> write(104) -> None:
1780 i> write(104) -> None:
1781 i> hello\n
1781 i> hello\n
1782 i> between\n
1782 i> between\n
1783 i> pairs 81\n
1783 i> pairs 81\n
1784 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1784 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1785 i> flush() -> None
1785 i> flush() -> None
1786 o> readline() -> 4:
1786 o> readline() -> 4:
1787 o> 384\n
1787 o> 384\n
1788 o> readline() -> 384:
1788 o> readline() -> 384:
1789 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1789 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1790 o> readline() -> 2:
1790 o> readline() -> 2:
1791 o> 1\n
1791 o> 1\n
1792 o> readline() -> 1:
1792 o> readline() -> 1:
1793 o> \n
1793 o> \n
1794 sending listkeys command
1794 sending listkeys command
1795 i> write(9) -> None:
1795 i> write(9) -> None:
1796 i> listkeys\n
1796 i> listkeys\n
1797 i> write(12) -> None:
1797 i> write(12) -> None:
1798 i> namespace 6\n
1798 i> namespace 6\n
1799 i> write(6) -> None: phases
1799 i> write(6) -> None: phases
1800 i> flush() -> None
1800 i> flush() -> None
1801 o> bufferedreadline() -> 3:
1801 o> bufferedreadline() -> 3:
1802 o> 15\n
1802 o> 15\n
1803 o> bufferedread(15) -> 15: publishing True
1803 o> bufferedread(15) -> 15: publishing True
1804 response: publishing True
1804 response: publishing True
1805
1805
1806 testing ssh2
1806 testing ssh2
1807 creating ssh peer from handshake results
1807 creating ssh peer from handshake results
1808 i> write(171) -> None:
1808 i> write(171) -> None:
1809 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1809 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1810 i> hello\n
1810 i> hello\n
1811 i> between\n
1811 i> between\n
1812 i> pairs 81\n
1812 i> pairs 81\n
1813 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1813 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1814 i> flush() -> None
1814 i> flush() -> None
1815 o> readline() -> 62:
1815 o> readline() -> 62:
1816 o> upgraded * exp-ssh-v2-0001\n (glob)
1816 o> upgraded * exp-ssh-v2-0001\n (glob)
1817 o> readline() -> 4:
1817 o> readline() -> 4:
1818 o> 383\n
1818 o> 383\n
1819 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1819 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1820 o> read(1) -> 1:
1820 o> read(1) -> 1:
1821 o> \n
1821 o> \n
1822 sending listkeys command
1822 sending listkeys command
1823 i> write(9) -> None:
1823 i> write(9) -> None:
1824 i> listkeys\n
1824 i> listkeys\n
1825 i> write(12) -> None:
1825 i> write(12) -> None:
1826 i> namespace 6\n
1826 i> namespace 6\n
1827 i> write(6) -> None: phases
1827 i> write(6) -> None: phases
1828 i> flush() -> None
1828 i> flush() -> None
1829 o> bufferedreadline() -> 3:
1829 o> bufferedreadline() -> 3:
1830 o> 15\n
1830 o> 15\n
1831 o> bufferedread(15) -> 15: publishing True
1831 o> bufferedread(15) -> 15: publishing True
1832 response: publishing True
1832 response: publishing True
1833
1834 $ cd ..
1835
1836 Test batching of requests
1837
1838 $ hg init batching
1839 $ cd batching
1840 $ echo 0 > foo
1841 $ hg add foo
1842 $ hg -q commit -m initial
1843 $ hg phase --public
1844 $ echo 1 > foo
1845 $ hg commit -m 'commit 1'
1846 $ hg -q up 0
1847 $ echo 2 > foo
1848 $ hg commit -m 'commit 2'
1849 created new head
1850 $ hg book -r 1 bookA
1851 $ hg book -r 2 bookB
1852
1853 $ debugwireproto << EOF
1854 > batchbegin
1855 > command heads
1856 > command listkeys
1857 > namespace bookmarks
1858 > command listkeys
1859 > namespace phases
1860 > batchsubmit
1861 > EOF
1862 testing ssh1
1863 creating ssh peer from handshake results
1864 i> write(104) -> None:
1865 i> hello\n
1866 i> between\n
1867 i> pairs 81\n
1868 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1869 i> flush() -> None
1870 o> readline() -> 4:
1871 o> 384\n
1872 o> readline() -> 384:
1873 o> capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
1874 o> readline() -> 2:
1875 o> 1\n
1876 o> readline() -> 1:
1877 o> \n
1878 sending batch with 3 sub-commands
1879 i> write(6) -> None:
1880 i> batch\n
1881 i> write(4) -> None:
1882 i> * 0\n
1883 i> write(8) -> None:
1884 i> cmds 61\n
1885 i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
1886 i> flush() -> None
1887 o> bufferedreadline() -> 4:
1888 o> 278\n
1889 o> bufferedread(278) -> 278:
1890 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1891 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1892 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
1893 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
1894 o> publishing True
1895 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1896 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
1897 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
1898
1899 testing ssh2
1900 creating ssh peer from handshake results
1901 i> write(171) -> None:
1902 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1903 i> hello\n
1904 i> between\n
1905 i> pairs 81\n
1906 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1907 i> flush() -> None
1908 o> readline() -> 62:
1909 o> upgraded * exp-ssh-v2-0001\n (glob)
1910 o> readline() -> 4:
1911 o> 383\n
1912 o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
1913 o> read(1) -> 1:
1914 o> \n
1915 sending batch with 3 sub-commands
1916 i> write(6) -> None:
1917 i> batch\n
1918 i> write(4) -> None:
1919 i> * 0\n
1920 i> write(8) -> None:
1921 i> cmds 61\n
1922 i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
1923 i> flush() -> None
1924 o> bufferedreadline() -> 4:
1925 o> 278\n
1926 o> bufferedread(278) -> 278:
1927 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1928 o> ;bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1929 o> bookB bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\n
1930 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 1\n
1931 o> publishing True
1932 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
1933 response #1: bookA 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB bfebe6bd38eebc6f8202e419c1171268987ea6a6
1934 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab 1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6 1\npublishing True
General Comments 0
You need to be logged in to leave comments. Login now