##// END OF EJS Templates
tags: add a debug command to display .hg/cache/hgtagsfnodes1...
Valentin Gatien-Baron -
r44772:d8b53385 default
parent child Browse files
Show More
@@ -1,4294 +1,4304 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 platform
16 import platform
17 import random
17 import random
18 import re
18 import re
19 import socket
19 import socket
20 import ssl
20 import ssl
21 import stat
21 import stat
22 import string
22 import string
23 import subprocess
23 import subprocess
24 import sys
24 import sys
25 import time
25 import time
26
26
27 from .i18n import _
27 from .i18n import _
28 from .node import (
28 from .node import (
29 bin,
29 bin,
30 hex,
30 hex,
31 nullhex,
31 nullhex,
32 nullid,
32 nullid,
33 nullrev,
33 nullrev,
34 short,
34 short,
35 )
35 )
36 from .pycompat import (
36 from .pycompat import (
37 getattr,
37 getattr,
38 open,
38 open,
39 )
39 )
40 from . import (
40 from . import (
41 bundle2,
41 bundle2,
42 changegroup,
42 changegroup,
43 cmdutil,
43 cmdutil,
44 color,
44 color,
45 context,
45 context,
46 copies,
46 copies,
47 dagparser,
47 dagparser,
48 encoding,
48 encoding,
49 error,
49 error,
50 exchange,
50 exchange,
51 extensions,
51 extensions,
52 filemerge,
52 filemerge,
53 filesetlang,
53 filesetlang,
54 formatter,
54 formatter,
55 hg,
55 hg,
56 httppeer,
56 httppeer,
57 localrepo,
57 localrepo,
58 lock as lockmod,
58 lock as lockmod,
59 logcmdutil,
59 logcmdutil,
60 merge as mergemod,
60 merge as mergemod,
61 obsolete,
61 obsolete,
62 obsutil,
62 obsutil,
63 pathutil,
63 pathutil,
64 phases,
64 phases,
65 policy,
65 policy,
66 pvec,
66 pvec,
67 pycompat,
67 pycompat,
68 registrar,
68 registrar,
69 repair,
69 repair,
70 revlog,
70 revlog,
71 revset,
71 revset,
72 revsetlang,
72 revsetlang,
73 scmutil,
73 scmutil,
74 setdiscovery,
74 setdiscovery,
75 simplemerge,
75 simplemerge,
76 sshpeer,
76 sshpeer,
77 sslutil,
77 sslutil,
78 streamclone,
78 streamclone,
79 tags as tagsmod,
79 templater,
80 templater,
80 treediscovery,
81 treediscovery,
81 upgrade,
82 upgrade,
82 url as urlmod,
83 url as urlmod,
83 util,
84 util,
84 vfs as vfsmod,
85 vfs as vfsmod,
85 wireprotoframing,
86 wireprotoframing,
86 wireprotoserver,
87 wireprotoserver,
87 wireprotov2peer,
88 wireprotov2peer,
88 )
89 )
89 from .utils import (
90 from .utils import (
90 cborutil,
91 cborutil,
91 compression,
92 compression,
92 dateutil,
93 dateutil,
93 procutil,
94 procutil,
94 stringutil,
95 stringutil,
95 )
96 )
96
97
97 from .revlogutils import deltas as deltautil
98 from .revlogutils import deltas as deltautil
98
99
99 release = lockmod.release
100 release = lockmod.release
100
101
101 command = registrar.command()
102 command = registrar.command()
102
103
103
104
104 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
105 @command(b'debugancestor', [], _(b'[INDEX] REV1 REV2'), optionalrepo=True)
105 def debugancestor(ui, repo, *args):
106 def debugancestor(ui, repo, *args):
106 """find the ancestor revision of two revisions in a given index"""
107 """find the ancestor revision of two revisions in a given index"""
107 if len(args) == 3:
108 if len(args) == 3:
108 index, rev1, rev2 = args
109 index, rev1, rev2 = args
109 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
110 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
110 lookup = r.lookup
111 lookup = r.lookup
111 elif len(args) == 2:
112 elif len(args) == 2:
112 if not repo:
113 if not repo:
113 raise error.Abort(
114 raise error.Abort(
114 _(b'there is no Mercurial repository here (.hg not found)')
115 _(b'there is no Mercurial repository here (.hg not found)')
115 )
116 )
116 rev1, rev2 = args
117 rev1, rev2 = args
117 r = repo.changelog
118 r = repo.changelog
118 lookup = repo.lookup
119 lookup = repo.lookup
119 else:
120 else:
120 raise error.Abort(_(b'either two or three arguments required'))
121 raise error.Abort(_(b'either two or three arguments required'))
121 a = r.ancestor(lookup(rev1), lookup(rev2))
122 a = r.ancestor(lookup(rev1), lookup(rev2))
122 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
123 ui.write(b'%d:%s\n' % (r.rev(a), hex(a)))
123
124
124
125
125 @command(b'debugapplystreamclonebundle', [], b'FILE')
126 @command(b'debugapplystreamclonebundle', [], b'FILE')
126 def debugapplystreamclonebundle(ui, repo, fname):
127 def debugapplystreamclonebundle(ui, repo, fname):
127 """apply a stream clone bundle file"""
128 """apply a stream clone bundle file"""
128 f = hg.openpath(ui, fname)
129 f = hg.openpath(ui, fname)
129 gen = exchange.readbundle(ui, f, fname)
130 gen = exchange.readbundle(ui, f, fname)
130 gen.apply(repo)
131 gen.apply(repo)
131
132
132
133
133 @command(
134 @command(
134 b'debugbuilddag',
135 b'debugbuilddag',
135 [
136 [
136 (
137 (
137 b'm',
138 b'm',
138 b'mergeable-file',
139 b'mergeable-file',
139 None,
140 None,
140 _(b'add single file mergeable changes'),
141 _(b'add single file mergeable changes'),
141 ),
142 ),
142 (
143 (
143 b'o',
144 b'o',
144 b'overwritten-file',
145 b'overwritten-file',
145 None,
146 None,
146 _(b'add single file all revs overwrite'),
147 _(b'add single file all revs overwrite'),
147 ),
148 ),
148 (b'n', b'new-file', None, _(b'add new file at each rev')),
149 (b'n', b'new-file', None, _(b'add new file at each rev')),
149 ],
150 ],
150 _(b'[OPTION]... [TEXT]'),
151 _(b'[OPTION]... [TEXT]'),
151 )
152 )
152 def debugbuilddag(
153 def debugbuilddag(
153 ui,
154 ui,
154 repo,
155 repo,
155 text=None,
156 text=None,
156 mergeable_file=False,
157 mergeable_file=False,
157 overwritten_file=False,
158 overwritten_file=False,
158 new_file=False,
159 new_file=False,
159 ):
160 ):
160 """builds a repo with a given DAG from scratch in the current empty repo
161 """builds a repo with a given DAG from scratch in the current empty repo
161
162
162 The description of the DAG is read from stdin if not given on the
163 The description of the DAG is read from stdin if not given on the
163 command line.
164 command line.
164
165
165 Elements:
166 Elements:
166
167
167 - "+n" is a linear run of n nodes based on the current default parent
168 - "+n" is a linear run of n nodes based on the current default parent
168 - "." is a single node based on the current default parent
169 - "." is a single node based on the current default parent
169 - "$" resets the default parent to null (implied at the start);
170 - "$" resets the default parent to null (implied at the start);
170 otherwise the default parent is always the last node created
171 otherwise the default parent is always the last node created
171 - "<p" sets the default parent to the backref p
172 - "<p" sets the default parent to the backref p
172 - "*p" is a fork at parent p, which is a backref
173 - "*p" is a fork at parent p, which is a backref
173 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
174 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
174 - "/p2" is a merge of the preceding node and p2
175 - "/p2" is a merge of the preceding node and p2
175 - ":tag" defines a local tag for the preceding node
176 - ":tag" defines a local tag for the preceding node
176 - "@branch" sets the named branch for subsequent nodes
177 - "@branch" sets the named branch for subsequent nodes
177 - "#...\\n" is a comment up to the end of the line
178 - "#...\\n" is a comment up to the end of the line
178
179
179 Whitespace between the above elements is ignored.
180 Whitespace between the above elements is ignored.
180
181
181 A backref is either
182 A backref is either
182
183
183 - a number n, which references the node curr-n, where curr is the current
184 - a number n, which references the node curr-n, where curr is the current
184 node, or
185 node, or
185 - the name of a local tag you placed earlier using ":tag", or
186 - the name of a local tag you placed earlier using ":tag", or
186 - empty to denote the default parent.
187 - empty to denote the default parent.
187
188
188 All string valued-elements are either strictly alphanumeric, or must
189 All string valued-elements are either strictly alphanumeric, or must
189 be enclosed in double quotes ("..."), with "\\" as escape character.
190 be enclosed in double quotes ("..."), with "\\" as escape character.
190 """
191 """
191
192
192 if text is None:
193 if text is None:
193 ui.status(_(b"reading DAG from stdin\n"))
194 ui.status(_(b"reading DAG from stdin\n"))
194 text = ui.fin.read()
195 text = ui.fin.read()
195
196
196 cl = repo.changelog
197 cl = repo.changelog
197 if len(cl) > 0:
198 if len(cl) > 0:
198 raise error.Abort(_(b'repository is not empty'))
199 raise error.Abort(_(b'repository is not empty'))
199
200
200 # determine number of revs in DAG
201 # determine number of revs in DAG
201 total = 0
202 total = 0
202 for type, data in dagparser.parsedag(text):
203 for type, data in dagparser.parsedag(text):
203 if type == b'n':
204 if type == b'n':
204 total += 1
205 total += 1
205
206
206 if mergeable_file:
207 if mergeable_file:
207 linesperrev = 2
208 linesperrev = 2
208 # make a file with k lines per rev
209 # make a file with k lines per rev
209 initialmergedlines = [
210 initialmergedlines = [
210 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
211 b'%d' % i for i in pycompat.xrange(0, total * linesperrev)
211 ]
212 ]
212 initialmergedlines.append(b"")
213 initialmergedlines.append(b"")
213
214
214 tags = []
215 tags = []
215 progress = ui.makeprogress(
216 progress = ui.makeprogress(
216 _(b'building'), unit=_(b'revisions'), total=total
217 _(b'building'), unit=_(b'revisions'), total=total
217 )
218 )
218 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
219 with progress, repo.wlock(), repo.lock(), repo.transaction(b"builddag"):
219 at = -1
220 at = -1
220 atbranch = b'default'
221 atbranch = b'default'
221 nodeids = []
222 nodeids = []
222 id = 0
223 id = 0
223 progress.update(id)
224 progress.update(id)
224 for type, data in dagparser.parsedag(text):
225 for type, data in dagparser.parsedag(text):
225 if type == b'n':
226 if type == b'n':
226 ui.note((b'node %s\n' % pycompat.bytestr(data)))
227 ui.note((b'node %s\n' % pycompat.bytestr(data)))
227 id, ps = data
228 id, ps = data
228
229
229 files = []
230 files = []
230 filecontent = {}
231 filecontent = {}
231
232
232 p2 = None
233 p2 = None
233 if mergeable_file:
234 if mergeable_file:
234 fn = b"mf"
235 fn = b"mf"
235 p1 = repo[ps[0]]
236 p1 = repo[ps[0]]
236 if len(ps) > 1:
237 if len(ps) > 1:
237 p2 = repo[ps[1]]
238 p2 = repo[ps[1]]
238 pa = p1.ancestor(p2)
239 pa = p1.ancestor(p2)
239 base, local, other = [
240 base, local, other = [
240 x[fn].data() for x in (pa, p1, p2)
241 x[fn].data() for x in (pa, p1, p2)
241 ]
242 ]
242 m3 = simplemerge.Merge3Text(base, local, other)
243 m3 = simplemerge.Merge3Text(base, local, other)
243 ml = [l.strip() for l in m3.merge_lines()]
244 ml = [l.strip() for l in m3.merge_lines()]
244 ml.append(b"")
245 ml.append(b"")
245 elif at > 0:
246 elif at > 0:
246 ml = p1[fn].data().split(b"\n")
247 ml = p1[fn].data().split(b"\n")
247 else:
248 else:
248 ml = initialmergedlines
249 ml = initialmergedlines
249 ml[id * linesperrev] += b" r%i" % id
250 ml[id * linesperrev] += b" r%i" % id
250 mergedtext = b"\n".join(ml)
251 mergedtext = b"\n".join(ml)
251 files.append(fn)
252 files.append(fn)
252 filecontent[fn] = mergedtext
253 filecontent[fn] = mergedtext
253
254
254 if overwritten_file:
255 if overwritten_file:
255 fn = b"of"
256 fn = b"of"
256 files.append(fn)
257 files.append(fn)
257 filecontent[fn] = b"r%i\n" % id
258 filecontent[fn] = b"r%i\n" % id
258
259
259 if new_file:
260 if new_file:
260 fn = b"nf%i" % id
261 fn = b"nf%i" % id
261 files.append(fn)
262 files.append(fn)
262 filecontent[fn] = b"r%i\n" % id
263 filecontent[fn] = b"r%i\n" % id
263 if len(ps) > 1:
264 if len(ps) > 1:
264 if not p2:
265 if not p2:
265 p2 = repo[ps[1]]
266 p2 = repo[ps[1]]
266 for fn in p2:
267 for fn in p2:
267 if fn.startswith(b"nf"):
268 if fn.startswith(b"nf"):
268 files.append(fn)
269 files.append(fn)
269 filecontent[fn] = p2[fn].data()
270 filecontent[fn] = p2[fn].data()
270
271
271 def fctxfn(repo, cx, path):
272 def fctxfn(repo, cx, path):
272 if path in filecontent:
273 if path in filecontent:
273 return context.memfilectx(
274 return context.memfilectx(
274 repo, cx, path, filecontent[path]
275 repo, cx, path, filecontent[path]
275 )
276 )
276 return None
277 return None
277
278
278 if len(ps) == 0 or ps[0] < 0:
279 if len(ps) == 0 or ps[0] < 0:
279 pars = [None, None]
280 pars = [None, None]
280 elif len(ps) == 1:
281 elif len(ps) == 1:
281 pars = [nodeids[ps[0]], None]
282 pars = [nodeids[ps[0]], None]
282 else:
283 else:
283 pars = [nodeids[p] for p in ps]
284 pars = [nodeids[p] for p in ps]
284 cx = context.memctx(
285 cx = context.memctx(
285 repo,
286 repo,
286 pars,
287 pars,
287 b"r%i" % id,
288 b"r%i" % id,
288 files,
289 files,
289 fctxfn,
290 fctxfn,
290 date=(id, 0),
291 date=(id, 0),
291 user=b"debugbuilddag",
292 user=b"debugbuilddag",
292 extra={b'branch': atbranch},
293 extra={b'branch': atbranch},
293 )
294 )
294 nodeid = repo.commitctx(cx)
295 nodeid = repo.commitctx(cx)
295 nodeids.append(nodeid)
296 nodeids.append(nodeid)
296 at = id
297 at = id
297 elif type == b'l':
298 elif type == b'l':
298 id, name = data
299 id, name = data
299 ui.note((b'tag %s\n' % name))
300 ui.note((b'tag %s\n' % name))
300 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
301 tags.append(b"%s %s\n" % (hex(repo.changelog.node(id)), name))
301 elif type == b'a':
302 elif type == b'a':
302 ui.note((b'branch %s\n' % data))
303 ui.note((b'branch %s\n' % data))
303 atbranch = data
304 atbranch = data
304 progress.update(id)
305 progress.update(id)
305
306
306 if tags:
307 if tags:
307 repo.vfs.write(b"localtags", b"".join(tags))
308 repo.vfs.write(b"localtags", b"".join(tags))
308
309
309
310
310 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
311 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
311 indent_string = b' ' * indent
312 indent_string = b' ' * indent
312 if all:
313 if all:
313 ui.writenoi18n(
314 ui.writenoi18n(
314 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
315 b"%sformat: id, p1, p2, cset, delta base, len(delta)\n"
315 % indent_string
316 % indent_string
316 )
317 )
317
318
318 def showchunks(named):
319 def showchunks(named):
319 ui.write(b"\n%s%s\n" % (indent_string, named))
320 ui.write(b"\n%s%s\n" % (indent_string, named))
320 for deltadata in gen.deltaiter():
321 for deltadata in gen.deltaiter():
321 node, p1, p2, cs, deltabase, delta, flags = deltadata
322 node, p1, p2, cs, deltabase, delta, flags = deltadata
322 ui.write(
323 ui.write(
323 b"%s%s %s %s %s %s %d\n"
324 b"%s%s %s %s %s %s %d\n"
324 % (
325 % (
325 indent_string,
326 indent_string,
326 hex(node),
327 hex(node),
327 hex(p1),
328 hex(p1),
328 hex(p2),
329 hex(p2),
329 hex(cs),
330 hex(cs),
330 hex(deltabase),
331 hex(deltabase),
331 len(delta),
332 len(delta),
332 )
333 )
333 )
334 )
334
335
335 gen.changelogheader()
336 gen.changelogheader()
336 showchunks(b"changelog")
337 showchunks(b"changelog")
337 gen.manifestheader()
338 gen.manifestheader()
338 showchunks(b"manifest")
339 showchunks(b"manifest")
339 for chunkdata in iter(gen.filelogheader, {}):
340 for chunkdata in iter(gen.filelogheader, {}):
340 fname = chunkdata[b'filename']
341 fname = chunkdata[b'filename']
341 showchunks(fname)
342 showchunks(fname)
342 else:
343 else:
343 if isinstance(gen, bundle2.unbundle20):
344 if isinstance(gen, bundle2.unbundle20):
344 raise error.Abort(_(b'use debugbundle2 for this file'))
345 raise error.Abort(_(b'use debugbundle2 for this file'))
345 gen.changelogheader()
346 gen.changelogheader()
346 for deltadata in gen.deltaiter():
347 for deltadata in gen.deltaiter():
347 node, p1, p2, cs, deltabase, delta, flags = deltadata
348 node, p1, p2, cs, deltabase, delta, flags = deltadata
348 ui.write(b"%s%s\n" % (indent_string, hex(node)))
349 ui.write(b"%s%s\n" % (indent_string, hex(node)))
349
350
350
351
351 def _debugobsmarkers(ui, part, indent=0, **opts):
352 def _debugobsmarkers(ui, part, indent=0, **opts):
352 """display version and markers contained in 'data'"""
353 """display version and markers contained in 'data'"""
353 opts = pycompat.byteskwargs(opts)
354 opts = pycompat.byteskwargs(opts)
354 data = part.read()
355 data = part.read()
355 indent_string = b' ' * indent
356 indent_string = b' ' * indent
356 try:
357 try:
357 version, markers = obsolete._readmarkers(data)
358 version, markers = obsolete._readmarkers(data)
358 except error.UnknownVersion as exc:
359 except error.UnknownVersion as exc:
359 msg = b"%sunsupported version: %s (%d bytes)\n"
360 msg = b"%sunsupported version: %s (%d bytes)\n"
360 msg %= indent_string, exc.version, len(data)
361 msg %= indent_string, exc.version, len(data)
361 ui.write(msg)
362 ui.write(msg)
362 else:
363 else:
363 msg = b"%sversion: %d (%d bytes)\n"
364 msg = b"%sversion: %d (%d bytes)\n"
364 msg %= indent_string, version, len(data)
365 msg %= indent_string, version, len(data)
365 ui.write(msg)
366 ui.write(msg)
366 fm = ui.formatter(b'debugobsolete', opts)
367 fm = ui.formatter(b'debugobsolete', opts)
367 for rawmarker in sorted(markers):
368 for rawmarker in sorted(markers):
368 m = obsutil.marker(None, rawmarker)
369 m = obsutil.marker(None, rawmarker)
369 fm.startitem()
370 fm.startitem()
370 fm.plain(indent_string)
371 fm.plain(indent_string)
371 cmdutil.showmarker(fm, m)
372 cmdutil.showmarker(fm, m)
372 fm.end()
373 fm.end()
373
374
374
375
375 def _debugphaseheads(ui, data, indent=0):
376 def _debugphaseheads(ui, data, indent=0):
376 """display version and markers contained in 'data'"""
377 """display version and markers contained in 'data'"""
377 indent_string = b' ' * indent
378 indent_string = b' ' * indent
378 headsbyphase = phases.binarydecode(data)
379 headsbyphase = phases.binarydecode(data)
379 for phase in phases.allphases:
380 for phase in phases.allphases:
380 for head in headsbyphase[phase]:
381 for head in headsbyphase[phase]:
381 ui.write(indent_string)
382 ui.write(indent_string)
382 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
383 ui.write(b'%s %s\n' % (hex(head), phases.phasenames[phase]))
383
384
384
385
385 def _quasirepr(thing):
386 def _quasirepr(thing):
386 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
387 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
387 return b'{%s}' % (
388 return b'{%s}' % (
388 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
389 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))
389 )
390 )
390 return pycompat.bytestr(repr(thing))
391 return pycompat.bytestr(repr(thing))
391
392
392
393
393 def _debugbundle2(ui, gen, all=None, **opts):
394 def _debugbundle2(ui, gen, all=None, **opts):
394 """lists the contents of a bundle2"""
395 """lists the contents of a bundle2"""
395 if not isinstance(gen, bundle2.unbundle20):
396 if not isinstance(gen, bundle2.unbundle20):
396 raise error.Abort(_(b'not a bundle2 file'))
397 raise error.Abort(_(b'not a bundle2 file'))
397 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
398 ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
398 parttypes = opts.get('part_type', [])
399 parttypes = opts.get('part_type', [])
399 for part in gen.iterparts():
400 for part in gen.iterparts():
400 if parttypes and part.type not in parttypes:
401 if parttypes and part.type not in parttypes:
401 continue
402 continue
402 msg = b'%s -- %s (mandatory: %r)\n'
403 msg = b'%s -- %s (mandatory: %r)\n'
403 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
404 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
404 if part.type == b'changegroup':
405 if part.type == b'changegroup':
405 version = part.params.get(b'version', b'01')
406 version = part.params.get(b'version', b'01')
406 cg = changegroup.getunbundler(version, part, b'UN')
407 cg = changegroup.getunbundler(version, part, b'UN')
407 if not ui.quiet:
408 if not ui.quiet:
408 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
409 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
409 if part.type == b'obsmarkers':
410 if part.type == b'obsmarkers':
410 if not ui.quiet:
411 if not ui.quiet:
411 _debugobsmarkers(ui, part, indent=4, **opts)
412 _debugobsmarkers(ui, part, indent=4, **opts)
412 if part.type == b'phase-heads':
413 if part.type == b'phase-heads':
413 if not ui.quiet:
414 if not ui.quiet:
414 _debugphaseheads(ui, part, indent=4)
415 _debugphaseheads(ui, part, indent=4)
415
416
416
417
417 @command(
418 @command(
418 b'debugbundle',
419 b'debugbundle',
419 [
420 [
420 (b'a', b'all', None, _(b'show all details')),
421 (b'a', b'all', None, _(b'show all details')),
421 (b'', b'part-type', [], _(b'show only the named part type')),
422 (b'', b'part-type', [], _(b'show only the named part type')),
422 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
423 (b'', b'spec', None, _(b'print the bundlespec of the bundle')),
423 ],
424 ],
424 _(b'FILE'),
425 _(b'FILE'),
425 norepo=True,
426 norepo=True,
426 )
427 )
427 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
428 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
428 """lists the contents of a bundle"""
429 """lists the contents of a bundle"""
429 with hg.openpath(ui, bundlepath) as f:
430 with hg.openpath(ui, bundlepath) as f:
430 if spec:
431 if spec:
431 spec = exchange.getbundlespec(ui, f)
432 spec = exchange.getbundlespec(ui, f)
432 ui.write(b'%s\n' % spec)
433 ui.write(b'%s\n' % spec)
433 return
434 return
434
435
435 gen = exchange.readbundle(ui, f, bundlepath)
436 gen = exchange.readbundle(ui, f, bundlepath)
436 if isinstance(gen, bundle2.unbundle20):
437 if isinstance(gen, bundle2.unbundle20):
437 return _debugbundle2(ui, gen, all=all, **opts)
438 return _debugbundle2(ui, gen, all=all, **opts)
438 _debugchangegroup(ui, gen, all=all, **opts)
439 _debugchangegroup(ui, gen, all=all, **opts)
439
440
440
441
441 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
442 @command(b'debugcapabilities', [], _(b'PATH'), norepo=True)
442 def debugcapabilities(ui, path, **opts):
443 def debugcapabilities(ui, path, **opts):
443 """lists the capabilities of a remote peer"""
444 """lists the capabilities of a remote peer"""
444 opts = pycompat.byteskwargs(opts)
445 opts = pycompat.byteskwargs(opts)
445 peer = hg.peer(ui, opts, path)
446 peer = hg.peer(ui, opts, path)
446 caps = peer.capabilities()
447 caps = peer.capabilities()
447 ui.writenoi18n(b'Main capabilities:\n')
448 ui.writenoi18n(b'Main capabilities:\n')
448 for c in sorted(caps):
449 for c in sorted(caps):
449 ui.write(b' %s\n' % c)
450 ui.write(b' %s\n' % c)
450 b2caps = bundle2.bundle2caps(peer)
451 b2caps = bundle2.bundle2caps(peer)
451 if b2caps:
452 if b2caps:
452 ui.writenoi18n(b'Bundle2 capabilities:\n')
453 ui.writenoi18n(b'Bundle2 capabilities:\n')
453 for key, values in sorted(pycompat.iteritems(b2caps)):
454 for key, values in sorted(pycompat.iteritems(b2caps)):
454 ui.write(b' %s\n' % key)
455 ui.write(b' %s\n' % key)
455 for v in values:
456 for v in values:
456 ui.write(b' %s\n' % v)
457 ui.write(b' %s\n' % v)
457
458
458
459
459 @command(b'debugcheckstate', [], b'')
460 @command(b'debugcheckstate', [], b'')
460 def debugcheckstate(ui, repo):
461 def debugcheckstate(ui, repo):
461 """validate the correctness of the current dirstate"""
462 """validate the correctness of the current dirstate"""
462 parent1, parent2 = repo.dirstate.parents()
463 parent1, parent2 = repo.dirstate.parents()
463 m1 = repo[parent1].manifest()
464 m1 = repo[parent1].manifest()
464 m2 = repo[parent2].manifest()
465 m2 = repo[parent2].manifest()
465 errors = 0
466 errors = 0
466 for f in repo.dirstate:
467 for f in repo.dirstate:
467 state = repo.dirstate[f]
468 state = repo.dirstate[f]
468 if state in b"nr" and f not in m1:
469 if state in b"nr" and f not in m1:
469 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
470 ui.warn(_(b"%s in state %s, but not in manifest1\n") % (f, state))
470 errors += 1
471 errors += 1
471 if state in b"a" and f in m1:
472 if state in b"a" and f in m1:
472 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
473 ui.warn(_(b"%s in state %s, but also in manifest1\n") % (f, state))
473 errors += 1
474 errors += 1
474 if state in b"m" and f not in m1 and f not in m2:
475 if state in b"m" and f not in m1 and f not in m2:
475 ui.warn(
476 ui.warn(
476 _(b"%s in state %s, but not in either manifest\n") % (f, state)
477 _(b"%s in state %s, but not in either manifest\n") % (f, state)
477 )
478 )
478 errors += 1
479 errors += 1
479 for f in m1:
480 for f in m1:
480 state = repo.dirstate[f]
481 state = repo.dirstate[f]
481 if state not in b"nrm":
482 if state not in b"nrm":
482 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
483 ui.warn(_(b"%s in manifest1, but listed as state %s") % (f, state))
483 errors += 1
484 errors += 1
484 if errors:
485 if errors:
485 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
486 errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
486 raise error.Abort(errstr)
487 raise error.Abort(errstr)
487
488
488
489
489 @command(
490 @command(
490 b'debugcolor',
491 b'debugcolor',
491 [(b'', b'style', None, _(b'show all configured styles'))],
492 [(b'', b'style', None, _(b'show all configured styles'))],
492 b'hg debugcolor',
493 b'hg debugcolor',
493 )
494 )
494 def debugcolor(ui, repo, **opts):
495 def debugcolor(ui, repo, **opts):
495 """show available color, effects or style"""
496 """show available color, effects or style"""
496 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
497 ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
497 if opts.get('style'):
498 if opts.get('style'):
498 return _debugdisplaystyle(ui)
499 return _debugdisplaystyle(ui)
499 else:
500 else:
500 return _debugdisplaycolor(ui)
501 return _debugdisplaycolor(ui)
501
502
502
503
503 def _debugdisplaycolor(ui):
504 def _debugdisplaycolor(ui):
504 ui = ui.copy()
505 ui = ui.copy()
505 ui._styles.clear()
506 ui._styles.clear()
506 for effect in color._activeeffects(ui).keys():
507 for effect in color._activeeffects(ui).keys():
507 ui._styles[effect] = effect
508 ui._styles[effect] = effect
508 if ui._terminfoparams:
509 if ui._terminfoparams:
509 for k, v in ui.configitems(b'color'):
510 for k, v in ui.configitems(b'color'):
510 if k.startswith(b'color.'):
511 if k.startswith(b'color.'):
511 ui._styles[k] = k[6:]
512 ui._styles[k] = k[6:]
512 elif k.startswith(b'terminfo.'):
513 elif k.startswith(b'terminfo.'):
513 ui._styles[k] = k[9:]
514 ui._styles[k] = k[9:]
514 ui.write(_(b'available colors:\n'))
515 ui.write(_(b'available colors:\n'))
515 # sort label with a '_' after the other to group '_background' entry.
516 # sort label with a '_' after the other to group '_background' entry.
516 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
517 items = sorted(ui._styles.items(), key=lambda i: (b'_' in i[0], i[0], i[1]))
517 for colorname, label in items:
518 for colorname, label in items:
518 ui.write(b'%s\n' % colorname, label=label)
519 ui.write(b'%s\n' % colorname, label=label)
519
520
520
521
521 def _debugdisplaystyle(ui):
522 def _debugdisplaystyle(ui):
522 ui.write(_(b'available style:\n'))
523 ui.write(_(b'available style:\n'))
523 if not ui._styles:
524 if not ui._styles:
524 return
525 return
525 width = max(len(s) for s in ui._styles)
526 width = max(len(s) for s in ui._styles)
526 for label, effects in sorted(ui._styles.items()):
527 for label, effects in sorted(ui._styles.items()):
527 ui.write(b'%s' % label, label=label)
528 ui.write(b'%s' % label, label=label)
528 if effects:
529 if effects:
529 # 50
530 # 50
530 ui.write(b': ')
531 ui.write(b': ')
531 ui.write(b' ' * (max(0, width - len(label))))
532 ui.write(b' ' * (max(0, width - len(label))))
532 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
533 ui.write(b', '.join(ui.label(e, e) for e in effects.split()))
533 ui.write(b'\n')
534 ui.write(b'\n')
534
535
535
536
536 @command(b'debugcreatestreamclonebundle', [], b'FILE')
537 @command(b'debugcreatestreamclonebundle', [], b'FILE')
537 def debugcreatestreamclonebundle(ui, repo, fname):
538 def debugcreatestreamclonebundle(ui, repo, fname):
538 """create a stream clone bundle file
539 """create a stream clone bundle file
539
540
540 Stream bundles are special bundles that are essentially archives of
541 Stream bundles are special bundles that are essentially archives of
541 revlog files. They are commonly used for cloning very quickly.
542 revlog files. They are commonly used for cloning very quickly.
542 """
543 """
543 # TODO we may want to turn this into an abort when this functionality
544 # TODO we may want to turn this into an abort when this functionality
544 # is moved into `hg bundle`.
545 # is moved into `hg bundle`.
545 if phases.hassecret(repo):
546 if phases.hassecret(repo):
546 ui.warn(
547 ui.warn(
547 _(
548 _(
548 b'(warning: stream clone bundle will contain secret '
549 b'(warning: stream clone bundle will contain secret '
549 b'revisions)\n'
550 b'revisions)\n'
550 )
551 )
551 )
552 )
552
553
553 requirements, gen = streamclone.generatebundlev1(repo)
554 requirements, gen = streamclone.generatebundlev1(repo)
554 changegroup.writechunks(ui, gen, fname)
555 changegroup.writechunks(ui, gen, fname)
555
556
556 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
557 ui.write(_(b'bundle requirements: %s\n') % b', '.join(sorted(requirements)))
557
558
558
559
559 @command(
560 @command(
560 b'debugdag',
561 b'debugdag',
561 [
562 [
562 (b't', b'tags', None, _(b'use tags as labels')),
563 (b't', b'tags', None, _(b'use tags as labels')),
563 (b'b', b'branches', None, _(b'annotate with branch names')),
564 (b'b', b'branches', None, _(b'annotate with branch names')),
564 (b'', b'dots', None, _(b'use dots for runs')),
565 (b'', b'dots', None, _(b'use dots for runs')),
565 (b's', b'spaces', None, _(b'separate elements by spaces')),
566 (b's', b'spaces', None, _(b'separate elements by spaces')),
566 ],
567 ],
567 _(b'[OPTION]... [FILE [REV]...]'),
568 _(b'[OPTION]... [FILE [REV]...]'),
568 optionalrepo=True,
569 optionalrepo=True,
569 )
570 )
570 def debugdag(ui, repo, file_=None, *revs, **opts):
571 def debugdag(ui, repo, file_=None, *revs, **opts):
571 """format the changelog or an index DAG as a concise textual description
572 """format the changelog or an index DAG as a concise textual description
572
573
573 If you pass a revlog index, the revlog's DAG is emitted. If you list
574 If you pass a revlog index, the revlog's DAG is emitted. If you list
574 revision numbers, they get labeled in the output as rN.
575 revision numbers, they get labeled in the output as rN.
575
576
576 Otherwise, the changelog DAG of the current repo is emitted.
577 Otherwise, the changelog DAG of the current repo is emitted.
577 """
578 """
578 spaces = opts.get('spaces')
579 spaces = opts.get('spaces')
579 dots = opts.get('dots')
580 dots = opts.get('dots')
580 if file_:
581 if file_:
581 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
582 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
582 revs = set((int(r) for r in revs))
583 revs = set((int(r) for r in revs))
583
584
584 def events():
585 def events():
585 for r in rlog:
586 for r in rlog:
586 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
587 yield b'n', (r, list(p for p in rlog.parentrevs(r) if p != -1))
587 if r in revs:
588 if r in revs:
588 yield b'l', (r, b"r%i" % r)
589 yield b'l', (r, b"r%i" % r)
589
590
590 elif repo:
591 elif repo:
591 cl = repo.changelog
592 cl = repo.changelog
592 tags = opts.get('tags')
593 tags = opts.get('tags')
593 branches = opts.get('branches')
594 branches = opts.get('branches')
594 if tags:
595 if tags:
595 labels = {}
596 labels = {}
596 for l, n in repo.tags().items():
597 for l, n in repo.tags().items():
597 labels.setdefault(cl.rev(n), []).append(l)
598 labels.setdefault(cl.rev(n), []).append(l)
598
599
599 def events():
600 def events():
600 b = b"default"
601 b = b"default"
601 for r in cl:
602 for r in cl:
602 if branches:
603 if branches:
603 newb = cl.read(cl.node(r))[5][b'branch']
604 newb = cl.read(cl.node(r))[5][b'branch']
604 if newb != b:
605 if newb != b:
605 yield b'a', newb
606 yield b'a', newb
606 b = newb
607 b = newb
607 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
608 yield b'n', (r, list(p for p in cl.parentrevs(r) if p != -1))
608 if tags:
609 if tags:
609 ls = labels.get(r)
610 ls = labels.get(r)
610 if ls:
611 if ls:
611 for l in ls:
612 for l in ls:
612 yield b'l', (r, l)
613 yield b'l', (r, l)
613
614
614 else:
615 else:
615 raise error.Abort(_(b'need repo for changelog dag'))
616 raise error.Abort(_(b'need repo for changelog dag'))
616
617
617 for line in dagparser.dagtextlines(
618 for line in dagparser.dagtextlines(
618 events(),
619 events(),
619 addspaces=spaces,
620 addspaces=spaces,
620 wraplabels=True,
621 wraplabels=True,
621 wrapannotations=True,
622 wrapannotations=True,
622 wrapnonlinear=dots,
623 wrapnonlinear=dots,
623 usedots=dots,
624 usedots=dots,
624 maxlinewidth=70,
625 maxlinewidth=70,
625 ):
626 ):
626 ui.write(line)
627 ui.write(line)
627 ui.write(b"\n")
628 ui.write(b"\n")
628
629
629
630
630 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
631 @command(b'debugdata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
631 def debugdata(ui, repo, file_, rev=None, **opts):
632 def debugdata(ui, repo, file_, rev=None, **opts):
632 """dump the contents of a data file revision"""
633 """dump the contents of a data file revision"""
633 opts = pycompat.byteskwargs(opts)
634 opts = pycompat.byteskwargs(opts)
634 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
635 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
635 if rev is not None:
636 if rev is not None:
636 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
637 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
637 file_, rev = None, file_
638 file_, rev = None, file_
638 elif rev is None:
639 elif rev is None:
639 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
640 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
640 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
641 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
641 try:
642 try:
642 ui.write(r.rawdata(r.lookup(rev)))
643 ui.write(r.rawdata(r.lookup(rev)))
643 except KeyError:
644 except KeyError:
644 raise error.Abort(_(b'invalid revision identifier %s') % rev)
645 raise error.Abort(_(b'invalid revision identifier %s') % rev)
645
646
646
647
647 @command(
648 @command(
648 b'debugdate',
649 b'debugdate',
649 [(b'e', b'extended', None, _(b'try extended date formats'))],
650 [(b'e', b'extended', None, _(b'try extended date formats'))],
650 _(b'[-e] DATE [RANGE]'),
651 _(b'[-e] DATE [RANGE]'),
651 norepo=True,
652 norepo=True,
652 optionalrepo=True,
653 optionalrepo=True,
653 )
654 )
654 def debugdate(ui, date, range=None, **opts):
655 def debugdate(ui, date, range=None, **opts):
655 """parse and display a date"""
656 """parse and display a date"""
656 if opts["extended"]:
657 if opts["extended"]:
657 d = dateutil.parsedate(date, dateutil.extendeddateformats)
658 d = dateutil.parsedate(date, dateutil.extendeddateformats)
658 else:
659 else:
659 d = dateutil.parsedate(date)
660 d = dateutil.parsedate(date)
660 ui.writenoi18n(b"internal: %d %d\n" % d)
661 ui.writenoi18n(b"internal: %d %d\n" % d)
661 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
662 ui.writenoi18n(b"standard: %s\n" % dateutil.datestr(d))
662 if range:
663 if range:
663 m = dateutil.matchdate(range)
664 m = dateutil.matchdate(range)
664 ui.writenoi18n(b"match: %s\n" % m(d[0]))
665 ui.writenoi18n(b"match: %s\n" % m(d[0]))
665
666
666
667
667 @command(
668 @command(
668 b'debugdeltachain',
669 b'debugdeltachain',
669 cmdutil.debugrevlogopts + cmdutil.formatteropts,
670 cmdutil.debugrevlogopts + cmdutil.formatteropts,
670 _(b'-c|-m|FILE'),
671 _(b'-c|-m|FILE'),
671 optionalrepo=True,
672 optionalrepo=True,
672 )
673 )
673 def debugdeltachain(ui, repo, file_=None, **opts):
674 def debugdeltachain(ui, repo, file_=None, **opts):
674 """dump information about delta chains in a revlog
675 """dump information about delta chains in a revlog
675
676
676 Output can be templatized. Available template keywords are:
677 Output can be templatized. Available template keywords are:
677
678
678 :``rev``: revision number
679 :``rev``: revision number
679 :``chainid``: delta chain identifier (numbered by unique base)
680 :``chainid``: delta chain identifier (numbered by unique base)
680 :``chainlen``: delta chain length to this revision
681 :``chainlen``: delta chain length to this revision
681 :``prevrev``: previous revision in delta chain
682 :``prevrev``: previous revision in delta chain
682 :``deltatype``: role of delta / how it was computed
683 :``deltatype``: role of delta / how it was computed
683 :``compsize``: compressed size of revision
684 :``compsize``: compressed size of revision
684 :``uncompsize``: uncompressed size of revision
685 :``uncompsize``: uncompressed size of revision
685 :``chainsize``: total size of compressed revisions in chain
686 :``chainsize``: total size of compressed revisions in chain
686 :``chainratio``: total chain size divided by uncompressed revision size
687 :``chainratio``: total chain size divided by uncompressed revision size
687 (new delta chains typically start at ratio 2.00)
688 (new delta chains typically start at ratio 2.00)
688 :``lindist``: linear distance from base revision in delta chain to end
689 :``lindist``: linear distance from base revision in delta chain to end
689 of this revision
690 of this revision
690 :``extradist``: total size of revisions not part of this delta chain from
691 :``extradist``: total size of revisions not part of this delta chain from
691 base of delta chain to end of this revision; a measurement
692 base of delta chain to end of this revision; a measurement
692 of how much extra data we need to read/seek across to read
693 of how much extra data we need to read/seek across to read
693 the delta chain for this revision
694 the delta chain for this revision
694 :``extraratio``: extradist divided by chainsize; another representation of
695 :``extraratio``: extradist divided by chainsize; another representation of
695 how much unrelated data is needed to load this delta chain
696 how much unrelated data is needed to load this delta chain
696
697
697 If the repository is configured to use the sparse read, additional keywords
698 If the repository is configured to use the sparse read, additional keywords
698 are available:
699 are available:
699
700
700 :``readsize``: total size of data read from the disk for a revision
701 :``readsize``: total size of data read from the disk for a revision
701 (sum of the sizes of all the blocks)
702 (sum of the sizes of all the blocks)
702 :``largestblock``: size of the largest block of data read from the disk
703 :``largestblock``: size of the largest block of data read from the disk
703 :``readdensity``: density of useful bytes in the data read from the disk
704 :``readdensity``: density of useful bytes in the data read from the disk
704 :``srchunks``: in how many data hunks the whole revision would be read
705 :``srchunks``: in how many data hunks the whole revision would be read
705
706
706 The sparse read can be enabled with experimental.sparse-read = True
707 The sparse read can be enabled with experimental.sparse-read = True
707 """
708 """
708 opts = pycompat.byteskwargs(opts)
709 opts = pycompat.byteskwargs(opts)
709 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
710 r = cmdutil.openrevlog(repo, b'debugdeltachain', file_, opts)
710 index = r.index
711 index = r.index
711 start = r.start
712 start = r.start
712 length = r.length
713 length = r.length
713 generaldelta = r.version & revlog.FLAG_GENERALDELTA
714 generaldelta = r.version & revlog.FLAG_GENERALDELTA
714 withsparseread = getattr(r, '_withsparseread', False)
715 withsparseread = getattr(r, '_withsparseread', False)
715
716
716 def revinfo(rev):
717 def revinfo(rev):
717 e = index[rev]
718 e = index[rev]
718 compsize = e[1]
719 compsize = e[1]
719 uncompsize = e[2]
720 uncompsize = e[2]
720 chainsize = 0
721 chainsize = 0
721
722
722 if generaldelta:
723 if generaldelta:
723 if e[3] == e[5]:
724 if e[3] == e[5]:
724 deltatype = b'p1'
725 deltatype = b'p1'
725 elif e[3] == e[6]:
726 elif e[3] == e[6]:
726 deltatype = b'p2'
727 deltatype = b'p2'
727 elif e[3] == rev - 1:
728 elif e[3] == rev - 1:
728 deltatype = b'prev'
729 deltatype = b'prev'
729 elif e[3] == rev:
730 elif e[3] == rev:
730 deltatype = b'base'
731 deltatype = b'base'
731 else:
732 else:
732 deltatype = b'other'
733 deltatype = b'other'
733 else:
734 else:
734 if e[3] == rev:
735 if e[3] == rev:
735 deltatype = b'base'
736 deltatype = b'base'
736 else:
737 else:
737 deltatype = b'prev'
738 deltatype = b'prev'
738
739
739 chain = r._deltachain(rev)[0]
740 chain = r._deltachain(rev)[0]
740 for iterrev in chain:
741 for iterrev in chain:
741 e = index[iterrev]
742 e = index[iterrev]
742 chainsize += e[1]
743 chainsize += e[1]
743
744
744 return compsize, uncompsize, deltatype, chain, chainsize
745 return compsize, uncompsize, deltatype, chain, chainsize
745
746
746 fm = ui.formatter(b'debugdeltachain', opts)
747 fm = ui.formatter(b'debugdeltachain', opts)
747
748
748 fm.plain(
749 fm.plain(
749 b' rev chain# chainlen prev delta '
750 b' rev chain# chainlen prev delta '
750 b'size rawsize chainsize ratio lindist extradist '
751 b'size rawsize chainsize ratio lindist extradist '
751 b'extraratio'
752 b'extraratio'
752 )
753 )
753 if withsparseread:
754 if withsparseread:
754 fm.plain(b' readsize largestblk rddensity srchunks')
755 fm.plain(b' readsize largestblk rddensity srchunks')
755 fm.plain(b'\n')
756 fm.plain(b'\n')
756
757
757 chainbases = {}
758 chainbases = {}
758 for rev in r:
759 for rev in r:
759 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
760 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
760 chainbase = chain[0]
761 chainbase = chain[0]
761 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
762 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
762 basestart = start(chainbase)
763 basestart = start(chainbase)
763 revstart = start(rev)
764 revstart = start(rev)
764 lineardist = revstart + comp - basestart
765 lineardist = revstart + comp - basestart
765 extradist = lineardist - chainsize
766 extradist = lineardist - chainsize
766 try:
767 try:
767 prevrev = chain[-2]
768 prevrev = chain[-2]
768 except IndexError:
769 except IndexError:
769 prevrev = -1
770 prevrev = -1
770
771
771 if uncomp != 0:
772 if uncomp != 0:
772 chainratio = float(chainsize) / float(uncomp)
773 chainratio = float(chainsize) / float(uncomp)
773 else:
774 else:
774 chainratio = chainsize
775 chainratio = chainsize
775
776
776 if chainsize != 0:
777 if chainsize != 0:
777 extraratio = float(extradist) / float(chainsize)
778 extraratio = float(extradist) / float(chainsize)
778 else:
779 else:
779 extraratio = extradist
780 extraratio = extradist
780
781
781 fm.startitem()
782 fm.startitem()
782 fm.write(
783 fm.write(
783 b'rev chainid chainlen prevrev deltatype compsize '
784 b'rev chainid chainlen prevrev deltatype compsize '
784 b'uncompsize chainsize chainratio lindist extradist '
785 b'uncompsize chainsize chainratio lindist extradist '
785 b'extraratio',
786 b'extraratio',
786 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
787 b'%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
787 rev,
788 rev,
788 chainid,
789 chainid,
789 len(chain),
790 len(chain),
790 prevrev,
791 prevrev,
791 deltatype,
792 deltatype,
792 comp,
793 comp,
793 uncomp,
794 uncomp,
794 chainsize,
795 chainsize,
795 chainratio,
796 chainratio,
796 lineardist,
797 lineardist,
797 extradist,
798 extradist,
798 extraratio,
799 extraratio,
799 rev=rev,
800 rev=rev,
800 chainid=chainid,
801 chainid=chainid,
801 chainlen=len(chain),
802 chainlen=len(chain),
802 prevrev=prevrev,
803 prevrev=prevrev,
803 deltatype=deltatype,
804 deltatype=deltatype,
804 compsize=comp,
805 compsize=comp,
805 uncompsize=uncomp,
806 uncompsize=uncomp,
806 chainsize=chainsize,
807 chainsize=chainsize,
807 chainratio=chainratio,
808 chainratio=chainratio,
808 lindist=lineardist,
809 lindist=lineardist,
809 extradist=extradist,
810 extradist=extradist,
810 extraratio=extraratio,
811 extraratio=extraratio,
811 )
812 )
812 if withsparseread:
813 if withsparseread:
813 readsize = 0
814 readsize = 0
814 largestblock = 0
815 largestblock = 0
815 srchunks = 0
816 srchunks = 0
816
817
817 for revschunk in deltautil.slicechunk(r, chain):
818 for revschunk in deltautil.slicechunk(r, chain):
818 srchunks += 1
819 srchunks += 1
819 blkend = start(revschunk[-1]) + length(revschunk[-1])
820 blkend = start(revschunk[-1]) + length(revschunk[-1])
820 blksize = blkend - start(revschunk[0])
821 blksize = blkend - start(revschunk[0])
821
822
822 readsize += blksize
823 readsize += blksize
823 if largestblock < blksize:
824 if largestblock < blksize:
824 largestblock = blksize
825 largestblock = blksize
825
826
826 if readsize:
827 if readsize:
827 readdensity = float(chainsize) / float(readsize)
828 readdensity = float(chainsize) / float(readsize)
828 else:
829 else:
829 readdensity = 1
830 readdensity = 1
830
831
831 fm.write(
832 fm.write(
832 b'readsize largestblock readdensity srchunks',
833 b'readsize largestblock readdensity srchunks',
833 b' %10d %10d %9.5f %8d',
834 b' %10d %10d %9.5f %8d',
834 readsize,
835 readsize,
835 largestblock,
836 largestblock,
836 readdensity,
837 readdensity,
837 srchunks,
838 srchunks,
838 readsize=readsize,
839 readsize=readsize,
839 largestblock=largestblock,
840 largestblock=largestblock,
840 readdensity=readdensity,
841 readdensity=readdensity,
841 srchunks=srchunks,
842 srchunks=srchunks,
842 )
843 )
843
844
844 fm.plain(b'\n')
845 fm.plain(b'\n')
845
846
846 fm.end()
847 fm.end()
847
848
848
849
849 @command(
850 @command(
850 b'debugdirstate|debugstate',
851 b'debugdirstate|debugstate',
851 [
852 [
852 (
853 (
853 b'',
854 b'',
854 b'nodates',
855 b'nodates',
855 None,
856 None,
856 _(b'do not display the saved mtime (DEPRECATED)'),
857 _(b'do not display the saved mtime (DEPRECATED)'),
857 ),
858 ),
858 (b'', b'dates', True, _(b'display the saved mtime')),
859 (b'', b'dates', True, _(b'display the saved mtime')),
859 (b'', b'datesort', None, _(b'sort by saved mtime')),
860 (b'', b'datesort', None, _(b'sort by saved mtime')),
860 ],
861 ],
861 _(b'[OPTION]...'),
862 _(b'[OPTION]...'),
862 )
863 )
863 def debugstate(ui, repo, **opts):
864 def debugstate(ui, repo, **opts):
864 """show the contents of the current dirstate"""
865 """show the contents of the current dirstate"""
865
866
866 nodates = not opts['dates']
867 nodates = not opts['dates']
867 if opts.get('nodates') is not None:
868 if opts.get('nodates') is not None:
868 nodates = True
869 nodates = True
869 datesort = opts.get('datesort')
870 datesort = opts.get('datesort')
870
871
871 if datesort:
872 if datesort:
872 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
873 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
873 else:
874 else:
874 keyfunc = None # sort by filename
875 keyfunc = None # sort by filename
875 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
876 for file_, ent in sorted(pycompat.iteritems(repo.dirstate), key=keyfunc):
876 if ent[3] == -1:
877 if ent[3] == -1:
877 timestr = b'unset '
878 timestr = b'unset '
878 elif nodates:
879 elif nodates:
879 timestr = b'set '
880 timestr = b'set '
880 else:
881 else:
881 timestr = time.strftime(
882 timestr = time.strftime(
882 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
883 "%Y-%m-%d %H:%M:%S ", time.localtime(ent[3])
883 )
884 )
884 timestr = encoding.strtolocal(timestr)
885 timestr = encoding.strtolocal(timestr)
885 if ent[1] & 0o20000:
886 if ent[1] & 0o20000:
886 mode = b'lnk'
887 mode = b'lnk'
887 else:
888 else:
888 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
889 mode = b'%3o' % (ent[1] & 0o777 & ~util.umask)
889 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
890 ui.write(b"%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
890 for f in repo.dirstate.copies():
891 for f in repo.dirstate.copies():
891 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
892 ui.write(_(b"copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
892
893
893
894
894 @command(
895 @command(
895 b'debugdiscovery',
896 b'debugdiscovery',
896 [
897 [
897 (b'', b'old', None, _(b'use old-style discovery')),
898 (b'', b'old', None, _(b'use old-style discovery')),
898 (
899 (
899 b'',
900 b'',
900 b'nonheads',
901 b'nonheads',
901 None,
902 None,
902 _(b'use old-style discovery with non-heads included'),
903 _(b'use old-style discovery with non-heads included'),
903 ),
904 ),
904 (b'', b'rev', [], b'restrict discovery to this set of revs'),
905 (b'', b'rev', [], b'restrict discovery to this set of revs'),
905 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
906 (b'', b'seed', b'12323', b'specify the random seed use for discovery'),
906 ]
907 ]
907 + cmdutil.remoteopts,
908 + cmdutil.remoteopts,
908 _(b'[--rev REV] [OTHER]'),
909 _(b'[--rev REV] [OTHER]'),
909 )
910 )
910 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
911 def debugdiscovery(ui, repo, remoteurl=b"default", **opts):
911 """runs the changeset discovery protocol in isolation"""
912 """runs the changeset discovery protocol in isolation"""
912 opts = pycompat.byteskwargs(opts)
913 opts = pycompat.byteskwargs(opts)
913 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
914 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
914 remote = hg.peer(repo, opts, remoteurl)
915 remote = hg.peer(repo, opts, remoteurl)
915 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
916 ui.status(_(b'comparing with %s\n') % util.hidepassword(remoteurl))
916
917
917 # make sure tests are repeatable
918 # make sure tests are repeatable
918 random.seed(int(opts[b'seed']))
919 random.seed(int(opts[b'seed']))
919
920
920 if opts.get(b'old'):
921 if opts.get(b'old'):
921
922
922 def doit(pushedrevs, remoteheads, remote=remote):
923 def doit(pushedrevs, remoteheads, remote=remote):
923 if not util.safehasattr(remote, b'branches'):
924 if not util.safehasattr(remote, b'branches'):
924 # enable in-client legacy support
925 # enable in-client legacy support
925 remote = localrepo.locallegacypeer(remote.local())
926 remote = localrepo.locallegacypeer(remote.local())
926 common, _in, hds = treediscovery.findcommonincoming(
927 common, _in, hds = treediscovery.findcommonincoming(
927 repo, remote, force=True
928 repo, remote, force=True
928 )
929 )
929 common = set(common)
930 common = set(common)
930 if not opts.get(b'nonheads'):
931 if not opts.get(b'nonheads'):
931 ui.writenoi18n(
932 ui.writenoi18n(
932 b"unpruned common: %s\n"
933 b"unpruned common: %s\n"
933 % b" ".join(sorted(short(n) for n in common))
934 % b" ".join(sorted(short(n) for n in common))
934 )
935 )
935
936
936 clnode = repo.changelog.node
937 clnode = repo.changelog.node
937 common = repo.revs(b'heads(::%ln)', common)
938 common = repo.revs(b'heads(::%ln)', common)
938 common = {clnode(r) for r in common}
939 common = {clnode(r) for r in common}
939 return common, hds
940 return common, hds
940
941
941 else:
942 else:
942
943
943 def doit(pushedrevs, remoteheads, remote=remote):
944 def doit(pushedrevs, remoteheads, remote=remote):
944 nodes = None
945 nodes = None
945 if pushedrevs:
946 if pushedrevs:
946 revs = scmutil.revrange(repo, pushedrevs)
947 revs = scmutil.revrange(repo, pushedrevs)
947 nodes = [repo[r].node() for r in revs]
948 nodes = [repo[r].node() for r in revs]
948 common, any, hds = setdiscovery.findcommonheads(
949 common, any, hds = setdiscovery.findcommonheads(
949 ui, repo, remote, ancestorsof=nodes
950 ui, repo, remote, ancestorsof=nodes
950 )
951 )
951 return common, hds
952 return common, hds
952
953
953 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
954 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
954 localrevs = opts[b'rev']
955 localrevs = opts[b'rev']
955 with util.timedcm('debug-discovery') as t:
956 with util.timedcm('debug-discovery') as t:
956 common, hds = doit(localrevs, remoterevs)
957 common, hds = doit(localrevs, remoterevs)
957
958
958 # compute all statistics
959 # compute all statistics
959 common = set(common)
960 common = set(common)
960 rheads = set(hds)
961 rheads = set(hds)
961 lheads = set(repo.heads())
962 lheads = set(repo.heads())
962
963
963 data = {}
964 data = {}
964 data[b'elapsed'] = t.elapsed
965 data[b'elapsed'] = t.elapsed
965 data[b'nb-common'] = len(common)
966 data[b'nb-common'] = len(common)
966 data[b'nb-common-local'] = len(common & lheads)
967 data[b'nb-common-local'] = len(common & lheads)
967 data[b'nb-common-remote'] = len(common & rheads)
968 data[b'nb-common-remote'] = len(common & rheads)
968 data[b'nb-common-both'] = len(common & rheads & lheads)
969 data[b'nb-common-both'] = len(common & rheads & lheads)
969 data[b'nb-local'] = len(lheads)
970 data[b'nb-local'] = len(lheads)
970 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
971 data[b'nb-local-missing'] = data[b'nb-local'] - data[b'nb-common-local']
971 data[b'nb-remote'] = len(rheads)
972 data[b'nb-remote'] = len(rheads)
972 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
973 data[b'nb-remote-unknown'] = data[b'nb-remote'] - data[b'nb-common-remote']
973 data[b'nb-revs'] = len(repo.revs(b'all()'))
974 data[b'nb-revs'] = len(repo.revs(b'all()'))
974 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
975 data[b'nb-revs-common'] = len(repo.revs(b'::%ln', common))
975 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
976 data[b'nb-revs-missing'] = data[b'nb-revs'] - data[b'nb-revs-common']
976
977
977 # display discovery summary
978 # display discovery summary
978 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
979 ui.writenoi18n(b"elapsed time: %(elapsed)f seconds\n" % data)
979 ui.writenoi18n(b"heads summary:\n")
980 ui.writenoi18n(b"heads summary:\n")
980 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
981 ui.writenoi18n(b" total common heads: %(nb-common)9d\n" % data)
981 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
982 ui.writenoi18n(b" also local heads: %(nb-common-local)9d\n" % data)
982 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
983 ui.writenoi18n(b" also remote heads: %(nb-common-remote)9d\n" % data)
983 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
984 ui.writenoi18n(b" both: %(nb-common-both)9d\n" % data)
984 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
985 ui.writenoi18n(b" local heads: %(nb-local)9d\n" % data)
985 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
986 ui.writenoi18n(b" common: %(nb-common-local)9d\n" % data)
986 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
987 ui.writenoi18n(b" missing: %(nb-local-missing)9d\n" % data)
987 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
988 ui.writenoi18n(b" remote heads: %(nb-remote)9d\n" % data)
988 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
989 ui.writenoi18n(b" common: %(nb-common-remote)9d\n" % data)
989 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
990 ui.writenoi18n(b" unknown: %(nb-remote-unknown)9d\n" % data)
990 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
991 ui.writenoi18n(b"local changesets: %(nb-revs)9d\n" % data)
991 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
992 ui.writenoi18n(b" common: %(nb-revs-common)9d\n" % data)
992 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
993 ui.writenoi18n(b" missing: %(nb-revs-missing)9d\n" % data)
993
994
994 if ui.verbose:
995 if ui.verbose:
995 ui.writenoi18n(
996 ui.writenoi18n(
996 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
997 b"common heads: %s\n" % b" ".join(sorted(short(n) for n in common))
997 )
998 )
998
999
999
1000
1000 _chunksize = 4 << 10
1001 _chunksize = 4 << 10
1001
1002
1002
1003
1003 @command(
1004 @command(
1004 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1005 b'debugdownload', [(b'o', b'output', b'', _(b'path')),], optionalrepo=True
1005 )
1006 )
1006 def debugdownload(ui, repo, url, output=None, **opts):
1007 def debugdownload(ui, repo, url, output=None, **opts):
1007 """download a resource using Mercurial logic and config
1008 """download a resource using Mercurial logic and config
1008 """
1009 """
1009 fh = urlmod.open(ui, url, output)
1010 fh = urlmod.open(ui, url, output)
1010
1011
1011 dest = ui
1012 dest = ui
1012 if output:
1013 if output:
1013 dest = open(output, b"wb", _chunksize)
1014 dest = open(output, b"wb", _chunksize)
1014 try:
1015 try:
1015 data = fh.read(_chunksize)
1016 data = fh.read(_chunksize)
1016 while data:
1017 while data:
1017 dest.write(data)
1018 dest.write(data)
1018 data = fh.read(_chunksize)
1019 data = fh.read(_chunksize)
1019 finally:
1020 finally:
1020 if output:
1021 if output:
1021 dest.close()
1022 dest.close()
1022
1023
1023
1024
1024 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1025 @command(b'debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
1025 def debugextensions(ui, repo, **opts):
1026 def debugextensions(ui, repo, **opts):
1026 '''show information about active extensions'''
1027 '''show information about active extensions'''
1027 opts = pycompat.byteskwargs(opts)
1028 opts = pycompat.byteskwargs(opts)
1028 exts = extensions.extensions(ui)
1029 exts = extensions.extensions(ui)
1029 hgver = util.version()
1030 hgver = util.version()
1030 fm = ui.formatter(b'debugextensions', opts)
1031 fm = ui.formatter(b'debugextensions', opts)
1031 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1032 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
1032 isinternal = extensions.ismoduleinternal(extmod)
1033 isinternal = extensions.ismoduleinternal(extmod)
1033 extsource = None
1034 extsource = None
1034
1035
1035 if util.safehasattr(extmod, '__file__'):
1036 if util.safehasattr(extmod, '__file__'):
1036 extsource = pycompat.fsencode(extmod.__file__)
1037 extsource = pycompat.fsencode(extmod.__file__)
1037 elif getattr(sys, 'oxidized', False):
1038 elif getattr(sys, 'oxidized', False):
1038 extsource = pycompat.sysexecutable
1039 extsource = pycompat.sysexecutable
1039 if isinternal:
1040 if isinternal:
1040 exttestedwith = [] # never expose magic string to users
1041 exttestedwith = [] # never expose magic string to users
1041 else:
1042 else:
1042 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1043 exttestedwith = getattr(extmod, 'testedwith', b'').split()
1043 extbuglink = getattr(extmod, 'buglink', None)
1044 extbuglink = getattr(extmod, 'buglink', None)
1044
1045
1045 fm.startitem()
1046 fm.startitem()
1046
1047
1047 if ui.quiet or ui.verbose:
1048 if ui.quiet or ui.verbose:
1048 fm.write(b'name', b'%s\n', extname)
1049 fm.write(b'name', b'%s\n', extname)
1049 else:
1050 else:
1050 fm.write(b'name', b'%s', extname)
1051 fm.write(b'name', b'%s', extname)
1051 if isinternal or hgver in exttestedwith:
1052 if isinternal or hgver in exttestedwith:
1052 fm.plain(b'\n')
1053 fm.plain(b'\n')
1053 elif not exttestedwith:
1054 elif not exttestedwith:
1054 fm.plain(_(b' (untested!)\n'))
1055 fm.plain(_(b' (untested!)\n'))
1055 else:
1056 else:
1056 lasttestedversion = exttestedwith[-1]
1057 lasttestedversion = exttestedwith[-1]
1057 fm.plain(b' (%s!)\n' % lasttestedversion)
1058 fm.plain(b' (%s!)\n' % lasttestedversion)
1058
1059
1059 fm.condwrite(
1060 fm.condwrite(
1060 ui.verbose and extsource,
1061 ui.verbose and extsource,
1061 b'source',
1062 b'source',
1062 _(b' location: %s\n'),
1063 _(b' location: %s\n'),
1063 extsource or b"",
1064 extsource or b"",
1064 )
1065 )
1065
1066
1066 if ui.verbose:
1067 if ui.verbose:
1067 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1068 fm.plain(_(b' bundled: %s\n') % [b'no', b'yes'][isinternal])
1068 fm.data(bundled=isinternal)
1069 fm.data(bundled=isinternal)
1069
1070
1070 fm.condwrite(
1071 fm.condwrite(
1071 ui.verbose and exttestedwith,
1072 ui.verbose and exttestedwith,
1072 b'testedwith',
1073 b'testedwith',
1073 _(b' tested with: %s\n'),
1074 _(b' tested with: %s\n'),
1074 fm.formatlist(exttestedwith, name=b'ver'),
1075 fm.formatlist(exttestedwith, name=b'ver'),
1075 )
1076 )
1076
1077
1077 fm.condwrite(
1078 fm.condwrite(
1078 ui.verbose and extbuglink,
1079 ui.verbose and extbuglink,
1079 b'buglink',
1080 b'buglink',
1080 _(b' bug reporting: %s\n'),
1081 _(b' bug reporting: %s\n'),
1081 extbuglink or b"",
1082 extbuglink or b"",
1082 )
1083 )
1083
1084
1084 fm.end()
1085 fm.end()
1085
1086
1086
1087
1087 @command(
1088 @command(
1088 b'debugfileset',
1089 b'debugfileset',
1089 [
1090 [
1090 (
1091 (
1091 b'r',
1092 b'r',
1092 b'rev',
1093 b'rev',
1093 b'',
1094 b'',
1094 _(b'apply the filespec on this revision'),
1095 _(b'apply the filespec on this revision'),
1095 _(b'REV'),
1096 _(b'REV'),
1096 ),
1097 ),
1097 (
1098 (
1098 b'',
1099 b'',
1099 b'all-files',
1100 b'all-files',
1100 False,
1101 False,
1101 _(b'test files from all revisions and working directory'),
1102 _(b'test files from all revisions and working directory'),
1102 ),
1103 ),
1103 (
1104 (
1104 b's',
1105 b's',
1105 b'show-matcher',
1106 b'show-matcher',
1106 None,
1107 None,
1107 _(b'print internal representation of matcher'),
1108 _(b'print internal representation of matcher'),
1108 ),
1109 ),
1109 (
1110 (
1110 b'p',
1111 b'p',
1111 b'show-stage',
1112 b'show-stage',
1112 [],
1113 [],
1113 _(b'print parsed tree at the given stage'),
1114 _(b'print parsed tree at the given stage'),
1114 _(b'NAME'),
1115 _(b'NAME'),
1115 ),
1116 ),
1116 ],
1117 ],
1117 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1118 _(b'[-r REV] [--all-files] [OPTION]... FILESPEC'),
1118 )
1119 )
1119 def debugfileset(ui, repo, expr, **opts):
1120 def debugfileset(ui, repo, expr, **opts):
1120 '''parse and apply a fileset specification'''
1121 '''parse and apply a fileset specification'''
1121 from . import fileset
1122 from . import fileset
1122
1123
1123 fileset.symbols # force import of fileset so we have predicates to optimize
1124 fileset.symbols # force import of fileset so we have predicates to optimize
1124 opts = pycompat.byteskwargs(opts)
1125 opts = pycompat.byteskwargs(opts)
1125 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1126 ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
1126
1127
1127 stages = [
1128 stages = [
1128 (b'parsed', pycompat.identity),
1129 (b'parsed', pycompat.identity),
1129 (b'analyzed', filesetlang.analyze),
1130 (b'analyzed', filesetlang.analyze),
1130 (b'optimized', filesetlang.optimize),
1131 (b'optimized', filesetlang.optimize),
1131 ]
1132 ]
1132 stagenames = set(n for n, f in stages)
1133 stagenames = set(n for n, f in stages)
1133
1134
1134 showalways = set()
1135 showalways = set()
1135 if ui.verbose and not opts[b'show_stage']:
1136 if ui.verbose and not opts[b'show_stage']:
1136 # show parsed tree by --verbose (deprecated)
1137 # show parsed tree by --verbose (deprecated)
1137 showalways.add(b'parsed')
1138 showalways.add(b'parsed')
1138 if opts[b'show_stage'] == [b'all']:
1139 if opts[b'show_stage'] == [b'all']:
1139 showalways.update(stagenames)
1140 showalways.update(stagenames)
1140 else:
1141 else:
1141 for n in opts[b'show_stage']:
1142 for n in opts[b'show_stage']:
1142 if n not in stagenames:
1143 if n not in stagenames:
1143 raise error.Abort(_(b'invalid stage name: %s') % n)
1144 raise error.Abort(_(b'invalid stage name: %s') % n)
1144 showalways.update(opts[b'show_stage'])
1145 showalways.update(opts[b'show_stage'])
1145
1146
1146 tree = filesetlang.parse(expr)
1147 tree = filesetlang.parse(expr)
1147 for n, f in stages:
1148 for n, f in stages:
1148 tree = f(tree)
1149 tree = f(tree)
1149 if n in showalways:
1150 if n in showalways:
1150 if opts[b'show_stage'] or n != b'parsed':
1151 if opts[b'show_stage'] or n != b'parsed':
1151 ui.write(b"* %s:\n" % n)
1152 ui.write(b"* %s:\n" % n)
1152 ui.write(filesetlang.prettyformat(tree), b"\n")
1153 ui.write(filesetlang.prettyformat(tree), b"\n")
1153
1154
1154 files = set()
1155 files = set()
1155 if opts[b'all_files']:
1156 if opts[b'all_files']:
1156 for r in repo:
1157 for r in repo:
1157 c = repo[r]
1158 c = repo[r]
1158 files.update(c.files())
1159 files.update(c.files())
1159 files.update(c.substate)
1160 files.update(c.substate)
1160 if opts[b'all_files'] or ctx.rev() is None:
1161 if opts[b'all_files'] or ctx.rev() is None:
1161 wctx = repo[None]
1162 wctx = repo[None]
1162 files.update(
1163 files.update(
1163 repo.dirstate.walk(
1164 repo.dirstate.walk(
1164 scmutil.matchall(repo),
1165 scmutil.matchall(repo),
1165 subrepos=list(wctx.substate),
1166 subrepos=list(wctx.substate),
1166 unknown=True,
1167 unknown=True,
1167 ignored=True,
1168 ignored=True,
1168 )
1169 )
1169 )
1170 )
1170 files.update(wctx.substate)
1171 files.update(wctx.substate)
1171 else:
1172 else:
1172 files.update(ctx.files())
1173 files.update(ctx.files())
1173 files.update(ctx.substate)
1174 files.update(ctx.substate)
1174
1175
1175 m = ctx.matchfileset(repo.getcwd(), expr)
1176 m = ctx.matchfileset(repo.getcwd(), expr)
1176 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1177 if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
1177 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1178 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1178 for f in sorted(files):
1179 for f in sorted(files):
1179 if not m(f):
1180 if not m(f):
1180 continue
1181 continue
1181 ui.write(b"%s\n" % f)
1182 ui.write(b"%s\n" % f)
1182
1183
1183
1184
1184 @command(b'debugformat', [] + cmdutil.formatteropts)
1185 @command(b'debugformat', [] + cmdutil.formatteropts)
1185 def debugformat(ui, repo, **opts):
1186 def debugformat(ui, repo, **opts):
1186 """display format information about the current repository
1187 """display format information about the current repository
1187
1188
1188 Use --verbose to get extra information about current config value and
1189 Use --verbose to get extra information about current config value and
1189 Mercurial default."""
1190 Mercurial default."""
1190 opts = pycompat.byteskwargs(opts)
1191 opts = pycompat.byteskwargs(opts)
1191 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1192 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
1192 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1193 maxvariantlength = max(len(b'format-variant'), maxvariantlength)
1193
1194
1194 def makeformatname(name):
1195 def makeformatname(name):
1195 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1196 return b'%s:' + (b' ' * (maxvariantlength - len(name)))
1196
1197
1197 fm = ui.formatter(b'debugformat', opts)
1198 fm = ui.formatter(b'debugformat', opts)
1198 if fm.isplain():
1199 if fm.isplain():
1199
1200
1200 def formatvalue(value):
1201 def formatvalue(value):
1201 if util.safehasattr(value, b'startswith'):
1202 if util.safehasattr(value, b'startswith'):
1202 return value
1203 return value
1203 if value:
1204 if value:
1204 return b'yes'
1205 return b'yes'
1205 else:
1206 else:
1206 return b'no'
1207 return b'no'
1207
1208
1208 else:
1209 else:
1209 formatvalue = pycompat.identity
1210 formatvalue = pycompat.identity
1210
1211
1211 fm.plain(b'format-variant')
1212 fm.plain(b'format-variant')
1212 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1213 fm.plain(b' ' * (maxvariantlength - len(b'format-variant')))
1213 fm.plain(b' repo')
1214 fm.plain(b' repo')
1214 if ui.verbose:
1215 if ui.verbose:
1215 fm.plain(b' config default')
1216 fm.plain(b' config default')
1216 fm.plain(b'\n')
1217 fm.plain(b'\n')
1217 for fv in upgrade.allformatvariant:
1218 for fv in upgrade.allformatvariant:
1218 fm.startitem()
1219 fm.startitem()
1219 repovalue = fv.fromrepo(repo)
1220 repovalue = fv.fromrepo(repo)
1220 configvalue = fv.fromconfig(repo)
1221 configvalue = fv.fromconfig(repo)
1221
1222
1222 if repovalue != configvalue:
1223 if repovalue != configvalue:
1223 namelabel = b'formatvariant.name.mismatchconfig'
1224 namelabel = b'formatvariant.name.mismatchconfig'
1224 repolabel = b'formatvariant.repo.mismatchconfig'
1225 repolabel = b'formatvariant.repo.mismatchconfig'
1225 elif repovalue != fv.default:
1226 elif repovalue != fv.default:
1226 namelabel = b'formatvariant.name.mismatchdefault'
1227 namelabel = b'formatvariant.name.mismatchdefault'
1227 repolabel = b'formatvariant.repo.mismatchdefault'
1228 repolabel = b'formatvariant.repo.mismatchdefault'
1228 else:
1229 else:
1229 namelabel = b'formatvariant.name.uptodate'
1230 namelabel = b'formatvariant.name.uptodate'
1230 repolabel = b'formatvariant.repo.uptodate'
1231 repolabel = b'formatvariant.repo.uptodate'
1231
1232
1232 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1233 fm.write(b'name', makeformatname(fv.name), fv.name, label=namelabel)
1233 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1234 fm.write(b'repo', b' %3s', formatvalue(repovalue), label=repolabel)
1234 if fv.default != configvalue:
1235 if fv.default != configvalue:
1235 configlabel = b'formatvariant.config.special'
1236 configlabel = b'formatvariant.config.special'
1236 else:
1237 else:
1237 configlabel = b'formatvariant.config.default'
1238 configlabel = b'formatvariant.config.default'
1238 fm.condwrite(
1239 fm.condwrite(
1239 ui.verbose,
1240 ui.verbose,
1240 b'config',
1241 b'config',
1241 b' %6s',
1242 b' %6s',
1242 formatvalue(configvalue),
1243 formatvalue(configvalue),
1243 label=configlabel,
1244 label=configlabel,
1244 )
1245 )
1245 fm.condwrite(
1246 fm.condwrite(
1246 ui.verbose,
1247 ui.verbose,
1247 b'default',
1248 b'default',
1248 b' %7s',
1249 b' %7s',
1249 formatvalue(fv.default),
1250 formatvalue(fv.default),
1250 label=b'formatvariant.default',
1251 label=b'formatvariant.default',
1251 )
1252 )
1252 fm.plain(b'\n')
1253 fm.plain(b'\n')
1253 fm.end()
1254 fm.end()
1254
1255
1255
1256
1256 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1257 @command(b'debugfsinfo', [], _(b'[PATH]'), norepo=True)
1257 def debugfsinfo(ui, path=b"."):
1258 def debugfsinfo(ui, path=b"."):
1258 """show information detected about current filesystem"""
1259 """show information detected about current filesystem"""
1259 ui.writenoi18n(b'path: %s\n' % path)
1260 ui.writenoi18n(b'path: %s\n' % path)
1260 ui.writenoi18n(
1261 ui.writenoi18n(
1261 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1262 b'mounted on: %s\n' % (util.getfsmountpoint(path) or b'(unknown)')
1262 )
1263 )
1263 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1264 ui.writenoi18n(b'exec: %s\n' % (util.checkexec(path) and b'yes' or b'no'))
1264 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1265 ui.writenoi18n(b'fstype: %s\n' % (util.getfstype(path) or b'(unknown)'))
1265 ui.writenoi18n(
1266 ui.writenoi18n(
1266 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1267 b'symlink: %s\n' % (util.checklink(path) and b'yes' or b'no')
1267 )
1268 )
1268 ui.writenoi18n(
1269 ui.writenoi18n(
1269 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1270 b'hardlink: %s\n' % (util.checknlink(path) and b'yes' or b'no')
1270 )
1271 )
1271 casesensitive = b'(unknown)'
1272 casesensitive = b'(unknown)'
1272 try:
1273 try:
1273 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1274 with pycompat.namedtempfile(prefix=b'.debugfsinfo', dir=path) as f:
1274 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1275 casesensitive = util.fscasesensitive(f.name) and b'yes' or b'no'
1275 except OSError:
1276 except OSError:
1276 pass
1277 pass
1277 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1278 ui.writenoi18n(b'case-sensitive: %s\n' % casesensitive)
1278
1279
1279
1280
1280 @command(
1281 @command(
1281 b'debuggetbundle',
1282 b'debuggetbundle',
1282 [
1283 [
1283 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1284 (b'H', b'head', [], _(b'id of head node'), _(b'ID')),
1284 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1285 (b'C', b'common', [], _(b'id of common node'), _(b'ID')),
1285 (
1286 (
1286 b't',
1287 b't',
1287 b'type',
1288 b'type',
1288 b'bzip2',
1289 b'bzip2',
1289 _(b'bundle compression type to use'),
1290 _(b'bundle compression type to use'),
1290 _(b'TYPE'),
1291 _(b'TYPE'),
1291 ),
1292 ),
1292 ],
1293 ],
1293 _(b'REPO FILE [-H|-C ID]...'),
1294 _(b'REPO FILE [-H|-C ID]...'),
1294 norepo=True,
1295 norepo=True,
1295 )
1296 )
1296 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1297 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1297 """retrieves a bundle from a repo
1298 """retrieves a bundle from a repo
1298
1299
1299 Every ID must be a full-length hex node id string. Saves the bundle to the
1300 Every ID must be a full-length hex node id string. Saves the bundle to the
1300 given file.
1301 given file.
1301 """
1302 """
1302 opts = pycompat.byteskwargs(opts)
1303 opts = pycompat.byteskwargs(opts)
1303 repo = hg.peer(ui, opts, repopath)
1304 repo = hg.peer(ui, opts, repopath)
1304 if not repo.capable(b'getbundle'):
1305 if not repo.capable(b'getbundle'):
1305 raise error.Abort(b"getbundle() not supported by target repository")
1306 raise error.Abort(b"getbundle() not supported by target repository")
1306 args = {}
1307 args = {}
1307 if common:
1308 if common:
1308 args['common'] = [bin(s) for s in common]
1309 args['common'] = [bin(s) for s in common]
1309 if head:
1310 if head:
1310 args['heads'] = [bin(s) for s in head]
1311 args['heads'] = [bin(s) for s in head]
1311 # TODO: get desired bundlecaps from command line.
1312 # TODO: get desired bundlecaps from command line.
1312 args['bundlecaps'] = None
1313 args['bundlecaps'] = None
1313 bundle = repo.getbundle(b'debug', **args)
1314 bundle = repo.getbundle(b'debug', **args)
1314
1315
1315 bundletype = opts.get(b'type', b'bzip2').lower()
1316 bundletype = opts.get(b'type', b'bzip2').lower()
1316 btypes = {
1317 btypes = {
1317 b'none': b'HG10UN',
1318 b'none': b'HG10UN',
1318 b'bzip2': b'HG10BZ',
1319 b'bzip2': b'HG10BZ',
1319 b'gzip': b'HG10GZ',
1320 b'gzip': b'HG10GZ',
1320 b'bundle2': b'HG20',
1321 b'bundle2': b'HG20',
1321 }
1322 }
1322 bundletype = btypes.get(bundletype)
1323 bundletype = btypes.get(bundletype)
1323 if bundletype not in bundle2.bundletypes:
1324 if bundletype not in bundle2.bundletypes:
1324 raise error.Abort(_(b'unknown bundle type specified with --type'))
1325 raise error.Abort(_(b'unknown bundle type specified with --type'))
1325 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1326 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1326
1327
1327
1328
1328 @command(b'debugignore', [], b'[FILE]')
1329 @command(b'debugignore', [], b'[FILE]')
1329 def debugignore(ui, repo, *files, **opts):
1330 def debugignore(ui, repo, *files, **opts):
1330 """display the combined ignore pattern and information about ignored files
1331 """display the combined ignore pattern and information about ignored files
1331
1332
1332 With no argument display the combined ignore pattern.
1333 With no argument display the combined ignore pattern.
1333
1334
1334 Given space separated file names, shows if the given file is ignored and
1335 Given space separated file names, shows if the given file is ignored and
1335 if so, show the ignore rule (file and line number) that matched it.
1336 if so, show the ignore rule (file and line number) that matched it.
1336 """
1337 """
1337 ignore = repo.dirstate._ignore
1338 ignore = repo.dirstate._ignore
1338 if not files:
1339 if not files:
1339 # Show all the patterns
1340 # Show all the patterns
1340 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1341 ui.write(b"%s\n" % pycompat.byterepr(ignore))
1341 else:
1342 else:
1342 m = scmutil.match(repo[None], pats=files)
1343 m = scmutil.match(repo[None], pats=files)
1343 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1344 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1344 for f in m.files():
1345 for f in m.files():
1345 nf = util.normpath(f)
1346 nf = util.normpath(f)
1346 ignored = None
1347 ignored = None
1347 ignoredata = None
1348 ignoredata = None
1348 if nf != b'.':
1349 if nf != b'.':
1349 if ignore(nf):
1350 if ignore(nf):
1350 ignored = nf
1351 ignored = nf
1351 ignoredata = repo.dirstate._ignorefileandline(nf)
1352 ignoredata = repo.dirstate._ignorefileandline(nf)
1352 else:
1353 else:
1353 for p in pathutil.finddirs(nf):
1354 for p in pathutil.finddirs(nf):
1354 if ignore(p):
1355 if ignore(p):
1355 ignored = p
1356 ignored = p
1356 ignoredata = repo.dirstate._ignorefileandline(p)
1357 ignoredata = repo.dirstate._ignorefileandline(p)
1357 break
1358 break
1358 if ignored:
1359 if ignored:
1359 if ignored == nf:
1360 if ignored == nf:
1360 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1361 ui.write(_(b"%s is ignored\n") % uipathfn(f))
1361 else:
1362 else:
1362 ui.write(
1363 ui.write(
1363 _(
1364 _(
1364 b"%s is ignored because of "
1365 b"%s is ignored because of "
1365 b"containing directory %s\n"
1366 b"containing directory %s\n"
1366 )
1367 )
1367 % (uipathfn(f), ignored)
1368 % (uipathfn(f), ignored)
1368 )
1369 )
1369 ignorefile, lineno, line = ignoredata
1370 ignorefile, lineno, line = ignoredata
1370 ui.write(
1371 ui.write(
1371 _(b"(ignore rule in %s, line %d: '%s')\n")
1372 _(b"(ignore rule in %s, line %d: '%s')\n")
1372 % (ignorefile, lineno, line)
1373 % (ignorefile, lineno, line)
1373 )
1374 )
1374 else:
1375 else:
1375 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1376 ui.write(_(b"%s is not ignored\n") % uipathfn(f))
1376
1377
1377
1378
1378 @command(
1379 @command(
1379 b'debugindex',
1380 b'debugindex',
1380 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1381 cmdutil.debugrevlogopts + cmdutil.formatteropts,
1381 _(b'-c|-m|FILE'),
1382 _(b'-c|-m|FILE'),
1382 )
1383 )
1383 def debugindex(ui, repo, file_=None, **opts):
1384 def debugindex(ui, repo, file_=None, **opts):
1384 """dump index data for a storage primitive"""
1385 """dump index data for a storage primitive"""
1385 opts = pycompat.byteskwargs(opts)
1386 opts = pycompat.byteskwargs(opts)
1386 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1387 store = cmdutil.openstorage(repo, b'debugindex', file_, opts)
1387
1388
1388 if ui.debugflag:
1389 if ui.debugflag:
1389 shortfn = hex
1390 shortfn = hex
1390 else:
1391 else:
1391 shortfn = short
1392 shortfn = short
1392
1393
1393 idlen = 12
1394 idlen = 12
1394 for i in store:
1395 for i in store:
1395 idlen = len(shortfn(store.node(i)))
1396 idlen = len(shortfn(store.node(i)))
1396 break
1397 break
1397
1398
1398 fm = ui.formatter(b'debugindex', opts)
1399 fm = ui.formatter(b'debugindex', opts)
1399 fm.plain(
1400 fm.plain(
1400 b' rev linkrev %s %s p2\n'
1401 b' rev linkrev %s %s p2\n'
1401 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1402 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen))
1402 )
1403 )
1403
1404
1404 for rev in store:
1405 for rev in store:
1405 node = store.node(rev)
1406 node = store.node(rev)
1406 parents = store.parents(node)
1407 parents = store.parents(node)
1407
1408
1408 fm.startitem()
1409 fm.startitem()
1409 fm.write(b'rev', b'%6d ', rev)
1410 fm.write(b'rev', b'%6d ', rev)
1410 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1411 fm.write(b'linkrev', b'%7d ', store.linkrev(rev))
1411 fm.write(b'node', b'%s ', shortfn(node))
1412 fm.write(b'node', b'%s ', shortfn(node))
1412 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1413 fm.write(b'p1', b'%s ', shortfn(parents[0]))
1413 fm.write(b'p2', b'%s', shortfn(parents[1]))
1414 fm.write(b'p2', b'%s', shortfn(parents[1]))
1414 fm.plain(b'\n')
1415 fm.plain(b'\n')
1415
1416
1416 fm.end()
1417 fm.end()
1417
1418
1418
1419
1419 @command(
1420 @command(
1420 b'debugindexdot',
1421 b'debugindexdot',
1421 cmdutil.debugrevlogopts,
1422 cmdutil.debugrevlogopts,
1422 _(b'-c|-m|FILE'),
1423 _(b'-c|-m|FILE'),
1423 optionalrepo=True,
1424 optionalrepo=True,
1424 )
1425 )
1425 def debugindexdot(ui, repo, file_=None, **opts):
1426 def debugindexdot(ui, repo, file_=None, **opts):
1426 """dump an index DAG as a graphviz dot file"""
1427 """dump an index DAG as a graphviz dot file"""
1427 opts = pycompat.byteskwargs(opts)
1428 opts = pycompat.byteskwargs(opts)
1428 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1429 r = cmdutil.openstorage(repo, b'debugindexdot', file_, opts)
1429 ui.writenoi18n(b"digraph G {\n")
1430 ui.writenoi18n(b"digraph G {\n")
1430 for i in r:
1431 for i in r:
1431 node = r.node(i)
1432 node = r.node(i)
1432 pp = r.parents(node)
1433 pp = r.parents(node)
1433 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1434 ui.write(b"\t%d -> %d\n" % (r.rev(pp[0]), i))
1434 if pp[1] != nullid:
1435 if pp[1] != nullid:
1435 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1436 ui.write(b"\t%d -> %d\n" % (r.rev(pp[1]), i))
1436 ui.write(b"}\n")
1437 ui.write(b"}\n")
1437
1438
1438
1439
1439 @command(b'debugindexstats', [])
1440 @command(b'debugindexstats', [])
1440 def debugindexstats(ui, repo):
1441 def debugindexstats(ui, repo):
1441 """show stats related to the changelog index"""
1442 """show stats related to the changelog index"""
1442 repo.changelog.shortest(nullid, 1)
1443 repo.changelog.shortest(nullid, 1)
1443 index = repo.changelog.index
1444 index = repo.changelog.index
1444 if not util.safehasattr(index, b'stats'):
1445 if not util.safehasattr(index, b'stats'):
1445 raise error.Abort(_(b'debugindexstats only works with native code'))
1446 raise error.Abort(_(b'debugindexstats only works with native code'))
1446 for k, v in sorted(index.stats().items()):
1447 for k, v in sorted(index.stats().items()):
1447 ui.write(b'%s: %d\n' % (k, v))
1448 ui.write(b'%s: %d\n' % (k, v))
1448
1449
1449
1450
1450 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1451 @command(b'debuginstall', [] + cmdutil.formatteropts, b'', norepo=True)
1451 def debuginstall(ui, **opts):
1452 def debuginstall(ui, **opts):
1452 '''test Mercurial installation
1453 '''test Mercurial installation
1453
1454
1454 Returns 0 on success.
1455 Returns 0 on success.
1455 '''
1456 '''
1456 opts = pycompat.byteskwargs(opts)
1457 opts = pycompat.byteskwargs(opts)
1457
1458
1458 problems = 0
1459 problems = 0
1459
1460
1460 fm = ui.formatter(b'debuginstall', opts)
1461 fm = ui.formatter(b'debuginstall', opts)
1461 fm.startitem()
1462 fm.startitem()
1462
1463
1463 # encoding
1464 # encoding
1464 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1465 fm.write(b'encoding', _(b"checking encoding (%s)...\n"), encoding.encoding)
1465 err = None
1466 err = None
1466 try:
1467 try:
1467 codecs.lookup(pycompat.sysstr(encoding.encoding))
1468 codecs.lookup(pycompat.sysstr(encoding.encoding))
1468 except LookupError as inst:
1469 except LookupError as inst:
1469 err = stringutil.forcebytestr(inst)
1470 err = stringutil.forcebytestr(inst)
1470 problems += 1
1471 problems += 1
1471 fm.condwrite(
1472 fm.condwrite(
1472 err,
1473 err,
1473 b'encodingerror',
1474 b'encodingerror',
1474 _(b" %s\n (check that your locale is properly set)\n"),
1475 _(b" %s\n (check that your locale is properly set)\n"),
1475 err,
1476 err,
1476 )
1477 )
1477
1478
1478 # Python
1479 # Python
1479 pythonlib = None
1480 pythonlib = None
1480 if util.safehasattr(os, '__file__'):
1481 if util.safehasattr(os, '__file__'):
1481 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1482 pythonlib = os.path.dirname(pycompat.fsencode(os.__file__))
1482 elif getattr(sys, 'oxidized', False):
1483 elif getattr(sys, 'oxidized', False):
1483 pythonlib = pycompat.sysexecutable
1484 pythonlib = pycompat.sysexecutable
1484
1485
1485 fm.write(
1486 fm.write(
1486 b'pythonexe',
1487 b'pythonexe',
1487 _(b"checking Python executable (%s)\n"),
1488 _(b"checking Python executable (%s)\n"),
1488 pycompat.sysexecutable or _(b"unknown"),
1489 pycompat.sysexecutable or _(b"unknown"),
1489 )
1490 )
1490 fm.write(
1491 fm.write(
1491 b'pythonimplementation',
1492 b'pythonimplementation',
1492 _(b"checking Python implementation (%s)\n"),
1493 _(b"checking Python implementation (%s)\n"),
1493 pycompat.sysbytes(platform.python_implementation()),
1494 pycompat.sysbytes(platform.python_implementation()),
1494 )
1495 )
1495 fm.write(
1496 fm.write(
1496 b'pythonver',
1497 b'pythonver',
1497 _(b"checking Python version (%s)\n"),
1498 _(b"checking Python version (%s)\n"),
1498 (b"%d.%d.%d" % sys.version_info[:3]),
1499 (b"%d.%d.%d" % sys.version_info[:3]),
1499 )
1500 )
1500 fm.write(
1501 fm.write(
1501 b'pythonlib',
1502 b'pythonlib',
1502 _(b"checking Python lib (%s)...\n"),
1503 _(b"checking Python lib (%s)...\n"),
1503 pythonlib or _(b"unknown"),
1504 pythonlib or _(b"unknown"),
1504 )
1505 )
1505
1506
1506 security = set(sslutil.supportedprotocols)
1507 security = set(sslutil.supportedprotocols)
1507 if sslutil.hassni:
1508 if sslutil.hassni:
1508 security.add(b'sni')
1509 security.add(b'sni')
1509
1510
1510 fm.write(
1511 fm.write(
1511 b'pythonsecurity',
1512 b'pythonsecurity',
1512 _(b"checking Python security support (%s)\n"),
1513 _(b"checking Python security support (%s)\n"),
1513 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1514 fm.formatlist(sorted(security), name=b'protocol', fmt=b'%s', sep=b','),
1514 )
1515 )
1515
1516
1516 # These are warnings, not errors. So don't increment problem count. This
1517 # These are warnings, not errors. So don't increment problem count. This
1517 # may change in the future.
1518 # may change in the future.
1518 if b'tls1.2' not in security:
1519 if b'tls1.2' not in security:
1519 fm.plain(
1520 fm.plain(
1520 _(
1521 _(
1521 b' TLS 1.2 not supported by Python install; '
1522 b' TLS 1.2 not supported by Python install; '
1522 b'network connections lack modern security\n'
1523 b'network connections lack modern security\n'
1523 )
1524 )
1524 )
1525 )
1525 if b'sni' not in security:
1526 if b'sni' not in security:
1526 fm.plain(
1527 fm.plain(
1527 _(
1528 _(
1528 b' SNI not supported by Python install; may have '
1529 b' SNI not supported by Python install; may have '
1529 b'connectivity issues with some servers\n'
1530 b'connectivity issues with some servers\n'
1530 )
1531 )
1531 )
1532 )
1532
1533
1533 # TODO print CA cert info
1534 # TODO print CA cert info
1534
1535
1535 # hg version
1536 # hg version
1536 hgver = util.version()
1537 hgver = util.version()
1537 fm.write(
1538 fm.write(
1538 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1539 b'hgver', _(b"checking Mercurial version (%s)\n"), hgver.split(b'+')[0]
1539 )
1540 )
1540 fm.write(
1541 fm.write(
1541 b'hgverextra',
1542 b'hgverextra',
1542 _(b"checking Mercurial custom build (%s)\n"),
1543 _(b"checking Mercurial custom build (%s)\n"),
1543 b'+'.join(hgver.split(b'+')[1:]),
1544 b'+'.join(hgver.split(b'+')[1:]),
1544 )
1545 )
1545
1546
1546 # compiled modules
1547 # compiled modules
1547 hgmodules = None
1548 hgmodules = None
1548 if util.safehasattr(sys.modules[__name__], '__file__'):
1549 if util.safehasattr(sys.modules[__name__], '__file__'):
1549 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1550 hgmodules = os.path.dirname(pycompat.fsencode(__file__))
1550 elif getattr(sys, 'oxidized', False):
1551 elif getattr(sys, 'oxidized', False):
1551 hgmodules = pycompat.sysexecutable
1552 hgmodules = pycompat.sysexecutable
1552
1553
1553 fm.write(
1554 fm.write(
1554 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1555 b'hgmodulepolicy', _(b"checking module policy (%s)\n"), policy.policy
1555 )
1556 )
1556 fm.write(
1557 fm.write(
1557 b'hgmodules',
1558 b'hgmodules',
1558 _(b"checking installed modules (%s)...\n"),
1559 _(b"checking installed modules (%s)...\n"),
1559 hgmodules or _(b"unknown"),
1560 hgmodules or _(b"unknown"),
1560 )
1561 )
1561
1562
1562 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1563 rustandc = policy.policy in (b'rust+c', b'rust+c-allow')
1563 rustext = rustandc # for now, that's the only case
1564 rustext = rustandc # for now, that's the only case
1564 cext = policy.policy in (b'c', b'allow') or rustandc
1565 cext = policy.policy in (b'c', b'allow') or rustandc
1565 nopure = cext or rustext
1566 nopure = cext or rustext
1566 if nopure:
1567 if nopure:
1567 err = None
1568 err = None
1568 try:
1569 try:
1569 if cext:
1570 if cext:
1570 from .cext import ( # pytype: disable=import-error
1571 from .cext import ( # pytype: disable=import-error
1571 base85,
1572 base85,
1572 bdiff,
1573 bdiff,
1573 mpatch,
1574 mpatch,
1574 osutil,
1575 osutil,
1575 )
1576 )
1576
1577
1577 # quiet pyflakes
1578 # quiet pyflakes
1578 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1579 dir(bdiff), dir(mpatch), dir(base85), dir(osutil)
1579 if rustext:
1580 if rustext:
1580 from .rustext import ( # pytype: disable=import-error
1581 from .rustext import ( # pytype: disable=import-error
1581 ancestor,
1582 ancestor,
1582 dirstate,
1583 dirstate,
1583 )
1584 )
1584
1585
1585 dir(ancestor), dir(dirstate) # quiet pyflakes
1586 dir(ancestor), dir(dirstate) # quiet pyflakes
1586 except Exception as inst:
1587 except Exception as inst:
1587 err = stringutil.forcebytestr(inst)
1588 err = stringutil.forcebytestr(inst)
1588 problems += 1
1589 problems += 1
1589 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1590 fm.condwrite(err, b'extensionserror', b" %s\n", err)
1590
1591
1591 compengines = util.compengines._engines.values()
1592 compengines = util.compengines._engines.values()
1592 fm.write(
1593 fm.write(
1593 b'compengines',
1594 b'compengines',
1594 _(b'checking registered compression engines (%s)\n'),
1595 _(b'checking registered compression engines (%s)\n'),
1595 fm.formatlist(
1596 fm.formatlist(
1596 sorted(e.name() for e in compengines),
1597 sorted(e.name() for e in compengines),
1597 name=b'compengine',
1598 name=b'compengine',
1598 fmt=b'%s',
1599 fmt=b'%s',
1599 sep=b', ',
1600 sep=b', ',
1600 ),
1601 ),
1601 )
1602 )
1602 fm.write(
1603 fm.write(
1603 b'compenginesavail',
1604 b'compenginesavail',
1604 _(b'checking available compression engines (%s)\n'),
1605 _(b'checking available compression engines (%s)\n'),
1605 fm.formatlist(
1606 fm.formatlist(
1606 sorted(e.name() for e in compengines if e.available()),
1607 sorted(e.name() for e in compengines if e.available()),
1607 name=b'compengine',
1608 name=b'compengine',
1608 fmt=b'%s',
1609 fmt=b'%s',
1609 sep=b', ',
1610 sep=b', ',
1610 ),
1611 ),
1611 )
1612 )
1612 wirecompengines = compression.compengines.supportedwireengines(
1613 wirecompengines = compression.compengines.supportedwireengines(
1613 compression.SERVERROLE
1614 compression.SERVERROLE
1614 )
1615 )
1615 fm.write(
1616 fm.write(
1616 b'compenginesserver',
1617 b'compenginesserver',
1617 _(
1618 _(
1618 b'checking available compression engines '
1619 b'checking available compression engines '
1619 b'for wire protocol (%s)\n'
1620 b'for wire protocol (%s)\n'
1620 ),
1621 ),
1621 fm.formatlist(
1622 fm.formatlist(
1622 [e.name() for e in wirecompengines if e.wireprotosupport()],
1623 [e.name() for e in wirecompengines if e.wireprotosupport()],
1623 name=b'compengine',
1624 name=b'compengine',
1624 fmt=b'%s',
1625 fmt=b'%s',
1625 sep=b', ',
1626 sep=b', ',
1626 ),
1627 ),
1627 )
1628 )
1628 re2 = b'missing'
1629 re2 = b'missing'
1629 if util._re2:
1630 if util._re2:
1630 re2 = b'available'
1631 re2 = b'available'
1631 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1632 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
1632 fm.data(re2=bool(util._re2))
1633 fm.data(re2=bool(util._re2))
1633
1634
1634 # templates
1635 # templates
1635 p = templater.templatepaths()
1636 p = templater.templatepaths()
1636 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1637 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
1637 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1638 fm.condwrite(not p, b'', _(b" no template directories found\n"))
1638 if p:
1639 if p:
1639 m = templater.templatepath(b"map-cmdline.default")
1640 m = templater.templatepath(b"map-cmdline.default")
1640 if m:
1641 if m:
1641 # template found, check if it is working
1642 # template found, check if it is working
1642 err = None
1643 err = None
1643 try:
1644 try:
1644 templater.templater.frommapfile(m)
1645 templater.templater.frommapfile(m)
1645 except Exception as inst:
1646 except Exception as inst:
1646 err = stringutil.forcebytestr(inst)
1647 err = stringutil.forcebytestr(inst)
1647 p = None
1648 p = None
1648 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1649 fm.condwrite(err, b'defaulttemplateerror', b" %s\n", err)
1649 else:
1650 else:
1650 p = None
1651 p = None
1651 fm.condwrite(
1652 fm.condwrite(
1652 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1653 p, b'defaulttemplate', _(b"checking default template (%s)\n"), m
1653 )
1654 )
1654 fm.condwrite(
1655 fm.condwrite(
1655 not m,
1656 not m,
1656 b'defaulttemplatenotfound',
1657 b'defaulttemplatenotfound',
1657 _(b" template '%s' not found\n"),
1658 _(b" template '%s' not found\n"),
1658 b"default",
1659 b"default",
1659 )
1660 )
1660 if not p:
1661 if not p:
1661 problems += 1
1662 problems += 1
1662 fm.condwrite(
1663 fm.condwrite(
1663 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1664 not p, b'', _(b" (templates seem to have been installed incorrectly)\n")
1664 )
1665 )
1665
1666
1666 # editor
1667 # editor
1667 editor = ui.geteditor()
1668 editor = ui.geteditor()
1668 editor = util.expandpath(editor)
1669 editor = util.expandpath(editor)
1669 editorbin = procutil.shellsplit(editor)[0]
1670 editorbin = procutil.shellsplit(editor)[0]
1670 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1671 fm.write(b'editor', _(b"checking commit editor... (%s)\n"), editorbin)
1671 cmdpath = procutil.findexe(editorbin)
1672 cmdpath = procutil.findexe(editorbin)
1672 fm.condwrite(
1673 fm.condwrite(
1673 not cmdpath and editor == b'vi',
1674 not cmdpath and editor == b'vi',
1674 b'vinotfound',
1675 b'vinotfound',
1675 _(
1676 _(
1676 b" No commit editor set and can't find %s in PATH\n"
1677 b" No commit editor set and can't find %s in PATH\n"
1677 b" (specify a commit editor in your configuration"
1678 b" (specify a commit editor in your configuration"
1678 b" file)\n"
1679 b" file)\n"
1679 ),
1680 ),
1680 not cmdpath and editor == b'vi' and editorbin,
1681 not cmdpath and editor == b'vi' and editorbin,
1681 )
1682 )
1682 fm.condwrite(
1683 fm.condwrite(
1683 not cmdpath and editor != b'vi',
1684 not cmdpath and editor != b'vi',
1684 b'editornotfound',
1685 b'editornotfound',
1685 _(
1686 _(
1686 b" Can't find editor '%s' in PATH\n"
1687 b" Can't find editor '%s' in PATH\n"
1687 b" (specify a commit editor in your configuration"
1688 b" (specify a commit editor in your configuration"
1688 b" file)\n"
1689 b" file)\n"
1689 ),
1690 ),
1690 not cmdpath and editorbin,
1691 not cmdpath and editorbin,
1691 )
1692 )
1692 if not cmdpath and editor != b'vi':
1693 if not cmdpath and editor != b'vi':
1693 problems += 1
1694 problems += 1
1694
1695
1695 # check username
1696 # check username
1696 username = None
1697 username = None
1697 err = None
1698 err = None
1698 try:
1699 try:
1699 username = ui.username()
1700 username = ui.username()
1700 except error.Abort as e:
1701 except error.Abort as e:
1701 err = stringutil.forcebytestr(e)
1702 err = stringutil.forcebytestr(e)
1702 problems += 1
1703 problems += 1
1703
1704
1704 fm.condwrite(
1705 fm.condwrite(
1705 username, b'username', _(b"checking username (%s)\n"), username
1706 username, b'username', _(b"checking username (%s)\n"), username
1706 )
1707 )
1707 fm.condwrite(
1708 fm.condwrite(
1708 err,
1709 err,
1709 b'usernameerror',
1710 b'usernameerror',
1710 _(
1711 _(
1711 b"checking username...\n %s\n"
1712 b"checking username...\n %s\n"
1712 b" (specify a username in your configuration file)\n"
1713 b" (specify a username in your configuration file)\n"
1713 ),
1714 ),
1714 err,
1715 err,
1715 )
1716 )
1716
1717
1717 for name, mod in extensions.extensions():
1718 for name, mod in extensions.extensions():
1718 handler = getattr(mod, 'debuginstall', None)
1719 handler = getattr(mod, 'debuginstall', None)
1719 if handler is not None:
1720 if handler is not None:
1720 problems += handler(ui, fm)
1721 problems += handler(ui, fm)
1721
1722
1722 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1723 fm.condwrite(not problems, b'', _(b"no problems detected\n"))
1723 if not problems:
1724 if not problems:
1724 fm.data(problems=problems)
1725 fm.data(problems=problems)
1725 fm.condwrite(
1726 fm.condwrite(
1726 problems,
1727 problems,
1727 b'problems',
1728 b'problems',
1728 _(b"%d problems detected, please check your install!\n"),
1729 _(b"%d problems detected, please check your install!\n"),
1729 problems,
1730 problems,
1730 )
1731 )
1731 fm.end()
1732 fm.end()
1732
1733
1733 return problems
1734 return problems
1734
1735
1735
1736
1736 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1737 @command(b'debugknown', [], _(b'REPO ID...'), norepo=True)
1737 def debugknown(ui, repopath, *ids, **opts):
1738 def debugknown(ui, repopath, *ids, **opts):
1738 """test whether node ids are known to a repo
1739 """test whether node ids are known to a repo
1739
1740
1740 Every ID must be a full-length hex node id string. Returns a list of 0s
1741 Every ID must be a full-length hex node id string. Returns a list of 0s
1741 and 1s indicating unknown/known.
1742 and 1s indicating unknown/known.
1742 """
1743 """
1743 opts = pycompat.byteskwargs(opts)
1744 opts = pycompat.byteskwargs(opts)
1744 repo = hg.peer(ui, opts, repopath)
1745 repo = hg.peer(ui, opts, repopath)
1745 if not repo.capable(b'known'):
1746 if not repo.capable(b'known'):
1746 raise error.Abort(b"known() not supported by target repository")
1747 raise error.Abort(b"known() not supported by target repository")
1747 flags = repo.known([bin(s) for s in ids])
1748 flags = repo.known([bin(s) for s in ids])
1748 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1749 ui.write(b"%s\n" % (b"".join([f and b"1" or b"0" for f in flags])))
1749
1750
1750
1751
1751 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1752 @command(b'debuglabelcomplete', [], _(b'LABEL...'))
1752 def debuglabelcomplete(ui, repo, *args):
1753 def debuglabelcomplete(ui, repo, *args):
1753 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1754 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1754 debugnamecomplete(ui, repo, *args)
1755 debugnamecomplete(ui, repo, *args)
1755
1756
1756
1757
1757 @command(
1758 @command(
1758 b'debuglocks',
1759 b'debuglocks',
1759 [
1760 [
1760 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1761 (b'L', b'force-lock', None, _(b'free the store lock (DANGEROUS)')),
1761 (
1762 (
1762 b'W',
1763 b'W',
1763 b'force-wlock',
1764 b'force-wlock',
1764 None,
1765 None,
1765 _(b'free the working state lock (DANGEROUS)'),
1766 _(b'free the working state lock (DANGEROUS)'),
1766 ),
1767 ),
1767 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1768 (b's', b'set-lock', None, _(b'set the store lock until stopped')),
1768 (
1769 (
1769 b'S',
1770 b'S',
1770 b'set-wlock',
1771 b'set-wlock',
1771 None,
1772 None,
1772 _(b'set the working state lock until stopped'),
1773 _(b'set the working state lock until stopped'),
1773 ),
1774 ),
1774 ],
1775 ],
1775 _(b'[OPTION]...'),
1776 _(b'[OPTION]...'),
1776 )
1777 )
1777 def debuglocks(ui, repo, **opts):
1778 def debuglocks(ui, repo, **opts):
1778 """show or modify state of locks
1779 """show or modify state of locks
1779
1780
1780 By default, this command will show which locks are held. This
1781 By default, this command will show which locks are held. This
1781 includes the user and process holding the lock, the amount of time
1782 includes the user and process holding the lock, the amount of time
1782 the lock has been held, and the machine name where the process is
1783 the lock has been held, and the machine name where the process is
1783 running if it's not local.
1784 running if it's not local.
1784
1785
1785 Locks protect the integrity of Mercurial's data, so should be
1786 Locks protect the integrity of Mercurial's data, so should be
1786 treated with care. System crashes or other interruptions may cause
1787 treated with care. System crashes or other interruptions may cause
1787 locks to not be properly released, though Mercurial will usually
1788 locks to not be properly released, though Mercurial will usually
1788 detect and remove such stale locks automatically.
1789 detect and remove such stale locks automatically.
1789
1790
1790 However, detecting stale locks may not always be possible (for
1791 However, detecting stale locks may not always be possible (for
1791 instance, on a shared filesystem). Removing locks may also be
1792 instance, on a shared filesystem). Removing locks may also be
1792 blocked by filesystem permissions.
1793 blocked by filesystem permissions.
1793
1794
1794 Setting a lock will prevent other commands from changing the data.
1795 Setting a lock will prevent other commands from changing the data.
1795 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1796 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1796 The set locks are removed when the command exits.
1797 The set locks are removed when the command exits.
1797
1798
1798 Returns 0 if no locks are held.
1799 Returns 0 if no locks are held.
1799
1800
1800 """
1801 """
1801
1802
1802 if opts.get('force_lock'):
1803 if opts.get('force_lock'):
1803 repo.svfs.unlink(b'lock')
1804 repo.svfs.unlink(b'lock')
1804 if opts.get('force_wlock'):
1805 if opts.get('force_wlock'):
1805 repo.vfs.unlink(b'wlock')
1806 repo.vfs.unlink(b'wlock')
1806 if opts.get('force_lock') or opts.get('force_wlock'):
1807 if opts.get('force_lock') or opts.get('force_wlock'):
1807 return 0
1808 return 0
1808
1809
1809 locks = []
1810 locks = []
1810 try:
1811 try:
1811 if opts.get('set_wlock'):
1812 if opts.get('set_wlock'):
1812 try:
1813 try:
1813 locks.append(repo.wlock(False))
1814 locks.append(repo.wlock(False))
1814 except error.LockHeld:
1815 except error.LockHeld:
1815 raise error.Abort(_(b'wlock is already held'))
1816 raise error.Abort(_(b'wlock is already held'))
1816 if opts.get('set_lock'):
1817 if opts.get('set_lock'):
1817 try:
1818 try:
1818 locks.append(repo.lock(False))
1819 locks.append(repo.lock(False))
1819 except error.LockHeld:
1820 except error.LockHeld:
1820 raise error.Abort(_(b'lock is already held'))
1821 raise error.Abort(_(b'lock is already held'))
1821 if len(locks):
1822 if len(locks):
1822 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1823 ui.promptchoice(_(b"ready to release the lock (y)? $$ &Yes"))
1823 return 0
1824 return 0
1824 finally:
1825 finally:
1825 release(*locks)
1826 release(*locks)
1826
1827
1827 now = time.time()
1828 now = time.time()
1828 held = 0
1829 held = 0
1829
1830
1830 def report(vfs, name, method):
1831 def report(vfs, name, method):
1831 # this causes stale locks to get reaped for more accurate reporting
1832 # this causes stale locks to get reaped for more accurate reporting
1832 try:
1833 try:
1833 l = method(False)
1834 l = method(False)
1834 except error.LockHeld:
1835 except error.LockHeld:
1835 l = None
1836 l = None
1836
1837
1837 if l:
1838 if l:
1838 l.release()
1839 l.release()
1839 else:
1840 else:
1840 try:
1841 try:
1841 st = vfs.lstat(name)
1842 st = vfs.lstat(name)
1842 age = now - st[stat.ST_MTIME]
1843 age = now - st[stat.ST_MTIME]
1843 user = util.username(st.st_uid)
1844 user = util.username(st.st_uid)
1844 locker = vfs.readlock(name)
1845 locker = vfs.readlock(name)
1845 if b":" in locker:
1846 if b":" in locker:
1846 host, pid = locker.split(b':')
1847 host, pid = locker.split(b':')
1847 if host == socket.gethostname():
1848 if host == socket.gethostname():
1848 locker = b'user %s, process %s' % (user or b'None', pid)
1849 locker = b'user %s, process %s' % (user or b'None', pid)
1849 else:
1850 else:
1850 locker = b'user %s, process %s, host %s' % (
1851 locker = b'user %s, process %s, host %s' % (
1851 user or b'None',
1852 user or b'None',
1852 pid,
1853 pid,
1853 host,
1854 host,
1854 )
1855 )
1855 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1856 ui.writenoi18n(b"%-6s %s (%ds)\n" % (name + b":", locker, age))
1856 return 1
1857 return 1
1857 except OSError as e:
1858 except OSError as e:
1858 if e.errno != errno.ENOENT:
1859 if e.errno != errno.ENOENT:
1859 raise
1860 raise
1860
1861
1861 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1862 ui.writenoi18n(b"%-6s free\n" % (name + b":"))
1862 return 0
1863 return 0
1863
1864
1864 held += report(repo.svfs, b"lock", repo.lock)
1865 held += report(repo.svfs, b"lock", repo.lock)
1865 held += report(repo.vfs, b"wlock", repo.wlock)
1866 held += report(repo.vfs, b"wlock", repo.wlock)
1866
1867
1867 return held
1868 return held
1868
1869
1869
1870
1870 @command(
1871 @command(
1871 b'debugmanifestfulltextcache',
1872 b'debugmanifestfulltextcache',
1872 [
1873 [
1873 (b'', b'clear', False, _(b'clear the cache')),
1874 (b'', b'clear', False, _(b'clear the cache')),
1874 (
1875 (
1875 b'a',
1876 b'a',
1876 b'add',
1877 b'add',
1877 [],
1878 [],
1878 _(b'add the given manifest nodes to the cache'),
1879 _(b'add the given manifest nodes to the cache'),
1879 _(b'NODE'),
1880 _(b'NODE'),
1880 ),
1881 ),
1881 ],
1882 ],
1882 b'',
1883 b'',
1883 )
1884 )
1884 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1885 def debugmanifestfulltextcache(ui, repo, add=(), **opts):
1885 """show, clear or amend the contents of the manifest fulltext cache"""
1886 """show, clear or amend the contents of the manifest fulltext cache"""
1886
1887
1887 def getcache():
1888 def getcache():
1888 r = repo.manifestlog.getstorage(b'')
1889 r = repo.manifestlog.getstorage(b'')
1889 try:
1890 try:
1890 return r._fulltextcache
1891 return r._fulltextcache
1891 except AttributeError:
1892 except AttributeError:
1892 msg = _(
1893 msg = _(
1893 b"Current revlog implementation doesn't appear to have a "
1894 b"Current revlog implementation doesn't appear to have a "
1894 b"manifest fulltext cache\n"
1895 b"manifest fulltext cache\n"
1895 )
1896 )
1896 raise error.Abort(msg)
1897 raise error.Abort(msg)
1897
1898
1898 if opts.get('clear'):
1899 if opts.get('clear'):
1899 with repo.wlock():
1900 with repo.wlock():
1900 cache = getcache()
1901 cache = getcache()
1901 cache.clear(clear_persisted_data=True)
1902 cache.clear(clear_persisted_data=True)
1902 return
1903 return
1903
1904
1904 if add:
1905 if add:
1905 with repo.wlock():
1906 with repo.wlock():
1906 m = repo.manifestlog
1907 m = repo.manifestlog
1907 store = m.getstorage(b'')
1908 store = m.getstorage(b'')
1908 for n in add:
1909 for n in add:
1909 try:
1910 try:
1910 manifest = m[store.lookup(n)]
1911 manifest = m[store.lookup(n)]
1911 except error.LookupError as e:
1912 except error.LookupError as e:
1912 raise error.Abort(e, hint=b"Check your manifest node id")
1913 raise error.Abort(e, hint=b"Check your manifest node id")
1913 manifest.read() # stores revisision in cache too
1914 manifest.read() # stores revisision in cache too
1914 return
1915 return
1915
1916
1916 cache = getcache()
1917 cache = getcache()
1917 if not len(cache):
1918 if not len(cache):
1918 ui.write(_(b'cache empty\n'))
1919 ui.write(_(b'cache empty\n'))
1919 else:
1920 else:
1920 ui.write(
1921 ui.write(
1921 _(
1922 _(
1922 b'cache contains %d manifest entries, in order of most to '
1923 b'cache contains %d manifest entries, in order of most to '
1923 b'least recent:\n'
1924 b'least recent:\n'
1924 )
1925 )
1925 % (len(cache),)
1926 % (len(cache),)
1926 )
1927 )
1927 totalsize = 0
1928 totalsize = 0
1928 for nodeid in cache:
1929 for nodeid in cache:
1929 # Use cache.get to not update the LRU order
1930 # Use cache.get to not update the LRU order
1930 data = cache.peek(nodeid)
1931 data = cache.peek(nodeid)
1931 size = len(data)
1932 size = len(data)
1932 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1933 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1933 ui.write(
1934 ui.write(
1934 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1935 _(b'id: %s, size %s\n') % (hex(nodeid), util.bytecount(size))
1935 )
1936 )
1936 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1937 ondisk = cache._opener.stat(b'manifestfulltextcache').st_size
1937 ui.write(
1938 ui.write(
1938 _(b'total cache data size %s, on-disk %s\n')
1939 _(b'total cache data size %s, on-disk %s\n')
1939 % (util.bytecount(totalsize), util.bytecount(ondisk))
1940 % (util.bytecount(totalsize), util.bytecount(ondisk))
1940 )
1941 )
1941
1942
1942
1943
1943 @command(b'debugmergestate', [], b'')
1944 @command(b'debugmergestate', [], b'')
1944 def debugmergestate(ui, repo, *args):
1945 def debugmergestate(ui, repo, *args):
1945 """print merge state
1946 """print merge state
1946
1947
1947 Use --verbose to print out information about whether v1 or v2 merge state
1948 Use --verbose to print out information about whether v1 or v2 merge state
1948 was chosen."""
1949 was chosen."""
1949
1950
1950 def _hashornull(h):
1951 def _hashornull(h):
1951 if h == nullhex:
1952 if h == nullhex:
1952 return b'null'
1953 return b'null'
1953 else:
1954 else:
1954 return h
1955 return h
1955
1956
1956 def printrecords(version):
1957 def printrecords(version):
1957 ui.writenoi18n(b'* version %d records\n' % version)
1958 ui.writenoi18n(b'* version %d records\n' % version)
1958 if version == 1:
1959 if version == 1:
1959 records = v1records
1960 records = v1records
1960 else:
1961 else:
1961 records = v2records
1962 records = v2records
1962
1963
1963 for rtype, record in records:
1964 for rtype, record in records:
1964 # pretty print some record types
1965 # pretty print some record types
1965 if rtype == b'L':
1966 if rtype == b'L':
1966 ui.writenoi18n(b'local: %s\n' % record)
1967 ui.writenoi18n(b'local: %s\n' % record)
1967 elif rtype == b'O':
1968 elif rtype == b'O':
1968 ui.writenoi18n(b'other: %s\n' % record)
1969 ui.writenoi18n(b'other: %s\n' % record)
1969 elif rtype == b'm':
1970 elif rtype == b'm':
1970 driver, mdstate = record.split(b'\0', 1)
1971 driver, mdstate = record.split(b'\0', 1)
1971 ui.writenoi18n(
1972 ui.writenoi18n(
1972 b'merge driver: %s (state "%s")\n' % (driver, mdstate)
1973 b'merge driver: %s (state "%s")\n' % (driver, mdstate)
1973 )
1974 )
1974 elif rtype in b'FDC':
1975 elif rtype in b'FDC':
1975 r = record.split(b'\0')
1976 r = record.split(b'\0')
1976 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1977 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1977 if version == 1:
1978 if version == 1:
1978 onode = b'not stored in v1 format'
1979 onode = b'not stored in v1 format'
1979 flags = r[7]
1980 flags = r[7]
1980 else:
1981 else:
1981 onode, flags = r[7:9]
1982 onode, flags = r[7:9]
1982 ui.writenoi18n(
1983 ui.writenoi18n(
1983 b'file: %s (record type "%s", state "%s", hash %s)\n'
1984 b'file: %s (record type "%s", state "%s", hash %s)\n'
1984 % (f, rtype, state, _hashornull(hash))
1985 % (f, rtype, state, _hashornull(hash))
1985 )
1986 )
1986 ui.writenoi18n(
1987 ui.writenoi18n(
1987 b' local path: %s (flags "%s")\n' % (lfile, flags)
1988 b' local path: %s (flags "%s")\n' % (lfile, flags)
1988 )
1989 )
1989 ui.writenoi18n(
1990 ui.writenoi18n(
1990 b' ancestor path: %s (node %s)\n'
1991 b' ancestor path: %s (node %s)\n'
1991 % (afile, _hashornull(anode))
1992 % (afile, _hashornull(anode))
1992 )
1993 )
1993 ui.writenoi18n(
1994 ui.writenoi18n(
1994 b' other path: %s (node %s)\n'
1995 b' other path: %s (node %s)\n'
1995 % (ofile, _hashornull(onode))
1996 % (ofile, _hashornull(onode))
1996 )
1997 )
1997 elif rtype == b'f':
1998 elif rtype == b'f':
1998 filename, rawextras = record.split(b'\0', 1)
1999 filename, rawextras = record.split(b'\0', 1)
1999 extras = rawextras.split(b'\0')
2000 extras = rawextras.split(b'\0')
2000 i = 0
2001 i = 0
2001 extrastrings = []
2002 extrastrings = []
2002 while i < len(extras):
2003 while i < len(extras):
2003 extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
2004 extrastrings.append(b'%s = %s' % (extras[i], extras[i + 1]))
2004 i += 2
2005 i += 2
2005
2006
2006 ui.writenoi18n(
2007 ui.writenoi18n(
2007 b'file extras: %s (%s)\n'
2008 b'file extras: %s (%s)\n'
2008 % (filename, b', '.join(extrastrings))
2009 % (filename, b', '.join(extrastrings))
2009 )
2010 )
2010 elif rtype == b'l':
2011 elif rtype == b'l':
2011 labels = record.split(b'\0', 2)
2012 labels = record.split(b'\0', 2)
2012 labels = [l for l in labels if len(l) > 0]
2013 labels = [l for l in labels if len(l) > 0]
2013 ui.writenoi18n(b'labels:\n')
2014 ui.writenoi18n(b'labels:\n')
2014 ui.write((b' local: %s\n' % labels[0]))
2015 ui.write((b' local: %s\n' % labels[0]))
2015 ui.write((b' other: %s\n' % labels[1]))
2016 ui.write((b' other: %s\n' % labels[1]))
2016 if len(labels) > 2:
2017 if len(labels) > 2:
2017 ui.write((b' base: %s\n' % labels[2]))
2018 ui.write((b' base: %s\n' % labels[2]))
2018 else:
2019 else:
2019 ui.writenoi18n(
2020 ui.writenoi18n(
2020 b'unrecognized entry: %s\t%s\n'
2021 b'unrecognized entry: %s\t%s\n'
2021 % (rtype, record.replace(b'\0', b'\t'))
2022 % (rtype, record.replace(b'\0', b'\t'))
2022 )
2023 )
2023
2024
2024 # Avoid mergestate.read() since it may raise an exception for unsupported
2025 # Avoid mergestate.read() since it may raise an exception for unsupported
2025 # merge state records. We shouldn't be doing this, but this is OK since this
2026 # merge state records. We shouldn't be doing this, but this is OK since this
2026 # command is pretty low-level.
2027 # command is pretty low-level.
2027 ms = mergemod.mergestate(repo)
2028 ms = mergemod.mergestate(repo)
2028
2029
2029 # sort so that reasonable information is on top
2030 # sort so that reasonable information is on top
2030 v1records = ms._readrecordsv1()
2031 v1records = ms._readrecordsv1()
2031 v2records = ms._readrecordsv2()
2032 v2records = ms._readrecordsv2()
2032 order = b'LOml'
2033 order = b'LOml'
2033
2034
2034 def key(r):
2035 def key(r):
2035 idx = order.find(r[0])
2036 idx = order.find(r[0])
2036 if idx == -1:
2037 if idx == -1:
2037 return (1, r[1])
2038 return (1, r[1])
2038 else:
2039 else:
2039 return (0, idx)
2040 return (0, idx)
2040
2041
2041 v1records.sort(key=key)
2042 v1records.sort(key=key)
2042 v2records.sort(key=key)
2043 v2records.sort(key=key)
2043
2044
2044 if not v1records and not v2records:
2045 if not v1records and not v2records:
2045 ui.writenoi18n(b'no merge state found\n')
2046 ui.writenoi18n(b'no merge state found\n')
2046 elif not v2records:
2047 elif not v2records:
2047 ui.notenoi18n(b'no version 2 merge state\n')
2048 ui.notenoi18n(b'no version 2 merge state\n')
2048 printrecords(1)
2049 printrecords(1)
2049 elif ms._v1v2match(v1records, v2records):
2050 elif ms._v1v2match(v1records, v2records):
2050 ui.notenoi18n(b'v1 and v2 states match: using v2\n')
2051 ui.notenoi18n(b'v1 and v2 states match: using v2\n')
2051 printrecords(2)
2052 printrecords(2)
2052 else:
2053 else:
2053 ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
2054 ui.notenoi18n(b'v1 and v2 states mismatch: using v1\n')
2054 printrecords(1)
2055 printrecords(1)
2055 if ui.verbose:
2056 if ui.verbose:
2056 printrecords(2)
2057 printrecords(2)
2057
2058
2058
2059
2059 @command(b'debugnamecomplete', [], _(b'NAME...'))
2060 @command(b'debugnamecomplete', [], _(b'NAME...'))
2060 def debugnamecomplete(ui, repo, *args):
2061 def debugnamecomplete(ui, repo, *args):
2061 '''complete "names" - tags, open branch names, bookmark names'''
2062 '''complete "names" - tags, open branch names, bookmark names'''
2062
2063
2063 names = set()
2064 names = set()
2064 # since we previously only listed open branches, we will handle that
2065 # since we previously only listed open branches, we will handle that
2065 # specially (after this for loop)
2066 # specially (after this for loop)
2066 for name, ns in pycompat.iteritems(repo.names):
2067 for name, ns in pycompat.iteritems(repo.names):
2067 if name != b'branches':
2068 if name != b'branches':
2068 names.update(ns.listnames(repo))
2069 names.update(ns.listnames(repo))
2069 names.update(
2070 names.update(
2070 tag
2071 tag
2071 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2072 for (tag, heads, tip, closed) in repo.branchmap().iterbranches()
2072 if not closed
2073 if not closed
2073 )
2074 )
2074 completions = set()
2075 completions = set()
2075 if not args:
2076 if not args:
2076 args = [b'']
2077 args = [b'']
2077 for a in args:
2078 for a in args:
2078 completions.update(n for n in names if n.startswith(a))
2079 completions.update(n for n in names if n.startswith(a))
2079 ui.write(b'\n'.join(sorted(completions)))
2080 ui.write(b'\n'.join(sorted(completions)))
2080 ui.write(b'\n')
2081 ui.write(b'\n')
2081
2082
2082
2083
2083 @command(
2084 @command(
2084 b'debugobsolete',
2085 b'debugobsolete',
2085 [
2086 [
2086 (b'', b'flags', 0, _(b'markers flag')),
2087 (b'', b'flags', 0, _(b'markers flag')),
2087 (
2088 (
2088 b'',
2089 b'',
2089 b'record-parents',
2090 b'record-parents',
2090 False,
2091 False,
2091 _(b'record parent information for the precursor'),
2092 _(b'record parent information for the precursor'),
2092 ),
2093 ),
2093 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2094 (b'r', b'rev', [], _(b'display markers relevant to REV')),
2094 (
2095 (
2095 b'',
2096 b'',
2096 b'exclusive',
2097 b'exclusive',
2097 False,
2098 False,
2098 _(b'restrict display to markers only relevant to REV'),
2099 _(b'restrict display to markers only relevant to REV'),
2099 ),
2100 ),
2100 (b'', b'index', False, _(b'display index of the marker')),
2101 (b'', b'index', False, _(b'display index of the marker')),
2101 (b'', b'delete', [], _(b'delete markers specified by indices')),
2102 (b'', b'delete', [], _(b'delete markers specified by indices')),
2102 ]
2103 ]
2103 + cmdutil.commitopts2
2104 + cmdutil.commitopts2
2104 + cmdutil.formatteropts,
2105 + cmdutil.formatteropts,
2105 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2106 _(b'[OBSOLETED [REPLACEMENT ...]]'),
2106 )
2107 )
2107 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2108 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2108 """create arbitrary obsolete marker
2109 """create arbitrary obsolete marker
2109
2110
2110 With no arguments, displays the list of obsolescence markers."""
2111 With no arguments, displays the list of obsolescence markers."""
2111
2112
2112 opts = pycompat.byteskwargs(opts)
2113 opts = pycompat.byteskwargs(opts)
2113
2114
2114 def parsenodeid(s):
2115 def parsenodeid(s):
2115 try:
2116 try:
2116 # We do not use revsingle/revrange functions here to accept
2117 # We do not use revsingle/revrange functions here to accept
2117 # arbitrary node identifiers, possibly not present in the
2118 # arbitrary node identifiers, possibly not present in the
2118 # local repository.
2119 # local repository.
2119 n = bin(s)
2120 n = bin(s)
2120 if len(n) != len(nullid):
2121 if len(n) != len(nullid):
2121 raise TypeError()
2122 raise TypeError()
2122 return n
2123 return n
2123 except TypeError:
2124 except TypeError:
2124 raise error.Abort(
2125 raise error.Abort(
2125 b'changeset references must be full hexadecimal '
2126 b'changeset references must be full hexadecimal '
2126 b'node identifiers'
2127 b'node identifiers'
2127 )
2128 )
2128
2129
2129 if opts.get(b'delete'):
2130 if opts.get(b'delete'):
2130 indices = []
2131 indices = []
2131 for v in opts.get(b'delete'):
2132 for v in opts.get(b'delete'):
2132 try:
2133 try:
2133 indices.append(int(v))
2134 indices.append(int(v))
2134 except ValueError:
2135 except ValueError:
2135 raise error.Abort(
2136 raise error.Abort(
2136 _(b'invalid index value: %r') % v,
2137 _(b'invalid index value: %r') % v,
2137 hint=_(b'use integers for indices'),
2138 hint=_(b'use integers for indices'),
2138 )
2139 )
2139
2140
2140 if repo.currenttransaction():
2141 if repo.currenttransaction():
2141 raise error.Abort(
2142 raise error.Abort(
2142 _(b'cannot delete obsmarkers in the middle of transaction.')
2143 _(b'cannot delete obsmarkers in the middle of transaction.')
2143 )
2144 )
2144
2145
2145 with repo.lock():
2146 with repo.lock():
2146 n = repair.deleteobsmarkers(repo.obsstore, indices)
2147 n = repair.deleteobsmarkers(repo.obsstore, indices)
2147 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2148 ui.write(_(b'deleted %i obsolescence markers\n') % n)
2148
2149
2149 return
2150 return
2150
2151
2151 if precursor is not None:
2152 if precursor is not None:
2152 if opts[b'rev']:
2153 if opts[b'rev']:
2153 raise error.Abort(b'cannot select revision when creating marker')
2154 raise error.Abort(b'cannot select revision when creating marker')
2154 metadata = {}
2155 metadata = {}
2155 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2156 metadata[b'user'] = encoding.fromlocal(opts[b'user'] or ui.username())
2156 succs = tuple(parsenodeid(succ) for succ in successors)
2157 succs = tuple(parsenodeid(succ) for succ in successors)
2157 l = repo.lock()
2158 l = repo.lock()
2158 try:
2159 try:
2159 tr = repo.transaction(b'debugobsolete')
2160 tr = repo.transaction(b'debugobsolete')
2160 try:
2161 try:
2161 date = opts.get(b'date')
2162 date = opts.get(b'date')
2162 if date:
2163 if date:
2163 date = dateutil.parsedate(date)
2164 date = dateutil.parsedate(date)
2164 else:
2165 else:
2165 date = None
2166 date = None
2166 prec = parsenodeid(precursor)
2167 prec = parsenodeid(precursor)
2167 parents = None
2168 parents = None
2168 if opts[b'record_parents']:
2169 if opts[b'record_parents']:
2169 if prec not in repo.unfiltered():
2170 if prec not in repo.unfiltered():
2170 raise error.Abort(
2171 raise error.Abort(
2171 b'cannot used --record-parents on '
2172 b'cannot used --record-parents on '
2172 b'unknown changesets'
2173 b'unknown changesets'
2173 )
2174 )
2174 parents = repo.unfiltered()[prec].parents()
2175 parents = repo.unfiltered()[prec].parents()
2175 parents = tuple(p.node() for p in parents)
2176 parents = tuple(p.node() for p in parents)
2176 repo.obsstore.create(
2177 repo.obsstore.create(
2177 tr,
2178 tr,
2178 prec,
2179 prec,
2179 succs,
2180 succs,
2180 opts[b'flags'],
2181 opts[b'flags'],
2181 parents=parents,
2182 parents=parents,
2182 date=date,
2183 date=date,
2183 metadata=metadata,
2184 metadata=metadata,
2184 ui=ui,
2185 ui=ui,
2185 )
2186 )
2186 tr.close()
2187 tr.close()
2187 except ValueError as exc:
2188 except ValueError as exc:
2188 raise error.Abort(
2189 raise error.Abort(
2189 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2190 _(b'bad obsmarker input: %s') % pycompat.bytestr(exc)
2190 )
2191 )
2191 finally:
2192 finally:
2192 tr.release()
2193 tr.release()
2193 finally:
2194 finally:
2194 l.release()
2195 l.release()
2195 else:
2196 else:
2196 if opts[b'rev']:
2197 if opts[b'rev']:
2197 revs = scmutil.revrange(repo, opts[b'rev'])
2198 revs = scmutil.revrange(repo, opts[b'rev'])
2198 nodes = [repo[r].node() for r in revs]
2199 nodes = [repo[r].node() for r in revs]
2199 markers = list(
2200 markers = list(
2200 obsutil.getmarkers(
2201 obsutil.getmarkers(
2201 repo, nodes=nodes, exclusive=opts[b'exclusive']
2202 repo, nodes=nodes, exclusive=opts[b'exclusive']
2202 )
2203 )
2203 )
2204 )
2204 markers.sort(key=lambda x: x._data)
2205 markers.sort(key=lambda x: x._data)
2205 else:
2206 else:
2206 markers = obsutil.getmarkers(repo)
2207 markers = obsutil.getmarkers(repo)
2207
2208
2208 markerstoiter = markers
2209 markerstoiter = markers
2209 isrelevant = lambda m: True
2210 isrelevant = lambda m: True
2210 if opts.get(b'rev') and opts.get(b'index'):
2211 if opts.get(b'rev') and opts.get(b'index'):
2211 markerstoiter = obsutil.getmarkers(repo)
2212 markerstoiter = obsutil.getmarkers(repo)
2212 markerset = set(markers)
2213 markerset = set(markers)
2213 isrelevant = lambda m: m in markerset
2214 isrelevant = lambda m: m in markerset
2214
2215
2215 fm = ui.formatter(b'debugobsolete', opts)
2216 fm = ui.formatter(b'debugobsolete', opts)
2216 for i, m in enumerate(markerstoiter):
2217 for i, m in enumerate(markerstoiter):
2217 if not isrelevant(m):
2218 if not isrelevant(m):
2218 # marker can be irrelevant when we're iterating over a set
2219 # marker can be irrelevant when we're iterating over a set
2219 # of markers (markerstoiter) which is bigger than the set
2220 # of markers (markerstoiter) which is bigger than the set
2220 # of markers we want to display (markers)
2221 # of markers we want to display (markers)
2221 # this can happen if both --index and --rev options are
2222 # this can happen if both --index and --rev options are
2222 # provided and thus we need to iterate over all of the markers
2223 # provided and thus we need to iterate over all of the markers
2223 # to get the correct indices, but only display the ones that
2224 # to get the correct indices, but only display the ones that
2224 # are relevant to --rev value
2225 # are relevant to --rev value
2225 continue
2226 continue
2226 fm.startitem()
2227 fm.startitem()
2227 ind = i if opts.get(b'index') else None
2228 ind = i if opts.get(b'index') else None
2228 cmdutil.showmarker(fm, m, index=ind)
2229 cmdutil.showmarker(fm, m, index=ind)
2229 fm.end()
2230 fm.end()
2230
2231
2231
2232
2232 @command(
2233 @command(
2233 b'debugp1copies',
2234 b'debugp1copies',
2234 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2235 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2235 _(b'[-r REV]'),
2236 _(b'[-r REV]'),
2236 )
2237 )
2237 def debugp1copies(ui, repo, **opts):
2238 def debugp1copies(ui, repo, **opts):
2238 """dump copy information compared to p1"""
2239 """dump copy information compared to p1"""
2239
2240
2240 opts = pycompat.byteskwargs(opts)
2241 opts = pycompat.byteskwargs(opts)
2241 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2242 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2242 for dst, src in ctx.p1copies().items():
2243 for dst, src in ctx.p1copies().items():
2243 ui.write(b'%s -> %s\n' % (src, dst))
2244 ui.write(b'%s -> %s\n' % (src, dst))
2244
2245
2245
2246
2246 @command(
2247 @command(
2247 b'debugp2copies',
2248 b'debugp2copies',
2248 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2249 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2249 _(b'[-r REV]'),
2250 _(b'[-r REV]'),
2250 )
2251 )
2251 def debugp1copies(ui, repo, **opts):
2252 def debugp1copies(ui, repo, **opts):
2252 """dump copy information compared to p2"""
2253 """dump copy information compared to p2"""
2253
2254
2254 opts = pycompat.byteskwargs(opts)
2255 opts = pycompat.byteskwargs(opts)
2255 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2256 ctx = scmutil.revsingle(repo, opts.get(b'rev'), default=None)
2256 for dst, src in ctx.p2copies().items():
2257 for dst, src in ctx.p2copies().items():
2257 ui.write(b'%s -> %s\n' % (src, dst))
2258 ui.write(b'%s -> %s\n' % (src, dst))
2258
2259
2259
2260
2260 @command(
2261 @command(
2261 b'debugpathcomplete',
2262 b'debugpathcomplete',
2262 [
2263 [
2263 (b'f', b'full', None, _(b'complete an entire path')),
2264 (b'f', b'full', None, _(b'complete an entire path')),
2264 (b'n', b'normal', None, _(b'show only normal files')),
2265 (b'n', b'normal', None, _(b'show only normal files')),
2265 (b'a', b'added', None, _(b'show only added files')),
2266 (b'a', b'added', None, _(b'show only added files')),
2266 (b'r', b'removed', None, _(b'show only removed files')),
2267 (b'r', b'removed', None, _(b'show only removed files')),
2267 ],
2268 ],
2268 _(b'FILESPEC...'),
2269 _(b'FILESPEC...'),
2269 )
2270 )
2270 def debugpathcomplete(ui, repo, *specs, **opts):
2271 def debugpathcomplete(ui, repo, *specs, **opts):
2271 '''complete part or all of a tracked path
2272 '''complete part or all of a tracked path
2272
2273
2273 This command supports shells that offer path name completion. It
2274 This command supports shells that offer path name completion. It
2274 currently completes only files already known to the dirstate.
2275 currently completes only files already known to the dirstate.
2275
2276
2276 Completion extends only to the next path segment unless
2277 Completion extends only to the next path segment unless
2277 --full is specified, in which case entire paths are used.'''
2278 --full is specified, in which case entire paths are used.'''
2278
2279
2279 def complete(path, acceptable):
2280 def complete(path, acceptable):
2280 dirstate = repo.dirstate
2281 dirstate = repo.dirstate
2281 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2282 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
2282 rootdir = repo.root + pycompat.ossep
2283 rootdir = repo.root + pycompat.ossep
2283 if spec != repo.root and not spec.startswith(rootdir):
2284 if spec != repo.root and not spec.startswith(rootdir):
2284 return [], []
2285 return [], []
2285 if os.path.isdir(spec):
2286 if os.path.isdir(spec):
2286 spec += b'/'
2287 spec += b'/'
2287 spec = spec[len(rootdir) :]
2288 spec = spec[len(rootdir) :]
2288 fixpaths = pycompat.ossep != b'/'
2289 fixpaths = pycompat.ossep != b'/'
2289 if fixpaths:
2290 if fixpaths:
2290 spec = spec.replace(pycompat.ossep, b'/')
2291 spec = spec.replace(pycompat.ossep, b'/')
2291 speclen = len(spec)
2292 speclen = len(spec)
2292 fullpaths = opts['full']
2293 fullpaths = opts['full']
2293 files, dirs = set(), set()
2294 files, dirs = set(), set()
2294 adddir, addfile = dirs.add, files.add
2295 adddir, addfile = dirs.add, files.add
2295 for f, st in pycompat.iteritems(dirstate):
2296 for f, st in pycompat.iteritems(dirstate):
2296 if f.startswith(spec) and st[0] in acceptable:
2297 if f.startswith(spec) and st[0] in acceptable:
2297 if fixpaths:
2298 if fixpaths:
2298 f = f.replace(b'/', pycompat.ossep)
2299 f = f.replace(b'/', pycompat.ossep)
2299 if fullpaths:
2300 if fullpaths:
2300 addfile(f)
2301 addfile(f)
2301 continue
2302 continue
2302 s = f.find(pycompat.ossep, speclen)
2303 s = f.find(pycompat.ossep, speclen)
2303 if s >= 0:
2304 if s >= 0:
2304 adddir(f[:s])
2305 adddir(f[:s])
2305 else:
2306 else:
2306 addfile(f)
2307 addfile(f)
2307 return files, dirs
2308 return files, dirs
2308
2309
2309 acceptable = b''
2310 acceptable = b''
2310 if opts['normal']:
2311 if opts['normal']:
2311 acceptable += b'nm'
2312 acceptable += b'nm'
2312 if opts['added']:
2313 if opts['added']:
2313 acceptable += b'a'
2314 acceptable += b'a'
2314 if opts['removed']:
2315 if opts['removed']:
2315 acceptable += b'r'
2316 acceptable += b'r'
2316 cwd = repo.getcwd()
2317 cwd = repo.getcwd()
2317 if not specs:
2318 if not specs:
2318 specs = [b'.']
2319 specs = [b'.']
2319
2320
2320 files, dirs = set(), set()
2321 files, dirs = set(), set()
2321 for spec in specs:
2322 for spec in specs:
2322 f, d = complete(spec, acceptable or b'nmar')
2323 f, d = complete(spec, acceptable or b'nmar')
2323 files.update(f)
2324 files.update(f)
2324 dirs.update(d)
2325 dirs.update(d)
2325 files.update(dirs)
2326 files.update(dirs)
2326 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2327 ui.write(b'\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2327 ui.write(b'\n')
2328 ui.write(b'\n')
2328
2329
2329
2330
2330 @command(
2331 @command(
2331 b'debugpathcopies',
2332 b'debugpathcopies',
2332 cmdutil.walkopts,
2333 cmdutil.walkopts,
2333 b'hg debugpathcopies REV1 REV2 [FILE]',
2334 b'hg debugpathcopies REV1 REV2 [FILE]',
2334 inferrepo=True,
2335 inferrepo=True,
2335 )
2336 )
2336 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2337 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts):
2337 """show copies between two revisions"""
2338 """show copies between two revisions"""
2338 ctx1 = scmutil.revsingle(repo, rev1)
2339 ctx1 = scmutil.revsingle(repo, rev1)
2339 ctx2 = scmutil.revsingle(repo, rev2)
2340 ctx2 = scmutil.revsingle(repo, rev2)
2340 m = scmutil.match(ctx1, pats, opts)
2341 m = scmutil.match(ctx1, pats, opts)
2341 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2342 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()):
2342 ui.write(b'%s -> %s\n' % (src, dst))
2343 ui.write(b'%s -> %s\n' % (src, dst))
2343
2344
2344
2345
2345 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2346 @command(b'debugpeer', [], _(b'PATH'), norepo=True)
2346 def debugpeer(ui, path):
2347 def debugpeer(ui, path):
2347 """establish a connection to a peer repository"""
2348 """establish a connection to a peer repository"""
2348 # Always enable peer request logging. Requires --debug to display
2349 # Always enable peer request logging. Requires --debug to display
2349 # though.
2350 # though.
2350 overrides = {
2351 overrides = {
2351 (b'devel', b'debug.peer-request'): True,
2352 (b'devel', b'debug.peer-request'): True,
2352 }
2353 }
2353
2354
2354 with ui.configoverride(overrides):
2355 with ui.configoverride(overrides):
2355 peer = hg.peer(ui, {}, path)
2356 peer = hg.peer(ui, {}, path)
2356
2357
2357 local = peer.local() is not None
2358 local = peer.local() is not None
2358 canpush = peer.canpush()
2359 canpush = peer.canpush()
2359
2360
2360 ui.write(_(b'url: %s\n') % peer.url())
2361 ui.write(_(b'url: %s\n') % peer.url())
2361 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2362 ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
2362 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2363 ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
2363
2364
2364
2365
2365 @command(
2366 @command(
2366 b'debugpickmergetool',
2367 b'debugpickmergetool',
2367 [
2368 [
2368 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2369 (b'r', b'rev', b'', _(b'check for files in this revision'), _(b'REV')),
2369 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2370 (b'', b'changedelete', None, _(b'emulate merging change and delete')),
2370 ]
2371 ]
2371 + cmdutil.walkopts
2372 + cmdutil.walkopts
2372 + cmdutil.mergetoolopts,
2373 + cmdutil.mergetoolopts,
2373 _(b'[PATTERN]...'),
2374 _(b'[PATTERN]...'),
2374 inferrepo=True,
2375 inferrepo=True,
2375 )
2376 )
2376 def debugpickmergetool(ui, repo, *pats, **opts):
2377 def debugpickmergetool(ui, repo, *pats, **opts):
2377 """examine which merge tool is chosen for specified file
2378 """examine which merge tool is chosen for specified file
2378
2379
2379 As described in :hg:`help merge-tools`, Mercurial examines
2380 As described in :hg:`help merge-tools`, Mercurial examines
2380 configurations below in this order to decide which merge tool is
2381 configurations below in this order to decide which merge tool is
2381 chosen for specified file.
2382 chosen for specified file.
2382
2383
2383 1. ``--tool`` option
2384 1. ``--tool`` option
2384 2. ``HGMERGE`` environment variable
2385 2. ``HGMERGE`` environment variable
2385 3. configurations in ``merge-patterns`` section
2386 3. configurations in ``merge-patterns`` section
2386 4. configuration of ``ui.merge``
2387 4. configuration of ``ui.merge``
2387 5. configurations in ``merge-tools`` section
2388 5. configurations in ``merge-tools`` section
2388 6. ``hgmerge`` tool (for historical reason only)
2389 6. ``hgmerge`` tool (for historical reason only)
2389 7. default tool for fallback (``:merge`` or ``:prompt``)
2390 7. default tool for fallback (``:merge`` or ``:prompt``)
2390
2391
2391 This command writes out examination result in the style below::
2392 This command writes out examination result in the style below::
2392
2393
2393 FILE = MERGETOOL
2394 FILE = MERGETOOL
2394
2395
2395 By default, all files known in the first parent context of the
2396 By default, all files known in the first parent context of the
2396 working directory are examined. Use file patterns and/or -I/-X
2397 working directory are examined. Use file patterns and/or -I/-X
2397 options to limit target files. -r/--rev is also useful to examine
2398 options to limit target files. -r/--rev is also useful to examine
2398 files in another context without actual updating to it.
2399 files in another context without actual updating to it.
2399
2400
2400 With --debug, this command shows warning messages while matching
2401 With --debug, this command shows warning messages while matching
2401 against ``merge-patterns`` and so on, too. It is recommended to
2402 against ``merge-patterns`` and so on, too. It is recommended to
2402 use this option with explicit file patterns and/or -I/-X options,
2403 use this option with explicit file patterns and/or -I/-X options,
2403 because this option increases amount of output per file according
2404 because this option increases amount of output per file according
2404 to configurations in hgrc.
2405 to configurations in hgrc.
2405
2406
2406 With -v/--verbose, this command shows configurations below at
2407 With -v/--verbose, this command shows configurations below at
2407 first (only if specified).
2408 first (only if specified).
2408
2409
2409 - ``--tool`` option
2410 - ``--tool`` option
2410 - ``HGMERGE`` environment variable
2411 - ``HGMERGE`` environment variable
2411 - configuration of ``ui.merge``
2412 - configuration of ``ui.merge``
2412
2413
2413 If merge tool is chosen before matching against
2414 If merge tool is chosen before matching against
2414 ``merge-patterns``, this command can't show any helpful
2415 ``merge-patterns``, this command can't show any helpful
2415 information, even with --debug. In such case, information above is
2416 information, even with --debug. In such case, information above is
2416 useful to know why a merge tool is chosen.
2417 useful to know why a merge tool is chosen.
2417 """
2418 """
2418 opts = pycompat.byteskwargs(opts)
2419 opts = pycompat.byteskwargs(opts)
2419 overrides = {}
2420 overrides = {}
2420 if opts[b'tool']:
2421 if opts[b'tool']:
2421 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2422 overrides[(b'ui', b'forcemerge')] = opts[b'tool']
2422 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2423 ui.notenoi18n(b'with --tool %r\n' % (pycompat.bytestr(opts[b'tool'])))
2423
2424
2424 with ui.configoverride(overrides, b'debugmergepatterns'):
2425 with ui.configoverride(overrides, b'debugmergepatterns'):
2425 hgmerge = encoding.environ.get(b"HGMERGE")
2426 hgmerge = encoding.environ.get(b"HGMERGE")
2426 if hgmerge is not None:
2427 if hgmerge is not None:
2427 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2428 ui.notenoi18n(b'with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge)))
2428 uimerge = ui.config(b"ui", b"merge")
2429 uimerge = ui.config(b"ui", b"merge")
2429 if uimerge:
2430 if uimerge:
2430 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2431 ui.notenoi18n(b'with ui.merge=%r\n' % (pycompat.bytestr(uimerge)))
2431
2432
2432 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2433 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2433 m = scmutil.match(ctx, pats, opts)
2434 m = scmutil.match(ctx, pats, opts)
2434 changedelete = opts[b'changedelete']
2435 changedelete = opts[b'changedelete']
2435 for path in ctx.walk(m):
2436 for path in ctx.walk(m):
2436 fctx = ctx[path]
2437 fctx = ctx[path]
2437 try:
2438 try:
2438 if not ui.debugflag:
2439 if not ui.debugflag:
2439 ui.pushbuffer(error=True)
2440 ui.pushbuffer(error=True)
2440 tool, toolpath = filemerge._picktool(
2441 tool, toolpath = filemerge._picktool(
2441 repo,
2442 repo,
2442 ui,
2443 ui,
2443 path,
2444 path,
2444 fctx.isbinary(),
2445 fctx.isbinary(),
2445 b'l' in fctx.flags(),
2446 b'l' in fctx.flags(),
2446 changedelete,
2447 changedelete,
2447 )
2448 )
2448 finally:
2449 finally:
2449 if not ui.debugflag:
2450 if not ui.debugflag:
2450 ui.popbuffer()
2451 ui.popbuffer()
2451 ui.write(b'%s = %s\n' % (path, tool))
2452 ui.write(b'%s = %s\n' % (path, tool))
2452
2453
2453
2454
2454 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2455 @command(b'debugpushkey', [], _(b'REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2455 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2456 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2456 '''access the pushkey key/value protocol
2457 '''access the pushkey key/value protocol
2457
2458
2458 With two args, list the keys in the given namespace.
2459 With two args, list the keys in the given namespace.
2459
2460
2460 With five args, set a key to new if it currently is set to old.
2461 With five args, set a key to new if it currently is set to old.
2461 Reports success or failure.
2462 Reports success or failure.
2462 '''
2463 '''
2463
2464
2464 target = hg.peer(ui, {}, repopath)
2465 target = hg.peer(ui, {}, repopath)
2465 if keyinfo:
2466 if keyinfo:
2466 key, old, new = keyinfo
2467 key, old, new = keyinfo
2467 with target.commandexecutor() as e:
2468 with target.commandexecutor() as e:
2468 r = e.callcommand(
2469 r = e.callcommand(
2469 b'pushkey',
2470 b'pushkey',
2470 {
2471 {
2471 b'namespace': namespace,
2472 b'namespace': namespace,
2472 b'key': key,
2473 b'key': key,
2473 b'old': old,
2474 b'old': old,
2474 b'new': new,
2475 b'new': new,
2475 },
2476 },
2476 ).result()
2477 ).result()
2477
2478
2478 ui.status(pycompat.bytestr(r) + b'\n')
2479 ui.status(pycompat.bytestr(r) + b'\n')
2479 return not r
2480 return not r
2480 else:
2481 else:
2481 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2482 for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
2482 ui.write(
2483 ui.write(
2483 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2484 b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
2484 )
2485 )
2485
2486
2486
2487
2487 @command(b'debugpvec', [], _(b'A B'))
2488 @command(b'debugpvec', [], _(b'A B'))
2488 def debugpvec(ui, repo, a, b=None):
2489 def debugpvec(ui, repo, a, b=None):
2489 ca = scmutil.revsingle(repo, a)
2490 ca = scmutil.revsingle(repo, a)
2490 cb = scmutil.revsingle(repo, b)
2491 cb = scmutil.revsingle(repo, b)
2491 pa = pvec.ctxpvec(ca)
2492 pa = pvec.ctxpvec(ca)
2492 pb = pvec.ctxpvec(cb)
2493 pb = pvec.ctxpvec(cb)
2493 if pa == pb:
2494 if pa == pb:
2494 rel = b"="
2495 rel = b"="
2495 elif pa > pb:
2496 elif pa > pb:
2496 rel = b">"
2497 rel = b">"
2497 elif pa < pb:
2498 elif pa < pb:
2498 rel = b"<"
2499 rel = b"<"
2499 elif pa | pb:
2500 elif pa | pb:
2500 rel = b"|"
2501 rel = b"|"
2501 ui.write(_(b"a: %s\n") % pa)
2502 ui.write(_(b"a: %s\n") % pa)
2502 ui.write(_(b"b: %s\n") % pb)
2503 ui.write(_(b"b: %s\n") % pb)
2503 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2504 ui.write(_(b"depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2504 ui.write(
2505 ui.write(
2505 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2506 _(b"delta: %d hdist: %d distance: %d relation: %s\n")
2506 % (
2507 % (
2507 abs(pa._depth - pb._depth),
2508 abs(pa._depth - pb._depth),
2508 pvec._hamming(pa._vec, pb._vec),
2509 pvec._hamming(pa._vec, pb._vec),
2509 pa.distance(pb),
2510 pa.distance(pb),
2510 rel,
2511 rel,
2511 )
2512 )
2512 )
2513 )
2513
2514
2514
2515
2515 @command(
2516 @command(
2516 b'debugrebuilddirstate|debugrebuildstate',
2517 b'debugrebuilddirstate|debugrebuildstate',
2517 [
2518 [
2518 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2519 (b'r', b'rev', b'', _(b'revision to rebuild to'), _(b'REV')),
2519 (
2520 (
2520 b'',
2521 b'',
2521 b'minimal',
2522 b'minimal',
2522 None,
2523 None,
2523 _(
2524 _(
2524 b'only rebuild files that are inconsistent with '
2525 b'only rebuild files that are inconsistent with '
2525 b'the working copy parent'
2526 b'the working copy parent'
2526 ),
2527 ),
2527 ),
2528 ),
2528 ],
2529 ],
2529 _(b'[-r REV]'),
2530 _(b'[-r REV]'),
2530 )
2531 )
2531 def debugrebuilddirstate(ui, repo, rev, **opts):
2532 def debugrebuilddirstate(ui, repo, rev, **opts):
2532 """rebuild the dirstate as it would look like for the given revision
2533 """rebuild the dirstate as it would look like for the given revision
2533
2534
2534 If no revision is specified the first current parent will be used.
2535 If no revision is specified the first current parent will be used.
2535
2536
2536 The dirstate will be set to the files of the given revision.
2537 The dirstate will be set to the files of the given revision.
2537 The actual working directory content or existing dirstate
2538 The actual working directory content or existing dirstate
2538 information such as adds or removes is not considered.
2539 information such as adds or removes is not considered.
2539
2540
2540 ``minimal`` will only rebuild the dirstate status for files that claim to be
2541 ``minimal`` will only rebuild the dirstate status for files that claim to be
2541 tracked but are not in the parent manifest, or that exist in the parent
2542 tracked but are not in the parent manifest, or that exist in the parent
2542 manifest but are not in the dirstate. It will not change adds, removes, or
2543 manifest but are not in the dirstate. It will not change adds, removes, or
2543 modified files that are in the working copy parent.
2544 modified files that are in the working copy parent.
2544
2545
2545 One use of this command is to make the next :hg:`status` invocation
2546 One use of this command is to make the next :hg:`status` invocation
2546 check the actual file content.
2547 check the actual file content.
2547 """
2548 """
2548 ctx = scmutil.revsingle(repo, rev)
2549 ctx = scmutil.revsingle(repo, rev)
2549 with repo.wlock():
2550 with repo.wlock():
2550 dirstate = repo.dirstate
2551 dirstate = repo.dirstate
2551 changedfiles = None
2552 changedfiles = None
2552 # See command doc for what minimal does.
2553 # See command doc for what minimal does.
2553 if opts.get('minimal'):
2554 if opts.get('minimal'):
2554 manifestfiles = set(ctx.manifest().keys())
2555 manifestfiles = set(ctx.manifest().keys())
2555 dirstatefiles = set(dirstate)
2556 dirstatefiles = set(dirstate)
2556 manifestonly = manifestfiles - dirstatefiles
2557 manifestonly = manifestfiles - dirstatefiles
2557 dsonly = dirstatefiles - manifestfiles
2558 dsonly = dirstatefiles - manifestfiles
2558 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2559 dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
2559 changedfiles = manifestonly | dsnotadded
2560 changedfiles = manifestonly | dsnotadded
2560
2561
2561 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2562 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2562
2563
2563
2564
2564 @command(b'debugrebuildfncache', [], b'')
2565 @command(b'debugrebuildfncache', [], b'')
2565 def debugrebuildfncache(ui, repo):
2566 def debugrebuildfncache(ui, repo):
2566 """rebuild the fncache file"""
2567 """rebuild the fncache file"""
2567 repair.rebuildfncache(ui, repo)
2568 repair.rebuildfncache(ui, repo)
2568
2569
2569
2570
2570 @command(
2571 @command(
2571 b'debugrename',
2572 b'debugrename',
2572 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2573 [(b'r', b'rev', b'', _(b'revision to debug'), _(b'REV'))],
2573 _(b'[-r REV] [FILE]...'),
2574 _(b'[-r REV] [FILE]...'),
2574 )
2575 )
2575 def debugrename(ui, repo, *pats, **opts):
2576 def debugrename(ui, repo, *pats, **opts):
2576 """dump rename information"""
2577 """dump rename information"""
2577
2578
2578 opts = pycompat.byteskwargs(opts)
2579 opts = pycompat.byteskwargs(opts)
2579 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2580 ctx = scmutil.revsingle(repo, opts.get(b'rev'))
2580 m = scmutil.match(ctx, pats, opts)
2581 m = scmutil.match(ctx, pats, opts)
2581 for abs in ctx.walk(m):
2582 for abs in ctx.walk(m):
2582 fctx = ctx[abs]
2583 fctx = ctx[abs]
2583 o = fctx.filelog().renamed(fctx.filenode())
2584 o = fctx.filelog().renamed(fctx.filenode())
2584 rel = repo.pathto(abs)
2585 rel = repo.pathto(abs)
2585 if o:
2586 if o:
2586 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2587 ui.write(_(b"%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2587 else:
2588 else:
2588 ui.write(_(b"%s not renamed\n") % rel)
2589 ui.write(_(b"%s not renamed\n") % rel)
2589
2590
2590
2591
2591 @command(
2592 @command(
2592 b'debugrevlog',
2593 b'debugrevlog',
2593 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2594 cmdutil.debugrevlogopts + [(b'd', b'dump', False, _(b'dump index data'))],
2594 _(b'-c|-m|FILE'),
2595 _(b'-c|-m|FILE'),
2595 optionalrepo=True,
2596 optionalrepo=True,
2596 )
2597 )
2597 def debugrevlog(ui, repo, file_=None, **opts):
2598 def debugrevlog(ui, repo, file_=None, **opts):
2598 """show data and statistics about a revlog"""
2599 """show data and statistics about a revlog"""
2599 opts = pycompat.byteskwargs(opts)
2600 opts = pycompat.byteskwargs(opts)
2600 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2601 r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
2601
2602
2602 if opts.get(b"dump"):
2603 if opts.get(b"dump"):
2603 numrevs = len(r)
2604 numrevs = len(r)
2604 ui.write(
2605 ui.write(
2605 (
2606 (
2606 b"# rev p1rev p2rev start end deltastart base p1 p2"
2607 b"# rev p1rev p2rev start end deltastart base p1 p2"
2607 b" rawsize totalsize compression heads chainlen\n"
2608 b" rawsize totalsize compression heads chainlen\n"
2608 )
2609 )
2609 )
2610 )
2610 ts = 0
2611 ts = 0
2611 heads = set()
2612 heads = set()
2612
2613
2613 for rev in pycompat.xrange(numrevs):
2614 for rev in pycompat.xrange(numrevs):
2614 dbase = r.deltaparent(rev)
2615 dbase = r.deltaparent(rev)
2615 if dbase == -1:
2616 if dbase == -1:
2616 dbase = rev
2617 dbase = rev
2617 cbase = r.chainbase(rev)
2618 cbase = r.chainbase(rev)
2618 clen = r.chainlen(rev)
2619 clen = r.chainlen(rev)
2619 p1, p2 = r.parentrevs(rev)
2620 p1, p2 = r.parentrevs(rev)
2620 rs = r.rawsize(rev)
2621 rs = r.rawsize(rev)
2621 ts = ts + rs
2622 ts = ts + rs
2622 heads -= set(r.parentrevs(rev))
2623 heads -= set(r.parentrevs(rev))
2623 heads.add(rev)
2624 heads.add(rev)
2624 try:
2625 try:
2625 compression = ts / r.end(rev)
2626 compression = ts / r.end(rev)
2626 except ZeroDivisionError:
2627 except ZeroDivisionError:
2627 compression = 0
2628 compression = 0
2628 ui.write(
2629 ui.write(
2629 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2630 b"%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2630 b"%11d %5d %8d\n"
2631 b"%11d %5d %8d\n"
2631 % (
2632 % (
2632 rev,
2633 rev,
2633 p1,
2634 p1,
2634 p2,
2635 p2,
2635 r.start(rev),
2636 r.start(rev),
2636 r.end(rev),
2637 r.end(rev),
2637 r.start(dbase),
2638 r.start(dbase),
2638 r.start(cbase),
2639 r.start(cbase),
2639 r.start(p1),
2640 r.start(p1),
2640 r.start(p2),
2641 r.start(p2),
2641 rs,
2642 rs,
2642 ts,
2643 ts,
2643 compression,
2644 compression,
2644 len(heads),
2645 len(heads),
2645 clen,
2646 clen,
2646 )
2647 )
2647 )
2648 )
2648 return 0
2649 return 0
2649
2650
2650 v = r.version
2651 v = r.version
2651 format = v & 0xFFFF
2652 format = v & 0xFFFF
2652 flags = []
2653 flags = []
2653 gdelta = False
2654 gdelta = False
2654 if v & revlog.FLAG_INLINE_DATA:
2655 if v & revlog.FLAG_INLINE_DATA:
2655 flags.append(b'inline')
2656 flags.append(b'inline')
2656 if v & revlog.FLAG_GENERALDELTA:
2657 if v & revlog.FLAG_GENERALDELTA:
2657 gdelta = True
2658 gdelta = True
2658 flags.append(b'generaldelta')
2659 flags.append(b'generaldelta')
2659 if not flags:
2660 if not flags:
2660 flags = [b'(none)']
2661 flags = [b'(none)']
2661
2662
2662 ### tracks merge vs single parent
2663 ### tracks merge vs single parent
2663 nummerges = 0
2664 nummerges = 0
2664
2665
2665 ### tracks ways the "delta" are build
2666 ### tracks ways the "delta" are build
2666 # nodelta
2667 # nodelta
2667 numempty = 0
2668 numempty = 0
2668 numemptytext = 0
2669 numemptytext = 0
2669 numemptydelta = 0
2670 numemptydelta = 0
2670 # full file content
2671 # full file content
2671 numfull = 0
2672 numfull = 0
2672 # intermediate snapshot against a prior snapshot
2673 # intermediate snapshot against a prior snapshot
2673 numsemi = 0
2674 numsemi = 0
2674 # snapshot count per depth
2675 # snapshot count per depth
2675 numsnapdepth = collections.defaultdict(lambda: 0)
2676 numsnapdepth = collections.defaultdict(lambda: 0)
2676 # delta against previous revision
2677 # delta against previous revision
2677 numprev = 0
2678 numprev = 0
2678 # delta against first or second parent (not prev)
2679 # delta against first or second parent (not prev)
2679 nump1 = 0
2680 nump1 = 0
2680 nump2 = 0
2681 nump2 = 0
2681 # delta against neither prev nor parents
2682 # delta against neither prev nor parents
2682 numother = 0
2683 numother = 0
2683 # delta against prev that are also first or second parent
2684 # delta against prev that are also first or second parent
2684 # (details of `numprev`)
2685 # (details of `numprev`)
2685 nump1prev = 0
2686 nump1prev = 0
2686 nump2prev = 0
2687 nump2prev = 0
2687
2688
2688 # data about delta chain of each revs
2689 # data about delta chain of each revs
2689 chainlengths = []
2690 chainlengths = []
2690 chainbases = []
2691 chainbases = []
2691 chainspans = []
2692 chainspans = []
2692
2693
2693 # data about each revision
2694 # data about each revision
2694 datasize = [None, 0, 0]
2695 datasize = [None, 0, 0]
2695 fullsize = [None, 0, 0]
2696 fullsize = [None, 0, 0]
2696 semisize = [None, 0, 0]
2697 semisize = [None, 0, 0]
2697 # snapshot count per depth
2698 # snapshot count per depth
2698 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2699 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2699 deltasize = [None, 0, 0]
2700 deltasize = [None, 0, 0]
2700 chunktypecounts = {}
2701 chunktypecounts = {}
2701 chunktypesizes = {}
2702 chunktypesizes = {}
2702
2703
2703 def addsize(size, l):
2704 def addsize(size, l):
2704 if l[0] is None or size < l[0]:
2705 if l[0] is None or size < l[0]:
2705 l[0] = size
2706 l[0] = size
2706 if size > l[1]:
2707 if size > l[1]:
2707 l[1] = size
2708 l[1] = size
2708 l[2] += size
2709 l[2] += size
2709
2710
2710 numrevs = len(r)
2711 numrevs = len(r)
2711 for rev in pycompat.xrange(numrevs):
2712 for rev in pycompat.xrange(numrevs):
2712 p1, p2 = r.parentrevs(rev)
2713 p1, p2 = r.parentrevs(rev)
2713 delta = r.deltaparent(rev)
2714 delta = r.deltaparent(rev)
2714 if format > 0:
2715 if format > 0:
2715 addsize(r.rawsize(rev), datasize)
2716 addsize(r.rawsize(rev), datasize)
2716 if p2 != nullrev:
2717 if p2 != nullrev:
2717 nummerges += 1
2718 nummerges += 1
2718 size = r.length(rev)
2719 size = r.length(rev)
2719 if delta == nullrev:
2720 if delta == nullrev:
2720 chainlengths.append(0)
2721 chainlengths.append(0)
2721 chainbases.append(r.start(rev))
2722 chainbases.append(r.start(rev))
2722 chainspans.append(size)
2723 chainspans.append(size)
2723 if size == 0:
2724 if size == 0:
2724 numempty += 1
2725 numempty += 1
2725 numemptytext += 1
2726 numemptytext += 1
2726 else:
2727 else:
2727 numfull += 1
2728 numfull += 1
2728 numsnapdepth[0] += 1
2729 numsnapdepth[0] += 1
2729 addsize(size, fullsize)
2730 addsize(size, fullsize)
2730 addsize(size, snapsizedepth[0])
2731 addsize(size, snapsizedepth[0])
2731 else:
2732 else:
2732 chainlengths.append(chainlengths[delta] + 1)
2733 chainlengths.append(chainlengths[delta] + 1)
2733 baseaddr = chainbases[delta]
2734 baseaddr = chainbases[delta]
2734 revaddr = r.start(rev)
2735 revaddr = r.start(rev)
2735 chainbases.append(baseaddr)
2736 chainbases.append(baseaddr)
2736 chainspans.append((revaddr - baseaddr) + size)
2737 chainspans.append((revaddr - baseaddr) + size)
2737 if size == 0:
2738 if size == 0:
2738 numempty += 1
2739 numempty += 1
2739 numemptydelta += 1
2740 numemptydelta += 1
2740 elif r.issnapshot(rev):
2741 elif r.issnapshot(rev):
2741 addsize(size, semisize)
2742 addsize(size, semisize)
2742 numsemi += 1
2743 numsemi += 1
2743 depth = r.snapshotdepth(rev)
2744 depth = r.snapshotdepth(rev)
2744 numsnapdepth[depth] += 1
2745 numsnapdepth[depth] += 1
2745 addsize(size, snapsizedepth[depth])
2746 addsize(size, snapsizedepth[depth])
2746 else:
2747 else:
2747 addsize(size, deltasize)
2748 addsize(size, deltasize)
2748 if delta == rev - 1:
2749 if delta == rev - 1:
2749 numprev += 1
2750 numprev += 1
2750 if delta == p1:
2751 if delta == p1:
2751 nump1prev += 1
2752 nump1prev += 1
2752 elif delta == p2:
2753 elif delta == p2:
2753 nump2prev += 1
2754 nump2prev += 1
2754 elif delta == p1:
2755 elif delta == p1:
2755 nump1 += 1
2756 nump1 += 1
2756 elif delta == p2:
2757 elif delta == p2:
2757 nump2 += 1
2758 nump2 += 1
2758 elif delta != nullrev:
2759 elif delta != nullrev:
2759 numother += 1
2760 numother += 1
2760
2761
2761 # Obtain data on the raw chunks in the revlog.
2762 # Obtain data on the raw chunks in the revlog.
2762 if util.safehasattr(r, b'_getsegmentforrevs'):
2763 if util.safehasattr(r, b'_getsegmentforrevs'):
2763 segment = r._getsegmentforrevs(rev, rev)[1]
2764 segment = r._getsegmentforrevs(rev, rev)[1]
2764 else:
2765 else:
2765 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2766 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2766 if segment:
2767 if segment:
2767 chunktype = bytes(segment[0:1])
2768 chunktype = bytes(segment[0:1])
2768 else:
2769 else:
2769 chunktype = b'empty'
2770 chunktype = b'empty'
2770
2771
2771 if chunktype not in chunktypecounts:
2772 if chunktype not in chunktypecounts:
2772 chunktypecounts[chunktype] = 0
2773 chunktypecounts[chunktype] = 0
2773 chunktypesizes[chunktype] = 0
2774 chunktypesizes[chunktype] = 0
2774
2775
2775 chunktypecounts[chunktype] += 1
2776 chunktypecounts[chunktype] += 1
2776 chunktypesizes[chunktype] += size
2777 chunktypesizes[chunktype] += size
2777
2778
2778 # Adjust size min value for empty cases
2779 # Adjust size min value for empty cases
2779 for size in (datasize, fullsize, semisize, deltasize):
2780 for size in (datasize, fullsize, semisize, deltasize):
2780 if size[0] is None:
2781 if size[0] is None:
2781 size[0] = 0
2782 size[0] = 0
2782
2783
2783 numdeltas = numrevs - numfull - numempty - numsemi
2784 numdeltas = numrevs - numfull - numempty - numsemi
2784 numoprev = numprev - nump1prev - nump2prev
2785 numoprev = numprev - nump1prev - nump2prev
2785 totalrawsize = datasize[2]
2786 totalrawsize = datasize[2]
2786 datasize[2] /= numrevs
2787 datasize[2] /= numrevs
2787 fulltotal = fullsize[2]
2788 fulltotal = fullsize[2]
2788 if numfull == 0:
2789 if numfull == 0:
2789 fullsize[2] = 0
2790 fullsize[2] = 0
2790 else:
2791 else:
2791 fullsize[2] /= numfull
2792 fullsize[2] /= numfull
2792 semitotal = semisize[2]
2793 semitotal = semisize[2]
2793 snaptotal = {}
2794 snaptotal = {}
2794 if numsemi > 0:
2795 if numsemi > 0:
2795 semisize[2] /= numsemi
2796 semisize[2] /= numsemi
2796 for depth in snapsizedepth:
2797 for depth in snapsizedepth:
2797 snaptotal[depth] = snapsizedepth[depth][2]
2798 snaptotal[depth] = snapsizedepth[depth][2]
2798 snapsizedepth[depth][2] /= numsnapdepth[depth]
2799 snapsizedepth[depth][2] /= numsnapdepth[depth]
2799
2800
2800 deltatotal = deltasize[2]
2801 deltatotal = deltasize[2]
2801 if numdeltas > 0:
2802 if numdeltas > 0:
2802 deltasize[2] /= numdeltas
2803 deltasize[2] /= numdeltas
2803 totalsize = fulltotal + semitotal + deltatotal
2804 totalsize = fulltotal + semitotal + deltatotal
2804 avgchainlen = sum(chainlengths) / numrevs
2805 avgchainlen = sum(chainlengths) / numrevs
2805 maxchainlen = max(chainlengths)
2806 maxchainlen = max(chainlengths)
2806 maxchainspan = max(chainspans)
2807 maxchainspan = max(chainspans)
2807 compratio = 1
2808 compratio = 1
2808 if totalsize:
2809 if totalsize:
2809 compratio = totalrawsize / totalsize
2810 compratio = totalrawsize / totalsize
2810
2811
2811 basedfmtstr = b'%%%dd\n'
2812 basedfmtstr = b'%%%dd\n'
2812 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2813 basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
2813
2814
2814 def dfmtstr(max):
2815 def dfmtstr(max):
2815 return basedfmtstr % len(str(max))
2816 return basedfmtstr % len(str(max))
2816
2817
2817 def pcfmtstr(max, padding=0):
2818 def pcfmtstr(max, padding=0):
2818 return basepcfmtstr % (len(str(max)), b' ' * padding)
2819 return basepcfmtstr % (len(str(max)), b' ' * padding)
2819
2820
2820 def pcfmt(value, total):
2821 def pcfmt(value, total):
2821 if total:
2822 if total:
2822 return (value, 100 * float(value) / total)
2823 return (value, 100 * float(value) / total)
2823 else:
2824 else:
2824 return value, 100.0
2825 return value, 100.0
2825
2826
2826 ui.writenoi18n(b'format : %d\n' % format)
2827 ui.writenoi18n(b'format : %d\n' % format)
2827 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2828 ui.writenoi18n(b'flags : %s\n' % b', '.join(flags))
2828
2829
2829 ui.write(b'\n')
2830 ui.write(b'\n')
2830 fmt = pcfmtstr(totalsize)
2831 fmt = pcfmtstr(totalsize)
2831 fmt2 = dfmtstr(totalsize)
2832 fmt2 = dfmtstr(totalsize)
2832 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2833 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2833 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2834 ui.writenoi18n(b' merges : ' + fmt % pcfmt(nummerges, numrevs))
2834 ui.writenoi18n(
2835 ui.writenoi18n(
2835 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2836 b' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
2836 )
2837 )
2837 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2838 ui.writenoi18n(b'revisions : ' + fmt2 % numrevs)
2838 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2839 ui.writenoi18n(b' empty : ' + fmt % pcfmt(numempty, numrevs))
2839 ui.writenoi18n(
2840 ui.writenoi18n(
2840 b' text : '
2841 b' text : '
2841 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2842 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
2842 )
2843 )
2843 ui.writenoi18n(
2844 ui.writenoi18n(
2844 b' delta : '
2845 b' delta : '
2845 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2846 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
2846 )
2847 )
2847 ui.writenoi18n(
2848 ui.writenoi18n(
2848 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2849 b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)
2849 )
2850 )
2850 for depth in sorted(numsnapdepth):
2851 for depth in sorted(numsnapdepth):
2851 ui.write(
2852 ui.write(
2852 (b' lvl-%-3d : ' % depth)
2853 (b' lvl-%-3d : ' % depth)
2853 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2854 + fmt % pcfmt(numsnapdepth[depth], numrevs)
2854 )
2855 )
2855 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2856 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2856 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2857 ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
2857 ui.writenoi18n(
2858 ui.writenoi18n(
2858 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2859 b' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
2859 )
2860 )
2860 for depth in sorted(numsnapdepth):
2861 for depth in sorted(numsnapdepth):
2861 ui.write(
2862 ui.write(
2862 (b' lvl-%-3d : ' % depth)
2863 (b' lvl-%-3d : ' % depth)
2863 + fmt % pcfmt(snaptotal[depth], totalsize)
2864 + fmt % pcfmt(snaptotal[depth], totalsize)
2864 )
2865 )
2865 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2866 ui.writenoi18n(b' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2866
2867
2867 def fmtchunktype(chunktype):
2868 def fmtchunktype(chunktype):
2868 if chunktype == b'empty':
2869 if chunktype == b'empty':
2869 return b' %s : ' % chunktype
2870 return b' %s : ' % chunktype
2870 elif chunktype in pycompat.bytestr(string.ascii_letters):
2871 elif chunktype in pycompat.bytestr(string.ascii_letters):
2871 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2872 return b' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2872 else:
2873 else:
2873 return b' 0x%s : ' % hex(chunktype)
2874 return b' 0x%s : ' % hex(chunktype)
2874
2875
2875 ui.write(b'\n')
2876 ui.write(b'\n')
2876 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2877 ui.writenoi18n(b'chunks : ' + fmt2 % numrevs)
2877 for chunktype in sorted(chunktypecounts):
2878 for chunktype in sorted(chunktypecounts):
2878 ui.write(fmtchunktype(chunktype))
2879 ui.write(fmtchunktype(chunktype))
2879 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2880 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2880 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2881 ui.writenoi18n(b'chunks size : ' + fmt2 % totalsize)
2881 for chunktype in sorted(chunktypecounts):
2882 for chunktype in sorted(chunktypecounts):
2882 ui.write(fmtchunktype(chunktype))
2883 ui.write(fmtchunktype(chunktype))
2883 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2884 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2884
2885
2885 ui.write(b'\n')
2886 ui.write(b'\n')
2886 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2887 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2887 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2888 ui.writenoi18n(b'avg chain length : ' + fmt % avgchainlen)
2888 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2889 ui.writenoi18n(b'max chain length : ' + fmt % maxchainlen)
2889 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2890 ui.writenoi18n(b'max chain reach : ' + fmt % maxchainspan)
2890 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2891 ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
2891
2892
2892 if format > 0:
2893 if format > 0:
2893 ui.write(b'\n')
2894 ui.write(b'\n')
2894 ui.writenoi18n(
2895 ui.writenoi18n(
2895 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2896 b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
2896 % tuple(datasize)
2897 % tuple(datasize)
2897 )
2898 )
2898 ui.writenoi18n(
2899 ui.writenoi18n(
2899 b'full revision size (min/max/avg) : %d / %d / %d\n'
2900 b'full revision size (min/max/avg) : %d / %d / %d\n'
2900 % tuple(fullsize)
2901 % tuple(fullsize)
2901 )
2902 )
2902 ui.writenoi18n(
2903 ui.writenoi18n(
2903 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2904 b'inter-snapshot size (min/max/avg) : %d / %d / %d\n'
2904 % tuple(semisize)
2905 % tuple(semisize)
2905 )
2906 )
2906 for depth in sorted(snapsizedepth):
2907 for depth in sorted(snapsizedepth):
2907 if depth == 0:
2908 if depth == 0:
2908 continue
2909 continue
2909 ui.writenoi18n(
2910 ui.writenoi18n(
2910 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2911 b' level-%-3d (min/max/avg) : %d / %d / %d\n'
2911 % ((depth,) + tuple(snapsizedepth[depth]))
2912 % ((depth,) + tuple(snapsizedepth[depth]))
2912 )
2913 )
2913 ui.writenoi18n(
2914 ui.writenoi18n(
2914 b'delta size (min/max/avg) : %d / %d / %d\n'
2915 b'delta size (min/max/avg) : %d / %d / %d\n'
2915 % tuple(deltasize)
2916 % tuple(deltasize)
2916 )
2917 )
2917
2918
2918 if numdeltas > 0:
2919 if numdeltas > 0:
2919 ui.write(b'\n')
2920 ui.write(b'\n')
2920 fmt = pcfmtstr(numdeltas)
2921 fmt = pcfmtstr(numdeltas)
2921 fmt2 = pcfmtstr(numdeltas, 4)
2922 fmt2 = pcfmtstr(numdeltas, 4)
2922 ui.writenoi18n(
2923 ui.writenoi18n(
2923 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2924 b'deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)
2924 )
2925 )
2925 if numprev > 0:
2926 if numprev > 0:
2926 ui.writenoi18n(
2927 ui.writenoi18n(
2927 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2928 b' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev)
2928 )
2929 )
2929 ui.writenoi18n(
2930 ui.writenoi18n(
2930 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2931 b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev)
2931 )
2932 )
2932 ui.writenoi18n(
2933 ui.writenoi18n(
2933 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2934 b' other : ' + fmt2 % pcfmt(numoprev, numprev)
2934 )
2935 )
2935 if gdelta:
2936 if gdelta:
2936 ui.writenoi18n(
2937 ui.writenoi18n(
2937 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
2938 b'deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)
2938 )
2939 )
2939 ui.writenoi18n(
2940 ui.writenoi18n(
2940 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
2941 b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)
2941 )
2942 )
2942 ui.writenoi18n(
2943 ui.writenoi18n(
2943 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
2944 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
2944 )
2945 )
2945
2946
2946
2947
2947 @command(
2948 @command(
2948 b'debugrevlogindex',
2949 b'debugrevlogindex',
2949 cmdutil.debugrevlogopts
2950 cmdutil.debugrevlogopts
2950 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
2951 + [(b'f', b'format', 0, _(b'revlog format'), _(b'FORMAT'))],
2951 _(b'[-f FORMAT] -c|-m|FILE'),
2952 _(b'[-f FORMAT] -c|-m|FILE'),
2952 optionalrepo=True,
2953 optionalrepo=True,
2953 )
2954 )
2954 def debugrevlogindex(ui, repo, file_=None, **opts):
2955 def debugrevlogindex(ui, repo, file_=None, **opts):
2955 """dump the contents of a revlog index"""
2956 """dump the contents of a revlog index"""
2956 opts = pycompat.byteskwargs(opts)
2957 opts = pycompat.byteskwargs(opts)
2957 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
2958 r = cmdutil.openrevlog(repo, b'debugrevlogindex', file_, opts)
2958 format = opts.get(b'format', 0)
2959 format = opts.get(b'format', 0)
2959 if format not in (0, 1):
2960 if format not in (0, 1):
2960 raise error.Abort(_(b"unknown format %d") % format)
2961 raise error.Abort(_(b"unknown format %d") % format)
2961
2962
2962 if ui.debugflag:
2963 if ui.debugflag:
2963 shortfn = hex
2964 shortfn = hex
2964 else:
2965 else:
2965 shortfn = short
2966 shortfn = short
2966
2967
2967 # There might not be anything in r, so have a sane default
2968 # There might not be anything in r, so have a sane default
2968 idlen = 12
2969 idlen = 12
2969 for i in r:
2970 for i in r:
2970 idlen = len(shortfn(r.node(i)))
2971 idlen = len(shortfn(r.node(i)))
2971 break
2972 break
2972
2973
2973 if format == 0:
2974 if format == 0:
2974 if ui.verbose:
2975 if ui.verbose:
2975 ui.writenoi18n(
2976 ui.writenoi18n(
2976 b" rev offset length linkrev %s %s p2\n"
2977 b" rev offset length linkrev %s %s p2\n"
2977 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
2978 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
2978 )
2979 )
2979 else:
2980 else:
2980 ui.writenoi18n(
2981 ui.writenoi18n(
2981 b" rev linkrev %s %s p2\n"
2982 b" rev linkrev %s %s p2\n"
2982 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
2983 % (b"nodeid".ljust(idlen), b"p1".ljust(idlen))
2983 )
2984 )
2984 elif format == 1:
2985 elif format == 1:
2985 if ui.verbose:
2986 if ui.verbose:
2986 ui.writenoi18n(
2987 ui.writenoi18n(
2987 (
2988 (
2988 b" rev flag offset length size link p1"
2989 b" rev flag offset length size link p1"
2989 b" p2 %s\n"
2990 b" p2 %s\n"
2990 )
2991 )
2991 % b"nodeid".rjust(idlen)
2992 % b"nodeid".rjust(idlen)
2992 )
2993 )
2993 else:
2994 else:
2994 ui.writenoi18n(
2995 ui.writenoi18n(
2995 b" rev flag size link p1 p2 %s\n"
2996 b" rev flag size link p1 p2 %s\n"
2996 % b"nodeid".rjust(idlen)
2997 % b"nodeid".rjust(idlen)
2997 )
2998 )
2998
2999
2999 for i in r:
3000 for i in r:
3000 node = r.node(i)
3001 node = r.node(i)
3001 if format == 0:
3002 if format == 0:
3002 try:
3003 try:
3003 pp = r.parents(node)
3004 pp = r.parents(node)
3004 except Exception:
3005 except Exception:
3005 pp = [nullid, nullid]
3006 pp = [nullid, nullid]
3006 if ui.verbose:
3007 if ui.verbose:
3007 ui.write(
3008 ui.write(
3008 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3009 b"% 6d % 9d % 7d % 7d %s %s %s\n"
3009 % (
3010 % (
3010 i,
3011 i,
3011 r.start(i),
3012 r.start(i),
3012 r.length(i),
3013 r.length(i),
3013 r.linkrev(i),
3014 r.linkrev(i),
3014 shortfn(node),
3015 shortfn(node),
3015 shortfn(pp[0]),
3016 shortfn(pp[0]),
3016 shortfn(pp[1]),
3017 shortfn(pp[1]),
3017 )
3018 )
3018 )
3019 )
3019 else:
3020 else:
3020 ui.write(
3021 ui.write(
3021 b"% 6d % 7d %s %s %s\n"
3022 b"% 6d % 7d %s %s %s\n"
3022 % (
3023 % (
3023 i,
3024 i,
3024 r.linkrev(i),
3025 r.linkrev(i),
3025 shortfn(node),
3026 shortfn(node),
3026 shortfn(pp[0]),
3027 shortfn(pp[0]),
3027 shortfn(pp[1]),
3028 shortfn(pp[1]),
3028 )
3029 )
3029 )
3030 )
3030 elif format == 1:
3031 elif format == 1:
3031 pr = r.parentrevs(i)
3032 pr = r.parentrevs(i)
3032 if ui.verbose:
3033 if ui.verbose:
3033 ui.write(
3034 ui.write(
3034 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3035 b"% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n"
3035 % (
3036 % (
3036 i,
3037 i,
3037 r.flags(i),
3038 r.flags(i),
3038 r.start(i),
3039 r.start(i),
3039 r.length(i),
3040 r.length(i),
3040 r.rawsize(i),
3041 r.rawsize(i),
3041 r.linkrev(i),
3042 r.linkrev(i),
3042 pr[0],
3043 pr[0],
3043 pr[1],
3044 pr[1],
3044 shortfn(node),
3045 shortfn(node),
3045 )
3046 )
3046 )
3047 )
3047 else:
3048 else:
3048 ui.write(
3049 ui.write(
3049 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3050 b"% 6d %04x % 8d % 6d % 6d % 6d %s\n"
3050 % (
3051 % (
3051 i,
3052 i,
3052 r.flags(i),
3053 r.flags(i),
3053 r.rawsize(i),
3054 r.rawsize(i),
3054 r.linkrev(i),
3055 r.linkrev(i),
3055 pr[0],
3056 pr[0],
3056 pr[1],
3057 pr[1],
3057 shortfn(node),
3058 shortfn(node),
3058 )
3059 )
3059 )
3060 )
3060
3061
3061
3062
3062 @command(
3063 @command(
3063 b'debugrevspec',
3064 b'debugrevspec',
3064 [
3065 [
3065 (
3066 (
3066 b'',
3067 b'',
3067 b'optimize',
3068 b'optimize',
3068 None,
3069 None,
3069 _(b'print parsed tree after optimizing (DEPRECATED)'),
3070 _(b'print parsed tree after optimizing (DEPRECATED)'),
3070 ),
3071 ),
3071 (
3072 (
3072 b'',
3073 b'',
3073 b'show-revs',
3074 b'show-revs',
3074 True,
3075 True,
3075 _(b'print list of result revisions (default)'),
3076 _(b'print list of result revisions (default)'),
3076 ),
3077 ),
3077 (
3078 (
3078 b's',
3079 b's',
3079 b'show-set',
3080 b'show-set',
3080 None,
3081 None,
3081 _(b'print internal representation of result set'),
3082 _(b'print internal representation of result set'),
3082 ),
3083 ),
3083 (
3084 (
3084 b'p',
3085 b'p',
3085 b'show-stage',
3086 b'show-stage',
3086 [],
3087 [],
3087 _(b'print parsed tree at the given stage'),
3088 _(b'print parsed tree at the given stage'),
3088 _(b'NAME'),
3089 _(b'NAME'),
3089 ),
3090 ),
3090 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3091 (b'', b'no-optimized', False, _(b'evaluate tree without optimization')),
3091 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3092 (b'', b'verify-optimized', False, _(b'verify optimized result')),
3092 ],
3093 ],
3093 b'REVSPEC',
3094 b'REVSPEC',
3094 )
3095 )
3095 def debugrevspec(ui, repo, expr, **opts):
3096 def debugrevspec(ui, repo, expr, **opts):
3096 """parse and apply a revision specification
3097 """parse and apply a revision specification
3097
3098
3098 Use -p/--show-stage option to print the parsed tree at the given stages.
3099 Use -p/--show-stage option to print the parsed tree at the given stages.
3099 Use -p all to print tree at every stage.
3100 Use -p all to print tree at every stage.
3100
3101
3101 Use --no-show-revs option with -s or -p to print only the set
3102 Use --no-show-revs option with -s or -p to print only the set
3102 representation or the parsed tree respectively.
3103 representation or the parsed tree respectively.
3103
3104
3104 Use --verify-optimized to compare the optimized result with the unoptimized
3105 Use --verify-optimized to compare the optimized result with the unoptimized
3105 one. Returns 1 if the optimized result differs.
3106 one. Returns 1 if the optimized result differs.
3106 """
3107 """
3107 opts = pycompat.byteskwargs(opts)
3108 opts = pycompat.byteskwargs(opts)
3108 aliases = ui.configitems(b'revsetalias')
3109 aliases = ui.configitems(b'revsetalias')
3109 stages = [
3110 stages = [
3110 (b'parsed', lambda tree: tree),
3111 (b'parsed', lambda tree: tree),
3111 (
3112 (
3112 b'expanded',
3113 b'expanded',
3113 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3114 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn),
3114 ),
3115 ),
3115 (b'concatenated', revsetlang.foldconcat),
3116 (b'concatenated', revsetlang.foldconcat),
3116 (b'analyzed', revsetlang.analyze),
3117 (b'analyzed', revsetlang.analyze),
3117 (b'optimized', revsetlang.optimize),
3118 (b'optimized', revsetlang.optimize),
3118 ]
3119 ]
3119 if opts[b'no_optimized']:
3120 if opts[b'no_optimized']:
3120 stages = stages[:-1]
3121 stages = stages[:-1]
3121 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3122 if opts[b'verify_optimized'] and opts[b'no_optimized']:
3122 raise error.Abort(
3123 raise error.Abort(
3123 _(b'cannot use --verify-optimized with --no-optimized')
3124 _(b'cannot use --verify-optimized with --no-optimized')
3124 )
3125 )
3125 stagenames = set(n for n, f in stages)
3126 stagenames = set(n for n, f in stages)
3126
3127
3127 showalways = set()
3128 showalways = set()
3128 showchanged = set()
3129 showchanged = set()
3129 if ui.verbose and not opts[b'show_stage']:
3130 if ui.verbose and not opts[b'show_stage']:
3130 # show parsed tree by --verbose (deprecated)
3131 # show parsed tree by --verbose (deprecated)
3131 showalways.add(b'parsed')
3132 showalways.add(b'parsed')
3132 showchanged.update([b'expanded', b'concatenated'])
3133 showchanged.update([b'expanded', b'concatenated'])
3133 if opts[b'optimize']:
3134 if opts[b'optimize']:
3134 showalways.add(b'optimized')
3135 showalways.add(b'optimized')
3135 if opts[b'show_stage'] and opts[b'optimize']:
3136 if opts[b'show_stage'] and opts[b'optimize']:
3136 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3137 raise error.Abort(_(b'cannot use --optimize with --show-stage'))
3137 if opts[b'show_stage'] == [b'all']:
3138 if opts[b'show_stage'] == [b'all']:
3138 showalways.update(stagenames)
3139 showalways.update(stagenames)
3139 else:
3140 else:
3140 for n in opts[b'show_stage']:
3141 for n in opts[b'show_stage']:
3141 if n not in stagenames:
3142 if n not in stagenames:
3142 raise error.Abort(_(b'invalid stage name: %s') % n)
3143 raise error.Abort(_(b'invalid stage name: %s') % n)
3143 showalways.update(opts[b'show_stage'])
3144 showalways.update(opts[b'show_stage'])
3144
3145
3145 treebystage = {}
3146 treebystage = {}
3146 printedtree = None
3147 printedtree = None
3147 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3148 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
3148 for n, f in stages:
3149 for n, f in stages:
3149 treebystage[n] = tree = f(tree)
3150 treebystage[n] = tree = f(tree)
3150 if n in showalways or (n in showchanged and tree != printedtree):
3151 if n in showalways or (n in showchanged and tree != printedtree):
3151 if opts[b'show_stage'] or n != b'parsed':
3152 if opts[b'show_stage'] or n != b'parsed':
3152 ui.write(b"* %s:\n" % n)
3153 ui.write(b"* %s:\n" % n)
3153 ui.write(revsetlang.prettyformat(tree), b"\n")
3154 ui.write(revsetlang.prettyformat(tree), b"\n")
3154 printedtree = tree
3155 printedtree = tree
3155
3156
3156 if opts[b'verify_optimized']:
3157 if opts[b'verify_optimized']:
3157 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3158 arevs = revset.makematcher(treebystage[b'analyzed'])(repo)
3158 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3159 brevs = revset.makematcher(treebystage[b'optimized'])(repo)
3159 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3160 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3160 ui.writenoi18n(
3161 ui.writenoi18n(
3161 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3162 b"* analyzed set:\n", stringutil.prettyrepr(arevs), b"\n"
3162 )
3163 )
3163 ui.writenoi18n(
3164 ui.writenoi18n(
3164 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3165 b"* optimized set:\n", stringutil.prettyrepr(brevs), b"\n"
3165 )
3166 )
3166 arevs = list(arevs)
3167 arevs = list(arevs)
3167 brevs = list(brevs)
3168 brevs = list(brevs)
3168 if arevs == brevs:
3169 if arevs == brevs:
3169 return 0
3170 return 0
3170 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3171 ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
3171 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3172 ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
3172 sm = difflib.SequenceMatcher(None, arevs, brevs)
3173 sm = difflib.SequenceMatcher(None, arevs, brevs)
3173 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3174 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3174 if tag in ('delete', 'replace'):
3175 if tag in ('delete', 'replace'):
3175 for c in arevs[alo:ahi]:
3176 for c in arevs[alo:ahi]:
3176 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3177 ui.write(b'-%d\n' % c, label=b'diff.deleted')
3177 if tag in ('insert', 'replace'):
3178 if tag in ('insert', 'replace'):
3178 for c in brevs[blo:bhi]:
3179 for c in brevs[blo:bhi]:
3179 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3180 ui.write(b'+%d\n' % c, label=b'diff.inserted')
3180 if tag == 'equal':
3181 if tag == 'equal':
3181 for c in arevs[alo:ahi]:
3182 for c in arevs[alo:ahi]:
3182 ui.write(b' %d\n' % c)
3183 ui.write(b' %d\n' % c)
3183 return 1
3184 return 1
3184
3185
3185 func = revset.makematcher(tree)
3186 func = revset.makematcher(tree)
3186 revs = func(repo)
3187 revs = func(repo)
3187 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3188 if opts[b'show_set'] or (opts[b'show_set'] is None and ui.verbose):
3188 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3189 ui.writenoi18n(b"* set:\n", stringutil.prettyrepr(revs), b"\n")
3189 if not opts[b'show_revs']:
3190 if not opts[b'show_revs']:
3190 return
3191 return
3191 for c in revs:
3192 for c in revs:
3192 ui.write(b"%d\n" % c)
3193 ui.write(b"%d\n" % c)
3193
3194
3194
3195
3195 @command(
3196 @command(
3196 b'debugserve',
3197 b'debugserve',
3197 [
3198 [
3198 (
3199 (
3199 b'',
3200 b'',
3200 b'sshstdio',
3201 b'sshstdio',
3201 False,
3202 False,
3202 _(b'run an SSH server bound to process handles'),
3203 _(b'run an SSH server bound to process handles'),
3203 ),
3204 ),
3204 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3205 (b'', b'logiofd', b'', _(b'file descriptor to log server I/O to')),
3205 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3206 (b'', b'logiofile', b'', _(b'file to log server I/O to')),
3206 ],
3207 ],
3207 b'',
3208 b'',
3208 )
3209 )
3209 def debugserve(ui, repo, **opts):
3210 def debugserve(ui, repo, **opts):
3210 """run a server with advanced settings
3211 """run a server with advanced settings
3211
3212
3212 This command is similar to :hg:`serve`. It exists partially as a
3213 This command is similar to :hg:`serve`. It exists partially as a
3213 workaround to the fact that ``hg serve --stdio`` must have specific
3214 workaround to the fact that ``hg serve --stdio`` must have specific
3214 arguments for security reasons.
3215 arguments for security reasons.
3215 """
3216 """
3216 opts = pycompat.byteskwargs(opts)
3217 opts = pycompat.byteskwargs(opts)
3217
3218
3218 if not opts[b'sshstdio']:
3219 if not opts[b'sshstdio']:
3219 raise error.Abort(_(b'only --sshstdio is currently supported'))
3220 raise error.Abort(_(b'only --sshstdio is currently supported'))
3220
3221
3221 logfh = None
3222 logfh = None
3222
3223
3223 if opts[b'logiofd'] and opts[b'logiofile']:
3224 if opts[b'logiofd'] and opts[b'logiofile']:
3224 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3225 raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
3225
3226
3226 if opts[b'logiofd']:
3227 if opts[b'logiofd']:
3227 # Ideally we would be line buffered. But line buffering in binary
3228 # Ideally we would be line buffered. But line buffering in binary
3228 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3229 # mode isn't supported and emits a warning in Python 3.8+. Disabling
3229 # buffering could have performance impacts. But since this isn't
3230 # buffering could have performance impacts. But since this isn't
3230 # performance critical code, it should be fine.
3231 # performance critical code, it should be fine.
3231 try:
3232 try:
3232 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3233 logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
3233 except OSError as e:
3234 except OSError as e:
3234 if e.errno != errno.ESPIPE:
3235 if e.errno != errno.ESPIPE:
3235 raise
3236 raise
3236 # can't seek a pipe, so `ab` mode fails on py3
3237 # can't seek a pipe, so `ab` mode fails on py3
3237 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3238 logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
3238 elif opts[b'logiofile']:
3239 elif opts[b'logiofile']:
3239 logfh = open(opts[b'logiofile'], b'ab', 0)
3240 logfh = open(opts[b'logiofile'], b'ab', 0)
3240
3241
3241 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3242 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
3242 s.serve_forever()
3243 s.serve_forever()
3243
3244
3244
3245
3245 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3246 @command(b'debugsetparents', [], _(b'REV1 [REV2]'))
3246 def debugsetparents(ui, repo, rev1, rev2=None):
3247 def debugsetparents(ui, repo, rev1, rev2=None):
3247 """manually set the parents of the current working directory
3248 """manually set the parents of the current working directory
3248
3249
3249 This is useful for writing repository conversion tools, but should
3250 This is useful for writing repository conversion tools, but should
3250 be used with care. For example, neither the working directory nor the
3251 be used with care. For example, neither the working directory nor the
3251 dirstate is updated, so file status may be incorrect after running this
3252 dirstate is updated, so file status may be incorrect after running this
3252 command.
3253 command.
3253
3254
3254 Returns 0 on success.
3255 Returns 0 on success.
3255 """
3256 """
3256
3257
3257 node1 = scmutil.revsingle(repo, rev1).node()
3258 node1 = scmutil.revsingle(repo, rev1).node()
3258 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3259 node2 = scmutil.revsingle(repo, rev2, b'null').node()
3259
3260
3260 with repo.wlock():
3261 with repo.wlock():
3261 repo.setparents(node1, node2)
3262 repo.setparents(node1, node2)
3262
3263
3263
3264
3264 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3265 @command(b'debugsidedata', cmdutil.debugrevlogopts, _(b'-c|-m|FILE REV'))
3265 def debugsidedata(ui, repo, file_, rev=None, **opts):
3266 def debugsidedata(ui, repo, file_, rev=None, **opts):
3266 """dump the side data for a cl/manifest/file revision
3267 """dump the side data for a cl/manifest/file revision
3267
3268
3268 Use --verbose to dump the sidedata content."""
3269 Use --verbose to dump the sidedata content."""
3269 opts = pycompat.byteskwargs(opts)
3270 opts = pycompat.byteskwargs(opts)
3270 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3271 if opts.get(b'changelog') or opts.get(b'manifest') or opts.get(b'dir'):
3271 if rev is not None:
3272 if rev is not None:
3272 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3273 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3273 file_, rev = None, file_
3274 file_, rev = None, file_
3274 elif rev is None:
3275 elif rev is None:
3275 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3276 raise error.CommandError(b'debugdata', _(b'invalid arguments'))
3276 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3277 r = cmdutil.openstorage(repo, b'debugdata', file_, opts)
3277 r = getattr(r, '_revlog', r)
3278 r = getattr(r, '_revlog', r)
3278 try:
3279 try:
3279 sidedata = r.sidedata(r.lookup(rev))
3280 sidedata = r.sidedata(r.lookup(rev))
3280 except KeyError:
3281 except KeyError:
3281 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3282 raise error.Abort(_(b'invalid revision identifier %s') % rev)
3282 if sidedata:
3283 if sidedata:
3283 sidedata = list(sidedata.items())
3284 sidedata = list(sidedata.items())
3284 sidedata.sort()
3285 sidedata.sort()
3285 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3286 ui.writenoi18n(b'%d sidedata entries\n' % len(sidedata))
3286 for key, value in sidedata:
3287 for key, value in sidedata:
3287 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3288 ui.writenoi18n(b' entry-%04o size %d\n' % (key, len(value)))
3288 if ui.verbose:
3289 if ui.verbose:
3289 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3290 ui.writenoi18n(b' %s\n' % stringutil.pprint(value))
3290
3291
3291
3292
3292 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3293 @command(b'debugssl', [], b'[SOURCE]', optionalrepo=True)
3293 def debugssl(ui, repo, source=None, **opts):
3294 def debugssl(ui, repo, source=None, **opts):
3294 '''test a secure connection to a server
3295 '''test a secure connection to a server
3295
3296
3296 This builds the certificate chain for the server on Windows, installing the
3297 This builds the certificate chain for the server on Windows, installing the
3297 missing intermediates and trusted root via Windows Update if necessary. It
3298 missing intermediates and trusted root via Windows Update if necessary. It
3298 does nothing on other platforms.
3299 does nothing on other platforms.
3299
3300
3300 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3301 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
3301 that server is used. See :hg:`help urls` for more information.
3302 that server is used. See :hg:`help urls` for more information.
3302
3303
3303 If the update succeeds, retry the original operation. Otherwise, the cause
3304 If the update succeeds, retry the original operation. Otherwise, the cause
3304 of the SSL error is likely another issue.
3305 of the SSL error is likely another issue.
3305 '''
3306 '''
3306 if not pycompat.iswindows:
3307 if not pycompat.iswindows:
3307 raise error.Abort(
3308 raise error.Abort(
3308 _(b'certificate chain building is only possible on Windows')
3309 _(b'certificate chain building is only possible on Windows')
3309 )
3310 )
3310
3311
3311 if not source:
3312 if not source:
3312 if not repo:
3313 if not repo:
3313 raise error.Abort(
3314 raise error.Abort(
3314 _(
3315 _(
3315 b"there is no Mercurial repository here, and no "
3316 b"there is no Mercurial repository here, and no "
3316 b"server specified"
3317 b"server specified"
3317 )
3318 )
3318 )
3319 )
3319 source = b"default"
3320 source = b"default"
3320
3321
3321 source, branches = hg.parseurl(ui.expandpath(source))
3322 source, branches = hg.parseurl(ui.expandpath(source))
3322 url = util.url(source)
3323 url = util.url(source)
3323
3324
3324 defaultport = {b'https': 443, b'ssh': 22}
3325 defaultport = {b'https': 443, b'ssh': 22}
3325 if url.scheme in defaultport:
3326 if url.scheme in defaultport:
3326 try:
3327 try:
3327 addr = (url.host, int(url.port or defaultport[url.scheme]))
3328 addr = (url.host, int(url.port or defaultport[url.scheme]))
3328 except ValueError:
3329 except ValueError:
3329 raise error.Abort(_(b"malformed port number in URL"))
3330 raise error.Abort(_(b"malformed port number in URL"))
3330 else:
3331 else:
3331 raise error.Abort(_(b"only https and ssh connections are supported"))
3332 raise error.Abort(_(b"only https and ssh connections are supported"))
3332
3333
3333 from . import win32
3334 from . import win32
3334
3335
3335 s = ssl.wrap_socket(
3336 s = ssl.wrap_socket(
3336 socket.socket(),
3337 socket.socket(),
3337 ssl_version=ssl.PROTOCOL_TLS,
3338 ssl_version=ssl.PROTOCOL_TLS,
3338 cert_reqs=ssl.CERT_NONE,
3339 cert_reqs=ssl.CERT_NONE,
3339 ca_certs=None,
3340 ca_certs=None,
3340 )
3341 )
3341
3342
3342 try:
3343 try:
3343 s.connect(addr)
3344 s.connect(addr)
3344 cert = s.getpeercert(True)
3345 cert = s.getpeercert(True)
3345
3346
3346 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3347 ui.status(_(b'checking the certificate chain for %s\n') % url.host)
3347
3348
3348 complete = win32.checkcertificatechain(cert, build=False)
3349 complete = win32.checkcertificatechain(cert, build=False)
3349
3350
3350 if not complete:
3351 if not complete:
3351 ui.status(_(b'certificate chain is incomplete, updating... '))
3352 ui.status(_(b'certificate chain is incomplete, updating... '))
3352
3353
3353 if not win32.checkcertificatechain(cert):
3354 if not win32.checkcertificatechain(cert):
3354 ui.status(_(b'failed.\n'))
3355 ui.status(_(b'failed.\n'))
3355 else:
3356 else:
3356 ui.status(_(b'done.\n'))
3357 ui.status(_(b'done.\n'))
3357 else:
3358 else:
3358 ui.status(_(b'full certificate chain is available\n'))
3359 ui.status(_(b'full certificate chain is available\n'))
3359 finally:
3360 finally:
3360 s.close()
3361 s.close()
3361
3362
3362
3363
3363 @command(
3364 @command(
3364 b'debugsub',
3365 b'debugsub',
3365 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3366 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3366 _(b'[-r REV] [REV]'),
3367 _(b'[-r REV] [REV]'),
3367 )
3368 )
3368 def debugsub(ui, repo, rev=None):
3369 def debugsub(ui, repo, rev=None):
3369 ctx = scmutil.revsingle(repo, rev, None)
3370 ctx = scmutil.revsingle(repo, rev, None)
3370 for k, v in sorted(ctx.substate.items()):
3371 for k, v in sorted(ctx.substate.items()):
3371 ui.writenoi18n(b'path %s\n' % k)
3372 ui.writenoi18n(b'path %s\n' % k)
3372 ui.writenoi18n(b' source %s\n' % v[0])
3373 ui.writenoi18n(b' source %s\n' % v[0])
3373 ui.writenoi18n(b' revision %s\n' % v[1])
3374 ui.writenoi18n(b' revision %s\n' % v[1])
3374
3375
3375
3376
3376 @command(
3377 @command(
3377 b'debugsuccessorssets',
3378 b'debugsuccessorssets',
3378 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3379 [(b'', b'closest', False, _(b'return closest successors sets only'))],
3379 _(b'[REV]'),
3380 _(b'[REV]'),
3380 )
3381 )
3381 def debugsuccessorssets(ui, repo, *revs, **opts):
3382 def debugsuccessorssets(ui, repo, *revs, **opts):
3382 """show set of successors for revision
3383 """show set of successors for revision
3383
3384
3384 A successors set of changeset A is a consistent group of revisions that
3385 A successors set of changeset A is a consistent group of revisions that
3385 succeed A. It contains non-obsolete changesets only unless closests
3386 succeed A. It contains non-obsolete changesets only unless closests
3386 successors set is set.
3387 successors set is set.
3387
3388
3388 In most cases a changeset A has a single successors set containing a single
3389 In most cases a changeset A has a single successors set containing a single
3389 successor (changeset A replaced by A').
3390 successor (changeset A replaced by A').
3390
3391
3391 A changeset that is made obsolete with no successors are called "pruned".
3392 A changeset that is made obsolete with no successors are called "pruned".
3392 Such changesets have no successors sets at all.
3393 Such changesets have no successors sets at all.
3393
3394
3394 A changeset that has been "split" will have a successors set containing
3395 A changeset that has been "split" will have a successors set containing
3395 more than one successor.
3396 more than one successor.
3396
3397
3397 A changeset that has been rewritten in multiple different ways is called
3398 A changeset that has been rewritten in multiple different ways is called
3398 "divergent". Such changesets have multiple successor sets (each of which
3399 "divergent". Such changesets have multiple successor sets (each of which
3399 may also be split, i.e. have multiple successors).
3400 may also be split, i.e. have multiple successors).
3400
3401
3401 Results are displayed as follows::
3402 Results are displayed as follows::
3402
3403
3403 <rev1>
3404 <rev1>
3404 <successors-1A>
3405 <successors-1A>
3405 <rev2>
3406 <rev2>
3406 <successors-2A>
3407 <successors-2A>
3407 <successors-2B1> <successors-2B2> <successors-2B3>
3408 <successors-2B1> <successors-2B2> <successors-2B3>
3408
3409
3409 Here rev2 has two possible (i.e. divergent) successors sets. The first
3410 Here rev2 has two possible (i.e. divergent) successors sets. The first
3410 holds one element, whereas the second holds three (i.e. the changeset has
3411 holds one element, whereas the second holds three (i.e. the changeset has
3411 been split).
3412 been split).
3412 """
3413 """
3413 # passed to successorssets caching computation from one call to another
3414 # passed to successorssets caching computation from one call to another
3414 cache = {}
3415 cache = {}
3415 ctx2str = bytes
3416 ctx2str = bytes
3416 node2str = short
3417 node2str = short
3417 for rev in scmutil.revrange(repo, revs):
3418 for rev in scmutil.revrange(repo, revs):
3418 ctx = repo[rev]
3419 ctx = repo[rev]
3419 ui.write(b'%s\n' % ctx2str(ctx))
3420 ui.write(b'%s\n' % ctx2str(ctx))
3420 for succsset in obsutil.successorssets(
3421 for succsset in obsutil.successorssets(
3421 repo, ctx.node(), closest=opts['closest'], cache=cache
3422 repo, ctx.node(), closest=opts['closest'], cache=cache
3422 ):
3423 ):
3423 if succsset:
3424 if succsset:
3424 ui.write(b' ')
3425 ui.write(b' ')
3425 ui.write(node2str(succsset[0]))
3426 ui.write(node2str(succsset[0]))
3426 for node in succsset[1:]:
3427 for node in succsset[1:]:
3427 ui.write(b' ')
3428 ui.write(b' ')
3428 ui.write(node2str(node))
3429 ui.write(node2str(node))
3429 ui.write(b'\n')
3430 ui.write(b'\n')
3430
3431
3432 @command(b'debugtagscache', [])
3433 def debugtagscache(ui, repo):
3434 """display the contents of .hg/cache/hgtagsfnodes1"""
3435 cache = tagsmod.hgtagsfnodescache(repo.unfiltered())
3436 for r in repo:
3437 node = repo[r].node()
3438 tagsnode = cache.getfnode(node, computemissing=False)
3439 tagsnodedisplay = hex(tagsnode) if tagsnode else 'missing/invalid'
3440 ui.write(b'%s %s %s\n' % (r, hex(node), tagsnodedisplay))
3431
3441
3432 @command(
3442 @command(
3433 b'debugtemplate',
3443 b'debugtemplate',
3434 [
3444 [
3435 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3445 (b'r', b'rev', [], _(b'apply template on changesets'), _(b'REV')),
3436 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3446 (b'D', b'define', [], _(b'define template keyword'), _(b'KEY=VALUE')),
3437 ],
3447 ],
3438 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3448 _(b'[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
3439 optionalrepo=True,
3449 optionalrepo=True,
3440 )
3450 )
3441 def debugtemplate(ui, repo, tmpl, **opts):
3451 def debugtemplate(ui, repo, tmpl, **opts):
3442 """parse and apply a template
3452 """parse and apply a template
3443
3453
3444 If -r/--rev is given, the template is processed as a log template and
3454 If -r/--rev is given, the template is processed as a log template and
3445 applied to the given changesets. Otherwise, it is processed as a generic
3455 applied to the given changesets. Otherwise, it is processed as a generic
3446 template.
3456 template.
3447
3457
3448 Use --verbose to print the parsed tree.
3458 Use --verbose to print the parsed tree.
3449 """
3459 """
3450 revs = None
3460 revs = None
3451 if opts['rev']:
3461 if opts['rev']:
3452 if repo is None:
3462 if repo is None:
3453 raise error.RepoError(
3463 raise error.RepoError(
3454 _(b'there is no Mercurial repository here (.hg not found)')
3464 _(b'there is no Mercurial repository here (.hg not found)')
3455 )
3465 )
3456 revs = scmutil.revrange(repo, opts['rev'])
3466 revs = scmutil.revrange(repo, opts['rev'])
3457
3467
3458 props = {}
3468 props = {}
3459 for d in opts['define']:
3469 for d in opts['define']:
3460 try:
3470 try:
3461 k, v = (e.strip() for e in d.split(b'=', 1))
3471 k, v = (e.strip() for e in d.split(b'=', 1))
3462 if not k or k == b'ui':
3472 if not k or k == b'ui':
3463 raise ValueError
3473 raise ValueError
3464 props[k] = v
3474 props[k] = v
3465 except ValueError:
3475 except ValueError:
3466 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3476 raise error.Abort(_(b'malformed keyword definition: %s') % d)
3467
3477
3468 if ui.verbose:
3478 if ui.verbose:
3469 aliases = ui.configitems(b'templatealias')
3479 aliases = ui.configitems(b'templatealias')
3470 tree = templater.parse(tmpl)
3480 tree = templater.parse(tmpl)
3471 ui.note(templater.prettyformat(tree), b'\n')
3481 ui.note(templater.prettyformat(tree), b'\n')
3472 newtree = templater.expandaliases(tree, aliases)
3482 newtree = templater.expandaliases(tree, aliases)
3473 if newtree != tree:
3483 if newtree != tree:
3474 ui.notenoi18n(
3484 ui.notenoi18n(
3475 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3485 b"* expanded:\n", templater.prettyformat(newtree), b'\n'
3476 )
3486 )
3477
3487
3478 if revs is None:
3488 if revs is None:
3479 tres = formatter.templateresources(ui, repo)
3489 tres = formatter.templateresources(ui, repo)
3480 t = formatter.maketemplater(ui, tmpl, resources=tres)
3490 t = formatter.maketemplater(ui, tmpl, resources=tres)
3481 if ui.verbose:
3491 if ui.verbose:
3482 kwds, funcs = t.symbolsuseddefault()
3492 kwds, funcs = t.symbolsuseddefault()
3483 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3493 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3484 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3494 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3485 ui.write(t.renderdefault(props))
3495 ui.write(t.renderdefault(props))
3486 else:
3496 else:
3487 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3497 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
3488 if ui.verbose:
3498 if ui.verbose:
3489 kwds, funcs = displayer.t.symbolsuseddefault()
3499 kwds, funcs = displayer.t.symbolsuseddefault()
3490 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3500 ui.writenoi18n(b"* keywords: %s\n" % b', '.join(sorted(kwds)))
3491 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3501 ui.writenoi18n(b"* functions: %s\n" % b', '.join(sorted(funcs)))
3492 for r in revs:
3502 for r in revs:
3493 displayer.show(repo[r], **pycompat.strkwargs(props))
3503 displayer.show(repo[r], **pycompat.strkwargs(props))
3494 displayer.close()
3504 displayer.close()
3495
3505
3496
3506
3497 @command(
3507 @command(
3498 b'debuguigetpass',
3508 b'debuguigetpass',
3499 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3509 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3500 _(b'[-p TEXT]'),
3510 _(b'[-p TEXT]'),
3501 norepo=True,
3511 norepo=True,
3502 )
3512 )
3503 def debuguigetpass(ui, prompt=b''):
3513 def debuguigetpass(ui, prompt=b''):
3504 """show prompt to type password"""
3514 """show prompt to type password"""
3505 r = ui.getpass(prompt)
3515 r = ui.getpass(prompt)
3506 ui.writenoi18n(b'respose: %s\n' % r)
3516 ui.writenoi18n(b'respose: %s\n' % r)
3507
3517
3508
3518
3509 @command(
3519 @command(
3510 b'debuguiprompt',
3520 b'debuguiprompt',
3511 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3521 [(b'p', b'prompt', b'', _(b'prompt text'), _(b'TEXT')),],
3512 _(b'[-p TEXT]'),
3522 _(b'[-p TEXT]'),
3513 norepo=True,
3523 norepo=True,
3514 )
3524 )
3515 def debuguiprompt(ui, prompt=b''):
3525 def debuguiprompt(ui, prompt=b''):
3516 """show plain prompt"""
3526 """show plain prompt"""
3517 r = ui.prompt(prompt)
3527 r = ui.prompt(prompt)
3518 ui.writenoi18n(b'response: %s\n' % r)
3528 ui.writenoi18n(b'response: %s\n' % r)
3519
3529
3520
3530
3521 @command(b'debugupdatecaches', [])
3531 @command(b'debugupdatecaches', [])
3522 def debugupdatecaches(ui, repo, *pats, **opts):
3532 def debugupdatecaches(ui, repo, *pats, **opts):
3523 """warm all known caches in the repository"""
3533 """warm all known caches in the repository"""
3524 with repo.wlock(), repo.lock():
3534 with repo.wlock(), repo.lock():
3525 repo.updatecaches(full=True)
3535 repo.updatecaches(full=True)
3526
3536
3527
3537
3528 @command(
3538 @command(
3529 b'debugupgraderepo',
3539 b'debugupgraderepo',
3530 [
3540 [
3531 (
3541 (
3532 b'o',
3542 b'o',
3533 b'optimize',
3543 b'optimize',
3534 [],
3544 [],
3535 _(b'extra optimization to perform'),
3545 _(b'extra optimization to perform'),
3536 _(b'NAME'),
3546 _(b'NAME'),
3537 ),
3547 ),
3538 (b'', b'run', False, _(b'performs an upgrade')),
3548 (b'', b'run', False, _(b'performs an upgrade')),
3539 (b'', b'backup', True, _(b'keep the old repository content around')),
3549 (b'', b'backup', True, _(b'keep the old repository content around')),
3540 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3550 (b'', b'changelog', None, _(b'select the changelog for upgrade')),
3541 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3551 (b'', b'manifest', None, _(b'select the manifest for upgrade')),
3542 ],
3552 ],
3543 )
3553 )
3544 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3554 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts):
3545 """upgrade a repository to use different features
3555 """upgrade a repository to use different features
3546
3556
3547 If no arguments are specified, the repository is evaluated for upgrade
3557 If no arguments are specified, the repository is evaluated for upgrade
3548 and a list of problems and potential optimizations is printed.
3558 and a list of problems and potential optimizations is printed.
3549
3559
3550 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3560 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
3551 can be influenced via additional arguments. More details will be provided
3561 can be influenced via additional arguments. More details will be provided
3552 by the command output when run without ``--run``.
3562 by the command output when run without ``--run``.
3553
3563
3554 During the upgrade, the repository will be locked and no writes will be
3564 During the upgrade, the repository will be locked and no writes will be
3555 allowed.
3565 allowed.
3556
3566
3557 At the end of the upgrade, the repository may not be readable while new
3567 At the end of the upgrade, the repository may not be readable while new
3558 repository data is swapped in. This window will be as long as it takes to
3568 repository data is swapped in. This window will be as long as it takes to
3559 rename some directories inside the ``.hg`` directory. On most machines, this
3569 rename some directories inside the ``.hg`` directory. On most machines, this
3560 should complete almost instantaneously and the chances of a consumer being
3570 should complete almost instantaneously and the chances of a consumer being
3561 unable to access the repository should be low.
3571 unable to access the repository should be low.
3562
3572
3563 By default, all revlog will be upgraded. You can restrict this using flag
3573 By default, all revlog will be upgraded. You can restrict this using flag
3564 such as `--manifest`:
3574 such as `--manifest`:
3565
3575
3566 * `--manifest`: only optimize the manifest
3576 * `--manifest`: only optimize the manifest
3567 * `--no-manifest`: optimize all revlog but the manifest
3577 * `--no-manifest`: optimize all revlog but the manifest
3568 * `--changelog`: optimize the changelog only
3578 * `--changelog`: optimize the changelog only
3569 * `--no-changelog --no-manifest`: optimize filelogs only
3579 * `--no-changelog --no-manifest`: optimize filelogs only
3570 """
3580 """
3571 return upgrade.upgraderepo(
3581 return upgrade.upgraderepo(
3572 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3582 ui, repo, run=run, optimize=optimize, backup=backup, **opts
3573 )
3583 )
3574
3584
3575
3585
3576 @command(
3586 @command(
3577 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3587 b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True
3578 )
3588 )
3579 def debugwalk(ui, repo, *pats, **opts):
3589 def debugwalk(ui, repo, *pats, **opts):
3580 """show how files match on given patterns"""
3590 """show how files match on given patterns"""
3581 opts = pycompat.byteskwargs(opts)
3591 opts = pycompat.byteskwargs(opts)
3582 m = scmutil.match(repo[None], pats, opts)
3592 m = scmutil.match(repo[None], pats, opts)
3583 if ui.verbose:
3593 if ui.verbose:
3584 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3594 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
3585 items = list(repo[None].walk(m))
3595 items = list(repo[None].walk(m))
3586 if not items:
3596 if not items:
3587 return
3597 return
3588 f = lambda fn: fn
3598 f = lambda fn: fn
3589 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3599 if ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/':
3590 f = lambda fn: util.normpath(fn)
3600 f = lambda fn: util.normpath(fn)
3591 fmt = b'f %%-%ds %%-%ds %%s' % (
3601 fmt = b'f %%-%ds %%-%ds %%s' % (
3592 max([len(abs) for abs in items]),
3602 max([len(abs) for abs in items]),
3593 max([len(repo.pathto(abs)) for abs in items]),
3603 max([len(repo.pathto(abs)) for abs in items]),
3594 )
3604 )
3595 for abs in items:
3605 for abs in items:
3596 line = fmt % (
3606 line = fmt % (
3597 abs,
3607 abs,
3598 f(repo.pathto(abs)),
3608 f(repo.pathto(abs)),
3599 m.exact(abs) and b'exact' or b'',
3609 m.exact(abs) and b'exact' or b'',
3600 )
3610 )
3601 ui.write(b"%s\n" % line.rstrip())
3611 ui.write(b"%s\n" % line.rstrip())
3602
3612
3603
3613
3604 @command(b'debugwhyunstable', [], _(b'REV'))
3614 @command(b'debugwhyunstable', [], _(b'REV'))
3605 def debugwhyunstable(ui, repo, rev):
3615 def debugwhyunstable(ui, repo, rev):
3606 """explain instabilities of a changeset"""
3616 """explain instabilities of a changeset"""
3607 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3617 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
3608 dnodes = b''
3618 dnodes = b''
3609 if entry.get(b'divergentnodes'):
3619 if entry.get(b'divergentnodes'):
3610 dnodes = (
3620 dnodes = (
3611 b' '.join(
3621 b' '.join(
3612 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3622 b'%s (%s)' % (ctx.hex(), ctx.phasestr())
3613 for ctx in entry[b'divergentnodes']
3623 for ctx in entry[b'divergentnodes']
3614 )
3624 )
3615 + b' '
3625 + b' '
3616 )
3626 )
3617 ui.write(
3627 ui.write(
3618 b'%s: %s%s %s\n'
3628 b'%s: %s%s %s\n'
3619 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3629 % (entry[b'instability'], dnodes, entry[b'reason'], entry[b'node'])
3620 )
3630 )
3621
3631
3622
3632
3623 @command(
3633 @command(
3624 b'debugwireargs',
3634 b'debugwireargs',
3625 [
3635 [
3626 (b'', b'three', b'', b'three'),
3636 (b'', b'three', b'', b'three'),
3627 (b'', b'four', b'', b'four'),
3637 (b'', b'four', b'', b'four'),
3628 (b'', b'five', b'', b'five'),
3638 (b'', b'five', b'', b'five'),
3629 ]
3639 ]
3630 + cmdutil.remoteopts,
3640 + cmdutil.remoteopts,
3631 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3641 _(b'REPO [OPTIONS]... [ONE [TWO]]'),
3632 norepo=True,
3642 norepo=True,
3633 )
3643 )
3634 def debugwireargs(ui, repopath, *vals, **opts):
3644 def debugwireargs(ui, repopath, *vals, **opts):
3635 opts = pycompat.byteskwargs(opts)
3645 opts = pycompat.byteskwargs(opts)
3636 repo = hg.peer(ui, opts, repopath)
3646 repo = hg.peer(ui, opts, repopath)
3637 for opt in cmdutil.remoteopts:
3647 for opt in cmdutil.remoteopts:
3638 del opts[opt[1]]
3648 del opts[opt[1]]
3639 args = {}
3649 args = {}
3640 for k, v in pycompat.iteritems(opts):
3650 for k, v in pycompat.iteritems(opts):
3641 if v:
3651 if v:
3642 args[k] = v
3652 args[k] = v
3643 args = pycompat.strkwargs(args)
3653 args = pycompat.strkwargs(args)
3644 # run twice to check that we don't mess up the stream for the next command
3654 # run twice to check that we don't mess up the stream for the next command
3645 res1 = repo.debugwireargs(*vals, **args)
3655 res1 = repo.debugwireargs(*vals, **args)
3646 res2 = repo.debugwireargs(*vals, **args)
3656 res2 = repo.debugwireargs(*vals, **args)
3647 ui.write(b"%s\n" % res1)
3657 ui.write(b"%s\n" % res1)
3648 if res1 != res2:
3658 if res1 != res2:
3649 ui.warn(b"%s\n" % res2)
3659 ui.warn(b"%s\n" % res2)
3650
3660
3651
3661
3652 def _parsewirelangblocks(fh):
3662 def _parsewirelangblocks(fh):
3653 activeaction = None
3663 activeaction = None
3654 blocklines = []
3664 blocklines = []
3655 lastindent = 0
3665 lastindent = 0
3656
3666
3657 for line in fh:
3667 for line in fh:
3658 line = line.rstrip()
3668 line = line.rstrip()
3659 if not line:
3669 if not line:
3660 continue
3670 continue
3661
3671
3662 if line.startswith(b'#'):
3672 if line.startswith(b'#'):
3663 continue
3673 continue
3664
3674
3665 if not line.startswith(b' '):
3675 if not line.startswith(b' '):
3666 # New block. Flush previous one.
3676 # New block. Flush previous one.
3667 if activeaction:
3677 if activeaction:
3668 yield activeaction, blocklines
3678 yield activeaction, blocklines
3669
3679
3670 activeaction = line
3680 activeaction = line
3671 blocklines = []
3681 blocklines = []
3672 lastindent = 0
3682 lastindent = 0
3673 continue
3683 continue
3674
3684
3675 # Else we start with an indent.
3685 # Else we start with an indent.
3676
3686
3677 if not activeaction:
3687 if not activeaction:
3678 raise error.Abort(_(b'indented line outside of block'))
3688 raise error.Abort(_(b'indented line outside of block'))
3679
3689
3680 indent = len(line) - len(line.lstrip())
3690 indent = len(line) - len(line.lstrip())
3681
3691
3682 # If this line is indented more than the last line, concatenate it.
3692 # If this line is indented more than the last line, concatenate it.
3683 if indent > lastindent and blocklines:
3693 if indent > lastindent and blocklines:
3684 blocklines[-1] += line.lstrip()
3694 blocklines[-1] += line.lstrip()
3685 else:
3695 else:
3686 blocklines.append(line)
3696 blocklines.append(line)
3687 lastindent = indent
3697 lastindent = indent
3688
3698
3689 # Flush last block.
3699 # Flush last block.
3690 if activeaction:
3700 if activeaction:
3691 yield activeaction, blocklines
3701 yield activeaction, blocklines
3692
3702
3693
3703
3694 @command(
3704 @command(
3695 b'debugwireproto',
3705 b'debugwireproto',
3696 [
3706 [
3697 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3707 (b'', b'localssh', False, _(b'start an SSH server for this repo')),
3698 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3708 (b'', b'peer', b'', _(b'construct a specific version of the peer')),
3699 (
3709 (
3700 b'',
3710 b'',
3701 b'noreadstderr',
3711 b'noreadstderr',
3702 False,
3712 False,
3703 _(b'do not read from stderr of the remote'),
3713 _(b'do not read from stderr of the remote'),
3704 ),
3714 ),
3705 (
3715 (
3706 b'',
3716 b'',
3707 b'nologhandshake',
3717 b'nologhandshake',
3708 False,
3718 False,
3709 _(b'do not log I/O related to the peer handshake'),
3719 _(b'do not log I/O related to the peer handshake'),
3710 ),
3720 ),
3711 ]
3721 ]
3712 + cmdutil.remoteopts,
3722 + cmdutil.remoteopts,
3713 _(b'[PATH]'),
3723 _(b'[PATH]'),
3714 optionalrepo=True,
3724 optionalrepo=True,
3715 )
3725 )
3716 def debugwireproto(ui, repo, path=None, **opts):
3726 def debugwireproto(ui, repo, path=None, **opts):
3717 """send wire protocol commands to a server
3727 """send wire protocol commands to a server
3718
3728
3719 This command can be used to issue wire protocol commands to remote
3729 This command can be used to issue wire protocol commands to remote
3720 peers and to debug the raw data being exchanged.
3730 peers and to debug the raw data being exchanged.
3721
3731
3722 ``--localssh`` will start an SSH server against the current repository
3732 ``--localssh`` will start an SSH server against the current repository
3723 and connect to that. By default, the connection will perform a handshake
3733 and connect to that. By default, the connection will perform a handshake
3724 and establish an appropriate peer instance.
3734 and establish an appropriate peer instance.
3725
3735
3726 ``--peer`` can be used to bypass the handshake protocol and construct a
3736 ``--peer`` can be used to bypass the handshake protocol and construct a
3727 peer instance using the specified class type. Valid values are ``raw``,
3737 peer instance using the specified class type. Valid values are ``raw``,
3728 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3738 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
3729 raw data payloads and don't support higher-level command actions.
3739 raw data payloads and don't support higher-level command actions.
3730
3740
3731 ``--noreadstderr`` can be used to disable automatic reading from stderr
3741 ``--noreadstderr`` can be used to disable automatic reading from stderr
3732 of the peer (for SSH connections only). Disabling automatic reading of
3742 of the peer (for SSH connections only). Disabling automatic reading of
3733 stderr is useful for making output more deterministic.
3743 stderr is useful for making output more deterministic.
3734
3744
3735 Commands are issued via a mini language which is specified via stdin.
3745 Commands are issued via a mini language which is specified via stdin.
3736 The language consists of individual actions to perform. An action is
3746 The language consists of individual actions to perform. An action is
3737 defined by a block. A block is defined as a line with no leading
3747 defined by a block. A block is defined as a line with no leading
3738 space followed by 0 or more lines with leading space. Blocks are
3748 space followed by 0 or more lines with leading space. Blocks are
3739 effectively a high-level command with additional metadata.
3749 effectively a high-level command with additional metadata.
3740
3750
3741 Lines beginning with ``#`` are ignored.
3751 Lines beginning with ``#`` are ignored.
3742
3752
3743 The following sections denote available actions.
3753 The following sections denote available actions.
3744
3754
3745 raw
3755 raw
3746 ---
3756 ---
3747
3757
3748 Send raw data to the server.
3758 Send raw data to the server.
3749
3759
3750 The block payload contains the raw data to send as one atomic send
3760 The block payload contains the raw data to send as one atomic send
3751 operation. The data may not actually be delivered in a single system
3761 operation. The data may not actually be delivered in a single system
3752 call: it depends on the abilities of the transport being used.
3762 call: it depends on the abilities of the transport being used.
3753
3763
3754 Each line in the block is de-indented and concatenated. Then, that
3764 Each line in the block is de-indented and concatenated. Then, that
3755 value is evaluated as a Python b'' literal. This allows the use of
3765 value is evaluated as a Python b'' literal. This allows the use of
3756 backslash escaping, etc.
3766 backslash escaping, etc.
3757
3767
3758 raw+
3768 raw+
3759 ----
3769 ----
3760
3770
3761 Behaves like ``raw`` except flushes output afterwards.
3771 Behaves like ``raw`` except flushes output afterwards.
3762
3772
3763 command <X>
3773 command <X>
3764 -----------
3774 -----------
3765
3775
3766 Send a request to run a named command, whose name follows the ``command``
3776 Send a request to run a named command, whose name follows the ``command``
3767 string.
3777 string.
3768
3778
3769 Arguments to the command are defined as lines in this block. The format of
3779 Arguments to the command are defined as lines in this block. The format of
3770 each line is ``<key> <value>``. e.g.::
3780 each line is ``<key> <value>``. e.g.::
3771
3781
3772 command listkeys
3782 command listkeys
3773 namespace bookmarks
3783 namespace bookmarks
3774
3784
3775 If the value begins with ``eval:``, it will be interpreted as a Python
3785 If the value begins with ``eval:``, it will be interpreted as a Python
3776 literal expression. Otherwise values are interpreted as Python b'' literals.
3786 literal expression. Otherwise values are interpreted as Python b'' literals.
3777 This allows sending complex types and encoding special byte sequences via
3787 This allows sending complex types and encoding special byte sequences via
3778 backslash escaping.
3788 backslash escaping.
3779
3789
3780 The following arguments have special meaning:
3790 The following arguments have special meaning:
3781
3791
3782 ``PUSHFILE``
3792 ``PUSHFILE``
3783 When defined, the *push* mechanism of the peer will be used instead
3793 When defined, the *push* mechanism of the peer will be used instead
3784 of the static request-response mechanism and the content of the
3794 of the static request-response mechanism and the content of the
3785 file specified in the value of this argument will be sent as the
3795 file specified in the value of this argument will be sent as the
3786 command payload.
3796 command payload.
3787
3797
3788 This can be used to submit a local bundle file to the remote.
3798 This can be used to submit a local bundle file to the remote.
3789
3799
3790 batchbegin
3800 batchbegin
3791 ----------
3801 ----------
3792
3802
3793 Instruct the peer to begin a batched send.
3803 Instruct the peer to begin a batched send.
3794
3804
3795 All ``command`` blocks are queued for execution until the next
3805 All ``command`` blocks are queued for execution until the next
3796 ``batchsubmit`` block.
3806 ``batchsubmit`` block.
3797
3807
3798 batchsubmit
3808 batchsubmit
3799 -----------
3809 -----------
3800
3810
3801 Submit previously queued ``command`` blocks as a batch request.
3811 Submit previously queued ``command`` blocks as a batch request.
3802
3812
3803 This action MUST be paired with a ``batchbegin`` action.
3813 This action MUST be paired with a ``batchbegin`` action.
3804
3814
3805 httprequest <method> <path>
3815 httprequest <method> <path>
3806 ---------------------------
3816 ---------------------------
3807
3817
3808 (HTTP peer only)
3818 (HTTP peer only)
3809
3819
3810 Send an HTTP request to the peer.
3820 Send an HTTP request to the peer.
3811
3821
3812 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3822 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
3813
3823
3814 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
3824 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
3815 headers to add to the request. e.g. ``Accept: foo``.
3825 headers to add to the request. e.g. ``Accept: foo``.
3816
3826
3817 The following arguments are special:
3827 The following arguments are special:
3818
3828
3819 ``BODYFILE``
3829 ``BODYFILE``
3820 The content of the file defined as the value to this argument will be
3830 The content of the file defined as the value to this argument will be
3821 transferred verbatim as the HTTP request body.
3831 transferred verbatim as the HTTP request body.
3822
3832
3823 ``frame <type> <flags> <payload>``
3833 ``frame <type> <flags> <payload>``
3824 Send a unified protocol frame as part of the request body.
3834 Send a unified protocol frame as part of the request body.
3825
3835
3826 All frames will be collected and sent as the body to the HTTP
3836 All frames will be collected and sent as the body to the HTTP
3827 request.
3837 request.
3828
3838
3829 close
3839 close
3830 -----
3840 -----
3831
3841
3832 Close the connection to the server.
3842 Close the connection to the server.
3833
3843
3834 flush
3844 flush
3835 -----
3845 -----
3836
3846
3837 Flush data written to the server.
3847 Flush data written to the server.
3838
3848
3839 readavailable
3849 readavailable
3840 -------------
3850 -------------
3841
3851
3842 Close the write end of the connection and read all available data from
3852 Close the write end of the connection and read all available data from
3843 the server.
3853 the server.
3844
3854
3845 If the connection to the server encompasses multiple pipes, we poll both
3855 If the connection to the server encompasses multiple pipes, we poll both
3846 pipes and read available data.
3856 pipes and read available data.
3847
3857
3848 readline
3858 readline
3849 --------
3859 --------
3850
3860
3851 Read a line of output from the server. If there are multiple output
3861 Read a line of output from the server. If there are multiple output
3852 pipes, reads only the main pipe.
3862 pipes, reads only the main pipe.
3853
3863
3854 ereadline
3864 ereadline
3855 ---------
3865 ---------
3856
3866
3857 Like ``readline``, but read from the stderr pipe, if available.
3867 Like ``readline``, but read from the stderr pipe, if available.
3858
3868
3859 read <X>
3869 read <X>
3860 --------
3870 --------
3861
3871
3862 ``read()`` N bytes from the server's main output pipe.
3872 ``read()`` N bytes from the server's main output pipe.
3863
3873
3864 eread <X>
3874 eread <X>
3865 ---------
3875 ---------
3866
3876
3867 ``read()`` N bytes from the server's stderr pipe, if available.
3877 ``read()`` N bytes from the server's stderr pipe, if available.
3868
3878
3869 Specifying Unified Frame-Based Protocol Frames
3879 Specifying Unified Frame-Based Protocol Frames
3870 ----------------------------------------------
3880 ----------------------------------------------
3871
3881
3872 It is possible to emit a *Unified Frame-Based Protocol* by using special
3882 It is possible to emit a *Unified Frame-Based Protocol* by using special
3873 syntax.
3883 syntax.
3874
3884
3875 A frame is composed as a type, flags, and payload. These can be parsed
3885 A frame is composed as a type, flags, and payload. These can be parsed
3876 from a string of the form:
3886 from a string of the form:
3877
3887
3878 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3888 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3879
3889
3880 ``request-id`` and ``stream-id`` are integers defining the request and
3890 ``request-id`` and ``stream-id`` are integers defining the request and
3881 stream identifiers.
3891 stream identifiers.
3882
3892
3883 ``type`` can be an integer value for the frame type or the string name
3893 ``type`` can be an integer value for the frame type or the string name
3884 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3894 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3885 ``command-name``.
3895 ``command-name``.
3886
3896
3887 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3897 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3888 components. Each component (and there can be just one) can be an integer
3898 components. Each component (and there can be just one) can be an integer
3889 or a flag name for stream flags or frame flags, respectively. Values are
3899 or a flag name for stream flags or frame flags, respectively. Values are
3890 resolved to integers and then bitwise OR'd together.
3900 resolved to integers and then bitwise OR'd together.
3891
3901
3892 ``payload`` represents the raw frame payload. If it begins with
3902 ``payload`` represents the raw frame payload. If it begins with
3893 ``cbor:``, the following string is evaluated as Python code and the
3903 ``cbor:``, the following string is evaluated as Python code and the
3894 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3904 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3895 as a Python byte string literal.
3905 as a Python byte string literal.
3896 """
3906 """
3897 opts = pycompat.byteskwargs(opts)
3907 opts = pycompat.byteskwargs(opts)
3898
3908
3899 if opts[b'localssh'] and not repo:
3909 if opts[b'localssh'] and not repo:
3900 raise error.Abort(_(b'--localssh requires a repository'))
3910 raise error.Abort(_(b'--localssh requires a repository'))
3901
3911
3902 if opts[b'peer'] and opts[b'peer'] not in (
3912 if opts[b'peer'] and opts[b'peer'] not in (
3903 b'raw',
3913 b'raw',
3904 b'http2',
3914 b'http2',
3905 b'ssh1',
3915 b'ssh1',
3906 b'ssh2',
3916 b'ssh2',
3907 ):
3917 ):
3908 raise error.Abort(
3918 raise error.Abort(
3909 _(b'invalid value for --peer'),
3919 _(b'invalid value for --peer'),
3910 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
3920 hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
3911 )
3921 )
3912
3922
3913 if path and opts[b'localssh']:
3923 if path and opts[b'localssh']:
3914 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
3924 raise error.Abort(_(b'cannot specify --localssh with an explicit path'))
3915
3925
3916 if ui.interactive():
3926 if ui.interactive():
3917 ui.write(_(b'(waiting for commands on stdin)\n'))
3927 ui.write(_(b'(waiting for commands on stdin)\n'))
3918
3928
3919 blocks = list(_parsewirelangblocks(ui.fin))
3929 blocks = list(_parsewirelangblocks(ui.fin))
3920
3930
3921 proc = None
3931 proc = None
3922 stdin = None
3932 stdin = None
3923 stdout = None
3933 stdout = None
3924 stderr = None
3934 stderr = None
3925 opener = None
3935 opener = None
3926
3936
3927 if opts[b'localssh']:
3937 if opts[b'localssh']:
3928 # We start the SSH server in its own process so there is process
3938 # We start the SSH server in its own process so there is process
3929 # separation. This prevents a whole class of potential bugs around
3939 # separation. This prevents a whole class of potential bugs around
3930 # shared state from interfering with server operation.
3940 # shared state from interfering with server operation.
3931 args = procutil.hgcmd() + [
3941 args = procutil.hgcmd() + [
3932 b'-R',
3942 b'-R',
3933 repo.root,
3943 repo.root,
3934 b'debugserve',
3944 b'debugserve',
3935 b'--sshstdio',
3945 b'--sshstdio',
3936 ]
3946 ]
3937 proc = subprocess.Popen(
3947 proc = subprocess.Popen(
3938 pycompat.rapply(procutil.tonativestr, args),
3948 pycompat.rapply(procutil.tonativestr, args),
3939 stdin=subprocess.PIPE,
3949 stdin=subprocess.PIPE,
3940 stdout=subprocess.PIPE,
3950 stdout=subprocess.PIPE,
3941 stderr=subprocess.PIPE,
3951 stderr=subprocess.PIPE,
3942 bufsize=0,
3952 bufsize=0,
3943 )
3953 )
3944
3954
3945 stdin = proc.stdin
3955 stdin = proc.stdin
3946 stdout = proc.stdout
3956 stdout = proc.stdout
3947 stderr = proc.stderr
3957 stderr = proc.stderr
3948
3958
3949 # We turn the pipes into observers so we can log I/O.
3959 # We turn the pipes into observers so we can log I/O.
3950 if ui.verbose or opts[b'peer'] == b'raw':
3960 if ui.verbose or opts[b'peer'] == b'raw':
3951 stdin = util.makeloggingfileobject(
3961 stdin = util.makeloggingfileobject(
3952 ui, proc.stdin, b'i', logdata=True
3962 ui, proc.stdin, b'i', logdata=True
3953 )
3963 )
3954 stdout = util.makeloggingfileobject(
3964 stdout = util.makeloggingfileobject(
3955 ui, proc.stdout, b'o', logdata=True
3965 ui, proc.stdout, b'o', logdata=True
3956 )
3966 )
3957 stderr = util.makeloggingfileobject(
3967 stderr = util.makeloggingfileobject(
3958 ui, proc.stderr, b'e', logdata=True
3968 ui, proc.stderr, b'e', logdata=True
3959 )
3969 )
3960
3970
3961 # --localssh also implies the peer connection settings.
3971 # --localssh also implies the peer connection settings.
3962
3972
3963 url = b'ssh://localserver'
3973 url = b'ssh://localserver'
3964 autoreadstderr = not opts[b'noreadstderr']
3974 autoreadstderr = not opts[b'noreadstderr']
3965
3975
3966 if opts[b'peer'] == b'ssh1':
3976 if opts[b'peer'] == b'ssh1':
3967 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
3977 ui.write(_(b'creating ssh peer for wire protocol version 1\n'))
3968 peer = sshpeer.sshv1peer(
3978 peer = sshpeer.sshv1peer(
3969 ui,
3979 ui,
3970 url,
3980 url,
3971 proc,
3981 proc,
3972 stdin,
3982 stdin,
3973 stdout,
3983 stdout,
3974 stderr,
3984 stderr,
3975 None,
3985 None,
3976 autoreadstderr=autoreadstderr,
3986 autoreadstderr=autoreadstderr,
3977 )
3987 )
3978 elif opts[b'peer'] == b'ssh2':
3988 elif opts[b'peer'] == b'ssh2':
3979 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
3989 ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
3980 peer = sshpeer.sshv2peer(
3990 peer = sshpeer.sshv2peer(
3981 ui,
3991 ui,
3982 url,
3992 url,
3983 proc,
3993 proc,
3984 stdin,
3994 stdin,
3985 stdout,
3995 stdout,
3986 stderr,
3996 stderr,
3987 None,
3997 None,
3988 autoreadstderr=autoreadstderr,
3998 autoreadstderr=autoreadstderr,
3989 )
3999 )
3990 elif opts[b'peer'] == b'raw':
4000 elif opts[b'peer'] == b'raw':
3991 ui.write(_(b'using raw connection to peer\n'))
4001 ui.write(_(b'using raw connection to peer\n'))
3992 peer = None
4002 peer = None
3993 else:
4003 else:
3994 ui.write(_(b'creating ssh peer from handshake results\n'))
4004 ui.write(_(b'creating ssh peer from handshake results\n'))
3995 peer = sshpeer.makepeer(
4005 peer = sshpeer.makepeer(
3996 ui,
4006 ui,
3997 url,
4007 url,
3998 proc,
4008 proc,
3999 stdin,
4009 stdin,
4000 stdout,
4010 stdout,
4001 stderr,
4011 stderr,
4002 autoreadstderr=autoreadstderr,
4012 autoreadstderr=autoreadstderr,
4003 )
4013 )
4004
4014
4005 elif path:
4015 elif path:
4006 # We bypass hg.peer() so we can proxy the sockets.
4016 # We bypass hg.peer() so we can proxy the sockets.
4007 # TODO consider not doing this because we skip
4017 # TODO consider not doing this because we skip
4008 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4018 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
4009 u = util.url(path)
4019 u = util.url(path)
4010 if u.scheme != b'http':
4020 if u.scheme != b'http':
4011 raise error.Abort(_(b'only http:// paths are currently supported'))
4021 raise error.Abort(_(b'only http:// paths are currently supported'))
4012
4022
4013 url, authinfo = u.authinfo()
4023 url, authinfo = u.authinfo()
4014 openerargs = {
4024 openerargs = {
4015 'useragent': b'Mercurial debugwireproto',
4025 'useragent': b'Mercurial debugwireproto',
4016 }
4026 }
4017
4027
4018 # Turn pipes/sockets into observers so we can log I/O.
4028 # Turn pipes/sockets into observers so we can log I/O.
4019 if ui.verbose:
4029 if ui.verbose:
4020 openerargs.update(
4030 openerargs.update(
4021 {
4031 {
4022 'loggingfh': ui,
4032 'loggingfh': ui,
4023 'loggingname': b's',
4033 'loggingname': b's',
4024 'loggingopts': {'logdata': True, 'logdataapis': False,},
4034 'loggingopts': {'logdata': True, 'logdataapis': False,},
4025 }
4035 }
4026 )
4036 )
4027
4037
4028 if ui.debugflag:
4038 if ui.debugflag:
4029 openerargs['loggingopts']['logdataapis'] = True
4039 openerargs['loggingopts']['logdataapis'] = True
4030
4040
4031 # Don't send default headers when in raw mode. This allows us to
4041 # Don't send default headers when in raw mode. This allows us to
4032 # bypass most of the behavior of our URL handling code so we can
4042 # bypass most of the behavior of our URL handling code so we can
4033 # have near complete control over what's sent on the wire.
4043 # have near complete control over what's sent on the wire.
4034 if opts[b'peer'] == b'raw':
4044 if opts[b'peer'] == b'raw':
4035 openerargs['sendaccept'] = False
4045 openerargs['sendaccept'] = False
4036
4046
4037 opener = urlmod.opener(ui, authinfo, **openerargs)
4047 opener = urlmod.opener(ui, authinfo, **openerargs)
4038
4048
4039 if opts[b'peer'] == b'http2':
4049 if opts[b'peer'] == b'http2':
4040 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4050 ui.write(_(b'creating http peer for wire protocol version 2\n'))
4041 # We go through makepeer() because we need an API descriptor for
4051 # We go through makepeer() because we need an API descriptor for
4042 # the peer instance to be useful.
4052 # the peer instance to be useful.
4043 with ui.configoverride(
4053 with ui.configoverride(
4044 {(b'experimental', b'httppeer.advertise-v2'): True}
4054 {(b'experimental', b'httppeer.advertise-v2'): True}
4045 ):
4055 ):
4046 if opts[b'nologhandshake']:
4056 if opts[b'nologhandshake']:
4047 ui.pushbuffer()
4057 ui.pushbuffer()
4048
4058
4049 peer = httppeer.makepeer(ui, path, opener=opener)
4059 peer = httppeer.makepeer(ui, path, opener=opener)
4050
4060
4051 if opts[b'nologhandshake']:
4061 if opts[b'nologhandshake']:
4052 ui.popbuffer()
4062 ui.popbuffer()
4053
4063
4054 if not isinstance(peer, httppeer.httpv2peer):
4064 if not isinstance(peer, httppeer.httpv2peer):
4055 raise error.Abort(
4065 raise error.Abort(
4056 _(
4066 _(
4057 b'could not instantiate HTTP peer for '
4067 b'could not instantiate HTTP peer for '
4058 b'wire protocol version 2'
4068 b'wire protocol version 2'
4059 ),
4069 ),
4060 hint=_(
4070 hint=_(
4061 b'the server may not have the feature '
4071 b'the server may not have the feature '
4062 b'enabled or is not allowing this '
4072 b'enabled or is not allowing this '
4063 b'client version'
4073 b'client version'
4064 ),
4074 ),
4065 )
4075 )
4066
4076
4067 elif opts[b'peer'] == b'raw':
4077 elif opts[b'peer'] == b'raw':
4068 ui.write(_(b'using raw connection to peer\n'))
4078 ui.write(_(b'using raw connection to peer\n'))
4069 peer = None
4079 peer = None
4070 elif opts[b'peer']:
4080 elif opts[b'peer']:
4071 raise error.Abort(
4081 raise error.Abort(
4072 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4082 _(b'--peer %s not supported with HTTP peers') % opts[b'peer']
4073 )
4083 )
4074 else:
4084 else:
4075 peer = httppeer.makepeer(ui, path, opener=opener)
4085 peer = httppeer.makepeer(ui, path, opener=opener)
4076
4086
4077 # We /could/ populate stdin/stdout with sock.makefile()...
4087 # We /could/ populate stdin/stdout with sock.makefile()...
4078 else:
4088 else:
4079 raise error.Abort(_(b'unsupported connection configuration'))
4089 raise error.Abort(_(b'unsupported connection configuration'))
4080
4090
4081 batchedcommands = None
4091 batchedcommands = None
4082
4092
4083 # Now perform actions based on the parsed wire language instructions.
4093 # Now perform actions based on the parsed wire language instructions.
4084 for action, lines in blocks:
4094 for action, lines in blocks:
4085 if action in (b'raw', b'raw+'):
4095 if action in (b'raw', b'raw+'):
4086 if not stdin:
4096 if not stdin:
4087 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4097 raise error.Abort(_(b'cannot call raw/raw+ on this peer'))
4088
4098
4089 # Concatenate the data together.
4099 # Concatenate the data together.
4090 data = b''.join(l.lstrip() for l in lines)
4100 data = b''.join(l.lstrip() for l in lines)
4091 data = stringutil.unescapestr(data)
4101 data = stringutil.unescapestr(data)
4092 stdin.write(data)
4102 stdin.write(data)
4093
4103
4094 if action == b'raw+':
4104 if action == b'raw+':
4095 stdin.flush()
4105 stdin.flush()
4096 elif action == b'flush':
4106 elif action == b'flush':
4097 if not stdin:
4107 if not stdin:
4098 raise error.Abort(_(b'cannot call flush on this peer'))
4108 raise error.Abort(_(b'cannot call flush on this peer'))
4099 stdin.flush()
4109 stdin.flush()
4100 elif action.startswith(b'command'):
4110 elif action.startswith(b'command'):
4101 if not peer:
4111 if not peer:
4102 raise error.Abort(
4112 raise error.Abort(
4103 _(
4113 _(
4104 b'cannot send commands unless peer instance '
4114 b'cannot send commands unless peer instance '
4105 b'is available'
4115 b'is available'
4106 )
4116 )
4107 )
4117 )
4108
4118
4109 command = action.split(b' ', 1)[1]
4119 command = action.split(b' ', 1)[1]
4110
4120
4111 args = {}
4121 args = {}
4112 for line in lines:
4122 for line in lines:
4113 # We need to allow empty values.
4123 # We need to allow empty values.
4114 fields = line.lstrip().split(b' ', 1)
4124 fields = line.lstrip().split(b' ', 1)
4115 if len(fields) == 1:
4125 if len(fields) == 1:
4116 key = fields[0]
4126 key = fields[0]
4117 value = b''
4127 value = b''
4118 else:
4128 else:
4119 key, value = fields
4129 key, value = fields
4120
4130
4121 if value.startswith(b'eval:'):
4131 if value.startswith(b'eval:'):
4122 value = stringutil.evalpythonliteral(value[5:])
4132 value = stringutil.evalpythonliteral(value[5:])
4123 else:
4133 else:
4124 value = stringutil.unescapestr(value)
4134 value = stringutil.unescapestr(value)
4125
4135
4126 args[key] = value
4136 args[key] = value
4127
4137
4128 if batchedcommands is not None:
4138 if batchedcommands is not None:
4129 batchedcommands.append((command, args))
4139 batchedcommands.append((command, args))
4130 continue
4140 continue
4131
4141
4132 ui.status(_(b'sending %s command\n') % command)
4142 ui.status(_(b'sending %s command\n') % command)
4133
4143
4134 if b'PUSHFILE' in args:
4144 if b'PUSHFILE' in args:
4135 with open(args[b'PUSHFILE'], 'rb') as fh:
4145 with open(args[b'PUSHFILE'], 'rb') as fh:
4136 del args[b'PUSHFILE']
4146 del args[b'PUSHFILE']
4137 res, output = peer._callpush(
4147 res, output = peer._callpush(
4138 command, fh, **pycompat.strkwargs(args)
4148 command, fh, **pycompat.strkwargs(args)
4139 )
4149 )
4140 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4150 ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
4141 ui.status(
4151 ui.status(
4142 _(b'remote output: %s\n') % stringutil.escapestr(output)
4152 _(b'remote output: %s\n') % stringutil.escapestr(output)
4143 )
4153 )
4144 else:
4154 else:
4145 with peer.commandexecutor() as e:
4155 with peer.commandexecutor() as e:
4146 res = e.callcommand(command, args).result()
4156 res = e.callcommand(command, args).result()
4147
4157
4148 if isinstance(res, wireprotov2peer.commandresponse):
4158 if isinstance(res, wireprotov2peer.commandresponse):
4149 val = res.objects()
4159 val = res.objects()
4150 ui.status(
4160 ui.status(
4151 _(b'response: %s\n')
4161 _(b'response: %s\n')
4152 % stringutil.pprint(val, bprefix=True, indent=2)
4162 % stringutil.pprint(val, bprefix=True, indent=2)
4153 )
4163 )
4154 else:
4164 else:
4155 ui.status(
4165 ui.status(
4156 _(b'response: %s\n')
4166 _(b'response: %s\n')
4157 % stringutil.pprint(res, bprefix=True, indent=2)
4167 % stringutil.pprint(res, bprefix=True, indent=2)
4158 )
4168 )
4159
4169
4160 elif action == b'batchbegin':
4170 elif action == b'batchbegin':
4161 if batchedcommands is not None:
4171 if batchedcommands is not None:
4162 raise error.Abort(_(b'nested batchbegin not allowed'))
4172 raise error.Abort(_(b'nested batchbegin not allowed'))
4163
4173
4164 batchedcommands = []
4174 batchedcommands = []
4165 elif action == b'batchsubmit':
4175 elif action == b'batchsubmit':
4166 # There is a batching API we could go through. But it would be
4176 # There is a batching API we could go through. But it would be
4167 # difficult to normalize requests into function calls. It is easier
4177 # difficult to normalize requests into function calls. It is easier
4168 # to bypass this layer and normalize to commands + args.
4178 # to bypass this layer and normalize to commands + args.
4169 ui.status(
4179 ui.status(
4170 _(b'sending batch with %d sub-commands\n')
4180 _(b'sending batch with %d sub-commands\n')
4171 % len(batchedcommands)
4181 % len(batchedcommands)
4172 )
4182 )
4173 assert peer is not None
4183 assert peer is not None
4174 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4184 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
4175 ui.status(
4185 ui.status(
4176 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4186 _(b'response #%d: %s\n') % (i, stringutil.escapestr(chunk))
4177 )
4187 )
4178
4188
4179 batchedcommands = None
4189 batchedcommands = None
4180
4190
4181 elif action.startswith(b'httprequest '):
4191 elif action.startswith(b'httprequest '):
4182 if not opener:
4192 if not opener:
4183 raise error.Abort(
4193 raise error.Abort(
4184 _(b'cannot use httprequest without an HTTP peer')
4194 _(b'cannot use httprequest without an HTTP peer')
4185 )
4195 )
4186
4196
4187 request = action.split(b' ', 2)
4197 request = action.split(b' ', 2)
4188 if len(request) != 3:
4198 if len(request) != 3:
4189 raise error.Abort(
4199 raise error.Abort(
4190 _(
4200 _(
4191 b'invalid httprequest: expected format is '
4201 b'invalid httprequest: expected format is '
4192 b'"httprequest <method> <path>'
4202 b'"httprequest <method> <path>'
4193 )
4203 )
4194 )
4204 )
4195
4205
4196 method, httppath = request[1:]
4206 method, httppath = request[1:]
4197 headers = {}
4207 headers = {}
4198 body = None
4208 body = None
4199 frames = []
4209 frames = []
4200 for line in lines:
4210 for line in lines:
4201 line = line.lstrip()
4211 line = line.lstrip()
4202 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4212 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
4203 if m:
4213 if m:
4204 # Headers need to use native strings.
4214 # Headers need to use native strings.
4205 key = pycompat.strurl(m.group(1))
4215 key = pycompat.strurl(m.group(1))
4206 value = pycompat.strurl(m.group(2))
4216 value = pycompat.strurl(m.group(2))
4207 headers[key] = value
4217 headers[key] = value
4208 continue
4218 continue
4209
4219
4210 if line.startswith(b'BODYFILE '):
4220 if line.startswith(b'BODYFILE '):
4211 with open(line.split(b' ', 1), b'rb') as fh:
4221 with open(line.split(b' ', 1), b'rb') as fh:
4212 body = fh.read()
4222 body = fh.read()
4213 elif line.startswith(b'frame '):
4223 elif line.startswith(b'frame '):
4214 frame = wireprotoframing.makeframefromhumanstring(
4224 frame = wireprotoframing.makeframefromhumanstring(
4215 line[len(b'frame ') :]
4225 line[len(b'frame ') :]
4216 )
4226 )
4217
4227
4218 frames.append(frame)
4228 frames.append(frame)
4219 else:
4229 else:
4220 raise error.Abort(
4230 raise error.Abort(
4221 _(b'unknown argument to httprequest: %s') % line
4231 _(b'unknown argument to httprequest: %s') % line
4222 )
4232 )
4223
4233
4224 url = path + httppath
4234 url = path + httppath
4225
4235
4226 if frames:
4236 if frames:
4227 body = b''.join(bytes(f) for f in frames)
4237 body = b''.join(bytes(f) for f in frames)
4228
4238
4229 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4239 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
4230
4240
4231 # urllib.Request insists on using has_data() as a proxy for
4241 # urllib.Request insists on using has_data() as a proxy for
4232 # determining the request method. Override that to use our
4242 # determining the request method. Override that to use our
4233 # explicitly requested method.
4243 # explicitly requested method.
4234 req.get_method = lambda: pycompat.sysstr(method)
4244 req.get_method = lambda: pycompat.sysstr(method)
4235
4245
4236 try:
4246 try:
4237 res = opener.open(req)
4247 res = opener.open(req)
4238 body = res.read()
4248 body = res.read()
4239 except util.urlerr.urlerror as e:
4249 except util.urlerr.urlerror as e:
4240 # read() method must be called, but only exists in Python 2
4250 # read() method must be called, but only exists in Python 2
4241 getattr(e, 'read', lambda: None)()
4251 getattr(e, 'read', lambda: None)()
4242 continue
4252 continue
4243
4253
4244 ct = res.headers.get('Content-Type')
4254 ct = res.headers.get('Content-Type')
4245 if ct == 'application/mercurial-cbor':
4255 if ct == 'application/mercurial-cbor':
4246 ui.write(
4256 ui.write(
4247 _(b'cbor> %s\n')
4257 _(b'cbor> %s\n')
4248 % stringutil.pprint(
4258 % stringutil.pprint(
4249 cborutil.decodeall(body), bprefix=True, indent=2
4259 cborutil.decodeall(body), bprefix=True, indent=2
4250 )
4260 )
4251 )
4261 )
4252
4262
4253 elif action == b'close':
4263 elif action == b'close':
4254 assert peer is not None
4264 assert peer is not None
4255 peer.close()
4265 peer.close()
4256 elif action == b'readavailable':
4266 elif action == b'readavailable':
4257 if not stdout or not stderr:
4267 if not stdout or not stderr:
4258 raise error.Abort(
4268 raise error.Abort(
4259 _(b'readavailable not available on this peer')
4269 _(b'readavailable not available on this peer')
4260 )
4270 )
4261
4271
4262 stdin.close()
4272 stdin.close()
4263 stdout.read()
4273 stdout.read()
4264 stderr.read()
4274 stderr.read()
4265
4275
4266 elif action == b'readline':
4276 elif action == b'readline':
4267 if not stdout:
4277 if not stdout:
4268 raise error.Abort(_(b'readline not available on this peer'))
4278 raise error.Abort(_(b'readline not available on this peer'))
4269 stdout.readline()
4279 stdout.readline()
4270 elif action == b'ereadline':
4280 elif action == b'ereadline':
4271 if not stderr:
4281 if not stderr:
4272 raise error.Abort(_(b'ereadline not available on this peer'))
4282 raise error.Abort(_(b'ereadline not available on this peer'))
4273 stderr.readline()
4283 stderr.readline()
4274 elif action.startswith(b'read '):
4284 elif action.startswith(b'read '):
4275 count = int(action.split(b' ', 1)[1])
4285 count = int(action.split(b' ', 1)[1])
4276 if not stdout:
4286 if not stdout:
4277 raise error.Abort(_(b'read not available on this peer'))
4287 raise error.Abort(_(b'read not available on this peer'))
4278 stdout.read(count)
4288 stdout.read(count)
4279 elif action.startswith(b'eread '):
4289 elif action.startswith(b'eread '):
4280 count = int(action.split(b' ', 1)[1])
4290 count = int(action.split(b' ', 1)[1])
4281 if not stderr:
4291 if not stderr:
4282 raise error.Abort(_(b'eread not available on this peer'))
4292 raise error.Abort(_(b'eread not available on this peer'))
4283 stderr.read(count)
4293 stderr.read(count)
4284 else:
4294 else:
4285 raise error.Abort(_(b'unknown action: %s') % action)
4295 raise error.Abort(_(b'unknown action: %s') % action)
4286
4296
4287 if batchedcommands is not None:
4297 if batchedcommands is not None:
4288 raise error.Abort(_(b'unclosed "batchbegin" request'))
4298 raise error.Abort(_(b'unclosed "batchbegin" request'))
4289
4299
4290 if peer:
4300 if peer:
4291 peer.close()
4301 peer.close()
4292
4302
4293 if proc:
4303 if proc:
4294 proc.kill()
4304 proc.kill()
@@ -1,425 +1,427 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 annotate
6 annotate
7 archive
7 archive
8 backout
8 backout
9 bisect
9 bisect
10 bookmarks
10 bookmarks
11 branch
11 branch
12 branches
12 branches
13 bundle
13 bundle
14 cat
14 cat
15 clone
15 clone
16 commit
16 commit
17 config
17 config
18 continue
18 continue
19 copy
19 copy
20 diff
20 diff
21 export
21 export
22 files
22 files
23 forget
23 forget
24 graft
24 graft
25 grep
25 grep
26 heads
26 heads
27 help
27 help
28 identify
28 identify
29 import
29 import
30 incoming
30 incoming
31 init
31 init
32 locate
32 locate
33 log
33 log
34 manifest
34 manifest
35 merge
35 merge
36 outgoing
36 outgoing
37 parents
37 parents
38 paths
38 paths
39 phase
39 phase
40 pull
40 pull
41 push
41 push
42 recover
42 recover
43 remove
43 remove
44 rename
44 rename
45 resolve
45 resolve
46 revert
46 revert
47 rollback
47 rollback
48 root
48 root
49 serve
49 serve
50 shelve
50 shelve
51 status
51 status
52 summary
52 summary
53 tag
53 tag
54 tags
54 tags
55 tip
55 tip
56 unbundle
56 unbundle
57 unshelve
57 unshelve
58 update
58 update
59 verify
59 verify
60 version
60 version
61
61
62 Show all commands that start with "a"
62 Show all commands that start with "a"
63 $ hg debugcomplete a
63 $ hg debugcomplete a
64 abort
64 abort
65 add
65 add
66 addremove
66 addremove
67 annotate
67 annotate
68 archive
68 archive
69
69
70 Do not show debug commands if there are other candidates
70 Do not show debug commands if there are other candidates
71 $ hg debugcomplete d
71 $ hg debugcomplete d
72 diff
72 diff
73
73
74 Show debug commands if there are no other candidates
74 Show debug commands if there are no other candidates
75 $ hg debugcomplete debug
75 $ hg debugcomplete debug
76 debugancestor
76 debugancestor
77 debugapplystreamclonebundle
77 debugapplystreamclonebundle
78 debugbuilddag
78 debugbuilddag
79 debugbundle
79 debugbundle
80 debugcapabilities
80 debugcapabilities
81 debugcheckstate
81 debugcheckstate
82 debugcolor
82 debugcolor
83 debugcommands
83 debugcommands
84 debugcomplete
84 debugcomplete
85 debugconfig
85 debugconfig
86 debugcreatestreamclonebundle
86 debugcreatestreamclonebundle
87 debugdag
87 debugdag
88 debugdata
88 debugdata
89 debugdate
89 debugdate
90 debugdeltachain
90 debugdeltachain
91 debugdirstate
91 debugdirstate
92 debugdiscovery
92 debugdiscovery
93 debugdownload
93 debugdownload
94 debugextensions
94 debugextensions
95 debugfileset
95 debugfileset
96 debugformat
96 debugformat
97 debugfsinfo
97 debugfsinfo
98 debuggetbundle
98 debuggetbundle
99 debugignore
99 debugignore
100 debugindex
100 debugindex
101 debugindexdot
101 debugindexdot
102 debugindexstats
102 debugindexstats
103 debuginstall
103 debuginstall
104 debugknown
104 debugknown
105 debuglabelcomplete
105 debuglabelcomplete
106 debuglocks
106 debuglocks
107 debugmanifestfulltextcache
107 debugmanifestfulltextcache
108 debugmergestate
108 debugmergestate
109 debugnamecomplete
109 debugnamecomplete
110 debugobsolete
110 debugobsolete
111 debugp1copies
111 debugp1copies
112 debugp2copies
112 debugp2copies
113 debugpathcomplete
113 debugpathcomplete
114 debugpathcopies
114 debugpathcopies
115 debugpeer
115 debugpeer
116 debugpickmergetool
116 debugpickmergetool
117 debugpushkey
117 debugpushkey
118 debugpvec
118 debugpvec
119 debugrebuilddirstate
119 debugrebuilddirstate
120 debugrebuildfncache
120 debugrebuildfncache
121 debugrename
121 debugrename
122 debugrevlog
122 debugrevlog
123 debugrevlogindex
123 debugrevlogindex
124 debugrevspec
124 debugrevspec
125 debugserve
125 debugserve
126 debugsetparents
126 debugsetparents
127 debugsidedata
127 debugsidedata
128 debugssl
128 debugssl
129 debugsub
129 debugsub
130 debugsuccessorssets
130 debugsuccessorssets
131 debugtagscache
131 debugtemplate
132 debugtemplate
132 debuguigetpass
133 debuguigetpass
133 debuguiprompt
134 debuguiprompt
134 debugupdatecaches
135 debugupdatecaches
135 debugupgraderepo
136 debugupgraderepo
136 debugwalk
137 debugwalk
137 debugwhyunstable
138 debugwhyunstable
138 debugwireargs
139 debugwireargs
139 debugwireproto
140 debugwireproto
140
141
141 Do not show the alias of a debug command if there are other candidates
142 Do not show the alias of a debug command if there are other candidates
142 (this should hide rawcommit)
143 (this should hide rawcommit)
143 $ hg debugcomplete r
144 $ hg debugcomplete r
144 recover
145 recover
145 remove
146 remove
146 rename
147 rename
147 resolve
148 resolve
148 revert
149 revert
149 rollback
150 rollback
150 root
151 root
151 Show the alias of a debug command if there are no other candidates
152 Show the alias of a debug command if there are no other candidates
152 $ hg debugcomplete rawc
153 $ hg debugcomplete rawc
153
154
154
155
155 Show the global options
156 Show the global options
156 $ hg debugcomplete --options | sort
157 $ hg debugcomplete --options | sort
157 --color
158 --color
158 --config
159 --config
159 --cwd
160 --cwd
160 --debug
161 --debug
161 --debugger
162 --debugger
162 --encoding
163 --encoding
163 --encodingmode
164 --encodingmode
164 --help
165 --help
165 --hidden
166 --hidden
166 --noninteractive
167 --noninteractive
167 --pager
168 --pager
168 --profile
169 --profile
169 --quiet
170 --quiet
170 --repository
171 --repository
171 --time
172 --time
172 --traceback
173 --traceback
173 --verbose
174 --verbose
174 --version
175 --version
175 -R
176 -R
176 -h
177 -h
177 -q
178 -q
178 -v
179 -v
179 -y
180 -y
180
181
181 Show the options for the "serve" command
182 Show the options for the "serve" command
182 $ hg debugcomplete --options serve | sort
183 $ hg debugcomplete --options serve | sort
183 --accesslog
184 --accesslog
184 --address
185 --address
185 --certificate
186 --certificate
186 --cmdserver
187 --cmdserver
187 --color
188 --color
188 --config
189 --config
189 --cwd
190 --cwd
190 --daemon
191 --daemon
191 --daemon-postexec
192 --daemon-postexec
192 --debug
193 --debug
193 --debugger
194 --debugger
194 --encoding
195 --encoding
195 --encodingmode
196 --encodingmode
196 --errorlog
197 --errorlog
197 --help
198 --help
198 --hidden
199 --hidden
199 --ipv6
200 --ipv6
200 --name
201 --name
201 --noninteractive
202 --noninteractive
202 --pager
203 --pager
203 --pid-file
204 --pid-file
204 --port
205 --port
205 --prefix
206 --prefix
206 --print-url
207 --print-url
207 --profile
208 --profile
208 --quiet
209 --quiet
209 --repository
210 --repository
210 --stdio
211 --stdio
211 --style
212 --style
212 --subrepos
213 --subrepos
213 --templates
214 --templates
214 --time
215 --time
215 --traceback
216 --traceback
216 --verbose
217 --verbose
217 --version
218 --version
218 --web-conf
219 --web-conf
219 -6
220 -6
220 -A
221 -A
221 -E
222 -E
222 -R
223 -R
223 -S
224 -S
224 -a
225 -a
225 -d
226 -d
226 -h
227 -h
227 -n
228 -n
228 -p
229 -p
229 -q
230 -q
230 -t
231 -t
231 -v
232 -v
232 -y
233 -y
233
234
234 Show an error if we use --options with an ambiguous abbreviation
235 Show an error if we use --options with an ambiguous abbreviation
235 $ hg debugcomplete --options s
236 $ hg debugcomplete --options s
236 hg: command 's' is ambiguous:
237 hg: command 's' is ambiguous:
237 serve shelve showconfig status summary
238 serve shelve showconfig status summary
238 [255]
239 [255]
239
240
240 Show all commands + options
241 Show all commands + options
241 $ hg debugcommands
242 $ hg debugcommands
242 abort: dry-run
243 abort: dry-run
243 add: include, exclude, subrepos, dry-run
244 add: include, exclude, subrepos, dry-run
244 addremove: similarity, subrepos, include, exclude, dry-run
245 addremove: similarity, subrepos, include, exclude, dry-run
245 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
246 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
246 archive: no-decode, prefix, rev, type, subrepos, include, exclude
247 archive: no-decode, prefix, rev, type, subrepos, include, exclude
247 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
248 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
248 bisect: reset, good, bad, skip, extend, command, noupdate
249 bisect: reset, good, bad, skip, extend, command, noupdate
249 bookmarks: force, rev, delete, rename, inactive, list, template
250 bookmarks: force, rev, delete, rename, inactive, list, template
250 branch: force, clean, rev
251 branch: force, clean, rev
251 branches: active, closed, rev, template
252 branches: active, closed, rev, template
252 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
253 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
253 cat: output, rev, decode, include, exclude, template
254 cat: output, rev, decode, include, exclude, template
254 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
255 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
255 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
256 commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
256 config: untrusted, edit, local, global, template
257 config: untrusted, edit, local, global, template
257 continue: dry-run
258 continue: dry-run
258 copy: after, force, include, exclude, dry-run
259 copy: after, force, include, exclude, dry-run
259 debugancestor:
260 debugancestor:
260 debugapplystreamclonebundle:
261 debugapplystreamclonebundle:
261 debugbuilddag: mergeable-file, overwritten-file, new-file
262 debugbuilddag: mergeable-file, overwritten-file, new-file
262 debugbundle: all, part-type, spec
263 debugbundle: all, part-type, spec
263 debugcapabilities:
264 debugcapabilities:
264 debugcheckstate:
265 debugcheckstate:
265 debugcolor: style
266 debugcolor: style
266 debugcommands:
267 debugcommands:
267 debugcomplete: options
268 debugcomplete: options
268 debugcreatestreamclonebundle:
269 debugcreatestreamclonebundle:
269 debugdag: tags, branches, dots, spaces
270 debugdag: tags, branches, dots, spaces
270 debugdata: changelog, manifest, dir
271 debugdata: changelog, manifest, dir
271 debugdate: extended
272 debugdate: extended
272 debugdeltachain: changelog, manifest, dir, template
273 debugdeltachain: changelog, manifest, dir, template
273 debugdirstate: nodates, dates, datesort
274 debugdirstate: nodates, dates, datesort
274 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
275 debugdiscovery: old, nonheads, rev, seed, ssh, remotecmd, insecure
275 debugdownload: output
276 debugdownload: output
276 debugextensions: template
277 debugextensions: template
277 debugfileset: rev, all-files, show-matcher, show-stage
278 debugfileset: rev, all-files, show-matcher, show-stage
278 debugformat: template
279 debugformat: template
279 debugfsinfo:
280 debugfsinfo:
280 debuggetbundle: head, common, type
281 debuggetbundle: head, common, type
281 debugignore:
282 debugignore:
282 debugindex: changelog, manifest, dir, template
283 debugindex: changelog, manifest, dir, template
283 debugindexdot: changelog, manifest, dir
284 debugindexdot: changelog, manifest, dir
284 debugindexstats:
285 debugindexstats:
285 debuginstall: template
286 debuginstall: template
286 debugknown:
287 debugknown:
287 debuglabelcomplete:
288 debuglabelcomplete:
288 debuglocks: force-lock, force-wlock, set-lock, set-wlock
289 debuglocks: force-lock, force-wlock, set-lock, set-wlock
289 debugmanifestfulltextcache: clear, add
290 debugmanifestfulltextcache: clear, add
290 debugmergestate:
291 debugmergestate:
291 debugnamecomplete:
292 debugnamecomplete:
292 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
293 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
293 debugp1copies: rev
294 debugp1copies: rev
294 debugp2copies: rev
295 debugp2copies: rev
295 debugpathcomplete: full, normal, added, removed
296 debugpathcomplete: full, normal, added, removed
296 debugpathcopies: include, exclude
297 debugpathcopies: include, exclude
297 debugpeer:
298 debugpeer:
298 debugpickmergetool: rev, changedelete, include, exclude, tool
299 debugpickmergetool: rev, changedelete, include, exclude, tool
299 debugpushkey:
300 debugpushkey:
300 debugpvec:
301 debugpvec:
301 debugrebuilddirstate: rev, minimal
302 debugrebuilddirstate: rev, minimal
302 debugrebuildfncache:
303 debugrebuildfncache:
303 debugrename: rev
304 debugrename: rev
304 debugrevlog: changelog, manifest, dir, dump
305 debugrevlog: changelog, manifest, dir, dump
305 debugrevlogindex: changelog, manifest, dir, format
306 debugrevlogindex: changelog, manifest, dir, format
306 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
307 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
307 debugserve: sshstdio, logiofd, logiofile
308 debugserve: sshstdio, logiofd, logiofile
308 debugsetparents:
309 debugsetparents:
309 debugsidedata: changelog, manifest, dir
310 debugsidedata: changelog, manifest, dir
310 debugssl:
311 debugssl:
311 debugsub: rev
312 debugsub: rev
312 debugsuccessorssets: closest
313 debugsuccessorssets: closest
314 debugtagscache:
313 debugtemplate: rev, define
315 debugtemplate: rev, define
314 debuguigetpass: prompt
316 debuguigetpass: prompt
315 debuguiprompt: prompt
317 debuguiprompt: prompt
316 debugupdatecaches:
318 debugupdatecaches:
317 debugupgraderepo: optimize, run, backup, changelog, manifest
319 debugupgraderepo: optimize, run, backup, changelog, manifest
318 debugwalk: include, exclude
320 debugwalk: include, exclude
319 debugwhyunstable:
321 debugwhyunstable:
320 debugwireargs: three, four, five, ssh, remotecmd, insecure
322 debugwireargs: three, four, five, ssh, remotecmd, insecure
321 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
323 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
322 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
324 diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
323 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
325 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
324 files: rev, print0, include, exclude, template, subrepos
326 files: rev, print0, include, exclude, template, subrepos
325 forget: interactive, include, exclude, dry-run
327 forget: interactive, include, exclude, dry-run
326 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
328 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
327 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
329 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
328 heads: rev, topo, active, closed, style, template
330 heads: rev, topo, active, closed, style, template
329 help: extension, command, keyword, system
331 help: extension, command, keyword, system
330 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
332 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
331 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
333 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
332 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
334 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
333 init: ssh, remotecmd, insecure
335 init: ssh, remotecmd, insecure
334 locate: rev, print0, fullpath, include, exclude
336 locate: rev, print0, fullpath, include, exclude
335 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
337 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
336 manifest: rev, all, template
338 manifest: rev, all, template
337 merge: force, rev, preview, abort, tool
339 merge: force, rev, preview, abort, tool
338 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
340 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
339 parents: rev, style, template
341 parents: rev, style, template
340 paths: template
342 paths: template
341 phase: public, draft, secret, force, rev
343 phase: public, draft, secret, force, rev
342 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
344 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
343 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
345 push: force, rev, bookmark, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
344 recover: verify
346 recover: verify
345 remove: after, force, subrepos, include, exclude, dry-run
347 remove: after, force, subrepos, include, exclude, dry-run
346 rename: after, force, include, exclude, dry-run
348 rename: after, force, include, exclude, dry-run
347 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
349 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
348 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
350 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
349 rollback: dry-run, force
351 rollback: dry-run, force
350 root: template
352 root: template
351 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
353 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
352 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
354 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
353 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
355 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
354 summary: remote
356 summary: remote
355 tag: force, local, rev, remove, edit, message, date, user
357 tag: force, local, rev, remove, edit, message, date, user
356 tags: template
358 tags: template
357 tip: patch, git, style, template
359 tip: patch, git, style, template
358 unbundle: update
360 unbundle: update
359 unshelve: abort, continue, interactive, keep, name, tool, date
361 unshelve: abort, continue, interactive, keep, name, tool, date
360 update: clean, check, merge, date, rev, tool
362 update: clean, check, merge, date, rev, tool
361 verify: full
363 verify: full
362 version: template
364 version: template
363
365
364 $ hg init a
366 $ hg init a
365 $ cd a
367 $ cd a
366 $ echo fee > fee
368 $ echo fee > fee
367 $ hg ci -q -Amfee
369 $ hg ci -q -Amfee
368 $ hg tag fee
370 $ hg tag fee
369 $ mkdir fie
371 $ mkdir fie
370 $ echo dead > fie/dead
372 $ echo dead > fie/dead
371 $ echo live > fie/live
373 $ echo live > fie/live
372 $ hg bookmark fo
374 $ hg bookmark fo
373 $ hg branch -q fie
375 $ hg branch -q fie
374 $ hg ci -q -Amfie
376 $ hg ci -q -Amfie
375 $ echo fo > fo
377 $ echo fo > fo
376 $ hg branch -qf default
378 $ hg branch -qf default
377 $ hg ci -q -Amfo
379 $ hg ci -q -Amfo
378 $ echo Fum > Fum
380 $ echo Fum > Fum
379 $ hg ci -q -AmFum
381 $ hg ci -q -AmFum
380 $ hg bookmark Fum
382 $ hg bookmark Fum
381
383
382 Test debugpathcomplete
384 Test debugpathcomplete
383
385
384 $ hg debugpathcomplete f
386 $ hg debugpathcomplete f
385 fee
387 fee
386 fie
388 fie
387 fo
389 fo
388 $ hg debugpathcomplete -f f
390 $ hg debugpathcomplete -f f
389 fee
391 fee
390 fie/dead
392 fie/dead
391 fie/live
393 fie/live
392 fo
394 fo
393
395
394 $ hg rm Fum
396 $ hg rm Fum
395 $ hg debugpathcomplete -r F
397 $ hg debugpathcomplete -r F
396 Fum
398 Fum
397
399
398 Test debugnamecomplete
400 Test debugnamecomplete
399
401
400 $ hg debugnamecomplete
402 $ hg debugnamecomplete
401 Fum
403 Fum
402 default
404 default
403 fee
405 fee
404 fie
406 fie
405 fo
407 fo
406 tip
408 tip
407 $ hg debugnamecomplete f
409 $ hg debugnamecomplete f
408 fee
410 fee
409 fie
411 fie
410 fo
412 fo
411
413
412 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
414 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
413 used for completions in some shells.
415 used for completions in some shells.
414
416
415 $ hg debuglabelcomplete
417 $ hg debuglabelcomplete
416 Fum
418 Fum
417 default
419 default
418 fee
420 fee
419 fie
421 fie
420 fo
422 fo
421 tip
423 tip
422 $ hg debuglabelcomplete f
424 $ hg debuglabelcomplete f
423 fee
425 fee
424 fie
426 fie
425 fo
427 fo
@@ -1,3894 +1,3896 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 Extra extensions will be printed in help output in a non-reliable order since
47 Extra extensions will be printed in help output in a non-reliable order since
48 the extension is unknown.
48 the extension is unknown.
49 #if no-extraextensions
49 #if no-extraextensions
50
50
51 $ hg help
51 $ hg help
52 Mercurial Distributed SCM
52 Mercurial Distributed SCM
53
53
54 list of commands:
54 list of commands:
55
55
56 Repository creation:
56 Repository creation:
57
57
58 clone make a copy of an existing repository
58 clone make a copy of an existing repository
59 init create a new repository in the given directory
59 init create a new repository in the given directory
60
60
61 Remote repository management:
61 Remote repository management:
62
62
63 incoming show new changesets found in source
63 incoming show new changesets found in source
64 outgoing show changesets not found in the destination
64 outgoing show changesets not found in the destination
65 paths show aliases for remote repositories
65 paths show aliases for remote repositories
66 pull pull changes from the specified source
66 pull pull changes from the specified source
67 push push changes to the specified destination
67 push push changes to the specified destination
68 serve start stand-alone webserver
68 serve start stand-alone webserver
69
69
70 Change creation:
70 Change creation:
71
71
72 commit commit the specified files or all outstanding changes
72 commit commit the specified files or all outstanding changes
73
73
74 Change manipulation:
74 Change manipulation:
75
75
76 backout reverse effect of earlier changeset
76 backout reverse effect of earlier changeset
77 graft copy changes from other branches onto the current branch
77 graft copy changes from other branches onto the current branch
78 merge merge another revision into working directory
78 merge merge another revision into working directory
79
79
80 Change organization:
80 Change organization:
81
81
82 bookmarks create a new bookmark or list existing bookmarks
82 bookmarks create a new bookmark or list existing bookmarks
83 branch set or show the current branch name
83 branch set or show the current branch name
84 branches list repository named branches
84 branches list repository named branches
85 phase set or show the current phase name
85 phase set or show the current phase name
86 tag add one or more tags for the current or given revision
86 tag add one or more tags for the current or given revision
87 tags list repository tags
87 tags list repository tags
88
88
89 File content management:
89 File content management:
90
90
91 annotate show changeset information by line for each file
91 annotate show changeset information by line for each file
92 cat output the current or given revision of files
92 cat output the current or given revision of files
93 copy mark files as copied for the next commit
93 copy mark files as copied for the next commit
94 diff diff repository (or selected files)
94 diff diff repository (or selected files)
95 grep search for a pattern in specified files
95 grep search for a pattern in specified files
96
96
97 Change navigation:
97 Change navigation:
98
98
99 bisect subdivision search of changesets
99 bisect subdivision search of changesets
100 heads show branch heads
100 heads show branch heads
101 identify identify the working directory or specified revision
101 identify identify the working directory or specified revision
102 log show revision history of entire repository or files
102 log show revision history of entire repository or files
103
103
104 Working directory management:
104 Working directory management:
105
105
106 add add the specified files on the next commit
106 add add the specified files on the next commit
107 addremove add all new files, delete all missing files
107 addremove add all new files, delete all missing files
108 files list tracked files
108 files list tracked files
109 forget forget the specified files on the next commit
109 forget forget the specified files on the next commit
110 remove remove the specified files on the next commit
110 remove remove the specified files on the next commit
111 rename rename files; equivalent of copy + remove
111 rename rename files; equivalent of copy + remove
112 resolve redo merges or set/view the merge status of files
112 resolve redo merges or set/view the merge status of files
113 revert restore files to their checkout state
113 revert restore files to their checkout state
114 root print the root (top) of the current working directory
114 root print the root (top) of the current working directory
115 shelve save and set aside changes from the working directory
115 shelve save and set aside changes from the working directory
116 status show changed files in the working directory
116 status show changed files in the working directory
117 summary summarize working directory state
117 summary summarize working directory state
118 unshelve restore a shelved change to the working directory
118 unshelve restore a shelved change to the working directory
119 update update working directory (or switch revisions)
119 update update working directory (or switch revisions)
120
120
121 Change import/export:
121 Change import/export:
122
122
123 archive create an unversioned archive of a repository revision
123 archive create an unversioned archive of a repository revision
124 bundle create a bundle file
124 bundle create a bundle file
125 export dump the header and diffs for one or more changesets
125 export dump the header and diffs for one or more changesets
126 import import an ordered set of patches
126 import import an ordered set of patches
127 unbundle apply one or more bundle files
127 unbundle apply one or more bundle files
128
128
129 Repository maintenance:
129 Repository maintenance:
130
130
131 manifest output the current or given revision of the project manifest
131 manifest output the current or given revision of the project manifest
132 recover roll back an interrupted transaction
132 recover roll back an interrupted transaction
133 verify verify the integrity of the repository
133 verify verify the integrity of the repository
134
134
135 Help:
135 Help:
136
136
137 config show combined config settings from all hgrc files
137 config show combined config settings from all hgrc files
138 help show help for a given topic or a help overview
138 help show help for a given topic or a help overview
139 version output version and copyright information
139 version output version and copyright information
140
140
141 additional help topics:
141 additional help topics:
142
142
143 Mercurial identifiers:
143 Mercurial identifiers:
144
144
145 filesets Specifying File Sets
145 filesets Specifying File Sets
146 hgignore Syntax for Mercurial Ignore Files
146 hgignore Syntax for Mercurial Ignore Files
147 patterns File Name Patterns
147 patterns File Name Patterns
148 revisions Specifying Revisions
148 revisions Specifying Revisions
149 urls URL Paths
149 urls URL Paths
150
150
151 Mercurial output:
151 Mercurial output:
152
152
153 color Colorizing Outputs
153 color Colorizing Outputs
154 dates Date Formats
154 dates Date Formats
155 diffs Diff Formats
155 diffs Diff Formats
156 templating Template Usage
156 templating Template Usage
157
157
158 Mercurial configuration:
158 Mercurial configuration:
159
159
160 config Configuration Files
160 config Configuration Files
161 environment Environment Variables
161 environment Environment Variables
162 extensions Using Additional Features
162 extensions Using Additional Features
163 flags Command-line flags
163 flags Command-line flags
164 hgweb Configuring hgweb
164 hgweb Configuring hgweb
165 merge-tools Merge Tools
165 merge-tools Merge Tools
166 pager Pager Support
166 pager Pager Support
167
167
168 Concepts:
168 Concepts:
169
169
170 bundlespec Bundle File Formats
170 bundlespec Bundle File Formats
171 glossary Glossary
171 glossary Glossary
172 phases Working with Phases
172 phases Working with Phases
173 subrepos Subrepositories
173 subrepos Subrepositories
174
174
175 Miscellaneous:
175 Miscellaneous:
176
176
177 deprecated Deprecated Features
177 deprecated Deprecated Features
178 internals Technical implementation topics
178 internals Technical implementation topics
179 scripting Using Mercurial from scripts and automation
179 scripting Using Mercurial from scripts and automation
180
180
181 (use 'hg help -v' to show built-in aliases and global options)
181 (use 'hg help -v' to show built-in aliases and global options)
182
182
183 $ hg -q help
183 $ hg -q help
184 Repository creation:
184 Repository creation:
185
185
186 clone make a copy of an existing repository
186 clone make a copy of an existing repository
187 init create a new repository in the given directory
187 init create a new repository in the given directory
188
188
189 Remote repository management:
189 Remote repository management:
190
190
191 incoming show new changesets found in source
191 incoming show new changesets found in source
192 outgoing show changesets not found in the destination
192 outgoing show changesets not found in the destination
193 paths show aliases for remote repositories
193 paths show aliases for remote repositories
194 pull pull changes from the specified source
194 pull pull changes from the specified source
195 push push changes to the specified destination
195 push push changes to the specified destination
196 serve start stand-alone webserver
196 serve start stand-alone webserver
197
197
198 Change creation:
198 Change creation:
199
199
200 commit commit the specified files or all outstanding changes
200 commit commit the specified files or all outstanding changes
201
201
202 Change manipulation:
202 Change manipulation:
203
203
204 backout reverse effect of earlier changeset
204 backout reverse effect of earlier changeset
205 graft copy changes from other branches onto the current branch
205 graft copy changes from other branches onto the current branch
206 merge merge another revision into working directory
206 merge merge another revision into working directory
207
207
208 Change organization:
208 Change organization:
209
209
210 bookmarks create a new bookmark or list existing bookmarks
210 bookmarks create a new bookmark or list existing bookmarks
211 branch set or show the current branch name
211 branch set or show the current branch name
212 branches list repository named branches
212 branches list repository named branches
213 phase set or show the current phase name
213 phase set or show the current phase name
214 tag add one or more tags for the current or given revision
214 tag add one or more tags for the current or given revision
215 tags list repository tags
215 tags list repository tags
216
216
217 File content management:
217 File content management:
218
218
219 annotate show changeset information by line for each file
219 annotate show changeset information by line for each file
220 cat output the current or given revision of files
220 cat output the current or given revision of files
221 copy mark files as copied for the next commit
221 copy mark files as copied for the next commit
222 diff diff repository (or selected files)
222 diff diff repository (or selected files)
223 grep search for a pattern in specified files
223 grep search for a pattern in specified files
224
224
225 Change navigation:
225 Change navigation:
226
226
227 bisect subdivision search of changesets
227 bisect subdivision search of changesets
228 heads show branch heads
228 heads show branch heads
229 identify identify the working directory or specified revision
229 identify identify the working directory or specified revision
230 log show revision history of entire repository or files
230 log show revision history of entire repository or files
231
231
232 Working directory management:
232 Working directory management:
233
233
234 add add the specified files on the next commit
234 add add the specified files on the next commit
235 addremove add all new files, delete all missing files
235 addremove add all new files, delete all missing files
236 files list tracked files
236 files list tracked files
237 forget forget the specified files on the next commit
237 forget forget the specified files on the next commit
238 remove remove the specified files on the next commit
238 remove remove the specified files on the next commit
239 rename rename files; equivalent of copy + remove
239 rename rename files; equivalent of copy + remove
240 resolve redo merges or set/view the merge status of files
240 resolve redo merges or set/view the merge status of files
241 revert restore files to their checkout state
241 revert restore files to their checkout state
242 root print the root (top) of the current working directory
242 root print the root (top) of the current working directory
243 shelve save and set aside changes from the working directory
243 shelve save and set aside changes from the working directory
244 status show changed files in the working directory
244 status show changed files in the working directory
245 summary summarize working directory state
245 summary summarize working directory state
246 unshelve restore a shelved change to the working directory
246 unshelve restore a shelved change to the working directory
247 update update working directory (or switch revisions)
247 update update working directory (or switch revisions)
248
248
249 Change import/export:
249 Change import/export:
250
250
251 archive create an unversioned archive of a repository revision
251 archive create an unversioned archive of a repository revision
252 bundle create a bundle file
252 bundle create a bundle file
253 export dump the header and diffs for one or more changesets
253 export dump the header and diffs for one or more changesets
254 import import an ordered set of patches
254 import import an ordered set of patches
255 unbundle apply one or more bundle files
255 unbundle apply one or more bundle files
256
256
257 Repository maintenance:
257 Repository maintenance:
258
258
259 manifest output the current or given revision of the project manifest
259 manifest output the current or given revision of the project manifest
260 recover roll back an interrupted transaction
260 recover roll back an interrupted transaction
261 verify verify the integrity of the repository
261 verify verify the integrity of the repository
262
262
263 Help:
263 Help:
264
264
265 config show combined config settings from all hgrc files
265 config show combined config settings from all hgrc files
266 help show help for a given topic or a help overview
266 help show help for a given topic or a help overview
267 version output version and copyright information
267 version output version and copyright information
268
268
269 additional help topics:
269 additional help topics:
270
270
271 Mercurial identifiers:
271 Mercurial identifiers:
272
272
273 filesets Specifying File Sets
273 filesets Specifying File Sets
274 hgignore Syntax for Mercurial Ignore Files
274 hgignore Syntax for Mercurial Ignore Files
275 patterns File Name Patterns
275 patterns File Name Patterns
276 revisions Specifying Revisions
276 revisions Specifying Revisions
277 urls URL Paths
277 urls URL Paths
278
278
279 Mercurial output:
279 Mercurial output:
280
280
281 color Colorizing Outputs
281 color Colorizing Outputs
282 dates Date Formats
282 dates Date Formats
283 diffs Diff Formats
283 diffs Diff Formats
284 templating Template Usage
284 templating Template Usage
285
285
286 Mercurial configuration:
286 Mercurial configuration:
287
287
288 config Configuration Files
288 config Configuration Files
289 environment Environment Variables
289 environment Environment Variables
290 extensions Using Additional Features
290 extensions Using Additional Features
291 flags Command-line flags
291 flags Command-line flags
292 hgweb Configuring hgweb
292 hgweb Configuring hgweb
293 merge-tools Merge Tools
293 merge-tools Merge Tools
294 pager Pager Support
294 pager Pager Support
295
295
296 Concepts:
296 Concepts:
297
297
298 bundlespec Bundle File Formats
298 bundlespec Bundle File Formats
299 glossary Glossary
299 glossary Glossary
300 phases Working with Phases
300 phases Working with Phases
301 subrepos Subrepositories
301 subrepos Subrepositories
302
302
303 Miscellaneous:
303 Miscellaneous:
304
304
305 deprecated Deprecated Features
305 deprecated Deprecated Features
306 internals Technical implementation topics
306 internals Technical implementation topics
307 scripting Using Mercurial from scripts and automation
307 scripting Using Mercurial from scripts and automation
308
308
309 Test extension help:
309 Test extension help:
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
310 $ hg help extensions --config extensions.rebase= --config extensions.children=
311 Using Additional Features
311 Using Additional Features
312 """""""""""""""""""""""""
312 """""""""""""""""""""""""
313
313
314 Mercurial has the ability to add new features through the use of
314 Mercurial has the ability to add new features through the use of
315 extensions. Extensions may add new commands, add options to existing
315 extensions. Extensions may add new commands, add options to existing
316 commands, change the default behavior of commands, or implement hooks.
316 commands, change the default behavior of commands, or implement hooks.
317
317
318 To enable the "foo" extension, either shipped with Mercurial or in the
318 To enable the "foo" extension, either shipped with Mercurial or in the
319 Python search path, create an entry for it in your configuration file,
319 Python search path, create an entry for it in your configuration file,
320 like this:
320 like this:
321
321
322 [extensions]
322 [extensions]
323 foo =
323 foo =
324
324
325 You may also specify the full path to an extension:
325 You may also specify the full path to an extension:
326
326
327 [extensions]
327 [extensions]
328 myfeature = ~/.hgext/myfeature.py
328 myfeature = ~/.hgext/myfeature.py
329
329
330 See 'hg help config' for more information on configuration files.
330 See 'hg help config' for more information on configuration files.
331
331
332 Extensions are not loaded by default for a variety of reasons: they can
332 Extensions are not loaded by default for a variety of reasons: they can
333 increase startup overhead; they may be meant for advanced usage only; they
333 increase startup overhead; they may be meant for advanced usage only; they
334 may provide potentially dangerous abilities (such as letting you destroy
334 may provide potentially dangerous abilities (such as letting you destroy
335 or modify history); they might not be ready for prime time; or they may
335 or modify history); they might not be ready for prime time; or they may
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
336 alter some usual behaviors of stock Mercurial. It is thus up to the user
337 to activate extensions as needed.
337 to activate extensions as needed.
338
338
339 To explicitly disable an extension enabled in a configuration file of
339 To explicitly disable an extension enabled in a configuration file of
340 broader scope, prepend its path with !:
340 broader scope, prepend its path with !:
341
341
342 [extensions]
342 [extensions]
343 # disabling extension bar residing in /path/to/extension/bar.py
343 # disabling extension bar residing in /path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
344 bar = !/path/to/extension/bar.py
345 # ditto, but no path was supplied for extension baz
345 # ditto, but no path was supplied for extension baz
346 baz = !
346 baz = !
347
347
348 enabled extensions:
348 enabled extensions:
349
349
350 children command to display child changesets (DEPRECATED)
350 children command to display child changesets (DEPRECATED)
351 rebase command to move sets of revisions to a different ancestor
351 rebase command to move sets of revisions to a different ancestor
352
352
353 disabled extensions:
353 disabled extensions:
354
354
355 acl hooks for controlling repository access
355 acl hooks for controlling repository access
356 blackbox log repository events to a blackbox for debugging
356 blackbox log repository events to a blackbox for debugging
357 bugzilla hooks for integrating with the Bugzilla bug tracker
357 bugzilla hooks for integrating with the Bugzilla bug tracker
358 censor erase file content at a given revision
358 censor erase file content at a given revision
359 churn command to display statistics about repository history
359 churn command to display statistics about repository history
360 clonebundles advertise pre-generated bundles to seed clones
360 clonebundles advertise pre-generated bundles to seed clones
361 closehead close arbitrary heads without checking them out first
361 closehead close arbitrary heads without checking them out first
362 convert import revisions from foreign VCS repositories into
362 convert import revisions from foreign VCS repositories into
363 Mercurial
363 Mercurial
364 eol automatically manage newlines in repository files
364 eol automatically manage newlines in repository files
365 extdiff command to allow external programs to compare revisions
365 extdiff command to allow external programs to compare revisions
366 factotum http authentication with factotum
366 factotum http authentication with factotum
367 fastexport export repositories as git fast-import stream
367 fastexport export repositories as git fast-import stream
368 githelp try mapping git commands to Mercurial commands
368 githelp try mapping git commands to Mercurial commands
369 gpg commands to sign and verify changesets
369 gpg commands to sign and verify changesets
370 hgk browse the repository in a graphical way
370 hgk browse the repository in a graphical way
371 highlight syntax highlighting for hgweb (requires Pygments)
371 highlight syntax highlighting for hgweb (requires Pygments)
372 histedit interactive history editing
372 histedit interactive history editing
373 keyword expand keywords in tracked files
373 keyword expand keywords in tracked files
374 largefiles track large binary files
374 largefiles track large binary files
375 mq manage a stack of patches
375 mq manage a stack of patches
376 notify hooks for sending email push notifications
376 notify hooks for sending email push notifications
377 patchbomb command to send changesets as (a series of) patch emails
377 patchbomb command to send changesets as (a series of) patch emails
378 purge command to delete untracked files from the working
378 purge command to delete untracked files from the working
379 directory
379 directory
380 relink recreates hardlinks between repository clones
380 relink recreates hardlinks between repository clones
381 schemes extend schemes with shortcuts to repository swarms
381 schemes extend schemes with shortcuts to repository swarms
382 share share a common history between several working directories
382 share share a common history between several working directories
383 strip strip changesets and their descendants from history
383 strip strip changesets and their descendants from history
384 transplant command to transplant changesets from another branch
384 transplant command to transplant changesets from another branch
385 win32mbcs allow the use of MBCS paths with problematic encodings
385 win32mbcs allow the use of MBCS paths with problematic encodings
386 zeroconf discover and advertise repositories on the local network
386 zeroconf discover and advertise repositories on the local network
387
387
388 #endif
388 #endif
389
389
390 Verify that deprecated extensions are included if --verbose:
390 Verify that deprecated extensions are included if --verbose:
391
391
392 $ hg -v help extensions | grep children
392 $ hg -v help extensions | grep children
393 children command to display child changesets (DEPRECATED)
393 children command to display child changesets (DEPRECATED)
394
394
395 Verify that extension keywords appear in help templates
395 Verify that extension keywords appear in help templates
396
396
397 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
397 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
398
398
399 Test short command list with verbose option
399 Test short command list with verbose option
400
400
401 $ hg -v help shortlist
401 $ hg -v help shortlist
402 Mercurial Distributed SCM
402 Mercurial Distributed SCM
403
403
404 basic commands:
404 basic commands:
405
405
406 abort abort an unfinished operation (EXPERIMENTAL)
406 abort abort an unfinished operation (EXPERIMENTAL)
407 add add the specified files on the next commit
407 add add the specified files on the next commit
408 annotate, blame
408 annotate, blame
409 show changeset information by line for each file
409 show changeset information by line for each file
410 clone make a copy of an existing repository
410 clone make a copy of an existing repository
411 commit, ci commit the specified files or all outstanding changes
411 commit, ci commit the specified files or all outstanding changes
412 continue resumes an interrupted operation (EXPERIMENTAL)
412 continue resumes an interrupted operation (EXPERIMENTAL)
413 diff diff repository (or selected files)
413 diff diff repository (or selected files)
414 export dump the header and diffs for one or more changesets
414 export dump the header and diffs for one or more changesets
415 forget forget the specified files on the next commit
415 forget forget the specified files on the next commit
416 init create a new repository in the given directory
416 init create a new repository in the given directory
417 log, history show revision history of entire repository or files
417 log, history show revision history of entire repository or files
418 merge merge another revision into working directory
418 merge merge another revision into working directory
419 pull pull changes from the specified source
419 pull pull changes from the specified source
420 push push changes to the specified destination
420 push push changes to the specified destination
421 remove, rm remove the specified files on the next commit
421 remove, rm remove the specified files on the next commit
422 serve start stand-alone webserver
422 serve start stand-alone webserver
423 status, st show changed files in the working directory
423 status, st show changed files in the working directory
424 summary, sum summarize working directory state
424 summary, sum summarize working directory state
425 update, up, checkout, co
425 update, up, checkout, co
426 update working directory (or switch revisions)
426 update working directory (or switch revisions)
427
427
428 global options ([+] can be repeated):
428 global options ([+] can be repeated):
429
429
430 -R --repository REPO repository root directory or name of overlay bundle
430 -R --repository REPO repository root directory or name of overlay bundle
431 file
431 file
432 --cwd DIR change working directory
432 --cwd DIR change working directory
433 -y --noninteractive do not prompt, automatically pick the first choice for
433 -y --noninteractive do not prompt, automatically pick the first choice for
434 all prompts
434 all prompts
435 -q --quiet suppress output
435 -q --quiet suppress output
436 -v --verbose enable additional output
436 -v --verbose enable additional output
437 --color TYPE when to colorize (boolean, always, auto, never, or
437 --color TYPE when to colorize (boolean, always, auto, never, or
438 debug)
438 debug)
439 --config CONFIG [+] set/override config option (use 'section.name=value')
439 --config CONFIG [+] set/override config option (use 'section.name=value')
440 --debug enable debugging output
440 --debug enable debugging output
441 --debugger start debugger
441 --debugger start debugger
442 --encoding ENCODE set the charset encoding (default: ascii)
442 --encoding ENCODE set the charset encoding (default: ascii)
443 --encodingmode MODE set the charset encoding mode (default: strict)
443 --encodingmode MODE set the charset encoding mode (default: strict)
444 --traceback always print a traceback on exception
444 --traceback always print a traceback on exception
445 --time time how long the command takes
445 --time time how long the command takes
446 --profile print command execution profile
446 --profile print command execution profile
447 --version output version information and exit
447 --version output version information and exit
448 -h --help display help and exit
448 -h --help display help and exit
449 --hidden consider hidden changesets
449 --hidden consider hidden changesets
450 --pager TYPE when to paginate (boolean, always, auto, or never)
450 --pager TYPE when to paginate (boolean, always, auto, or never)
451 (default: auto)
451 (default: auto)
452
452
453 (use 'hg help' for the full list of commands)
453 (use 'hg help' for the full list of commands)
454
454
455 $ hg add -h
455 $ hg add -h
456 hg add [OPTION]... [FILE]...
456 hg add [OPTION]... [FILE]...
457
457
458 add the specified files on the next commit
458 add the specified files on the next commit
459
459
460 Schedule files to be version controlled and added to the repository.
460 Schedule files to be version controlled and added to the repository.
461
461
462 The files will be added to the repository at the next commit. To undo an
462 The files will be added to the repository at the next commit. To undo an
463 add before that, see 'hg forget'.
463 add before that, see 'hg forget'.
464
464
465 If no names are given, add all files to the repository (except files
465 If no names are given, add all files to the repository (except files
466 matching ".hgignore").
466 matching ".hgignore").
467
467
468 Returns 0 if all files are successfully added.
468 Returns 0 if all files are successfully added.
469
469
470 options ([+] can be repeated):
470 options ([+] can be repeated):
471
471
472 -I --include PATTERN [+] include names matching the given patterns
472 -I --include PATTERN [+] include names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
474 -S --subrepos recurse into subrepositories
474 -S --subrepos recurse into subrepositories
475 -n --dry-run do not perform actions, just print output
475 -n --dry-run do not perform actions, just print output
476
476
477 (some details hidden, use --verbose to show complete help)
477 (some details hidden, use --verbose to show complete help)
478
478
479 Verbose help for add
479 Verbose help for add
480
480
481 $ hg add -hv
481 $ hg add -hv
482 hg add [OPTION]... [FILE]...
482 hg add [OPTION]... [FILE]...
483
483
484 add the specified files on the next commit
484 add the specified files on the next commit
485
485
486 Schedule files to be version controlled and added to the repository.
486 Schedule files to be version controlled and added to the repository.
487
487
488 The files will be added to the repository at the next commit. To undo an
488 The files will be added to the repository at the next commit. To undo an
489 add before that, see 'hg forget'.
489 add before that, see 'hg forget'.
490
490
491 If no names are given, add all files to the repository (except files
491 If no names are given, add all files to the repository (except files
492 matching ".hgignore").
492 matching ".hgignore").
493
493
494 Examples:
494 Examples:
495
495
496 - New (unknown) files are added automatically by 'hg add':
496 - New (unknown) files are added automatically by 'hg add':
497
497
498 $ ls
498 $ ls
499 foo.c
499 foo.c
500 $ hg status
500 $ hg status
501 ? foo.c
501 ? foo.c
502 $ hg add
502 $ hg add
503 adding foo.c
503 adding foo.c
504 $ hg status
504 $ hg status
505 A foo.c
505 A foo.c
506
506
507 - Specific files to be added can be specified:
507 - Specific files to be added can be specified:
508
508
509 $ ls
509 $ ls
510 bar.c foo.c
510 bar.c foo.c
511 $ hg status
511 $ hg status
512 ? bar.c
512 ? bar.c
513 ? foo.c
513 ? foo.c
514 $ hg add bar.c
514 $ hg add bar.c
515 $ hg status
515 $ hg status
516 A bar.c
516 A bar.c
517 ? foo.c
517 ? foo.c
518
518
519 Returns 0 if all files are successfully added.
519 Returns 0 if all files are successfully added.
520
520
521 options ([+] can be repeated):
521 options ([+] can be repeated):
522
522
523 -I --include PATTERN [+] include names matching the given patterns
523 -I --include PATTERN [+] include names matching the given patterns
524 -X --exclude PATTERN [+] exclude names matching the given patterns
524 -X --exclude PATTERN [+] exclude names matching the given patterns
525 -S --subrepos recurse into subrepositories
525 -S --subrepos recurse into subrepositories
526 -n --dry-run do not perform actions, just print output
526 -n --dry-run do not perform actions, just print output
527
527
528 global options ([+] can be repeated):
528 global options ([+] can be repeated):
529
529
530 -R --repository REPO repository root directory or name of overlay bundle
530 -R --repository REPO repository root directory or name of overlay bundle
531 file
531 file
532 --cwd DIR change working directory
532 --cwd DIR change working directory
533 -y --noninteractive do not prompt, automatically pick the first choice for
533 -y --noninteractive do not prompt, automatically pick the first choice for
534 all prompts
534 all prompts
535 -q --quiet suppress output
535 -q --quiet suppress output
536 -v --verbose enable additional output
536 -v --verbose enable additional output
537 --color TYPE when to colorize (boolean, always, auto, never, or
537 --color TYPE when to colorize (boolean, always, auto, never, or
538 debug)
538 debug)
539 --config CONFIG [+] set/override config option (use 'section.name=value')
539 --config CONFIG [+] set/override config option (use 'section.name=value')
540 --debug enable debugging output
540 --debug enable debugging output
541 --debugger start debugger
541 --debugger start debugger
542 --encoding ENCODE set the charset encoding (default: ascii)
542 --encoding ENCODE set the charset encoding (default: ascii)
543 --encodingmode MODE set the charset encoding mode (default: strict)
543 --encodingmode MODE set the charset encoding mode (default: strict)
544 --traceback always print a traceback on exception
544 --traceback always print a traceback on exception
545 --time time how long the command takes
545 --time time how long the command takes
546 --profile print command execution profile
546 --profile print command execution profile
547 --version output version information and exit
547 --version output version information and exit
548 -h --help display help and exit
548 -h --help display help and exit
549 --hidden consider hidden changesets
549 --hidden consider hidden changesets
550 --pager TYPE when to paginate (boolean, always, auto, or never)
550 --pager TYPE when to paginate (boolean, always, auto, or never)
551 (default: auto)
551 (default: auto)
552
552
553 Test the textwidth config option
553 Test the textwidth config option
554
554
555 $ hg root -h --config ui.textwidth=50
555 $ hg root -h --config ui.textwidth=50
556 hg root
556 hg root
557
557
558 print the root (top) of the current working
558 print the root (top) of the current working
559 directory
559 directory
560
560
561 Print the root directory of the current
561 Print the root directory of the current
562 repository.
562 repository.
563
563
564 Returns 0 on success.
564 Returns 0 on success.
565
565
566 options:
566 options:
567
567
568 -T --template TEMPLATE display with template
568 -T --template TEMPLATE display with template
569
569
570 (some details hidden, use --verbose to show
570 (some details hidden, use --verbose to show
571 complete help)
571 complete help)
572
572
573 Test help option with version option
573 Test help option with version option
574
574
575 $ hg add -h --version
575 $ hg add -h --version
576 Mercurial Distributed SCM (version *) (glob)
576 Mercurial Distributed SCM (version *) (glob)
577 (see https://mercurial-scm.org for more information)
577 (see https://mercurial-scm.org for more information)
578
578
579 Copyright (C) 2005-* Matt Mackall and others (glob)
579 Copyright (C) 2005-* Matt Mackall and others (glob)
580 This is free software; see the source for copying conditions. There is NO
580 This is free software; see the source for copying conditions. There is NO
581 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
581 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
582
582
583 $ hg add --skjdfks
583 $ hg add --skjdfks
584 hg add: option --skjdfks not recognized
584 hg add: option --skjdfks not recognized
585 hg add [OPTION]... [FILE]...
585 hg add [OPTION]... [FILE]...
586
586
587 add the specified files on the next commit
587 add the specified files on the next commit
588
588
589 options ([+] can be repeated):
589 options ([+] can be repeated):
590
590
591 -I --include PATTERN [+] include names matching the given patterns
591 -I --include PATTERN [+] include names matching the given patterns
592 -X --exclude PATTERN [+] exclude names matching the given patterns
592 -X --exclude PATTERN [+] exclude names matching the given patterns
593 -S --subrepos recurse into subrepositories
593 -S --subrepos recurse into subrepositories
594 -n --dry-run do not perform actions, just print output
594 -n --dry-run do not perform actions, just print output
595
595
596 (use 'hg add -h' to show more help)
596 (use 'hg add -h' to show more help)
597 [255]
597 [255]
598
598
599 Test ambiguous command help
599 Test ambiguous command help
600
600
601 $ hg help ad
601 $ hg help ad
602 list of commands:
602 list of commands:
603
603
604 add add the specified files on the next commit
604 add add the specified files on the next commit
605 addremove add all new files, delete all missing files
605 addremove add all new files, delete all missing files
606
606
607 (use 'hg help -v ad' to show built-in aliases and global options)
607 (use 'hg help -v ad' to show built-in aliases and global options)
608
608
609 Test command without options
609 Test command without options
610
610
611 $ hg help verify
611 $ hg help verify
612 hg verify
612 hg verify
613
613
614 verify the integrity of the repository
614 verify the integrity of the repository
615
615
616 Verify the integrity of the current repository.
616 Verify the integrity of the current repository.
617
617
618 This will perform an extensive check of the repository's integrity,
618 This will perform an extensive check of the repository's integrity,
619 validating the hashes and checksums of each entry in the changelog,
619 validating the hashes and checksums of each entry in the changelog,
620 manifest, and tracked files, as well as the integrity of their crosslinks
620 manifest, and tracked files, as well as the integrity of their crosslinks
621 and indices.
621 and indices.
622
622
623 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
623 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
624 information about recovery from corruption of the repository.
624 information about recovery from corruption of the repository.
625
625
626 Returns 0 on success, 1 if errors are encountered.
626 Returns 0 on success, 1 if errors are encountered.
627
627
628 options:
628 options:
629
629
630 (some details hidden, use --verbose to show complete help)
630 (some details hidden, use --verbose to show complete help)
631
631
632 $ hg help diff
632 $ hg help diff
633 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
633 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
634
634
635 diff repository (or selected files)
635 diff repository (or selected files)
636
636
637 Show differences between revisions for the specified files.
637 Show differences between revisions for the specified files.
638
638
639 Differences between files are shown using the unified diff format.
639 Differences between files are shown using the unified diff format.
640
640
641 Note:
641 Note:
642 'hg diff' may generate unexpected results for merges, as it will
642 'hg diff' may generate unexpected results for merges, as it will
643 default to comparing against the working directory's first parent
643 default to comparing against the working directory's first parent
644 changeset if no revisions are specified.
644 changeset if no revisions are specified.
645
645
646 When two revision arguments are given, then changes are shown between
646 When two revision arguments are given, then changes are shown between
647 those revisions. If only one revision is specified then that revision is
647 those revisions. If only one revision is specified then that revision is
648 compared to the working directory, and, when no revisions are specified,
648 compared to the working directory, and, when no revisions are specified,
649 the working directory files are compared to its first parent.
649 the working directory files are compared to its first parent.
650
650
651 Alternatively you can specify -c/--change with a revision to see the
651 Alternatively you can specify -c/--change with a revision to see the
652 changes in that changeset relative to its first parent.
652 changes in that changeset relative to its first parent.
653
653
654 Without the -a/--text option, diff will avoid generating diffs of files it
654 Without the -a/--text option, diff will avoid generating diffs of files it
655 detects as binary. With -a, diff will generate a diff anyway, probably
655 detects as binary. With -a, diff will generate a diff anyway, probably
656 with undesirable results.
656 with undesirable results.
657
657
658 Use the -g/--git option to generate diffs in the git extended diff format.
658 Use the -g/--git option to generate diffs in the git extended diff format.
659 For more information, read 'hg help diffs'.
659 For more information, read 'hg help diffs'.
660
660
661 Returns 0 on success.
661 Returns 0 on success.
662
662
663 options ([+] can be repeated):
663 options ([+] can be repeated):
664
664
665 -r --rev REV [+] revision
665 -r --rev REV [+] revision
666 -c --change REV change made by revision
666 -c --change REV change made by revision
667 -a --text treat all files as text
667 -a --text treat all files as text
668 -g --git use git extended diff format
668 -g --git use git extended diff format
669 --binary generate binary diffs in git mode (default)
669 --binary generate binary diffs in git mode (default)
670 --nodates omit dates from diff headers
670 --nodates omit dates from diff headers
671 --noprefix omit a/ and b/ prefixes from filenames
671 --noprefix omit a/ and b/ prefixes from filenames
672 -p --show-function show which function each change is in
672 -p --show-function show which function each change is in
673 --reverse produce a diff that undoes the changes
673 --reverse produce a diff that undoes the changes
674 -w --ignore-all-space ignore white space when comparing lines
674 -w --ignore-all-space ignore white space when comparing lines
675 -b --ignore-space-change ignore changes in the amount of white space
675 -b --ignore-space-change ignore changes in the amount of white space
676 -B --ignore-blank-lines ignore changes whose lines are all blank
676 -B --ignore-blank-lines ignore changes whose lines are all blank
677 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
677 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
678 -U --unified NUM number of lines of context to show
678 -U --unified NUM number of lines of context to show
679 --stat output diffstat-style summary of changes
679 --stat output diffstat-style summary of changes
680 --root DIR produce diffs relative to subdirectory
680 --root DIR produce diffs relative to subdirectory
681 -I --include PATTERN [+] include names matching the given patterns
681 -I --include PATTERN [+] include names matching the given patterns
682 -X --exclude PATTERN [+] exclude names matching the given patterns
682 -X --exclude PATTERN [+] exclude names matching the given patterns
683 -S --subrepos recurse into subrepositories
683 -S --subrepos recurse into subrepositories
684
684
685 (some details hidden, use --verbose to show complete help)
685 (some details hidden, use --verbose to show complete help)
686
686
687 $ hg help status
687 $ hg help status
688 hg status [OPTION]... [FILE]...
688 hg status [OPTION]... [FILE]...
689
689
690 aliases: st
690 aliases: st
691
691
692 show changed files in the working directory
692 show changed files in the working directory
693
693
694 Show status of files in the repository. If names are given, only files
694 Show status of files in the repository. If names are given, only files
695 that match are shown. Files that are clean or ignored or the source of a
695 that match are shown. Files that are clean or ignored or the source of a
696 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
696 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
697 -C/--copies or -A/--all are given. Unless options described with "show
697 -C/--copies or -A/--all are given. Unless options described with "show
698 only ..." are given, the options -mardu are used.
698 only ..." are given, the options -mardu are used.
699
699
700 Option -q/--quiet hides untracked (unknown and ignored) files unless
700 Option -q/--quiet hides untracked (unknown and ignored) files unless
701 explicitly requested with -u/--unknown or -i/--ignored.
701 explicitly requested with -u/--unknown or -i/--ignored.
702
702
703 Note:
703 Note:
704 'hg status' may appear to disagree with diff if permissions have
704 'hg status' may appear to disagree with diff if permissions have
705 changed or a merge has occurred. The standard diff format does not
705 changed or a merge has occurred. The standard diff format does not
706 report permission changes and diff only reports changes relative to one
706 report permission changes and diff only reports changes relative to one
707 merge parent.
707 merge parent.
708
708
709 If one revision is given, it is used as the base revision. If two
709 If one revision is given, it is used as the base revision. If two
710 revisions are given, the differences between them are shown. The --change
710 revisions are given, the differences between them are shown. The --change
711 option can also be used as a shortcut to list the changed files of a
711 option can also be used as a shortcut to list the changed files of a
712 revision from its first parent.
712 revision from its first parent.
713
713
714 The codes used to show the status of files are:
714 The codes used to show the status of files are:
715
715
716 M = modified
716 M = modified
717 A = added
717 A = added
718 R = removed
718 R = removed
719 C = clean
719 C = clean
720 ! = missing (deleted by non-hg command, but still tracked)
720 ! = missing (deleted by non-hg command, but still tracked)
721 ? = not tracked
721 ? = not tracked
722 I = ignored
722 I = ignored
723 = origin of the previous file (with --copies)
723 = origin of the previous file (with --copies)
724
724
725 Returns 0 on success.
725 Returns 0 on success.
726
726
727 options ([+] can be repeated):
727 options ([+] can be repeated):
728
728
729 -A --all show status of all files
729 -A --all show status of all files
730 -m --modified show only modified files
730 -m --modified show only modified files
731 -a --added show only added files
731 -a --added show only added files
732 -r --removed show only removed files
732 -r --removed show only removed files
733 -d --deleted show only deleted (but tracked) files
733 -d --deleted show only deleted (but tracked) files
734 -c --clean show only files without changes
734 -c --clean show only files without changes
735 -u --unknown show only unknown (not tracked) files
735 -u --unknown show only unknown (not tracked) files
736 -i --ignored show only ignored files
736 -i --ignored show only ignored files
737 -n --no-status hide status prefix
737 -n --no-status hide status prefix
738 -C --copies show source of copied files
738 -C --copies show source of copied files
739 -0 --print0 end filenames with NUL, for use with xargs
739 -0 --print0 end filenames with NUL, for use with xargs
740 --rev REV [+] show difference from revision
740 --rev REV [+] show difference from revision
741 --change REV list the changed files of a revision
741 --change REV list the changed files of a revision
742 -I --include PATTERN [+] include names matching the given patterns
742 -I --include PATTERN [+] include names matching the given patterns
743 -X --exclude PATTERN [+] exclude names matching the given patterns
743 -X --exclude PATTERN [+] exclude names matching the given patterns
744 -S --subrepos recurse into subrepositories
744 -S --subrepos recurse into subrepositories
745 -T --template TEMPLATE display with template
745 -T --template TEMPLATE display with template
746
746
747 (some details hidden, use --verbose to show complete help)
747 (some details hidden, use --verbose to show complete help)
748
748
749 $ hg -q help status
749 $ hg -q help status
750 hg status [OPTION]... [FILE]...
750 hg status [OPTION]... [FILE]...
751
751
752 show changed files in the working directory
752 show changed files in the working directory
753
753
754 $ hg help foo
754 $ hg help foo
755 abort: no such help topic: foo
755 abort: no such help topic: foo
756 (try 'hg help --keyword foo')
756 (try 'hg help --keyword foo')
757 [255]
757 [255]
758
758
759 $ hg skjdfks
759 $ hg skjdfks
760 hg: unknown command 'skjdfks'
760 hg: unknown command 'skjdfks'
761 (use 'hg help' for a list of commands)
761 (use 'hg help' for a list of commands)
762 [255]
762 [255]
763
763
764 Typoed command gives suggestion
764 Typoed command gives suggestion
765 $ hg puls
765 $ hg puls
766 hg: unknown command 'puls'
766 hg: unknown command 'puls'
767 (did you mean one of pull, push?)
767 (did you mean one of pull, push?)
768 [255]
768 [255]
769
769
770 Not enabled extension gets suggested
770 Not enabled extension gets suggested
771
771
772 $ hg rebase
772 $ hg rebase
773 hg: unknown command 'rebase'
773 hg: unknown command 'rebase'
774 'rebase' is provided by the following extension:
774 'rebase' is provided by the following extension:
775
775
776 rebase command to move sets of revisions to a different ancestor
776 rebase command to move sets of revisions to a different ancestor
777
777
778 (use 'hg help extensions' for information on enabling extensions)
778 (use 'hg help extensions' for information on enabling extensions)
779 [255]
779 [255]
780
780
781 Disabled extension gets suggested
781 Disabled extension gets suggested
782 $ hg --config extensions.rebase=! rebase
782 $ hg --config extensions.rebase=! rebase
783 hg: unknown command 'rebase'
783 hg: unknown command 'rebase'
784 'rebase' is provided by the following extension:
784 'rebase' is provided by the following extension:
785
785
786 rebase command to move sets of revisions to a different ancestor
786 rebase command to move sets of revisions to a different ancestor
787
787
788 (use 'hg help extensions' for information on enabling extensions)
788 (use 'hg help extensions' for information on enabling extensions)
789 [255]
789 [255]
790
790
791 Make sure that we don't run afoul of the help system thinking that
791 Make sure that we don't run afoul of the help system thinking that
792 this is a section and erroring out weirdly.
792 this is a section and erroring out weirdly.
793
793
794 $ hg .log
794 $ hg .log
795 hg: unknown command '.log'
795 hg: unknown command '.log'
796 (did you mean log?)
796 (did you mean log?)
797 [255]
797 [255]
798
798
799 $ hg log.
799 $ hg log.
800 hg: unknown command 'log.'
800 hg: unknown command 'log.'
801 (did you mean log?)
801 (did you mean log?)
802 [255]
802 [255]
803 $ hg pu.lh
803 $ hg pu.lh
804 hg: unknown command 'pu.lh'
804 hg: unknown command 'pu.lh'
805 (did you mean one of pull, push?)
805 (did you mean one of pull, push?)
806 [255]
806 [255]
807
807
808 $ cat > helpext.py <<EOF
808 $ cat > helpext.py <<EOF
809 > import os
809 > import os
810 > from mercurial import commands, fancyopts, registrar
810 > from mercurial import commands, fancyopts, registrar
811 >
811 >
812 > def func(arg):
812 > def func(arg):
813 > return '%sfoo' % arg
813 > return '%sfoo' % arg
814 > class customopt(fancyopts.customopt):
814 > class customopt(fancyopts.customopt):
815 > def newstate(self, oldstate, newparam, abort):
815 > def newstate(self, oldstate, newparam, abort):
816 > return '%sbar' % oldstate
816 > return '%sbar' % oldstate
817 > cmdtable = {}
817 > cmdtable = {}
818 > command = registrar.command(cmdtable)
818 > command = registrar.command(cmdtable)
819 >
819 >
820 > @command(b'nohelp',
820 > @command(b'nohelp',
821 > [(b'', b'longdesc', 3, b'x'*67),
821 > [(b'', b'longdesc', 3, b'x'*67),
822 > (b'n', b'', None, b'normal desc'),
822 > (b'n', b'', None, b'normal desc'),
823 > (b'', b'newline', b'', b'line1\nline2'),
823 > (b'', b'newline', b'', b'line1\nline2'),
824 > (b'', b'default-off', False, b'enable X'),
824 > (b'', b'default-off', False, b'enable X'),
825 > (b'', b'default-on', True, b'enable Y'),
825 > (b'', b'default-on', True, b'enable Y'),
826 > (b'', b'callableopt', func, b'adds foo'),
826 > (b'', b'callableopt', func, b'adds foo'),
827 > (b'', b'customopt', customopt(''), b'adds bar'),
827 > (b'', b'customopt', customopt(''), b'adds bar'),
828 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
828 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
829 > b'hg nohelp',
829 > b'hg nohelp',
830 > norepo=True)
830 > norepo=True)
831 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
831 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
832 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
832 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
833 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
833 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
834 > def nohelp(ui, *args, **kwargs):
834 > def nohelp(ui, *args, **kwargs):
835 > pass
835 > pass
836 >
836 >
837 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
837 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
838 > def hashelp(ui, *args, **kwargs):
838 > def hashelp(ui, *args, **kwargs):
839 > """Extension command's help"""
839 > """Extension command's help"""
840 >
840 >
841 > def uisetup(ui):
841 > def uisetup(ui):
842 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
842 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
843 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
843 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
844 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
844 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
845 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
845 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
846 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
846 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
847 >
847 >
848 > EOF
848 > EOF
849 $ echo '[extensions]' >> $HGRCPATH
849 $ echo '[extensions]' >> $HGRCPATH
850 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
850 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
851
851
852 Test for aliases
852 Test for aliases
853
853
854 $ hg help | grep hgalias
854 $ hg help | grep hgalias
855 hgalias My doc
855 hgalias My doc
856
856
857 $ hg help hgalias
857 $ hg help hgalias
858 hg hgalias [--remote]
858 hg hgalias [--remote]
859
859
860 alias for: hg summary
860 alias for: hg summary
861
861
862 My doc
862 My doc
863
863
864 defined by: helpext
864 defined by: helpext
865
865
866 options:
866 options:
867
867
868 --remote check for push and pull
868 --remote check for push and pull
869
869
870 (some details hidden, use --verbose to show complete help)
870 (some details hidden, use --verbose to show complete help)
871 $ hg help hgaliasnodoc
871 $ hg help hgaliasnodoc
872 hg hgaliasnodoc [--remote]
872 hg hgaliasnodoc [--remote]
873
873
874 alias for: hg summary
874 alias for: hg summary
875
875
876 summarize working directory state
876 summarize working directory state
877
877
878 This generates a brief summary of the working directory state, including
878 This generates a brief summary of the working directory state, including
879 parents, branch, commit status, phase and available updates.
879 parents, branch, commit status, phase and available updates.
880
880
881 With the --remote option, this will check the default paths for incoming
881 With the --remote option, this will check the default paths for incoming
882 and outgoing changes. This can be time-consuming.
882 and outgoing changes. This can be time-consuming.
883
883
884 Returns 0 on success.
884 Returns 0 on success.
885
885
886 defined by: helpext
886 defined by: helpext
887
887
888 options:
888 options:
889
889
890 --remote check for push and pull
890 --remote check for push and pull
891
891
892 (some details hidden, use --verbose to show complete help)
892 (some details hidden, use --verbose to show complete help)
893
893
894 $ hg help shellalias
894 $ hg help shellalias
895 hg shellalias
895 hg shellalias
896
896
897 shell alias for: echo hi
897 shell alias for: echo hi
898
898
899 (no help text available)
899 (no help text available)
900
900
901 defined by: helpext
901 defined by: helpext
902
902
903 (some details hidden, use --verbose to show complete help)
903 (some details hidden, use --verbose to show complete help)
904
904
905 Test command with no help text
905 Test command with no help text
906
906
907 $ hg help nohelp
907 $ hg help nohelp
908 hg nohelp
908 hg nohelp
909
909
910 (no help text available)
910 (no help text available)
911
911
912 options:
912 options:
913
913
914 --longdesc VALUE
914 --longdesc VALUE
915 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
915 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
916 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
916 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
917 -n -- normal desc
917 -n -- normal desc
918 --newline VALUE line1 line2
918 --newline VALUE line1 line2
919 --default-off enable X
919 --default-off enable X
920 --[no-]default-on enable Y (default: on)
920 --[no-]default-on enable Y (default: on)
921 --callableopt VALUE adds foo
921 --callableopt VALUE adds foo
922 --customopt VALUE adds bar
922 --customopt VALUE adds bar
923 --customopt-withdefault VALUE adds bar (default: foo)
923 --customopt-withdefault VALUE adds bar (default: foo)
924
924
925 (some details hidden, use --verbose to show complete help)
925 (some details hidden, use --verbose to show complete help)
926
926
927 Test that default list of commands includes extension commands that have help,
927 Test that default list of commands includes extension commands that have help,
928 but not those that don't, except in verbose mode, when a keyword is passed, or
928 but not those that don't, except in verbose mode, when a keyword is passed, or
929 when help about the extension is requested.
929 when help about the extension is requested.
930
930
931 #if no-extraextensions
931 #if no-extraextensions
932
932
933 $ hg help | grep hashelp
933 $ hg help | grep hashelp
934 hashelp Extension command's help
934 hashelp Extension command's help
935 $ hg help | grep nohelp
935 $ hg help | grep nohelp
936 [1]
936 [1]
937 $ hg help -v | grep nohelp
937 $ hg help -v | grep nohelp
938 nohelp (no help text available)
938 nohelp (no help text available)
939
939
940 $ hg help -k nohelp
940 $ hg help -k nohelp
941 Commands:
941 Commands:
942
942
943 nohelp hg nohelp
943 nohelp hg nohelp
944
944
945 Extension Commands:
945 Extension Commands:
946
946
947 nohelp (no help text available)
947 nohelp (no help text available)
948
948
949 $ hg help helpext
949 $ hg help helpext
950 helpext extension - no help text available
950 helpext extension - no help text available
951
951
952 list of commands:
952 list of commands:
953
953
954 hashelp Extension command's help
954 hashelp Extension command's help
955 nohelp (no help text available)
955 nohelp (no help text available)
956
956
957 (use 'hg help -v helpext' to show built-in aliases and global options)
957 (use 'hg help -v helpext' to show built-in aliases and global options)
958
958
959 #endif
959 #endif
960
960
961 Test list of internal help commands
961 Test list of internal help commands
962
962
963 $ hg help debug
963 $ hg help debug
964 debug commands (internal and unsupported):
964 debug commands (internal and unsupported):
965
965
966 debugancestor
966 debugancestor
967 find the ancestor revision of two revisions in a given index
967 find the ancestor revision of two revisions in a given index
968 debugapplystreamclonebundle
968 debugapplystreamclonebundle
969 apply a stream clone bundle file
969 apply a stream clone bundle file
970 debugbuilddag
970 debugbuilddag
971 builds a repo with a given DAG from scratch in the current
971 builds a repo with a given DAG from scratch in the current
972 empty repo
972 empty repo
973 debugbundle lists the contents of a bundle
973 debugbundle lists the contents of a bundle
974 debugcapabilities
974 debugcapabilities
975 lists the capabilities of a remote peer
975 lists the capabilities of a remote peer
976 debugcheckstate
976 debugcheckstate
977 validate the correctness of the current dirstate
977 validate the correctness of the current dirstate
978 debugcolor show available color, effects or style
978 debugcolor show available color, effects or style
979 debugcommands
979 debugcommands
980 list all available commands and options
980 list all available commands and options
981 debugcomplete
981 debugcomplete
982 returns the completion list associated with the given command
982 returns the completion list associated with the given command
983 debugcreatestreamclonebundle
983 debugcreatestreamclonebundle
984 create a stream clone bundle file
984 create a stream clone bundle file
985 debugdag format the changelog or an index DAG as a concise textual
985 debugdag format the changelog or an index DAG as a concise textual
986 description
986 description
987 debugdata dump the contents of a data file revision
987 debugdata dump the contents of a data file revision
988 debugdate parse and display a date
988 debugdate parse and display a date
989 debugdeltachain
989 debugdeltachain
990 dump information about delta chains in a revlog
990 dump information about delta chains in a revlog
991 debugdirstate
991 debugdirstate
992 show the contents of the current dirstate
992 show the contents of the current dirstate
993 debugdiscovery
993 debugdiscovery
994 runs the changeset discovery protocol in isolation
994 runs the changeset discovery protocol in isolation
995 debugdownload
995 debugdownload
996 download a resource using Mercurial logic and config
996 download a resource using Mercurial logic and config
997 debugextensions
997 debugextensions
998 show information about active extensions
998 show information about active extensions
999 debugfileset parse and apply a fileset specification
999 debugfileset parse and apply a fileset specification
1000 debugformat display format information about the current repository
1000 debugformat display format information about the current repository
1001 debugfsinfo show information detected about current filesystem
1001 debugfsinfo show information detected about current filesystem
1002 debuggetbundle
1002 debuggetbundle
1003 retrieves a bundle from a repo
1003 retrieves a bundle from a repo
1004 debugignore display the combined ignore pattern and information about
1004 debugignore display the combined ignore pattern and information about
1005 ignored files
1005 ignored files
1006 debugindex dump index data for a storage primitive
1006 debugindex dump index data for a storage primitive
1007 debugindexdot
1007 debugindexdot
1008 dump an index DAG as a graphviz dot file
1008 dump an index DAG as a graphviz dot file
1009 debugindexstats
1009 debugindexstats
1010 show stats related to the changelog index
1010 show stats related to the changelog index
1011 debuginstall test Mercurial installation
1011 debuginstall test Mercurial installation
1012 debugknown test whether node ids are known to a repo
1012 debugknown test whether node ids are known to a repo
1013 debuglocks show or modify state of locks
1013 debuglocks show or modify state of locks
1014 debugmanifestfulltextcache
1014 debugmanifestfulltextcache
1015 show, clear or amend the contents of the manifest fulltext
1015 show, clear or amend the contents of the manifest fulltext
1016 cache
1016 cache
1017 debugmergestate
1017 debugmergestate
1018 print merge state
1018 print merge state
1019 debugnamecomplete
1019 debugnamecomplete
1020 complete "names" - tags, open branch names, bookmark names
1020 complete "names" - tags, open branch names, bookmark names
1021 debugobsolete
1021 debugobsolete
1022 create arbitrary obsolete marker
1022 create arbitrary obsolete marker
1023 debugoptADV (no help text available)
1023 debugoptADV (no help text available)
1024 debugoptDEP (no help text available)
1024 debugoptDEP (no help text available)
1025 debugoptEXP (no help text available)
1025 debugoptEXP (no help text available)
1026 debugp1copies
1026 debugp1copies
1027 dump copy information compared to p1
1027 dump copy information compared to p1
1028 debugp2copies
1028 debugp2copies
1029 dump copy information compared to p2
1029 dump copy information compared to p2
1030 debugpathcomplete
1030 debugpathcomplete
1031 complete part or all of a tracked path
1031 complete part or all of a tracked path
1032 debugpathcopies
1032 debugpathcopies
1033 show copies between two revisions
1033 show copies between two revisions
1034 debugpeer establish a connection to a peer repository
1034 debugpeer establish a connection to a peer repository
1035 debugpickmergetool
1035 debugpickmergetool
1036 examine which merge tool is chosen for specified file
1036 examine which merge tool is chosen for specified file
1037 debugpushkey access the pushkey key/value protocol
1037 debugpushkey access the pushkey key/value protocol
1038 debugpvec (no help text available)
1038 debugpvec (no help text available)
1039 debugrebuilddirstate
1039 debugrebuilddirstate
1040 rebuild the dirstate as it would look like for the given
1040 rebuild the dirstate as it would look like for the given
1041 revision
1041 revision
1042 debugrebuildfncache
1042 debugrebuildfncache
1043 rebuild the fncache file
1043 rebuild the fncache file
1044 debugrename dump rename information
1044 debugrename dump rename information
1045 debugrevlog show data and statistics about a revlog
1045 debugrevlog show data and statistics about a revlog
1046 debugrevlogindex
1046 debugrevlogindex
1047 dump the contents of a revlog index
1047 dump the contents of a revlog index
1048 debugrevspec parse and apply a revision specification
1048 debugrevspec parse and apply a revision specification
1049 debugserve run a server with advanced settings
1049 debugserve run a server with advanced settings
1050 debugsetparents
1050 debugsetparents
1051 manually set the parents of the current working directory
1051 manually set the parents of the current working directory
1052 debugsidedata
1052 debugsidedata
1053 dump the side data for a cl/manifest/file revision
1053 dump the side data for a cl/manifest/file revision
1054 debugssl test a secure connection to a server
1054 debugssl test a secure connection to a server
1055 debugsub (no help text available)
1055 debugsub (no help text available)
1056 debugsuccessorssets
1056 debugsuccessorssets
1057 show set of successors for revision
1057 show set of successors for revision
1058 debugtagscache
1059 display the contents of .hg/cache/hgtagsfnodes1
1058 debugtemplate
1060 debugtemplate
1059 parse and apply a template
1061 parse and apply a template
1060 debuguigetpass
1062 debuguigetpass
1061 show prompt to type password
1063 show prompt to type password
1062 debuguiprompt
1064 debuguiprompt
1063 show plain prompt
1065 show plain prompt
1064 debugupdatecaches
1066 debugupdatecaches
1065 warm all known caches in the repository
1067 warm all known caches in the repository
1066 debugupgraderepo
1068 debugupgraderepo
1067 upgrade a repository to use different features
1069 upgrade a repository to use different features
1068 debugwalk show how files match on given patterns
1070 debugwalk show how files match on given patterns
1069 debugwhyunstable
1071 debugwhyunstable
1070 explain instabilities of a changeset
1072 explain instabilities of a changeset
1071 debugwireargs
1073 debugwireargs
1072 (no help text available)
1074 (no help text available)
1073 debugwireproto
1075 debugwireproto
1074 send wire protocol commands to a server
1076 send wire protocol commands to a server
1075
1077
1076 (use 'hg help -v debug' to show built-in aliases and global options)
1078 (use 'hg help -v debug' to show built-in aliases and global options)
1077
1079
1078 internals topic renders index of available sub-topics
1080 internals topic renders index of available sub-topics
1079
1081
1080 $ hg help internals
1082 $ hg help internals
1081 Technical implementation topics
1083 Technical implementation topics
1082 """""""""""""""""""""""""""""""
1084 """""""""""""""""""""""""""""""
1083
1085
1084 To access a subtopic, use "hg help internals.{subtopic-name}"
1086 To access a subtopic, use "hg help internals.{subtopic-name}"
1085
1087
1086 bundle2 Bundle2
1088 bundle2 Bundle2
1087 bundles Bundles
1089 bundles Bundles
1088 cbor CBOR
1090 cbor CBOR
1089 censor Censor
1091 censor Censor
1090 changegroups Changegroups
1092 changegroups Changegroups
1091 config Config Registrar
1093 config Config Registrar
1092 extensions Extension API
1094 extensions Extension API
1093 mergestate Mergestate
1095 mergestate Mergestate
1094 requirements Repository Requirements
1096 requirements Repository Requirements
1095 revlogs Revision Logs
1097 revlogs Revision Logs
1096 wireprotocol Wire Protocol
1098 wireprotocol Wire Protocol
1097 wireprotocolrpc
1099 wireprotocolrpc
1098 Wire Protocol RPC
1100 Wire Protocol RPC
1099 wireprotocolv2
1101 wireprotocolv2
1100 Wire Protocol Version 2
1102 Wire Protocol Version 2
1101
1103
1102 sub-topics can be accessed
1104 sub-topics can be accessed
1103
1105
1104 $ hg help internals.changegroups
1106 $ hg help internals.changegroups
1105 Changegroups
1107 Changegroups
1106 """"""""""""
1108 """"""""""""
1107
1109
1108 Changegroups are representations of repository revlog data, specifically
1110 Changegroups are representations of repository revlog data, specifically
1109 the changelog data, root/flat manifest data, treemanifest data, and
1111 the changelog data, root/flat manifest data, treemanifest data, and
1110 filelogs.
1112 filelogs.
1111
1113
1112 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1114 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1113 level, versions "1" and "2" are almost exactly the same, with the only
1115 level, versions "1" and "2" are almost exactly the same, with the only
1114 difference being an additional item in the *delta header*. Version "3"
1116 difference being an additional item in the *delta header*. Version "3"
1115 adds support for storage flags in the *delta header* and optionally
1117 adds support for storage flags in the *delta header* and optionally
1116 exchanging treemanifests (enabled by setting an option on the
1118 exchanging treemanifests (enabled by setting an option on the
1117 "changegroup" part in the bundle2).
1119 "changegroup" part in the bundle2).
1118
1120
1119 Changegroups when not exchanging treemanifests consist of 3 logical
1121 Changegroups when not exchanging treemanifests consist of 3 logical
1120 segments:
1122 segments:
1121
1123
1122 +---------------------------------+
1124 +---------------------------------+
1123 | | | |
1125 | | | |
1124 | changeset | manifest | filelogs |
1126 | changeset | manifest | filelogs |
1125 | | | |
1127 | | | |
1126 | | | |
1128 | | | |
1127 +---------------------------------+
1129 +---------------------------------+
1128
1130
1129 When exchanging treemanifests, there are 4 logical segments:
1131 When exchanging treemanifests, there are 4 logical segments:
1130
1132
1131 +-------------------------------------------------+
1133 +-------------------------------------------------+
1132 | | | | |
1134 | | | | |
1133 | changeset | root | treemanifests | filelogs |
1135 | changeset | root | treemanifests | filelogs |
1134 | | manifest | | |
1136 | | manifest | | |
1135 | | | | |
1137 | | | | |
1136 +-------------------------------------------------+
1138 +-------------------------------------------------+
1137
1139
1138 The principle building block of each segment is a *chunk*. A *chunk* is a
1140 The principle building block of each segment is a *chunk*. A *chunk* is a
1139 framed piece of data:
1141 framed piece of data:
1140
1142
1141 +---------------------------------------+
1143 +---------------------------------------+
1142 | | |
1144 | | |
1143 | length | data |
1145 | length | data |
1144 | (4 bytes) | (<length - 4> bytes) |
1146 | (4 bytes) | (<length - 4> bytes) |
1145 | | |
1147 | | |
1146 +---------------------------------------+
1148 +---------------------------------------+
1147
1149
1148 All integers are big-endian signed integers. Each chunk starts with a
1150 All integers are big-endian signed integers. Each chunk starts with a
1149 32-bit integer indicating the length of the entire chunk (including the
1151 32-bit integer indicating the length of the entire chunk (including the
1150 length field itself).
1152 length field itself).
1151
1153
1152 There is a special case chunk that has a value of 0 for the length
1154 There is a special case chunk that has a value of 0 for the length
1153 ("0x00000000"). We call this an *empty chunk*.
1155 ("0x00000000"). We call this an *empty chunk*.
1154
1156
1155 Delta Groups
1157 Delta Groups
1156 ============
1158 ============
1157
1159
1158 A *delta group* expresses the content of a revlog as a series of deltas,
1160 A *delta group* expresses the content of a revlog as a series of deltas,
1159 or patches against previous revisions.
1161 or patches against previous revisions.
1160
1162
1161 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1163 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1162 to signal the end of the delta group:
1164 to signal the end of the delta group:
1163
1165
1164 +------------------------------------------------------------------------+
1166 +------------------------------------------------------------------------+
1165 | | | | | |
1167 | | | | | |
1166 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1168 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1167 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1169 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1168 | | | | | |
1170 | | | | | |
1169 +------------------------------------------------------------------------+
1171 +------------------------------------------------------------------------+
1170
1172
1171 Each *chunk*'s data consists of the following:
1173 Each *chunk*'s data consists of the following:
1172
1174
1173 +---------------------------------------+
1175 +---------------------------------------+
1174 | | |
1176 | | |
1175 | delta header | delta data |
1177 | delta header | delta data |
1176 | (various by version) | (various) |
1178 | (various by version) | (various) |
1177 | | |
1179 | | |
1178 +---------------------------------------+
1180 +---------------------------------------+
1179
1181
1180 The *delta data* is a series of *delta*s that describe a diff from an
1182 The *delta data* is a series of *delta*s that describe a diff from an
1181 existing entry (either that the recipient already has, or previously
1183 existing entry (either that the recipient already has, or previously
1182 specified in the bundle/changegroup).
1184 specified in the bundle/changegroup).
1183
1185
1184 The *delta header* is different between versions "1", "2", and "3" of the
1186 The *delta header* is different between versions "1", "2", and "3" of the
1185 changegroup format.
1187 changegroup format.
1186
1188
1187 Version 1 (headerlen=80):
1189 Version 1 (headerlen=80):
1188
1190
1189 +------------------------------------------------------+
1191 +------------------------------------------------------+
1190 | | | | |
1192 | | | | |
1191 | node | p1 node | p2 node | link node |
1193 | node | p1 node | p2 node | link node |
1192 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1194 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1193 | | | | |
1195 | | | | |
1194 +------------------------------------------------------+
1196 +------------------------------------------------------+
1195
1197
1196 Version 2 (headerlen=100):
1198 Version 2 (headerlen=100):
1197
1199
1198 +------------------------------------------------------------------+
1200 +------------------------------------------------------------------+
1199 | | | | | |
1201 | | | | | |
1200 | node | p1 node | p2 node | base node | link node |
1202 | node | p1 node | p2 node | base node | link node |
1201 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1203 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1202 | | | | | |
1204 | | | | | |
1203 +------------------------------------------------------------------+
1205 +------------------------------------------------------------------+
1204
1206
1205 Version 3 (headerlen=102):
1207 Version 3 (headerlen=102):
1206
1208
1207 +------------------------------------------------------------------------------+
1209 +------------------------------------------------------------------------------+
1208 | | | | | | |
1210 | | | | | | |
1209 | node | p1 node | p2 node | base node | link node | flags |
1211 | node | p1 node | p2 node | base node | link node | flags |
1210 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1212 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1211 | | | | | | |
1213 | | | | | | |
1212 +------------------------------------------------------------------------------+
1214 +------------------------------------------------------------------------------+
1213
1215
1214 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1216 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1215 contain a series of *delta*s, densely packed (no separators). These deltas
1217 contain a series of *delta*s, densely packed (no separators). These deltas
1216 describe a diff from an existing entry (either that the recipient already
1218 describe a diff from an existing entry (either that the recipient already
1217 has, or previously specified in the bundle/changegroup). The format is
1219 has, or previously specified in the bundle/changegroup). The format is
1218 described more fully in "hg help internals.bdiff", but briefly:
1220 described more fully in "hg help internals.bdiff", but briefly:
1219
1221
1220 +---------------------------------------------------------------+
1222 +---------------------------------------------------------------+
1221 | | | | |
1223 | | | | |
1222 | start offset | end offset | new length | content |
1224 | start offset | end offset | new length | content |
1223 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1225 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1224 | | | | |
1226 | | | | |
1225 +---------------------------------------------------------------+
1227 +---------------------------------------------------------------+
1226
1228
1227 Please note that the length field in the delta data does *not* include
1229 Please note that the length field in the delta data does *not* include
1228 itself.
1230 itself.
1229
1231
1230 In version 1, the delta is always applied against the previous node from
1232 In version 1, the delta is always applied against the previous node from
1231 the changegroup or the first parent if this is the first entry in the
1233 the changegroup or the first parent if this is the first entry in the
1232 changegroup.
1234 changegroup.
1233
1235
1234 In version 2 and up, the delta base node is encoded in the entry in the
1236 In version 2 and up, the delta base node is encoded in the entry in the
1235 changegroup. This allows the delta to be expressed against any parent,
1237 changegroup. This allows the delta to be expressed against any parent,
1236 which can result in smaller deltas and more efficient encoding of data.
1238 which can result in smaller deltas and more efficient encoding of data.
1237
1239
1238 The *flags* field holds bitwise flags affecting the processing of revision
1240 The *flags* field holds bitwise flags affecting the processing of revision
1239 data. The following flags are defined:
1241 data. The following flags are defined:
1240
1242
1241 32768
1243 32768
1242 Censored revision. The revision's fulltext has been replaced by censor
1244 Censored revision. The revision's fulltext has been replaced by censor
1243 metadata. May only occur on file revisions.
1245 metadata. May only occur on file revisions.
1244
1246
1245 16384
1247 16384
1246 Ellipsis revision. Revision hash does not match data (likely due to
1248 Ellipsis revision. Revision hash does not match data (likely due to
1247 rewritten parents).
1249 rewritten parents).
1248
1250
1249 8192
1251 8192
1250 Externally stored. The revision fulltext contains "key:value" "\n"
1252 Externally stored. The revision fulltext contains "key:value" "\n"
1251 delimited metadata defining an object stored elsewhere. Used by the LFS
1253 delimited metadata defining an object stored elsewhere. Used by the LFS
1252 extension.
1254 extension.
1253
1255
1254 For historical reasons, the integer values are identical to revlog version
1256 For historical reasons, the integer values are identical to revlog version
1255 1 per-revision storage flags and correspond to bits being set in this
1257 1 per-revision storage flags and correspond to bits being set in this
1256 2-byte field. Bits were allocated starting from the most-significant bit,
1258 2-byte field. Bits were allocated starting from the most-significant bit,
1257 hence the reverse ordering and allocation of these flags.
1259 hence the reverse ordering and allocation of these flags.
1258
1260
1259 Changeset Segment
1261 Changeset Segment
1260 =================
1262 =================
1261
1263
1262 The *changeset segment* consists of a single *delta group* holding
1264 The *changeset segment* consists of a single *delta group* holding
1263 changelog data. The *empty chunk* at the end of the *delta group* denotes
1265 changelog data. The *empty chunk* at the end of the *delta group* denotes
1264 the boundary to the *manifest segment*.
1266 the boundary to the *manifest segment*.
1265
1267
1266 Manifest Segment
1268 Manifest Segment
1267 ================
1269 ================
1268
1270
1269 The *manifest segment* consists of a single *delta group* holding manifest
1271 The *manifest segment* consists of a single *delta group* holding manifest
1270 data. If treemanifests are in use, it contains only the manifest for the
1272 data. If treemanifests are in use, it contains only the manifest for the
1271 root directory of the repository. Otherwise, it contains the entire
1273 root directory of the repository. Otherwise, it contains the entire
1272 manifest data. The *empty chunk* at the end of the *delta group* denotes
1274 manifest data. The *empty chunk* at the end of the *delta group* denotes
1273 the boundary to the next segment (either the *treemanifests segment* or
1275 the boundary to the next segment (either the *treemanifests segment* or
1274 the *filelogs segment*, depending on version and the request options).
1276 the *filelogs segment*, depending on version and the request options).
1275
1277
1276 Treemanifests Segment
1278 Treemanifests Segment
1277 ---------------------
1279 ---------------------
1278
1280
1279 The *treemanifests segment* only exists in changegroup version "3", and
1281 The *treemanifests segment* only exists in changegroup version "3", and
1280 only if the 'treemanifest' param is part of the bundle2 changegroup part
1282 only if the 'treemanifest' param is part of the bundle2 changegroup part
1281 (it is not possible to use changegroup version 3 outside of bundle2).
1283 (it is not possible to use changegroup version 3 outside of bundle2).
1282 Aside from the filenames in the *treemanifests segment* containing a
1284 Aside from the filenames in the *treemanifests segment* containing a
1283 trailing "/" character, it behaves identically to the *filelogs segment*
1285 trailing "/" character, it behaves identically to the *filelogs segment*
1284 (see below). The final sub-segment is followed by an *empty chunk*
1286 (see below). The final sub-segment is followed by an *empty chunk*
1285 (logically, a sub-segment with filename size 0). This denotes the boundary
1287 (logically, a sub-segment with filename size 0). This denotes the boundary
1286 to the *filelogs segment*.
1288 to the *filelogs segment*.
1287
1289
1288 Filelogs Segment
1290 Filelogs Segment
1289 ================
1291 ================
1290
1292
1291 The *filelogs segment* consists of multiple sub-segments, each
1293 The *filelogs segment* consists of multiple sub-segments, each
1292 corresponding to an individual file whose data is being described:
1294 corresponding to an individual file whose data is being described:
1293
1295
1294 +--------------------------------------------------+
1296 +--------------------------------------------------+
1295 | | | | | |
1297 | | | | | |
1296 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1298 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1297 | | | | | (4 bytes) |
1299 | | | | | (4 bytes) |
1298 | | | | | |
1300 | | | | | |
1299 +--------------------------------------------------+
1301 +--------------------------------------------------+
1300
1302
1301 The final filelog sub-segment is followed by an *empty chunk* (logically,
1303 The final filelog sub-segment is followed by an *empty chunk* (logically,
1302 a sub-segment with filename size 0). This denotes the end of the segment
1304 a sub-segment with filename size 0). This denotes the end of the segment
1303 and of the overall changegroup.
1305 and of the overall changegroup.
1304
1306
1305 Each filelog sub-segment consists of the following:
1307 Each filelog sub-segment consists of the following:
1306
1308
1307 +------------------------------------------------------+
1309 +------------------------------------------------------+
1308 | | | |
1310 | | | |
1309 | filename length | filename | delta group |
1311 | filename length | filename | delta group |
1310 | (4 bytes) | (<length - 4> bytes) | (various) |
1312 | (4 bytes) | (<length - 4> bytes) | (various) |
1311 | | | |
1313 | | | |
1312 +------------------------------------------------------+
1314 +------------------------------------------------------+
1313
1315
1314 That is, a *chunk* consisting of the filename (not terminated or padded)
1316 That is, a *chunk* consisting of the filename (not terminated or padded)
1315 followed by N chunks constituting the *delta group* for this file. The
1317 followed by N chunks constituting the *delta group* for this file. The
1316 *empty chunk* at the end of each *delta group* denotes the boundary to the
1318 *empty chunk* at the end of each *delta group* denotes the boundary to the
1317 next filelog sub-segment.
1319 next filelog sub-segment.
1318
1320
1319 non-existent subtopics print an error
1321 non-existent subtopics print an error
1320
1322
1321 $ hg help internals.foo
1323 $ hg help internals.foo
1322 abort: no such help topic: internals.foo
1324 abort: no such help topic: internals.foo
1323 (try 'hg help --keyword foo')
1325 (try 'hg help --keyword foo')
1324 [255]
1326 [255]
1325
1327
1326 test advanced, deprecated and experimental options are hidden in command help
1328 test advanced, deprecated and experimental options are hidden in command help
1327 $ hg help debugoptADV
1329 $ hg help debugoptADV
1328 hg debugoptADV
1330 hg debugoptADV
1329
1331
1330 (no help text available)
1332 (no help text available)
1331
1333
1332 options:
1334 options:
1333
1335
1334 (some details hidden, use --verbose to show complete help)
1336 (some details hidden, use --verbose to show complete help)
1335 $ hg help debugoptDEP
1337 $ hg help debugoptDEP
1336 hg debugoptDEP
1338 hg debugoptDEP
1337
1339
1338 (no help text available)
1340 (no help text available)
1339
1341
1340 options:
1342 options:
1341
1343
1342 (some details hidden, use --verbose to show complete help)
1344 (some details hidden, use --verbose to show complete help)
1343
1345
1344 $ hg help debugoptEXP
1346 $ hg help debugoptEXP
1345 hg debugoptEXP
1347 hg debugoptEXP
1346
1348
1347 (no help text available)
1349 (no help text available)
1348
1350
1349 options:
1351 options:
1350
1352
1351 (some details hidden, use --verbose to show complete help)
1353 (some details hidden, use --verbose to show complete help)
1352
1354
1353 test advanced, deprecated and experimental options are shown with -v
1355 test advanced, deprecated and experimental options are shown with -v
1354 $ hg help -v debugoptADV | grep aopt
1356 $ hg help -v debugoptADV | grep aopt
1355 --aopt option is (ADVANCED)
1357 --aopt option is (ADVANCED)
1356 $ hg help -v debugoptDEP | grep dopt
1358 $ hg help -v debugoptDEP | grep dopt
1357 --dopt option is (DEPRECATED)
1359 --dopt option is (DEPRECATED)
1358 $ hg help -v debugoptEXP | grep eopt
1360 $ hg help -v debugoptEXP | grep eopt
1359 --eopt option is (EXPERIMENTAL)
1361 --eopt option is (EXPERIMENTAL)
1360
1362
1361 #if gettext
1363 #if gettext
1362 test deprecated option is hidden with translation with untranslated description
1364 test deprecated option is hidden with translation with untranslated description
1363 (use many globy for not failing on changed transaction)
1365 (use many globy for not failing on changed transaction)
1364 $ LANGUAGE=sv hg help debugoptDEP
1366 $ LANGUAGE=sv hg help debugoptDEP
1365 hg debugoptDEP
1367 hg debugoptDEP
1366
1368
1367 (*) (glob)
1369 (*) (glob)
1368
1370
1369 options:
1371 options:
1370
1372
1371 (some details hidden, use --verbose to show complete help)
1373 (some details hidden, use --verbose to show complete help)
1372 #endif
1374 #endif
1373
1375
1374 Test commands that collide with topics (issue4240)
1376 Test commands that collide with topics (issue4240)
1375
1377
1376 $ hg config -hq
1378 $ hg config -hq
1377 hg config [-u] [NAME]...
1379 hg config [-u] [NAME]...
1378
1380
1379 show combined config settings from all hgrc files
1381 show combined config settings from all hgrc files
1380 $ hg showconfig -hq
1382 $ hg showconfig -hq
1381 hg config [-u] [NAME]...
1383 hg config [-u] [NAME]...
1382
1384
1383 show combined config settings from all hgrc files
1385 show combined config settings from all hgrc files
1384
1386
1385 Test a help topic
1387 Test a help topic
1386
1388
1387 $ hg help dates
1389 $ hg help dates
1388 Date Formats
1390 Date Formats
1389 """"""""""""
1391 """"""""""""
1390
1392
1391 Some commands allow the user to specify a date, e.g.:
1393 Some commands allow the user to specify a date, e.g.:
1392
1394
1393 - backout, commit, import, tag: Specify the commit date.
1395 - backout, commit, import, tag: Specify the commit date.
1394 - log, revert, update: Select revision(s) by date.
1396 - log, revert, update: Select revision(s) by date.
1395
1397
1396 Many date formats are valid. Here are some examples:
1398 Many date formats are valid. Here are some examples:
1397
1399
1398 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1400 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1399 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1401 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1400 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1402 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1401 - "Dec 6" (midnight)
1403 - "Dec 6" (midnight)
1402 - "13:18" (today assumed)
1404 - "13:18" (today assumed)
1403 - "3:39" (3:39AM assumed)
1405 - "3:39" (3:39AM assumed)
1404 - "3:39pm" (15:39)
1406 - "3:39pm" (15:39)
1405 - "2006-12-06 13:18:29" (ISO 8601 format)
1407 - "2006-12-06 13:18:29" (ISO 8601 format)
1406 - "2006-12-6 13:18"
1408 - "2006-12-6 13:18"
1407 - "2006-12-6"
1409 - "2006-12-6"
1408 - "12-6"
1410 - "12-6"
1409 - "12/6"
1411 - "12/6"
1410 - "12/6/6" (Dec 6 2006)
1412 - "12/6/6" (Dec 6 2006)
1411 - "today" (midnight)
1413 - "today" (midnight)
1412 - "yesterday" (midnight)
1414 - "yesterday" (midnight)
1413 - "now" - right now
1415 - "now" - right now
1414
1416
1415 Lastly, there is Mercurial's internal format:
1417 Lastly, there is Mercurial's internal format:
1416
1418
1417 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1419 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1418
1420
1419 This is the internal representation format for dates. The first number is
1421 This is the internal representation format for dates. The first number is
1420 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1422 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1421 is the offset of the local timezone, in seconds west of UTC (negative if
1423 is the offset of the local timezone, in seconds west of UTC (negative if
1422 the timezone is east of UTC).
1424 the timezone is east of UTC).
1423
1425
1424 The log command also accepts date ranges:
1426 The log command also accepts date ranges:
1425
1427
1426 - "<DATE" - at or before a given date/time
1428 - "<DATE" - at or before a given date/time
1427 - ">DATE" - on or after a given date/time
1429 - ">DATE" - on or after a given date/time
1428 - "DATE to DATE" - a date range, inclusive
1430 - "DATE to DATE" - a date range, inclusive
1429 - "-DAYS" - within a given number of days of today
1431 - "-DAYS" - within a given number of days of today
1430
1432
1431 Test repeated config section name
1433 Test repeated config section name
1432
1434
1433 $ hg help config.host
1435 $ hg help config.host
1434 "http_proxy.host"
1436 "http_proxy.host"
1435 Host name and (optional) port of the proxy server, for example
1437 Host name and (optional) port of the proxy server, for example
1436 "myproxy:8000".
1438 "myproxy:8000".
1437
1439
1438 "smtp.host"
1440 "smtp.host"
1439 Host name of mail server, e.g. "mail.example.com".
1441 Host name of mail server, e.g. "mail.example.com".
1440
1442
1441
1443
1442 Test section name with dot
1444 Test section name with dot
1443
1445
1444 $ hg help config.ui.username
1446 $ hg help config.ui.username
1445 "ui.username"
1447 "ui.username"
1446 The committer of a changeset created when running "commit". Typically
1448 The committer of a changeset created when running "commit". Typically
1447 a person's name and email address, e.g. "Fred Widget
1449 a person's name and email address, e.g. "Fred Widget
1448 <fred@example.com>". Environment variables in the username are
1450 <fred@example.com>". Environment variables in the username are
1449 expanded.
1451 expanded.
1450
1452
1451 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1453 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1452 empty, e.g. if the system admin set "username =" in the system hgrc,
1454 empty, e.g. if the system admin set "username =" in the system hgrc,
1453 it has to be specified manually or in a different hgrc file)
1455 it has to be specified manually or in a different hgrc file)
1454
1456
1455
1457
1456 $ hg help config.annotate.git
1458 $ hg help config.annotate.git
1457 abort: help section not found: config.annotate.git
1459 abort: help section not found: config.annotate.git
1458 [255]
1460 [255]
1459
1461
1460 $ hg help config.update.check
1462 $ hg help config.update.check
1461 "commands.update.check"
1463 "commands.update.check"
1462 Determines what level of checking 'hg update' will perform before
1464 Determines what level of checking 'hg update' will perform before
1463 moving to a destination revision. Valid values are "abort", "none",
1465 moving to a destination revision. Valid values are "abort", "none",
1464 "linear", and "noconflict". "abort" always fails if the working
1466 "linear", and "noconflict". "abort" always fails if the working
1465 directory has uncommitted changes. "none" performs no checking, and
1467 directory has uncommitted changes. "none" performs no checking, and
1466 may result in a merge with uncommitted changes. "linear" allows any
1468 may result in a merge with uncommitted changes. "linear" allows any
1467 update as long as it follows a straight line in the revision history,
1469 update as long as it follows a straight line in the revision history,
1468 and may trigger a merge with uncommitted changes. "noconflict" will
1470 and may trigger a merge with uncommitted changes. "noconflict" will
1469 allow any update which would not trigger a merge with uncommitted
1471 allow any update which would not trigger a merge with uncommitted
1470 changes, if any are present. (default: "linear")
1472 changes, if any are present. (default: "linear")
1471
1473
1472
1474
1473 $ hg help config.commands.update.check
1475 $ hg help config.commands.update.check
1474 "commands.update.check"
1476 "commands.update.check"
1475 Determines what level of checking 'hg update' will perform before
1477 Determines what level of checking 'hg update' will perform before
1476 moving to a destination revision. Valid values are "abort", "none",
1478 moving to a destination revision. Valid values are "abort", "none",
1477 "linear", and "noconflict". "abort" always fails if the working
1479 "linear", and "noconflict". "abort" always fails if the working
1478 directory has uncommitted changes. "none" performs no checking, and
1480 directory has uncommitted changes. "none" performs no checking, and
1479 may result in a merge with uncommitted changes. "linear" allows any
1481 may result in a merge with uncommitted changes. "linear" allows any
1480 update as long as it follows a straight line in the revision history,
1482 update as long as it follows a straight line in the revision history,
1481 and may trigger a merge with uncommitted changes. "noconflict" will
1483 and may trigger a merge with uncommitted changes. "noconflict" will
1482 allow any update which would not trigger a merge with uncommitted
1484 allow any update which would not trigger a merge with uncommitted
1483 changes, if any are present. (default: "linear")
1485 changes, if any are present. (default: "linear")
1484
1486
1485
1487
1486 $ hg help config.ommands.update.check
1488 $ hg help config.ommands.update.check
1487 abort: help section not found: config.ommands.update.check
1489 abort: help section not found: config.ommands.update.check
1488 [255]
1490 [255]
1489
1491
1490 Unrelated trailing paragraphs shouldn't be included
1492 Unrelated trailing paragraphs shouldn't be included
1491
1493
1492 $ hg help config.extramsg | grep '^$'
1494 $ hg help config.extramsg | grep '^$'
1493
1495
1494
1496
1495 Test capitalized section name
1497 Test capitalized section name
1496
1498
1497 $ hg help scripting.HGPLAIN > /dev/null
1499 $ hg help scripting.HGPLAIN > /dev/null
1498
1500
1499 Help subsection:
1501 Help subsection:
1500
1502
1501 $ hg help config.charsets |grep "Email example:" > /dev/null
1503 $ hg help config.charsets |grep "Email example:" > /dev/null
1502 [1]
1504 [1]
1503
1505
1504 Show nested definitions
1506 Show nested definitions
1505 ("profiling.type"[break]"ls"[break]"stat"[break])
1507 ("profiling.type"[break]"ls"[break]"stat"[break])
1506
1508
1507 $ hg help config.type | egrep '^$'|wc -l
1509 $ hg help config.type | egrep '^$'|wc -l
1508 \s*3 (re)
1510 \s*3 (re)
1509
1511
1510 $ hg help config.profiling.type.ls
1512 $ hg help config.profiling.type.ls
1511 "profiling.type.ls"
1513 "profiling.type.ls"
1512 Use Python's built-in instrumenting profiler. This profiler works on
1514 Use Python's built-in instrumenting profiler. This profiler works on
1513 all platforms, but each line number it reports is the first line of
1515 all platforms, but each line number it reports is the first line of
1514 a function. This restriction makes it difficult to identify the
1516 a function. This restriction makes it difficult to identify the
1515 expensive parts of a non-trivial function.
1517 expensive parts of a non-trivial function.
1516
1518
1517
1519
1518 Separate sections from subsections
1520 Separate sections from subsections
1519
1521
1520 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1522 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1521 "format"
1523 "format"
1522 --------
1524 --------
1523
1525
1524 "usegeneraldelta"
1526 "usegeneraldelta"
1525
1527
1526 "dotencode"
1528 "dotencode"
1527
1529
1528 "usefncache"
1530 "usefncache"
1529
1531
1530 "usestore"
1532 "usestore"
1531
1533
1532 "sparse-revlog"
1534 "sparse-revlog"
1533
1535
1534 "revlog-compression"
1536 "revlog-compression"
1535
1537
1536 "bookmarks-in-store"
1538 "bookmarks-in-store"
1537
1539
1538 "profiling"
1540 "profiling"
1539 -----------
1541 -----------
1540
1542
1541 "format"
1543 "format"
1542
1544
1543 "progress"
1545 "progress"
1544 ----------
1546 ----------
1545
1547
1546 "format"
1548 "format"
1547
1549
1548
1550
1549 Last item in help config.*:
1551 Last item in help config.*:
1550
1552
1551 $ hg help config.`hg help config|grep '^ "'| \
1553 $ hg help config.`hg help config|grep '^ "'| \
1552 > tail -1|sed 's![ "]*!!g'`| \
1554 > tail -1|sed 's![ "]*!!g'`| \
1553 > grep 'hg help -c config' > /dev/null
1555 > grep 'hg help -c config' > /dev/null
1554 [1]
1556 [1]
1555
1557
1556 note to use help -c for general hg help config:
1558 note to use help -c for general hg help config:
1557
1559
1558 $ hg help config |grep 'hg help -c config' > /dev/null
1560 $ hg help config |grep 'hg help -c config' > /dev/null
1559
1561
1560 Test templating help
1562 Test templating help
1561
1563
1562 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1564 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1563 desc String. The text of the changeset description.
1565 desc String. The text of the changeset description.
1564 diffstat String. Statistics of changes with the following format:
1566 diffstat String. Statistics of changes with the following format:
1565 firstline Any text. Returns the first line of text.
1567 firstline Any text. Returns the first line of text.
1566 nonempty Any text. Returns '(none)' if the string is empty.
1568 nonempty Any text. Returns '(none)' if the string is empty.
1567
1569
1568 Test deprecated items
1570 Test deprecated items
1569
1571
1570 $ hg help -v templating | grep currentbookmark
1572 $ hg help -v templating | grep currentbookmark
1571 currentbookmark
1573 currentbookmark
1572 $ hg help templating | (grep currentbookmark || true)
1574 $ hg help templating | (grep currentbookmark || true)
1573
1575
1574 Test help hooks
1576 Test help hooks
1575
1577
1576 $ cat > helphook1.py <<EOF
1578 $ cat > helphook1.py <<EOF
1577 > from mercurial import help
1579 > from mercurial import help
1578 >
1580 >
1579 > def rewrite(ui, topic, doc):
1581 > def rewrite(ui, topic, doc):
1580 > return doc + b'\nhelphook1\n'
1582 > return doc + b'\nhelphook1\n'
1581 >
1583 >
1582 > def extsetup(ui):
1584 > def extsetup(ui):
1583 > help.addtopichook(b'revisions', rewrite)
1585 > help.addtopichook(b'revisions', rewrite)
1584 > EOF
1586 > EOF
1585 $ cat > helphook2.py <<EOF
1587 $ cat > helphook2.py <<EOF
1586 > from mercurial import help
1588 > from mercurial import help
1587 >
1589 >
1588 > def rewrite(ui, topic, doc):
1590 > def rewrite(ui, topic, doc):
1589 > return doc + b'\nhelphook2\n'
1591 > return doc + b'\nhelphook2\n'
1590 >
1592 >
1591 > def extsetup(ui):
1593 > def extsetup(ui):
1592 > help.addtopichook(b'revisions', rewrite)
1594 > help.addtopichook(b'revisions', rewrite)
1593 > EOF
1595 > EOF
1594 $ echo '[extensions]' >> $HGRCPATH
1596 $ echo '[extensions]' >> $HGRCPATH
1595 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1597 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1596 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1598 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1597 $ hg help revsets | grep helphook
1599 $ hg help revsets | grep helphook
1598 helphook1
1600 helphook1
1599 helphook2
1601 helphook2
1600
1602
1601 help -c should only show debug --debug
1603 help -c should only show debug --debug
1602
1604
1603 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1605 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1604 [1]
1606 [1]
1605
1607
1606 help -c should only show deprecated for -v
1608 help -c should only show deprecated for -v
1607
1609
1608 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1610 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1609 [1]
1611 [1]
1610
1612
1611 Test -s / --system
1613 Test -s / --system
1612
1614
1613 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1615 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1614 > wc -l | sed -e 's/ //g'
1616 > wc -l | sed -e 's/ //g'
1615 0
1617 0
1616 $ hg help config.files --system unix | grep 'USER' | \
1618 $ hg help config.files --system unix | grep 'USER' | \
1617 > wc -l | sed -e 's/ //g'
1619 > wc -l | sed -e 's/ //g'
1618 0
1620 0
1619
1621
1620 Test -e / -c / -k combinations
1622 Test -e / -c / -k combinations
1621
1623
1622 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1624 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1623 Commands:
1625 Commands:
1624 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1626 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1625 Extensions:
1627 Extensions:
1626 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1628 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1627 Topics:
1629 Topics:
1628 Commands:
1630 Commands:
1629 Extensions:
1631 Extensions:
1630 Extension Commands:
1632 Extension Commands:
1631 $ hg help -c schemes
1633 $ hg help -c schemes
1632 abort: no such help topic: schemes
1634 abort: no such help topic: schemes
1633 (try 'hg help --keyword schemes')
1635 (try 'hg help --keyword schemes')
1634 [255]
1636 [255]
1635 $ hg help -e schemes |head -1
1637 $ hg help -e schemes |head -1
1636 schemes extension - extend schemes with shortcuts to repository swarms
1638 schemes extension - extend schemes with shortcuts to repository swarms
1637 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1639 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1638 Commands:
1640 Commands:
1639 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1641 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1640 Extensions:
1642 Extensions:
1641 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1643 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1642 Extensions:
1644 Extensions:
1643 Commands:
1645 Commands:
1644 $ hg help -c commit > /dev/null
1646 $ hg help -c commit > /dev/null
1645 $ hg help -e -c commit > /dev/null
1647 $ hg help -e -c commit > /dev/null
1646 $ hg help -e commit
1648 $ hg help -e commit
1647 abort: no such help topic: commit
1649 abort: no such help topic: commit
1648 (try 'hg help --keyword commit')
1650 (try 'hg help --keyword commit')
1649 [255]
1651 [255]
1650
1652
1651 Test keyword search help
1653 Test keyword search help
1652
1654
1653 $ cat > prefixedname.py <<EOF
1655 $ cat > prefixedname.py <<EOF
1654 > '''matched against word "clone"
1656 > '''matched against word "clone"
1655 > '''
1657 > '''
1656 > EOF
1658 > EOF
1657 $ echo '[extensions]' >> $HGRCPATH
1659 $ echo '[extensions]' >> $HGRCPATH
1658 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1660 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1659 $ hg help -k clone
1661 $ hg help -k clone
1660 Topics:
1662 Topics:
1661
1663
1662 config Configuration Files
1664 config Configuration Files
1663 extensions Using Additional Features
1665 extensions Using Additional Features
1664 glossary Glossary
1666 glossary Glossary
1665 phases Working with Phases
1667 phases Working with Phases
1666 subrepos Subrepositories
1668 subrepos Subrepositories
1667 urls URL Paths
1669 urls URL Paths
1668
1670
1669 Commands:
1671 Commands:
1670
1672
1671 bookmarks create a new bookmark or list existing bookmarks
1673 bookmarks create a new bookmark or list existing bookmarks
1672 clone make a copy of an existing repository
1674 clone make a copy of an existing repository
1673 paths show aliases for remote repositories
1675 paths show aliases for remote repositories
1674 pull pull changes from the specified source
1676 pull pull changes from the specified source
1675 update update working directory (or switch revisions)
1677 update update working directory (or switch revisions)
1676
1678
1677 Extensions:
1679 Extensions:
1678
1680
1679 clonebundles advertise pre-generated bundles to seed clones
1681 clonebundles advertise pre-generated bundles to seed clones
1680 narrow create clones which fetch history data for subset of files
1682 narrow create clones which fetch history data for subset of files
1681 (EXPERIMENTAL)
1683 (EXPERIMENTAL)
1682 prefixedname matched against word "clone"
1684 prefixedname matched against word "clone"
1683 relink recreates hardlinks between repository clones
1685 relink recreates hardlinks between repository clones
1684
1686
1685 Extension Commands:
1687 Extension Commands:
1686
1688
1687 qclone clone main and patch repository at same time
1689 qclone clone main and patch repository at same time
1688
1690
1689 Test unfound topic
1691 Test unfound topic
1690
1692
1691 $ hg help nonexistingtopicthatwillneverexisteverever
1693 $ hg help nonexistingtopicthatwillneverexisteverever
1692 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1694 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1693 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1695 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1694 [255]
1696 [255]
1695
1697
1696 Test unfound keyword
1698 Test unfound keyword
1697
1699
1698 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1700 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1699 abort: no matches
1701 abort: no matches
1700 (try 'hg help' for a list of topics)
1702 (try 'hg help' for a list of topics)
1701 [255]
1703 [255]
1702
1704
1703 Test omit indicating for help
1705 Test omit indicating for help
1704
1706
1705 $ cat > addverboseitems.py <<EOF
1707 $ cat > addverboseitems.py <<EOF
1706 > r'''extension to test omit indicating.
1708 > r'''extension to test omit indicating.
1707 >
1709 >
1708 > This paragraph is never omitted (for extension)
1710 > This paragraph is never omitted (for extension)
1709 >
1711 >
1710 > .. container:: verbose
1712 > .. container:: verbose
1711 >
1713 >
1712 > This paragraph is omitted,
1714 > This paragraph is omitted,
1713 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1715 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1714 >
1716 >
1715 > This paragraph is never omitted, too (for extension)
1717 > This paragraph is never omitted, too (for extension)
1716 > '''
1718 > '''
1717 > from __future__ import absolute_import
1719 > from __future__ import absolute_import
1718 > from mercurial import commands, help
1720 > from mercurial import commands, help
1719 > testtopic = br"""This paragraph is never omitted (for topic).
1721 > testtopic = br"""This paragraph is never omitted (for topic).
1720 >
1722 >
1721 > .. container:: verbose
1723 > .. container:: verbose
1722 >
1724 >
1723 > This paragraph is omitted,
1725 > This paragraph is omitted,
1724 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1726 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1725 >
1727 >
1726 > This paragraph is never omitted, too (for topic)
1728 > This paragraph is never omitted, too (for topic)
1727 > """
1729 > """
1728 > def extsetup(ui):
1730 > def extsetup(ui):
1729 > help.helptable.append(([b"topic-containing-verbose"],
1731 > help.helptable.append(([b"topic-containing-verbose"],
1730 > b"This is the topic to test omit indicating.",
1732 > b"This is the topic to test omit indicating.",
1731 > lambda ui: testtopic))
1733 > lambda ui: testtopic))
1732 > EOF
1734 > EOF
1733 $ echo '[extensions]' >> $HGRCPATH
1735 $ echo '[extensions]' >> $HGRCPATH
1734 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1736 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1735 $ hg help addverboseitems
1737 $ hg help addverboseitems
1736 addverboseitems extension - extension to test omit indicating.
1738 addverboseitems extension - extension to test omit indicating.
1737
1739
1738 This paragraph is never omitted (for extension)
1740 This paragraph is never omitted (for extension)
1739
1741
1740 This paragraph is never omitted, too (for extension)
1742 This paragraph is never omitted, too (for extension)
1741
1743
1742 (some details hidden, use --verbose to show complete help)
1744 (some details hidden, use --verbose to show complete help)
1743
1745
1744 no commands defined
1746 no commands defined
1745 $ hg help -v addverboseitems
1747 $ hg help -v addverboseitems
1746 addverboseitems extension - extension to test omit indicating.
1748 addverboseitems extension - extension to test omit indicating.
1747
1749
1748 This paragraph is never omitted (for extension)
1750 This paragraph is never omitted (for extension)
1749
1751
1750 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1752 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1751 extension)
1753 extension)
1752
1754
1753 This paragraph is never omitted, too (for extension)
1755 This paragraph is never omitted, too (for extension)
1754
1756
1755 no commands defined
1757 no commands defined
1756 $ hg help topic-containing-verbose
1758 $ hg help topic-containing-verbose
1757 This is the topic to test omit indicating.
1759 This is the topic to test omit indicating.
1758 """"""""""""""""""""""""""""""""""""""""""
1760 """"""""""""""""""""""""""""""""""""""""""
1759
1761
1760 This paragraph is never omitted (for topic).
1762 This paragraph is never omitted (for topic).
1761
1763
1762 This paragraph is never omitted, too (for topic)
1764 This paragraph is never omitted, too (for topic)
1763
1765
1764 (some details hidden, use --verbose to show complete help)
1766 (some details hidden, use --verbose to show complete help)
1765 $ hg help -v topic-containing-verbose
1767 $ hg help -v topic-containing-verbose
1766 This is the topic to test omit indicating.
1768 This is the topic to test omit indicating.
1767 """"""""""""""""""""""""""""""""""""""""""
1769 """"""""""""""""""""""""""""""""""""""""""
1768
1770
1769 This paragraph is never omitted (for topic).
1771 This paragraph is never omitted (for topic).
1770
1772
1771 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1773 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1772 topic)
1774 topic)
1773
1775
1774 This paragraph is never omitted, too (for topic)
1776 This paragraph is never omitted, too (for topic)
1775
1777
1776 Test section lookup
1778 Test section lookup
1777
1779
1778 $ hg help revset.merge
1780 $ hg help revset.merge
1779 "merge()"
1781 "merge()"
1780 Changeset is a merge changeset.
1782 Changeset is a merge changeset.
1781
1783
1782 $ hg help glossary.dag
1784 $ hg help glossary.dag
1783 DAG
1785 DAG
1784 The repository of changesets of a distributed version control system
1786 The repository of changesets of a distributed version control system
1785 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1787 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1786 of nodes and edges, where nodes correspond to changesets and edges
1788 of nodes and edges, where nodes correspond to changesets and edges
1787 imply a parent -> child relation. This graph can be visualized by
1789 imply a parent -> child relation. This graph can be visualized by
1788 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1790 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1789 limited by the requirement for children to have at most two parents.
1791 limited by the requirement for children to have at most two parents.
1790
1792
1791
1793
1792 $ hg help hgrc.paths
1794 $ hg help hgrc.paths
1793 "paths"
1795 "paths"
1794 -------
1796 -------
1795
1797
1796 Assigns symbolic names and behavior to repositories.
1798 Assigns symbolic names and behavior to repositories.
1797
1799
1798 Options are symbolic names defining the URL or directory that is the
1800 Options are symbolic names defining the URL or directory that is the
1799 location of the repository. Example:
1801 location of the repository. Example:
1800
1802
1801 [paths]
1803 [paths]
1802 my_server = https://example.com/my_repo
1804 my_server = https://example.com/my_repo
1803 local_path = /home/me/repo
1805 local_path = /home/me/repo
1804
1806
1805 These symbolic names can be used from the command line. To pull from
1807 These symbolic names can be used from the command line. To pull from
1806 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1808 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1807 local_path'.
1809 local_path'.
1808
1810
1809 Options containing colons (":") denote sub-options that can influence
1811 Options containing colons (":") denote sub-options that can influence
1810 behavior for that specific path. Example:
1812 behavior for that specific path. Example:
1811
1813
1812 [paths]
1814 [paths]
1813 my_server = https://example.com/my_path
1815 my_server = https://example.com/my_path
1814 my_server:pushurl = ssh://example.com/my_path
1816 my_server:pushurl = ssh://example.com/my_path
1815
1817
1816 The following sub-options can be defined:
1818 The following sub-options can be defined:
1817
1819
1818 "pushurl"
1820 "pushurl"
1819 The URL to use for push operations. If not defined, the location
1821 The URL to use for push operations. If not defined, the location
1820 defined by the path's main entry is used.
1822 defined by the path's main entry is used.
1821
1823
1822 "pushrev"
1824 "pushrev"
1823 A revset defining which revisions to push by default.
1825 A revset defining which revisions to push by default.
1824
1826
1825 When 'hg push' is executed without a "-r" argument, the revset defined
1827 When 'hg push' is executed without a "-r" argument, the revset defined
1826 by this sub-option is evaluated to determine what to push.
1828 by this sub-option is evaluated to determine what to push.
1827
1829
1828 For example, a value of "." will push the working directory's revision
1830 For example, a value of "." will push the working directory's revision
1829 by default.
1831 by default.
1830
1832
1831 Revsets specifying bookmarks will not result in the bookmark being
1833 Revsets specifying bookmarks will not result in the bookmark being
1832 pushed.
1834 pushed.
1833
1835
1834 The following special named paths exist:
1836 The following special named paths exist:
1835
1837
1836 "default"
1838 "default"
1837 The URL or directory to use when no source or remote is specified.
1839 The URL or directory to use when no source or remote is specified.
1838
1840
1839 'hg clone' will automatically define this path to the location the
1841 'hg clone' will automatically define this path to the location the
1840 repository was cloned from.
1842 repository was cloned from.
1841
1843
1842 "default-push"
1844 "default-push"
1843 (deprecated) The URL or directory for the default 'hg push' location.
1845 (deprecated) The URL or directory for the default 'hg push' location.
1844 "default:pushurl" should be used instead.
1846 "default:pushurl" should be used instead.
1845
1847
1846 $ hg help glossary.mcguffin
1848 $ hg help glossary.mcguffin
1847 abort: help section not found: glossary.mcguffin
1849 abort: help section not found: glossary.mcguffin
1848 [255]
1850 [255]
1849
1851
1850 $ hg help glossary.mc.guffin
1852 $ hg help glossary.mc.guffin
1851 abort: help section not found: glossary.mc.guffin
1853 abort: help section not found: glossary.mc.guffin
1852 [255]
1854 [255]
1853
1855
1854 $ hg help template.files
1856 $ hg help template.files
1855 files List of strings. All files modified, added, or removed by
1857 files List of strings. All files modified, added, or removed by
1856 this changeset.
1858 this changeset.
1857 files(pattern)
1859 files(pattern)
1858 All files of the current changeset matching the pattern. See
1860 All files of the current changeset matching the pattern. See
1859 'hg help patterns'.
1861 'hg help patterns'.
1860
1862
1861 Test section lookup by translated message
1863 Test section lookup by translated message
1862
1864
1863 str.lower() instead of encoding.lower(str) on translated message might
1865 str.lower() instead of encoding.lower(str) on translated message might
1864 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1866 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1865 as the second or later byte of multi-byte character.
1867 as the second or later byte of multi-byte character.
1866
1868
1867 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1869 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1868 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1870 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1869 replacement makes message meaningless.
1871 replacement makes message meaningless.
1870
1872
1871 This tests that section lookup by translated string isn't broken by
1873 This tests that section lookup by translated string isn't broken by
1872 such str.lower().
1874 such str.lower().
1873
1875
1874 $ "$PYTHON" <<EOF
1876 $ "$PYTHON" <<EOF
1875 > def escape(s):
1877 > def escape(s):
1876 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1878 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1877 > # translation of "record" in ja_JP.cp932
1879 > # translation of "record" in ja_JP.cp932
1878 > upper = b"\x8bL\x98^"
1880 > upper = b"\x8bL\x98^"
1879 > # str.lower()-ed section name should be treated as different one
1881 > # str.lower()-ed section name should be treated as different one
1880 > lower = b"\x8bl\x98^"
1882 > lower = b"\x8bl\x98^"
1881 > with open('ambiguous.py', 'wb') as fp:
1883 > with open('ambiguous.py', 'wb') as fp:
1882 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1884 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1883 > u'''summary of extension
1885 > u'''summary of extension
1884 >
1886 >
1885 > %s
1887 > %s
1886 > ----
1888 > ----
1887 >
1889 >
1888 > Upper name should show only this message
1890 > Upper name should show only this message
1889 >
1891 >
1890 > %s
1892 > %s
1891 > ----
1893 > ----
1892 >
1894 >
1893 > Lower name should show only this message
1895 > Lower name should show only this message
1894 >
1896 >
1895 > subsequent section
1897 > subsequent section
1896 > ------------------
1898 > ------------------
1897 >
1899 >
1898 > This should be hidden at 'hg help ambiguous' with section name.
1900 > This should be hidden at 'hg help ambiguous' with section name.
1899 > '''
1901 > '''
1900 > """ % (escape(upper), escape(lower)))
1902 > """ % (escape(upper), escape(lower)))
1901 > EOF
1903 > EOF
1902
1904
1903 $ cat >> $HGRCPATH <<EOF
1905 $ cat >> $HGRCPATH <<EOF
1904 > [extensions]
1906 > [extensions]
1905 > ambiguous = ./ambiguous.py
1907 > ambiguous = ./ambiguous.py
1906 > EOF
1908 > EOF
1907
1909
1908 $ "$PYTHON" <<EOF | sh
1910 $ "$PYTHON" <<EOF | sh
1909 > from mercurial import pycompat
1911 > from mercurial import pycompat
1910 > upper = b"\x8bL\x98^"
1912 > upper = b"\x8bL\x98^"
1911 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1913 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1912 > EOF
1914 > EOF
1913 \x8bL\x98^ (esc)
1915 \x8bL\x98^ (esc)
1914 ----
1916 ----
1915
1917
1916 Upper name should show only this message
1918 Upper name should show only this message
1917
1919
1918
1920
1919 $ "$PYTHON" <<EOF | sh
1921 $ "$PYTHON" <<EOF | sh
1920 > from mercurial import pycompat
1922 > from mercurial import pycompat
1921 > lower = b"\x8bl\x98^"
1923 > lower = b"\x8bl\x98^"
1922 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1924 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1923 > EOF
1925 > EOF
1924 \x8bl\x98^ (esc)
1926 \x8bl\x98^ (esc)
1925 ----
1927 ----
1926
1928
1927 Lower name should show only this message
1929 Lower name should show only this message
1928
1930
1929
1931
1930 $ cat >> $HGRCPATH <<EOF
1932 $ cat >> $HGRCPATH <<EOF
1931 > [extensions]
1933 > [extensions]
1932 > ambiguous = !
1934 > ambiguous = !
1933 > EOF
1935 > EOF
1934
1936
1935 Show help content of disabled extensions
1937 Show help content of disabled extensions
1936
1938
1937 $ cat >> $HGRCPATH <<EOF
1939 $ cat >> $HGRCPATH <<EOF
1938 > [extensions]
1940 > [extensions]
1939 > ambiguous = !./ambiguous.py
1941 > ambiguous = !./ambiguous.py
1940 > EOF
1942 > EOF
1941 $ hg help -e ambiguous
1943 $ hg help -e ambiguous
1942 ambiguous extension - (no help text available)
1944 ambiguous extension - (no help text available)
1943
1945
1944 (use 'hg help extensions' for information on enabling extensions)
1946 (use 'hg help extensions' for information on enabling extensions)
1945
1947
1946 Test dynamic list of merge tools only shows up once
1948 Test dynamic list of merge tools only shows up once
1947 $ hg help merge-tools
1949 $ hg help merge-tools
1948 Merge Tools
1950 Merge Tools
1949 """""""""""
1951 """""""""""
1950
1952
1951 To merge files Mercurial uses merge tools.
1953 To merge files Mercurial uses merge tools.
1952
1954
1953 A merge tool combines two different versions of a file into a merged file.
1955 A merge tool combines two different versions of a file into a merged file.
1954 Merge tools are given the two files and the greatest common ancestor of
1956 Merge tools are given the two files and the greatest common ancestor of
1955 the two file versions, so they can determine the changes made on both
1957 the two file versions, so they can determine the changes made on both
1956 branches.
1958 branches.
1957
1959
1958 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1960 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1959 backout' and in several extensions.
1961 backout' and in several extensions.
1960
1962
1961 Usually, the merge tool tries to automatically reconcile the files by
1963 Usually, the merge tool tries to automatically reconcile the files by
1962 combining all non-overlapping changes that occurred separately in the two
1964 combining all non-overlapping changes that occurred separately in the two
1963 different evolutions of the same initial base file. Furthermore, some
1965 different evolutions of the same initial base file. Furthermore, some
1964 interactive merge programs make it easier to manually resolve conflicting
1966 interactive merge programs make it easier to manually resolve conflicting
1965 merges, either in a graphical way, or by inserting some conflict markers.
1967 merges, either in a graphical way, or by inserting some conflict markers.
1966 Mercurial does not include any interactive merge programs but relies on
1968 Mercurial does not include any interactive merge programs but relies on
1967 external tools for that.
1969 external tools for that.
1968
1970
1969 Available merge tools
1971 Available merge tools
1970 =====================
1972 =====================
1971
1973
1972 External merge tools and their properties are configured in the merge-
1974 External merge tools and their properties are configured in the merge-
1973 tools configuration section - see hgrc(5) - but they can often just be
1975 tools configuration section - see hgrc(5) - but they can often just be
1974 named by their executable.
1976 named by their executable.
1975
1977
1976 A merge tool is generally usable if its executable can be found on the
1978 A merge tool is generally usable if its executable can be found on the
1977 system and if it can handle the merge. The executable is found if it is an
1979 system and if it can handle the merge. The executable is found if it is an
1978 absolute or relative executable path or the name of an application in the
1980 absolute or relative executable path or the name of an application in the
1979 executable search path. The tool is assumed to be able to handle the merge
1981 executable search path. The tool is assumed to be able to handle the merge
1980 if it can handle symlinks if the file is a symlink, if it can handle
1982 if it can handle symlinks if the file is a symlink, if it can handle
1981 binary files if the file is binary, and if a GUI is available if the tool
1983 binary files if the file is binary, and if a GUI is available if the tool
1982 requires a GUI.
1984 requires a GUI.
1983
1985
1984 There are some internal merge tools which can be used. The internal merge
1986 There are some internal merge tools which can be used. The internal merge
1985 tools are:
1987 tools are:
1986
1988
1987 ":dump"
1989 ":dump"
1988 Creates three versions of the files to merge, containing the contents of
1990 Creates three versions of the files to merge, containing the contents of
1989 local, other and base. These files can then be used to perform a merge
1991 local, other and base. These files can then be used to perform a merge
1990 manually. If the file to be merged is named "a.txt", these files will
1992 manually. If the file to be merged is named "a.txt", these files will
1991 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1993 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1992 they will be placed in the same directory as "a.txt".
1994 they will be placed in the same directory as "a.txt".
1993
1995
1994 This implies premerge. Therefore, files aren't dumped, if premerge runs
1996 This implies premerge. Therefore, files aren't dumped, if premerge runs
1995 successfully. Use :forcedump to forcibly write files out.
1997 successfully. Use :forcedump to forcibly write files out.
1996
1998
1997 (actual capabilities: binary, symlink)
1999 (actual capabilities: binary, symlink)
1998
2000
1999 ":fail"
2001 ":fail"
2000 Rather than attempting to merge files that were modified on both
2002 Rather than attempting to merge files that were modified on both
2001 branches, it marks them as unresolved. The resolve command must be used
2003 branches, it marks them as unresolved. The resolve command must be used
2002 to resolve these conflicts.
2004 to resolve these conflicts.
2003
2005
2004 (actual capabilities: binary, symlink)
2006 (actual capabilities: binary, symlink)
2005
2007
2006 ":forcedump"
2008 ":forcedump"
2007 Creates three versions of the files as same as :dump, but omits
2009 Creates three versions of the files as same as :dump, but omits
2008 premerge.
2010 premerge.
2009
2011
2010 (actual capabilities: binary, symlink)
2012 (actual capabilities: binary, symlink)
2011
2013
2012 ":local"
2014 ":local"
2013 Uses the local 'p1()' version of files as the merged version.
2015 Uses the local 'p1()' version of files as the merged version.
2014
2016
2015 (actual capabilities: binary, symlink)
2017 (actual capabilities: binary, symlink)
2016
2018
2017 ":merge"
2019 ":merge"
2018 Uses the internal non-interactive simple merge algorithm for merging
2020 Uses the internal non-interactive simple merge algorithm for merging
2019 files. It will fail if there are any conflicts and leave markers in the
2021 files. It will fail if there are any conflicts and leave markers in the
2020 partially merged file. Markers will have two sections, one for each side
2022 partially merged file. Markers will have two sections, one for each side
2021 of merge.
2023 of merge.
2022
2024
2023 ":merge-local"
2025 ":merge-local"
2024 Like :merge, but resolve all conflicts non-interactively in favor of the
2026 Like :merge, but resolve all conflicts non-interactively in favor of the
2025 local 'p1()' changes.
2027 local 'p1()' changes.
2026
2028
2027 ":merge-other"
2029 ":merge-other"
2028 Like :merge, but resolve all conflicts non-interactively in favor of the
2030 Like :merge, but resolve all conflicts non-interactively in favor of the
2029 other 'p2()' changes.
2031 other 'p2()' changes.
2030
2032
2031 ":merge3"
2033 ":merge3"
2032 Uses the internal non-interactive simple merge algorithm for merging
2034 Uses the internal non-interactive simple merge algorithm for merging
2033 files. It will fail if there are any conflicts and leave markers in the
2035 files. It will fail if there are any conflicts and leave markers in the
2034 partially merged file. Marker will have three sections, one from each
2036 partially merged file. Marker will have three sections, one from each
2035 side of the merge and one for the base content.
2037 side of the merge and one for the base content.
2036
2038
2037 ":other"
2039 ":other"
2038 Uses the other 'p2()' version of files as the merged version.
2040 Uses the other 'p2()' version of files as the merged version.
2039
2041
2040 (actual capabilities: binary, symlink)
2042 (actual capabilities: binary, symlink)
2041
2043
2042 ":prompt"
2044 ":prompt"
2043 Asks the user which of the local 'p1()' or the other 'p2()' version to
2045 Asks the user which of the local 'p1()' or the other 'p2()' version to
2044 keep as the merged version.
2046 keep as the merged version.
2045
2047
2046 (actual capabilities: binary, symlink)
2048 (actual capabilities: binary, symlink)
2047
2049
2048 ":tagmerge"
2050 ":tagmerge"
2049 Uses the internal tag merge algorithm (experimental).
2051 Uses the internal tag merge algorithm (experimental).
2050
2052
2051 ":union"
2053 ":union"
2052 Uses the internal non-interactive simple merge algorithm for merging
2054 Uses the internal non-interactive simple merge algorithm for merging
2053 files. It will use both left and right sides for conflict regions. No
2055 files. It will use both left and right sides for conflict regions. No
2054 markers are inserted.
2056 markers are inserted.
2055
2057
2056 Internal tools are always available and do not require a GUI but will by
2058 Internal tools are always available and do not require a GUI but will by
2057 default not handle symlinks or binary files. See next section for detail
2059 default not handle symlinks or binary files. See next section for detail
2058 about "actual capabilities" described above.
2060 about "actual capabilities" described above.
2059
2061
2060 Choosing a merge tool
2062 Choosing a merge tool
2061 =====================
2063 =====================
2062
2064
2063 Mercurial uses these rules when deciding which merge tool to use:
2065 Mercurial uses these rules when deciding which merge tool to use:
2064
2066
2065 1. If a tool has been specified with the --tool option to merge or
2067 1. If a tool has been specified with the --tool option to merge or
2066 resolve, it is used. If it is the name of a tool in the merge-tools
2068 resolve, it is used. If it is the name of a tool in the merge-tools
2067 configuration, its configuration is used. Otherwise the specified tool
2069 configuration, its configuration is used. Otherwise the specified tool
2068 must be executable by the shell.
2070 must be executable by the shell.
2069 2. If the "HGMERGE" environment variable is present, its value is used and
2071 2. If the "HGMERGE" environment variable is present, its value is used and
2070 must be executable by the shell.
2072 must be executable by the shell.
2071 3. If the filename of the file to be merged matches any of the patterns in
2073 3. If the filename of the file to be merged matches any of the patterns in
2072 the merge-patterns configuration section, the first usable merge tool
2074 the merge-patterns configuration section, the first usable merge tool
2073 corresponding to a matching pattern is used.
2075 corresponding to a matching pattern is used.
2074 4. If ui.merge is set it will be considered next. If the value is not the
2076 4. If ui.merge is set it will be considered next. If the value is not the
2075 name of a configured tool, the specified value is used and must be
2077 name of a configured tool, the specified value is used and must be
2076 executable by the shell. Otherwise the named tool is used if it is
2078 executable by the shell. Otherwise the named tool is used if it is
2077 usable.
2079 usable.
2078 5. If any usable merge tools are present in the merge-tools configuration
2080 5. If any usable merge tools are present in the merge-tools configuration
2079 section, the one with the highest priority is used.
2081 section, the one with the highest priority is used.
2080 6. If a program named "hgmerge" can be found on the system, it is used -
2082 6. If a program named "hgmerge" can be found on the system, it is used -
2081 but it will by default not be used for symlinks and binary files.
2083 but it will by default not be used for symlinks and binary files.
2082 7. If the file to be merged is not binary and is not a symlink, then
2084 7. If the file to be merged is not binary and is not a symlink, then
2083 internal ":merge" is used.
2085 internal ":merge" is used.
2084 8. Otherwise, ":prompt" is used.
2086 8. Otherwise, ":prompt" is used.
2085
2087
2086 For historical reason, Mercurial treats merge tools as below while
2088 For historical reason, Mercurial treats merge tools as below while
2087 examining rules above.
2089 examining rules above.
2088
2090
2089 step specified via binary symlink
2091 step specified via binary symlink
2090 ----------------------------------
2092 ----------------------------------
2091 1. --tool o/o o/o
2093 1. --tool o/o o/o
2092 2. HGMERGE o/o o/o
2094 2. HGMERGE o/o o/o
2093 3. merge-patterns o/o(*) x/?(*)
2095 3. merge-patterns o/o(*) x/?(*)
2094 4. ui.merge x/?(*) x/?(*)
2096 4. ui.merge x/?(*) x/?(*)
2095
2097
2096 Each capability column indicates Mercurial behavior for internal/external
2098 Each capability column indicates Mercurial behavior for internal/external
2097 merge tools at examining each rule.
2099 merge tools at examining each rule.
2098
2100
2099 - "o": "assume that a tool has capability"
2101 - "o": "assume that a tool has capability"
2100 - "x": "assume that a tool does not have capability"
2102 - "x": "assume that a tool does not have capability"
2101 - "?": "check actual capability of a tool"
2103 - "?": "check actual capability of a tool"
2102
2104
2103 If "merge.strict-capability-check" configuration is true, Mercurial checks
2105 If "merge.strict-capability-check" configuration is true, Mercurial checks
2104 capabilities of merge tools strictly in (*) cases above (= each capability
2106 capabilities of merge tools strictly in (*) cases above (= each capability
2105 column becomes "?/?"). It is false by default for backward compatibility.
2107 column becomes "?/?"). It is false by default for backward compatibility.
2106
2108
2107 Note:
2109 Note:
2108 After selecting a merge program, Mercurial will by default attempt to
2110 After selecting a merge program, Mercurial will by default attempt to
2109 merge the files using a simple merge algorithm first. Only if it
2111 merge the files using a simple merge algorithm first. Only if it
2110 doesn't succeed because of conflicting changes will Mercurial actually
2112 doesn't succeed because of conflicting changes will Mercurial actually
2111 execute the merge program. Whether to use the simple merge algorithm
2113 execute the merge program. Whether to use the simple merge algorithm
2112 first can be controlled by the premerge setting of the merge tool.
2114 first can be controlled by the premerge setting of the merge tool.
2113 Premerge is enabled by default unless the file is binary or a symlink.
2115 Premerge is enabled by default unless the file is binary or a symlink.
2114
2116
2115 See the merge-tools and ui sections of hgrc(5) for details on the
2117 See the merge-tools and ui sections of hgrc(5) for details on the
2116 configuration of merge tools.
2118 configuration of merge tools.
2117
2119
2118 Compression engines listed in `hg help bundlespec`
2120 Compression engines listed in `hg help bundlespec`
2119
2121
2120 $ hg help bundlespec | grep gzip
2122 $ hg help bundlespec | grep gzip
2121 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2123 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2122 An algorithm that produces smaller bundles than "gzip".
2124 An algorithm that produces smaller bundles than "gzip".
2123 This engine will likely produce smaller bundles than "gzip" but will be
2125 This engine will likely produce smaller bundles than "gzip" but will be
2124 "gzip"
2126 "gzip"
2125 better compression than "gzip". It also frequently yields better (?)
2127 better compression than "gzip". It also frequently yields better (?)
2126
2128
2127 Test usage of section marks in help documents
2129 Test usage of section marks in help documents
2128
2130
2129 $ cd "$TESTDIR"/../doc
2131 $ cd "$TESTDIR"/../doc
2130 $ "$PYTHON" check-seclevel.py
2132 $ "$PYTHON" check-seclevel.py
2131 $ cd $TESTTMP
2133 $ cd $TESTTMP
2132
2134
2133 #if serve
2135 #if serve
2134
2136
2135 Test the help pages in hgweb.
2137 Test the help pages in hgweb.
2136
2138
2137 Dish up an empty repo; serve it cold.
2139 Dish up an empty repo; serve it cold.
2138
2140
2139 $ hg init "$TESTTMP/test"
2141 $ hg init "$TESTTMP/test"
2140 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2142 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2141 $ cat hg.pid >> $DAEMON_PIDS
2143 $ cat hg.pid >> $DAEMON_PIDS
2142
2144
2143 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2145 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2144 200 Script output follows
2146 200 Script output follows
2145
2147
2146 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2148 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2147 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2149 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2148 <head>
2150 <head>
2149 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2151 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2150 <meta name="robots" content="index, nofollow" />
2152 <meta name="robots" content="index, nofollow" />
2151 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2153 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2152 <script type="text/javascript" src="/static/mercurial.js"></script>
2154 <script type="text/javascript" src="/static/mercurial.js"></script>
2153
2155
2154 <title>Help: Index</title>
2156 <title>Help: Index</title>
2155 </head>
2157 </head>
2156 <body>
2158 <body>
2157
2159
2158 <div class="container">
2160 <div class="container">
2159 <div class="menu">
2161 <div class="menu">
2160 <div class="logo">
2162 <div class="logo">
2161 <a href="https://mercurial-scm.org/">
2163 <a href="https://mercurial-scm.org/">
2162 <img src="/static/hglogo.png" alt="mercurial" /></a>
2164 <img src="/static/hglogo.png" alt="mercurial" /></a>
2163 </div>
2165 </div>
2164 <ul>
2166 <ul>
2165 <li><a href="/shortlog">log</a></li>
2167 <li><a href="/shortlog">log</a></li>
2166 <li><a href="/graph">graph</a></li>
2168 <li><a href="/graph">graph</a></li>
2167 <li><a href="/tags">tags</a></li>
2169 <li><a href="/tags">tags</a></li>
2168 <li><a href="/bookmarks">bookmarks</a></li>
2170 <li><a href="/bookmarks">bookmarks</a></li>
2169 <li><a href="/branches">branches</a></li>
2171 <li><a href="/branches">branches</a></li>
2170 </ul>
2172 </ul>
2171 <ul>
2173 <ul>
2172 <li class="active">help</li>
2174 <li class="active">help</li>
2173 </ul>
2175 </ul>
2174 </div>
2176 </div>
2175
2177
2176 <div class="main">
2178 <div class="main">
2177 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2179 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2178
2180
2179 <form class="search" action="/log">
2181 <form class="search" action="/log">
2180
2182
2181 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2183 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2182 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2184 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2183 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2185 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2184 </form>
2186 </form>
2185 <table class="bigtable">
2187 <table class="bigtable">
2186 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2188 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2187
2189
2188 <tr><td>
2190 <tr><td>
2189 <a href="/help/bundlespec">
2191 <a href="/help/bundlespec">
2190 bundlespec
2192 bundlespec
2191 </a>
2193 </a>
2192 </td><td>
2194 </td><td>
2193 Bundle File Formats
2195 Bundle File Formats
2194 </td></tr>
2196 </td></tr>
2195 <tr><td>
2197 <tr><td>
2196 <a href="/help/color">
2198 <a href="/help/color">
2197 color
2199 color
2198 </a>
2200 </a>
2199 </td><td>
2201 </td><td>
2200 Colorizing Outputs
2202 Colorizing Outputs
2201 </td></tr>
2203 </td></tr>
2202 <tr><td>
2204 <tr><td>
2203 <a href="/help/config">
2205 <a href="/help/config">
2204 config
2206 config
2205 </a>
2207 </a>
2206 </td><td>
2208 </td><td>
2207 Configuration Files
2209 Configuration Files
2208 </td></tr>
2210 </td></tr>
2209 <tr><td>
2211 <tr><td>
2210 <a href="/help/dates">
2212 <a href="/help/dates">
2211 dates
2213 dates
2212 </a>
2214 </a>
2213 </td><td>
2215 </td><td>
2214 Date Formats
2216 Date Formats
2215 </td></tr>
2217 </td></tr>
2216 <tr><td>
2218 <tr><td>
2217 <a href="/help/deprecated">
2219 <a href="/help/deprecated">
2218 deprecated
2220 deprecated
2219 </a>
2221 </a>
2220 </td><td>
2222 </td><td>
2221 Deprecated Features
2223 Deprecated Features
2222 </td></tr>
2224 </td></tr>
2223 <tr><td>
2225 <tr><td>
2224 <a href="/help/diffs">
2226 <a href="/help/diffs">
2225 diffs
2227 diffs
2226 </a>
2228 </a>
2227 </td><td>
2229 </td><td>
2228 Diff Formats
2230 Diff Formats
2229 </td></tr>
2231 </td></tr>
2230 <tr><td>
2232 <tr><td>
2231 <a href="/help/environment">
2233 <a href="/help/environment">
2232 environment
2234 environment
2233 </a>
2235 </a>
2234 </td><td>
2236 </td><td>
2235 Environment Variables
2237 Environment Variables
2236 </td></tr>
2238 </td></tr>
2237 <tr><td>
2239 <tr><td>
2238 <a href="/help/extensions">
2240 <a href="/help/extensions">
2239 extensions
2241 extensions
2240 </a>
2242 </a>
2241 </td><td>
2243 </td><td>
2242 Using Additional Features
2244 Using Additional Features
2243 </td></tr>
2245 </td></tr>
2244 <tr><td>
2246 <tr><td>
2245 <a href="/help/filesets">
2247 <a href="/help/filesets">
2246 filesets
2248 filesets
2247 </a>
2249 </a>
2248 </td><td>
2250 </td><td>
2249 Specifying File Sets
2251 Specifying File Sets
2250 </td></tr>
2252 </td></tr>
2251 <tr><td>
2253 <tr><td>
2252 <a href="/help/flags">
2254 <a href="/help/flags">
2253 flags
2255 flags
2254 </a>
2256 </a>
2255 </td><td>
2257 </td><td>
2256 Command-line flags
2258 Command-line flags
2257 </td></tr>
2259 </td></tr>
2258 <tr><td>
2260 <tr><td>
2259 <a href="/help/glossary">
2261 <a href="/help/glossary">
2260 glossary
2262 glossary
2261 </a>
2263 </a>
2262 </td><td>
2264 </td><td>
2263 Glossary
2265 Glossary
2264 </td></tr>
2266 </td></tr>
2265 <tr><td>
2267 <tr><td>
2266 <a href="/help/hgignore">
2268 <a href="/help/hgignore">
2267 hgignore
2269 hgignore
2268 </a>
2270 </a>
2269 </td><td>
2271 </td><td>
2270 Syntax for Mercurial Ignore Files
2272 Syntax for Mercurial Ignore Files
2271 </td></tr>
2273 </td></tr>
2272 <tr><td>
2274 <tr><td>
2273 <a href="/help/hgweb">
2275 <a href="/help/hgweb">
2274 hgweb
2276 hgweb
2275 </a>
2277 </a>
2276 </td><td>
2278 </td><td>
2277 Configuring hgweb
2279 Configuring hgweb
2278 </td></tr>
2280 </td></tr>
2279 <tr><td>
2281 <tr><td>
2280 <a href="/help/internals">
2282 <a href="/help/internals">
2281 internals
2283 internals
2282 </a>
2284 </a>
2283 </td><td>
2285 </td><td>
2284 Technical implementation topics
2286 Technical implementation topics
2285 </td></tr>
2287 </td></tr>
2286 <tr><td>
2288 <tr><td>
2287 <a href="/help/merge-tools">
2289 <a href="/help/merge-tools">
2288 merge-tools
2290 merge-tools
2289 </a>
2291 </a>
2290 </td><td>
2292 </td><td>
2291 Merge Tools
2293 Merge Tools
2292 </td></tr>
2294 </td></tr>
2293 <tr><td>
2295 <tr><td>
2294 <a href="/help/pager">
2296 <a href="/help/pager">
2295 pager
2297 pager
2296 </a>
2298 </a>
2297 </td><td>
2299 </td><td>
2298 Pager Support
2300 Pager Support
2299 </td></tr>
2301 </td></tr>
2300 <tr><td>
2302 <tr><td>
2301 <a href="/help/patterns">
2303 <a href="/help/patterns">
2302 patterns
2304 patterns
2303 </a>
2305 </a>
2304 </td><td>
2306 </td><td>
2305 File Name Patterns
2307 File Name Patterns
2306 </td></tr>
2308 </td></tr>
2307 <tr><td>
2309 <tr><td>
2308 <a href="/help/phases">
2310 <a href="/help/phases">
2309 phases
2311 phases
2310 </a>
2312 </a>
2311 </td><td>
2313 </td><td>
2312 Working with Phases
2314 Working with Phases
2313 </td></tr>
2315 </td></tr>
2314 <tr><td>
2316 <tr><td>
2315 <a href="/help/revisions">
2317 <a href="/help/revisions">
2316 revisions
2318 revisions
2317 </a>
2319 </a>
2318 </td><td>
2320 </td><td>
2319 Specifying Revisions
2321 Specifying Revisions
2320 </td></tr>
2322 </td></tr>
2321 <tr><td>
2323 <tr><td>
2322 <a href="/help/scripting">
2324 <a href="/help/scripting">
2323 scripting
2325 scripting
2324 </a>
2326 </a>
2325 </td><td>
2327 </td><td>
2326 Using Mercurial from scripts and automation
2328 Using Mercurial from scripts and automation
2327 </td></tr>
2329 </td></tr>
2328 <tr><td>
2330 <tr><td>
2329 <a href="/help/subrepos">
2331 <a href="/help/subrepos">
2330 subrepos
2332 subrepos
2331 </a>
2333 </a>
2332 </td><td>
2334 </td><td>
2333 Subrepositories
2335 Subrepositories
2334 </td></tr>
2336 </td></tr>
2335 <tr><td>
2337 <tr><td>
2336 <a href="/help/templating">
2338 <a href="/help/templating">
2337 templating
2339 templating
2338 </a>
2340 </a>
2339 </td><td>
2341 </td><td>
2340 Template Usage
2342 Template Usage
2341 </td></tr>
2343 </td></tr>
2342 <tr><td>
2344 <tr><td>
2343 <a href="/help/urls">
2345 <a href="/help/urls">
2344 urls
2346 urls
2345 </a>
2347 </a>
2346 </td><td>
2348 </td><td>
2347 URL Paths
2349 URL Paths
2348 </td></tr>
2350 </td></tr>
2349 <tr><td>
2351 <tr><td>
2350 <a href="/help/topic-containing-verbose">
2352 <a href="/help/topic-containing-verbose">
2351 topic-containing-verbose
2353 topic-containing-verbose
2352 </a>
2354 </a>
2353 </td><td>
2355 </td><td>
2354 This is the topic to test omit indicating.
2356 This is the topic to test omit indicating.
2355 </td></tr>
2357 </td></tr>
2356
2358
2357
2359
2358 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2360 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2359
2361
2360 <tr><td>
2362 <tr><td>
2361 <a href="/help/abort">
2363 <a href="/help/abort">
2362 abort
2364 abort
2363 </a>
2365 </a>
2364 </td><td>
2366 </td><td>
2365 abort an unfinished operation (EXPERIMENTAL)
2367 abort an unfinished operation (EXPERIMENTAL)
2366 </td></tr>
2368 </td></tr>
2367 <tr><td>
2369 <tr><td>
2368 <a href="/help/add">
2370 <a href="/help/add">
2369 add
2371 add
2370 </a>
2372 </a>
2371 </td><td>
2373 </td><td>
2372 add the specified files on the next commit
2374 add the specified files on the next commit
2373 </td></tr>
2375 </td></tr>
2374 <tr><td>
2376 <tr><td>
2375 <a href="/help/annotate">
2377 <a href="/help/annotate">
2376 annotate
2378 annotate
2377 </a>
2379 </a>
2378 </td><td>
2380 </td><td>
2379 show changeset information by line for each file
2381 show changeset information by line for each file
2380 </td></tr>
2382 </td></tr>
2381 <tr><td>
2383 <tr><td>
2382 <a href="/help/clone">
2384 <a href="/help/clone">
2383 clone
2385 clone
2384 </a>
2386 </a>
2385 </td><td>
2387 </td><td>
2386 make a copy of an existing repository
2388 make a copy of an existing repository
2387 </td></tr>
2389 </td></tr>
2388 <tr><td>
2390 <tr><td>
2389 <a href="/help/commit">
2391 <a href="/help/commit">
2390 commit
2392 commit
2391 </a>
2393 </a>
2392 </td><td>
2394 </td><td>
2393 commit the specified files or all outstanding changes
2395 commit the specified files or all outstanding changes
2394 </td></tr>
2396 </td></tr>
2395 <tr><td>
2397 <tr><td>
2396 <a href="/help/continue">
2398 <a href="/help/continue">
2397 continue
2399 continue
2398 </a>
2400 </a>
2399 </td><td>
2401 </td><td>
2400 resumes an interrupted operation (EXPERIMENTAL)
2402 resumes an interrupted operation (EXPERIMENTAL)
2401 </td></tr>
2403 </td></tr>
2402 <tr><td>
2404 <tr><td>
2403 <a href="/help/diff">
2405 <a href="/help/diff">
2404 diff
2406 diff
2405 </a>
2407 </a>
2406 </td><td>
2408 </td><td>
2407 diff repository (or selected files)
2409 diff repository (or selected files)
2408 </td></tr>
2410 </td></tr>
2409 <tr><td>
2411 <tr><td>
2410 <a href="/help/export">
2412 <a href="/help/export">
2411 export
2413 export
2412 </a>
2414 </a>
2413 </td><td>
2415 </td><td>
2414 dump the header and diffs for one or more changesets
2416 dump the header and diffs for one or more changesets
2415 </td></tr>
2417 </td></tr>
2416 <tr><td>
2418 <tr><td>
2417 <a href="/help/forget">
2419 <a href="/help/forget">
2418 forget
2420 forget
2419 </a>
2421 </a>
2420 </td><td>
2422 </td><td>
2421 forget the specified files on the next commit
2423 forget the specified files on the next commit
2422 </td></tr>
2424 </td></tr>
2423 <tr><td>
2425 <tr><td>
2424 <a href="/help/init">
2426 <a href="/help/init">
2425 init
2427 init
2426 </a>
2428 </a>
2427 </td><td>
2429 </td><td>
2428 create a new repository in the given directory
2430 create a new repository in the given directory
2429 </td></tr>
2431 </td></tr>
2430 <tr><td>
2432 <tr><td>
2431 <a href="/help/log">
2433 <a href="/help/log">
2432 log
2434 log
2433 </a>
2435 </a>
2434 </td><td>
2436 </td><td>
2435 show revision history of entire repository or files
2437 show revision history of entire repository or files
2436 </td></tr>
2438 </td></tr>
2437 <tr><td>
2439 <tr><td>
2438 <a href="/help/merge">
2440 <a href="/help/merge">
2439 merge
2441 merge
2440 </a>
2442 </a>
2441 </td><td>
2443 </td><td>
2442 merge another revision into working directory
2444 merge another revision into working directory
2443 </td></tr>
2445 </td></tr>
2444 <tr><td>
2446 <tr><td>
2445 <a href="/help/pull">
2447 <a href="/help/pull">
2446 pull
2448 pull
2447 </a>
2449 </a>
2448 </td><td>
2450 </td><td>
2449 pull changes from the specified source
2451 pull changes from the specified source
2450 </td></tr>
2452 </td></tr>
2451 <tr><td>
2453 <tr><td>
2452 <a href="/help/push">
2454 <a href="/help/push">
2453 push
2455 push
2454 </a>
2456 </a>
2455 </td><td>
2457 </td><td>
2456 push changes to the specified destination
2458 push changes to the specified destination
2457 </td></tr>
2459 </td></tr>
2458 <tr><td>
2460 <tr><td>
2459 <a href="/help/remove">
2461 <a href="/help/remove">
2460 remove
2462 remove
2461 </a>
2463 </a>
2462 </td><td>
2464 </td><td>
2463 remove the specified files on the next commit
2465 remove the specified files on the next commit
2464 </td></tr>
2466 </td></tr>
2465 <tr><td>
2467 <tr><td>
2466 <a href="/help/serve">
2468 <a href="/help/serve">
2467 serve
2469 serve
2468 </a>
2470 </a>
2469 </td><td>
2471 </td><td>
2470 start stand-alone webserver
2472 start stand-alone webserver
2471 </td></tr>
2473 </td></tr>
2472 <tr><td>
2474 <tr><td>
2473 <a href="/help/status">
2475 <a href="/help/status">
2474 status
2476 status
2475 </a>
2477 </a>
2476 </td><td>
2478 </td><td>
2477 show changed files in the working directory
2479 show changed files in the working directory
2478 </td></tr>
2480 </td></tr>
2479 <tr><td>
2481 <tr><td>
2480 <a href="/help/summary">
2482 <a href="/help/summary">
2481 summary
2483 summary
2482 </a>
2484 </a>
2483 </td><td>
2485 </td><td>
2484 summarize working directory state
2486 summarize working directory state
2485 </td></tr>
2487 </td></tr>
2486 <tr><td>
2488 <tr><td>
2487 <a href="/help/update">
2489 <a href="/help/update">
2488 update
2490 update
2489 </a>
2491 </a>
2490 </td><td>
2492 </td><td>
2491 update working directory (or switch revisions)
2493 update working directory (or switch revisions)
2492 </td></tr>
2494 </td></tr>
2493
2495
2494
2496
2495
2497
2496 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2498 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2497
2499
2498 <tr><td>
2500 <tr><td>
2499 <a href="/help/addremove">
2501 <a href="/help/addremove">
2500 addremove
2502 addremove
2501 </a>
2503 </a>
2502 </td><td>
2504 </td><td>
2503 add all new files, delete all missing files
2505 add all new files, delete all missing files
2504 </td></tr>
2506 </td></tr>
2505 <tr><td>
2507 <tr><td>
2506 <a href="/help/archive">
2508 <a href="/help/archive">
2507 archive
2509 archive
2508 </a>
2510 </a>
2509 </td><td>
2511 </td><td>
2510 create an unversioned archive of a repository revision
2512 create an unversioned archive of a repository revision
2511 </td></tr>
2513 </td></tr>
2512 <tr><td>
2514 <tr><td>
2513 <a href="/help/backout">
2515 <a href="/help/backout">
2514 backout
2516 backout
2515 </a>
2517 </a>
2516 </td><td>
2518 </td><td>
2517 reverse effect of earlier changeset
2519 reverse effect of earlier changeset
2518 </td></tr>
2520 </td></tr>
2519 <tr><td>
2521 <tr><td>
2520 <a href="/help/bisect">
2522 <a href="/help/bisect">
2521 bisect
2523 bisect
2522 </a>
2524 </a>
2523 </td><td>
2525 </td><td>
2524 subdivision search of changesets
2526 subdivision search of changesets
2525 </td></tr>
2527 </td></tr>
2526 <tr><td>
2528 <tr><td>
2527 <a href="/help/bookmarks">
2529 <a href="/help/bookmarks">
2528 bookmarks
2530 bookmarks
2529 </a>
2531 </a>
2530 </td><td>
2532 </td><td>
2531 create a new bookmark or list existing bookmarks
2533 create a new bookmark or list existing bookmarks
2532 </td></tr>
2534 </td></tr>
2533 <tr><td>
2535 <tr><td>
2534 <a href="/help/branch">
2536 <a href="/help/branch">
2535 branch
2537 branch
2536 </a>
2538 </a>
2537 </td><td>
2539 </td><td>
2538 set or show the current branch name
2540 set or show the current branch name
2539 </td></tr>
2541 </td></tr>
2540 <tr><td>
2542 <tr><td>
2541 <a href="/help/branches">
2543 <a href="/help/branches">
2542 branches
2544 branches
2543 </a>
2545 </a>
2544 </td><td>
2546 </td><td>
2545 list repository named branches
2547 list repository named branches
2546 </td></tr>
2548 </td></tr>
2547 <tr><td>
2549 <tr><td>
2548 <a href="/help/bundle">
2550 <a href="/help/bundle">
2549 bundle
2551 bundle
2550 </a>
2552 </a>
2551 </td><td>
2553 </td><td>
2552 create a bundle file
2554 create a bundle file
2553 </td></tr>
2555 </td></tr>
2554 <tr><td>
2556 <tr><td>
2555 <a href="/help/cat">
2557 <a href="/help/cat">
2556 cat
2558 cat
2557 </a>
2559 </a>
2558 </td><td>
2560 </td><td>
2559 output the current or given revision of files
2561 output the current or given revision of files
2560 </td></tr>
2562 </td></tr>
2561 <tr><td>
2563 <tr><td>
2562 <a href="/help/config">
2564 <a href="/help/config">
2563 config
2565 config
2564 </a>
2566 </a>
2565 </td><td>
2567 </td><td>
2566 show combined config settings from all hgrc files
2568 show combined config settings from all hgrc files
2567 </td></tr>
2569 </td></tr>
2568 <tr><td>
2570 <tr><td>
2569 <a href="/help/copy">
2571 <a href="/help/copy">
2570 copy
2572 copy
2571 </a>
2573 </a>
2572 </td><td>
2574 </td><td>
2573 mark files as copied for the next commit
2575 mark files as copied for the next commit
2574 </td></tr>
2576 </td></tr>
2575 <tr><td>
2577 <tr><td>
2576 <a href="/help/files">
2578 <a href="/help/files">
2577 files
2579 files
2578 </a>
2580 </a>
2579 </td><td>
2581 </td><td>
2580 list tracked files
2582 list tracked files
2581 </td></tr>
2583 </td></tr>
2582 <tr><td>
2584 <tr><td>
2583 <a href="/help/graft">
2585 <a href="/help/graft">
2584 graft
2586 graft
2585 </a>
2587 </a>
2586 </td><td>
2588 </td><td>
2587 copy changes from other branches onto the current branch
2589 copy changes from other branches onto the current branch
2588 </td></tr>
2590 </td></tr>
2589 <tr><td>
2591 <tr><td>
2590 <a href="/help/grep">
2592 <a href="/help/grep">
2591 grep
2593 grep
2592 </a>
2594 </a>
2593 </td><td>
2595 </td><td>
2594 search for a pattern in specified files
2596 search for a pattern in specified files
2595 </td></tr>
2597 </td></tr>
2596 <tr><td>
2598 <tr><td>
2597 <a href="/help/hashelp">
2599 <a href="/help/hashelp">
2598 hashelp
2600 hashelp
2599 </a>
2601 </a>
2600 </td><td>
2602 </td><td>
2601 Extension command's help
2603 Extension command's help
2602 </td></tr>
2604 </td></tr>
2603 <tr><td>
2605 <tr><td>
2604 <a href="/help/heads">
2606 <a href="/help/heads">
2605 heads
2607 heads
2606 </a>
2608 </a>
2607 </td><td>
2609 </td><td>
2608 show branch heads
2610 show branch heads
2609 </td></tr>
2611 </td></tr>
2610 <tr><td>
2612 <tr><td>
2611 <a href="/help/help">
2613 <a href="/help/help">
2612 help
2614 help
2613 </a>
2615 </a>
2614 </td><td>
2616 </td><td>
2615 show help for a given topic or a help overview
2617 show help for a given topic or a help overview
2616 </td></tr>
2618 </td></tr>
2617 <tr><td>
2619 <tr><td>
2618 <a href="/help/hgalias">
2620 <a href="/help/hgalias">
2619 hgalias
2621 hgalias
2620 </a>
2622 </a>
2621 </td><td>
2623 </td><td>
2622 My doc
2624 My doc
2623 </td></tr>
2625 </td></tr>
2624 <tr><td>
2626 <tr><td>
2625 <a href="/help/hgaliasnodoc">
2627 <a href="/help/hgaliasnodoc">
2626 hgaliasnodoc
2628 hgaliasnodoc
2627 </a>
2629 </a>
2628 </td><td>
2630 </td><td>
2629 summarize working directory state
2631 summarize working directory state
2630 </td></tr>
2632 </td></tr>
2631 <tr><td>
2633 <tr><td>
2632 <a href="/help/identify">
2634 <a href="/help/identify">
2633 identify
2635 identify
2634 </a>
2636 </a>
2635 </td><td>
2637 </td><td>
2636 identify the working directory or specified revision
2638 identify the working directory or specified revision
2637 </td></tr>
2639 </td></tr>
2638 <tr><td>
2640 <tr><td>
2639 <a href="/help/import">
2641 <a href="/help/import">
2640 import
2642 import
2641 </a>
2643 </a>
2642 </td><td>
2644 </td><td>
2643 import an ordered set of patches
2645 import an ordered set of patches
2644 </td></tr>
2646 </td></tr>
2645 <tr><td>
2647 <tr><td>
2646 <a href="/help/incoming">
2648 <a href="/help/incoming">
2647 incoming
2649 incoming
2648 </a>
2650 </a>
2649 </td><td>
2651 </td><td>
2650 show new changesets found in source
2652 show new changesets found in source
2651 </td></tr>
2653 </td></tr>
2652 <tr><td>
2654 <tr><td>
2653 <a href="/help/manifest">
2655 <a href="/help/manifest">
2654 manifest
2656 manifest
2655 </a>
2657 </a>
2656 </td><td>
2658 </td><td>
2657 output the current or given revision of the project manifest
2659 output the current or given revision of the project manifest
2658 </td></tr>
2660 </td></tr>
2659 <tr><td>
2661 <tr><td>
2660 <a href="/help/nohelp">
2662 <a href="/help/nohelp">
2661 nohelp
2663 nohelp
2662 </a>
2664 </a>
2663 </td><td>
2665 </td><td>
2664 (no help text available)
2666 (no help text available)
2665 </td></tr>
2667 </td></tr>
2666 <tr><td>
2668 <tr><td>
2667 <a href="/help/outgoing">
2669 <a href="/help/outgoing">
2668 outgoing
2670 outgoing
2669 </a>
2671 </a>
2670 </td><td>
2672 </td><td>
2671 show changesets not found in the destination
2673 show changesets not found in the destination
2672 </td></tr>
2674 </td></tr>
2673 <tr><td>
2675 <tr><td>
2674 <a href="/help/paths">
2676 <a href="/help/paths">
2675 paths
2677 paths
2676 </a>
2678 </a>
2677 </td><td>
2679 </td><td>
2678 show aliases for remote repositories
2680 show aliases for remote repositories
2679 </td></tr>
2681 </td></tr>
2680 <tr><td>
2682 <tr><td>
2681 <a href="/help/phase">
2683 <a href="/help/phase">
2682 phase
2684 phase
2683 </a>
2685 </a>
2684 </td><td>
2686 </td><td>
2685 set or show the current phase name
2687 set or show the current phase name
2686 </td></tr>
2688 </td></tr>
2687 <tr><td>
2689 <tr><td>
2688 <a href="/help/recover">
2690 <a href="/help/recover">
2689 recover
2691 recover
2690 </a>
2692 </a>
2691 </td><td>
2693 </td><td>
2692 roll back an interrupted transaction
2694 roll back an interrupted transaction
2693 </td></tr>
2695 </td></tr>
2694 <tr><td>
2696 <tr><td>
2695 <a href="/help/rename">
2697 <a href="/help/rename">
2696 rename
2698 rename
2697 </a>
2699 </a>
2698 </td><td>
2700 </td><td>
2699 rename files; equivalent of copy + remove
2701 rename files; equivalent of copy + remove
2700 </td></tr>
2702 </td></tr>
2701 <tr><td>
2703 <tr><td>
2702 <a href="/help/resolve">
2704 <a href="/help/resolve">
2703 resolve
2705 resolve
2704 </a>
2706 </a>
2705 </td><td>
2707 </td><td>
2706 redo merges or set/view the merge status of files
2708 redo merges or set/view the merge status of files
2707 </td></tr>
2709 </td></tr>
2708 <tr><td>
2710 <tr><td>
2709 <a href="/help/revert">
2711 <a href="/help/revert">
2710 revert
2712 revert
2711 </a>
2713 </a>
2712 </td><td>
2714 </td><td>
2713 restore files to their checkout state
2715 restore files to their checkout state
2714 </td></tr>
2716 </td></tr>
2715 <tr><td>
2717 <tr><td>
2716 <a href="/help/root">
2718 <a href="/help/root">
2717 root
2719 root
2718 </a>
2720 </a>
2719 </td><td>
2721 </td><td>
2720 print the root (top) of the current working directory
2722 print the root (top) of the current working directory
2721 </td></tr>
2723 </td></tr>
2722 <tr><td>
2724 <tr><td>
2723 <a href="/help/shellalias">
2725 <a href="/help/shellalias">
2724 shellalias
2726 shellalias
2725 </a>
2727 </a>
2726 </td><td>
2728 </td><td>
2727 (no help text available)
2729 (no help text available)
2728 </td></tr>
2730 </td></tr>
2729 <tr><td>
2731 <tr><td>
2730 <a href="/help/shelve">
2732 <a href="/help/shelve">
2731 shelve
2733 shelve
2732 </a>
2734 </a>
2733 </td><td>
2735 </td><td>
2734 save and set aside changes from the working directory
2736 save and set aside changes from the working directory
2735 </td></tr>
2737 </td></tr>
2736 <tr><td>
2738 <tr><td>
2737 <a href="/help/tag">
2739 <a href="/help/tag">
2738 tag
2740 tag
2739 </a>
2741 </a>
2740 </td><td>
2742 </td><td>
2741 add one or more tags for the current or given revision
2743 add one or more tags for the current or given revision
2742 </td></tr>
2744 </td></tr>
2743 <tr><td>
2745 <tr><td>
2744 <a href="/help/tags">
2746 <a href="/help/tags">
2745 tags
2747 tags
2746 </a>
2748 </a>
2747 </td><td>
2749 </td><td>
2748 list repository tags
2750 list repository tags
2749 </td></tr>
2751 </td></tr>
2750 <tr><td>
2752 <tr><td>
2751 <a href="/help/unbundle">
2753 <a href="/help/unbundle">
2752 unbundle
2754 unbundle
2753 </a>
2755 </a>
2754 </td><td>
2756 </td><td>
2755 apply one or more bundle files
2757 apply one or more bundle files
2756 </td></tr>
2758 </td></tr>
2757 <tr><td>
2759 <tr><td>
2758 <a href="/help/unshelve">
2760 <a href="/help/unshelve">
2759 unshelve
2761 unshelve
2760 </a>
2762 </a>
2761 </td><td>
2763 </td><td>
2762 restore a shelved change to the working directory
2764 restore a shelved change to the working directory
2763 </td></tr>
2765 </td></tr>
2764 <tr><td>
2766 <tr><td>
2765 <a href="/help/verify">
2767 <a href="/help/verify">
2766 verify
2768 verify
2767 </a>
2769 </a>
2768 </td><td>
2770 </td><td>
2769 verify the integrity of the repository
2771 verify the integrity of the repository
2770 </td></tr>
2772 </td></tr>
2771 <tr><td>
2773 <tr><td>
2772 <a href="/help/version">
2774 <a href="/help/version">
2773 version
2775 version
2774 </a>
2776 </a>
2775 </td><td>
2777 </td><td>
2776 output version and copyright information
2778 output version and copyright information
2777 </td></tr>
2779 </td></tr>
2778
2780
2779
2781
2780 </table>
2782 </table>
2781 </div>
2783 </div>
2782 </div>
2784 </div>
2783
2785
2784
2786
2785
2787
2786 </body>
2788 </body>
2787 </html>
2789 </html>
2788
2790
2789
2791
2790 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2792 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2791 200 Script output follows
2793 200 Script output follows
2792
2794
2793 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2795 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2794 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2796 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2795 <head>
2797 <head>
2796 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2798 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2797 <meta name="robots" content="index, nofollow" />
2799 <meta name="robots" content="index, nofollow" />
2798 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2800 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2799 <script type="text/javascript" src="/static/mercurial.js"></script>
2801 <script type="text/javascript" src="/static/mercurial.js"></script>
2800
2802
2801 <title>Help: add</title>
2803 <title>Help: add</title>
2802 </head>
2804 </head>
2803 <body>
2805 <body>
2804
2806
2805 <div class="container">
2807 <div class="container">
2806 <div class="menu">
2808 <div class="menu">
2807 <div class="logo">
2809 <div class="logo">
2808 <a href="https://mercurial-scm.org/">
2810 <a href="https://mercurial-scm.org/">
2809 <img src="/static/hglogo.png" alt="mercurial" /></a>
2811 <img src="/static/hglogo.png" alt="mercurial" /></a>
2810 </div>
2812 </div>
2811 <ul>
2813 <ul>
2812 <li><a href="/shortlog">log</a></li>
2814 <li><a href="/shortlog">log</a></li>
2813 <li><a href="/graph">graph</a></li>
2815 <li><a href="/graph">graph</a></li>
2814 <li><a href="/tags">tags</a></li>
2816 <li><a href="/tags">tags</a></li>
2815 <li><a href="/bookmarks">bookmarks</a></li>
2817 <li><a href="/bookmarks">bookmarks</a></li>
2816 <li><a href="/branches">branches</a></li>
2818 <li><a href="/branches">branches</a></li>
2817 </ul>
2819 </ul>
2818 <ul>
2820 <ul>
2819 <li class="active"><a href="/help">help</a></li>
2821 <li class="active"><a href="/help">help</a></li>
2820 </ul>
2822 </ul>
2821 </div>
2823 </div>
2822
2824
2823 <div class="main">
2825 <div class="main">
2824 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2826 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2825 <h3>Help: add</h3>
2827 <h3>Help: add</h3>
2826
2828
2827 <form class="search" action="/log">
2829 <form class="search" action="/log">
2828
2830
2829 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2831 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2830 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2832 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2831 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2833 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2832 </form>
2834 </form>
2833 <div id="doc">
2835 <div id="doc">
2834 <p>
2836 <p>
2835 hg add [OPTION]... [FILE]...
2837 hg add [OPTION]... [FILE]...
2836 </p>
2838 </p>
2837 <p>
2839 <p>
2838 add the specified files on the next commit
2840 add the specified files on the next commit
2839 </p>
2841 </p>
2840 <p>
2842 <p>
2841 Schedule files to be version controlled and added to the
2843 Schedule files to be version controlled and added to the
2842 repository.
2844 repository.
2843 </p>
2845 </p>
2844 <p>
2846 <p>
2845 The files will be added to the repository at the next commit. To
2847 The files will be added to the repository at the next commit. To
2846 undo an add before that, see 'hg forget'.
2848 undo an add before that, see 'hg forget'.
2847 </p>
2849 </p>
2848 <p>
2850 <p>
2849 If no names are given, add all files to the repository (except
2851 If no names are given, add all files to the repository (except
2850 files matching &quot;.hgignore&quot;).
2852 files matching &quot;.hgignore&quot;).
2851 </p>
2853 </p>
2852 <p>
2854 <p>
2853 Examples:
2855 Examples:
2854 </p>
2856 </p>
2855 <ul>
2857 <ul>
2856 <li> New (unknown) files are added automatically by 'hg add':
2858 <li> New (unknown) files are added automatically by 'hg add':
2857 <pre>
2859 <pre>
2858 \$ ls (re)
2860 \$ ls (re)
2859 foo.c
2861 foo.c
2860 \$ hg status (re)
2862 \$ hg status (re)
2861 ? foo.c
2863 ? foo.c
2862 \$ hg add (re)
2864 \$ hg add (re)
2863 adding foo.c
2865 adding foo.c
2864 \$ hg status (re)
2866 \$ hg status (re)
2865 A foo.c
2867 A foo.c
2866 </pre>
2868 </pre>
2867 <li> Specific files to be added can be specified:
2869 <li> Specific files to be added can be specified:
2868 <pre>
2870 <pre>
2869 \$ ls (re)
2871 \$ ls (re)
2870 bar.c foo.c
2872 bar.c foo.c
2871 \$ hg status (re)
2873 \$ hg status (re)
2872 ? bar.c
2874 ? bar.c
2873 ? foo.c
2875 ? foo.c
2874 \$ hg add bar.c (re)
2876 \$ hg add bar.c (re)
2875 \$ hg status (re)
2877 \$ hg status (re)
2876 A bar.c
2878 A bar.c
2877 ? foo.c
2879 ? foo.c
2878 </pre>
2880 </pre>
2879 </ul>
2881 </ul>
2880 <p>
2882 <p>
2881 Returns 0 if all files are successfully added.
2883 Returns 0 if all files are successfully added.
2882 </p>
2884 </p>
2883 <p>
2885 <p>
2884 options ([+] can be repeated):
2886 options ([+] can be repeated):
2885 </p>
2887 </p>
2886 <table>
2888 <table>
2887 <tr><td>-I</td>
2889 <tr><td>-I</td>
2888 <td>--include PATTERN [+]</td>
2890 <td>--include PATTERN [+]</td>
2889 <td>include names matching the given patterns</td></tr>
2891 <td>include names matching the given patterns</td></tr>
2890 <tr><td>-X</td>
2892 <tr><td>-X</td>
2891 <td>--exclude PATTERN [+]</td>
2893 <td>--exclude PATTERN [+]</td>
2892 <td>exclude names matching the given patterns</td></tr>
2894 <td>exclude names matching the given patterns</td></tr>
2893 <tr><td>-S</td>
2895 <tr><td>-S</td>
2894 <td>--subrepos</td>
2896 <td>--subrepos</td>
2895 <td>recurse into subrepositories</td></tr>
2897 <td>recurse into subrepositories</td></tr>
2896 <tr><td>-n</td>
2898 <tr><td>-n</td>
2897 <td>--dry-run</td>
2899 <td>--dry-run</td>
2898 <td>do not perform actions, just print output</td></tr>
2900 <td>do not perform actions, just print output</td></tr>
2899 </table>
2901 </table>
2900 <p>
2902 <p>
2901 global options ([+] can be repeated):
2903 global options ([+] can be repeated):
2902 </p>
2904 </p>
2903 <table>
2905 <table>
2904 <tr><td>-R</td>
2906 <tr><td>-R</td>
2905 <td>--repository REPO</td>
2907 <td>--repository REPO</td>
2906 <td>repository root directory or name of overlay bundle file</td></tr>
2908 <td>repository root directory or name of overlay bundle file</td></tr>
2907 <tr><td></td>
2909 <tr><td></td>
2908 <td>--cwd DIR</td>
2910 <td>--cwd DIR</td>
2909 <td>change working directory</td></tr>
2911 <td>change working directory</td></tr>
2910 <tr><td>-y</td>
2912 <tr><td>-y</td>
2911 <td>--noninteractive</td>
2913 <td>--noninteractive</td>
2912 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2914 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2913 <tr><td>-q</td>
2915 <tr><td>-q</td>
2914 <td>--quiet</td>
2916 <td>--quiet</td>
2915 <td>suppress output</td></tr>
2917 <td>suppress output</td></tr>
2916 <tr><td>-v</td>
2918 <tr><td>-v</td>
2917 <td>--verbose</td>
2919 <td>--verbose</td>
2918 <td>enable additional output</td></tr>
2920 <td>enable additional output</td></tr>
2919 <tr><td></td>
2921 <tr><td></td>
2920 <td>--color TYPE</td>
2922 <td>--color TYPE</td>
2921 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2923 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2922 <tr><td></td>
2924 <tr><td></td>
2923 <td>--config CONFIG [+]</td>
2925 <td>--config CONFIG [+]</td>
2924 <td>set/override config option (use 'section.name=value')</td></tr>
2926 <td>set/override config option (use 'section.name=value')</td></tr>
2925 <tr><td></td>
2927 <tr><td></td>
2926 <td>--debug</td>
2928 <td>--debug</td>
2927 <td>enable debugging output</td></tr>
2929 <td>enable debugging output</td></tr>
2928 <tr><td></td>
2930 <tr><td></td>
2929 <td>--debugger</td>
2931 <td>--debugger</td>
2930 <td>start debugger</td></tr>
2932 <td>start debugger</td></tr>
2931 <tr><td></td>
2933 <tr><td></td>
2932 <td>--encoding ENCODE</td>
2934 <td>--encoding ENCODE</td>
2933 <td>set the charset encoding (default: ascii)</td></tr>
2935 <td>set the charset encoding (default: ascii)</td></tr>
2934 <tr><td></td>
2936 <tr><td></td>
2935 <td>--encodingmode MODE</td>
2937 <td>--encodingmode MODE</td>
2936 <td>set the charset encoding mode (default: strict)</td></tr>
2938 <td>set the charset encoding mode (default: strict)</td></tr>
2937 <tr><td></td>
2939 <tr><td></td>
2938 <td>--traceback</td>
2940 <td>--traceback</td>
2939 <td>always print a traceback on exception</td></tr>
2941 <td>always print a traceback on exception</td></tr>
2940 <tr><td></td>
2942 <tr><td></td>
2941 <td>--time</td>
2943 <td>--time</td>
2942 <td>time how long the command takes</td></tr>
2944 <td>time how long the command takes</td></tr>
2943 <tr><td></td>
2945 <tr><td></td>
2944 <td>--profile</td>
2946 <td>--profile</td>
2945 <td>print command execution profile</td></tr>
2947 <td>print command execution profile</td></tr>
2946 <tr><td></td>
2948 <tr><td></td>
2947 <td>--version</td>
2949 <td>--version</td>
2948 <td>output version information and exit</td></tr>
2950 <td>output version information and exit</td></tr>
2949 <tr><td>-h</td>
2951 <tr><td>-h</td>
2950 <td>--help</td>
2952 <td>--help</td>
2951 <td>display help and exit</td></tr>
2953 <td>display help and exit</td></tr>
2952 <tr><td></td>
2954 <tr><td></td>
2953 <td>--hidden</td>
2955 <td>--hidden</td>
2954 <td>consider hidden changesets</td></tr>
2956 <td>consider hidden changesets</td></tr>
2955 <tr><td></td>
2957 <tr><td></td>
2956 <td>--pager TYPE</td>
2958 <td>--pager TYPE</td>
2957 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2959 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2958 </table>
2960 </table>
2959
2961
2960 </div>
2962 </div>
2961 </div>
2963 </div>
2962 </div>
2964 </div>
2963
2965
2964
2966
2965
2967
2966 </body>
2968 </body>
2967 </html>
2969 </html>
2968
2970
2969
2971
2970 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2972 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2971 200 Script output follows
2973 200 Script output follows
2972
2974
2973 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2975 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2974 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2976 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2975 <head>
2977 <head>
2976 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2978 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2977 <meta name="robots" content="index, nofollow" />
2979 <meta name="robots" content="index, nofollow" />
2978 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2980 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2979 <script type="text/javascript" src="/static/mercurial.js"></script>
2981 <script type="text/javascript" src="/static/mercurial.js"></script>
2980
2982
2981 <title>Help: remove</title>
2983 <title>Help: remove</title>
2982 </head>
2984 </head>
2983 <body>
2985 <body>
2984
2986
2985 <div class="container">
2987 <div class="container">
2986 <div class="menu">
2988 <div class="menu">
2987 <div class="logo">
2989 <div class="logo">
2988 <a href="https://mercurial-scm.org/">
2990 <a href="https://mercurial-scm.org/">
2989 <img src="/static/hglogo.png" alt="mercurial" /></a>
2991 <img src="/static/hglogo.png" alt="mercurial" /></a>
2990 </div>
2992 </div>
2991 <ul>
2993 <ul>
2992 <li><a href="/shortlog">log</a></li>
2994 <li><a href="/shortlog">log</a></li>
2993 <li><a href="/graph">graph</a></li>
2995 <li><a href="/graph">graph</a></li>
2994 <li><a href="/tags">tags</a></li>
2996 <li><a href="/tags">tags</a></li>
2995 <li><a href="/bookmarks">bookmarks</a></li>
2997 <li><a href="/bookmarks">bookmarks</a></li>
2996 <li><a href="/branches">branches</a></li>
2998 <li><a href="/branches">branches</a></li>
2997 </ul>
2999 </ul>
2998 <ul>
3000 <ul>
2999 <li class="active"><a href="/help">help</a></li>
3001 <li class="active"><a href="/help">help</a></li>
3000 </ul>
3002 </ul>
3001 </div>
3003 </div>
3002
3004
3003 <div class="main">
3005 <div class="main">
3004 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3006 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3005 <h3>Help: remove</h3>
3007 <h3>Help: remove</h3>
3006
3008
3007 <form class="search" action="/log">
3009 <form class="search" action="/log">
3008
3010
3009 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3011 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3010 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3012 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3011 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3013 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3012 </form>
3014 </form>
3013 <div id="doc">
3015 <div id="doc">
3014 <p>
3016 <p>
3015 hg remove [OPTION]... FILE...
3017 hg remove [OPTION]... FILE...
3016 </p>
3018 </p>
3017 <p>
3019 <p>
3018 aliases: rm
3020 aliases: rm
3019 </p>
3021 </p>
3020 <p>
3022 <p>
3021 remove the specified files on the next commit
3023 remove the specified files on the next commit
3022 </p>
3024 </p>
3023 <p>
3025 <p>
3024 Schedule the indicated files for removal from the current branch.
3026 Schedule the indicated files for removal from the current branch.
3025 </p>
3027 </p>
3026 <p>
3028 <p>
3027 This command schedules the files to be removed at the next commit.
3029 This command schedules the files to be removed at the next commit.
3028 To undo a remove before that, see 'hg revert'. To undo added
3030 To undo a remove before that, see 'hg revert'. To undo added
3029 files, see 'hg forget'.
3031 files, see 'hg forget'.
3030 </p>
3032 </p>
3031 <p>
3033 <p>
3032 -A/--after can be used to remove only files that have already
3034 -A/--after can be used to remove only files that have already
3033 been deleted, -f/--force can be used to force deletion, and -Af
3035 been deleted, -f/--force can be used to force deletion, and -Af
3034 can be used to remove files from the next revision without
3036 can be used to remove files from the next revision without
3035 deleting them from the working directory.
3037 deleting them from the working directory.
3036 </p>
3038 </p>
3037 <p>
3039 <p>
3038 The following table details the behavior of remove for different
3040 The following table details the behavior of remove for different
3039 file states (columns) and option combinations (rows). The file
3041 file states (columns) and option combinations (rows). The file
3040 states are Added [A], Clean [C], Modified [M] and Missing [!]
3042 states are Added [A], Clean [C], Modified [M] and Missing [!]
3041 (as reported by 'hg status'). The actions are Warn, Remove
3043 (as reported by 'hg status'). The actions are Warn, Remove
3042 (from branch) and Delete (from disk):
3044 (from branch) and Delete (from disk):
3043 </p>
3045 </p>
3044 <table>
3046 <table>
3045 <tr><td>opt/state</td>
3047 <tr><td>opt/state</td>
3046 <td>A</td>
3048 <td>A</td>
3047 <td>C</td>
3049 <td>C</td>
3048 <td>M</td>
3050 <td>M</td>
3049 <td>!</td></tr>
3051 <td>!</td></tr>
3050 <tr><td>none</td>
3052 <tr><td>none</td>
3051 <td>W</td>
3053 <td>W</td>
3052 <td>RD</td>
3054 <td>RD</td>
3053 <td>W</td>
3055 <td>W</td>
3054 <td>R</td></tr>
3056 <td>R</td></tr>
3055 <tr><td>-f</td>
3057 <tr><td>-f</td>
3056 <td>R</td>
3058 <td>R</td>
3057 <td>RD</td>
3059 <td>RD</td>
3058 <td>RD</td>
3060 <td>RD</td>
3059 <td>R</td></tr>
3061 <td>R</td></tr>
3060 <tr><td>-A</td>
3062 <tr><td>-A</td>
3061 <td>W</td>
3063 <td>W</td>
3062 <td>W</td>
3064 <td>W</td>
3063 <td>W</td>
3065 <td>W</td>
3064 <td>R</td></tr>
3066 <td>R</td></tr>
3065 <tr><td>-Af</td>
3067 <tr><td>-Af</td>
3066 <td>R</td>
3068 <td>R</td>
3067 <td>R</td>
3069 <td>R</td>
3068 <td>R</td>
3070 <td>R</td>
3069 <td>R</td></tr>
3071 <td>R</td></tr>
3070 </table>
3072 </table>
3071 <p>
3073 <p>
3072 <b>Note:</b>
3074 <b>Note:</b>
3073 </p>
3075 </p>
3074 <p>
3076 <p>
3075 'hg remove' never deletes files in Added [A] state from the
3077 'hg remove' never deletes files in Added [A] state from the
3076 working directory, not even if &quot;--force&quot; is specified.
3078 working directory, not even if &quot;--force&quot; is specified.
3077 </p>
3079 </p>
3078 <p>
3080 <p>
3079 Returns 0 on success, 1 if any warnings encountered.
3081 Returns 0 on success, 1 if any warnings encountered.
3080 </p>
3082 </p>
3081 <p>
3083 <p>
3082 options ([+] can be repeated):
3084 options ([+] can be repeated):
3083 </p>
3085 </p>
3084 <table>
3086 <table>
3085 <tr><td>-A</td>
3087 <tr><td>-A</td>
3086 <td>--after</td>
3088 <td>--after</td>
3087 <td>record delete for missing files</td></tr>
3089 <td>record delete for missing files</td></tr>
3088 <tr><td>-f</td>
3090 <tr><td>-f</td>
3089 <td>--force</td>
3091 <td>--force</td>
3090 <td>forget added files, delete modified files</td></tr>
3092 <td>forget added files, delete modified files</td></tr>
3091 <tr><td>-S</td>
3093 <tr><td>-S</td>
3092 <td>--subrepos</td>
3094 <td>--subrepos</td>
3093 <td>recurse into subrepositories</td></tr>
3095 <td>recurse into subrepositories</td></tr>
3094 <tr><td>-I</td>
3096 <tr><td>-I</td>
3095 <td>--include PATTERN [+]</td>
3097 <td>--include PATTERN [+]</td>
3096 <td>include names matching the given patterns</td></tr>
3098 <td>include names matching the given patterns</td></tr>
3097 <tr><td>-X</td>
3099 <tr><td>-X</td>
3098 <td>--exclude PATTERN [+]</td>
3100 <td>--exclude PATTERN [+]</td>
3099 <td>exclude names matching the given patterns</td></tr>
3101 <td>exclude names matching the given patterns</td></tr>
3100 <tr><td>-n</td>
3102 <tr><td>-n</td>
3101 <td>--dry-run</td>
3103 <td>--dry-run</td>
3102 <td>do not perform actions, just print output</td></tr>
3104 <td>do not perform actions, just print output</td></tr>
3103 </table>
3105 </table>
3104 <p>
3106 <p>
3105 global options ([+] can be repeated):
3107 global options ([+] can be repeated):
3106 </p>
3108 </p>
3107 <table>
3109 <table>
3108 <tr><td>-R</td>
3110 <tr><td>-R</td>
3109 <td>--repository REPO</td>
3111 <td>--repository REPO</td>
3110 <td>repository root directory or name of overlay bundle file</td></tr>
3112 <td>repository root directory or name of overlay bundle file</td></tr>
3111 <tr><td></td>
3113 <tr><td></td>
3112 <td>--cwd DIR</td>
3114 <td>--cwd DIR</td>
3113 <td>change working directory</td></tr>
3115 <td>change working directory</td></tr>
3114 <tr><td>-y</td>
3116 <tr><td>-y</td>
3115 <td>--noninteractive</td>
3117 <td>--noninteractive</td>
3116 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3118 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3117 <tr><td>-q</td>
3119 <tr><td>-q</td>
3118 <td>--quiet</td>
3120 <td>--quiet</td>
3119 <td>suppress output</td></tr>
3121 <td>suppress output</td></tr>
3120 <tr><td>-v</td>
3122 <tr><td>-v</td>
3121 <td>--verbose</td>
3123 <td>--verbose</td>
3122 <td>enable additional output</td></tr>
3124 <td>enable additional output</td></tr>
3123 <tr><td></td>
3125 <tr><td></td>
3124 <td>--color TYPE</td>
3126 <td>--color TYPE</td>
3125 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3127 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3126 <tr><td></td>
3128 <tr><td></td>
3127 <td>--config CONFIG [+]</td>
3129 <td>--config CONFIG [+]</td>
3128 <td>set/override config option (use 'section.name=value')</td></tr>
3130 <td>set/override config option (use 'section.name=value')</td></tr>
3129 <tr><td></td>
3131 <tr><td></td>
3130 <td>--debug</td>
3132 <td>--debug</td>
3131 <td>enable debugging output</td></tr>
3133 <td>enable debugging output</td></tr>
3132 <tr><td></td>
3134 <tr><td></td>
3133 <td>--debugger</td>
3135 <td>--debugger</td>
3134 <td>start debugger</td></tr>
3136 <td>start debugger</td></tr>
3135 <tr><td></td>
3137 <tr><td></td>
3136 <td>--encoding ENCODE</td>
3138 <td>--encoding ENCODE</td>
3137 <td>set the charset encoding (default: ascii)</td></tr>
3139 <td>set the charset encoding (default: ascii)</td></tr>
3138 <tr><td></td>
3140 <tr><td></td>
3139 <td>--encodingmode MODE</td>
3141 <td>--encodingmode MODE</td>
3140 <td>set the charset encoding mode (default: strict)</td></tr>
3142 <td>set the charset encoding mode (default: strict)</td></tr>
3141 <tr><td></td>
3143 <tr><td></td>
3142 <td>--traceback</td>
3144 <td>--traceback</td>
3143 <td>always print a traceback on exception</td></tr>
3145 <td>always print a traceback on exception</td></tr>
3144 <tr><td></td>
3146 <tr><td></td>
3145 <td>--time</td>
3147 <td>--time</td>
3146 <td>time how long the command takes</td></tr>
3148 <td>time how long the command takes</td></tr>
3147 <tr><td></td>
3149 <tr><td></td>
3148 <td>--profile</td>
3150 <td>--profile</td>
3149 <td>print command execution profile</td></tr>
3151 <td>print command execution profile</td></tr>
3150 <tr><td></td>
3152 <tr><td></td>
3151 <td>--version</td>
3153 <td>--version</td>
3152 <td>output version information and exit</td></tr>
3154 <td>output version information and exit</td></tr>
3153 <tr><td>-h</td>
3155 <tr><td>-h</td>
3154 <td>--help</td>
3156 <td>--help</td>
3155 <td>display help and exit</td></tr>
3157 <td>display help and exit</td></tr>
3156 <tr><td></td>
3158 <tr><td></td>
3157 <td>--hidden</td>
3159 <td>--hidden</td>
3158 <td>consider hidden changesets</td></tr>
3160 <td>consider hidden changesets</td></tr>
3159 <tr><td></td>
3161 <tr><td></td>
3160 <td>--pager TYPE</td>
3162 <td>--pager TYPE</td>
3161 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3163 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3162 </table>
3164 </table>
3163
3165
3164 </div>
3166 </div>
3165 </div>
3167 </div>
3166 </div>
3168 </div>
3167
3169
3168
3170
3169
3171
3170 </body>
3172 </body>
3171 </html>
3173 </html>
3172
3174
3173
3175
3174 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3176 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3175 200 Script output follows
3177 200 Script output follows
3176
3178
3177 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3179 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3178 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3180 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3179 <head>
3181 <head>
3180 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3182 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3181 <meta name="robots" content="index, nofollow" />
3183 <meta name="robots" content="index, nofollow" />
3182 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3184 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3183 <script type="text/javascript" src="/static/mercurial.js"></script>
3185 <script type="text/javascript" src="/static/mercurial.js"></script>
3184
3186
3185 <title>Help: dates</title>
3187 <title>Help: dates</title>
3186 </head>
3188 </head>
3187 <body>
3189 <body>
3188
3190
3189 <div class="container">
3191 <div class="container">
3190 <div class="menu">
3192 <div class="menu">
3191 <div class="logo">
3193 <div class="logo">
3192 <a href="https://mercurial-scm.org/">
3194 <a href="https://mercurial-scm.org/">
3193 <img src="/static/hglogo.png" alt="mercurial" /></a>
3195 <img src="/static/hglogo.png" alt="mercurial" /></a>
3194 </div>
3196 </div>
3195 <ul>
3197 <ul>
3196 <li><a href="/shortlog">log</a></li>
3198 <li><a href="/shortlog">log</a></li>
3197 <li><a href="/graph">graph</a></li>
3199 <li><a href="/graph">graph</a></li>
3198 <li><a href="/tags">tags</a></li>
3200 <li><a href="/tags">tags</a></li>
3199 <li><a href="/bookmarks">bookmarks</a></li>
3201 <li><a href="/bookmarks">bookmarks</a></li>
3200 <li><a href="/branches">branches</a></li>
3202 <li><a href="/branches">branches</a></li>
3201 </ul>
3203 </ul>
3202 <ul>
3204 <ul>
3203 <li class="active"><a href="/help">help</a></li>
3205 <li class="active"><a href="/help">help</a></li>
3204 </ul>
3206 </ul>
3205 </div>
3207 </div>
3206
3208
3207 <div class="main">
3209 <div class="main">
3208 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3210 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3209 <h3>Help: dates</h3>
3211 <h3>Help: dates</h3>
3210
3212
3211 <form class="search" action="/log">
3213 <form class="search" action="/log">
3212
3214
3213 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3215 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3214 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3216 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3215 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3217 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3216 </form>
3218 </form>
3217 <div id="doc">
3219 <div id="doc">
3218 <h1>Date Formats</h1>
3220 <h1>Date Formats</h1>
3219 <p>
3221 <p>
3220 Some commands allow the user to specify a date, e.g.:
3222 Some commands allow the user to specify a date, e.g.:
3221 </p>
3223 </p>
3222 <ul>
3224 <ul>
3223 <li> backout, commit, import, tag: Specify the commit date.
3225 <li> backout, commit, import, tag: Specify the commit date.
3224 <li> log, revert, update: Select revision(s) by date.
3226 <li> log, revert, update: Select revision(s) by date.
3225 </ul>
3227 </ul>
3226 <p>
3228 <p>
3227 Many date formats are valid. Here are some examples:
3229 Many date formats are valid. Here are some examples:
3228 </p>
3230 </p>
3229 <ul>
3231 <ul>
3230 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3232 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3231 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3233 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3232 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3234 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3233 <li> &quot;Dec 6&quot; (midnight)
3235 <li> &quot;Dec 6&quot; (midnight)
3234 <li> &quot;13:18&quot; (today assumed)
3236 <li> &quot;13:18&quot; (today assumed)
3235 <li> &quot;3:39&quot; (3:39AM assumed)
3237 <li> &quot;3:39&quot; (3:39AM assumed)
3236 <li> &quot;3:39pm&quot; (15:39)
3238 <li> &quot;3:39pm&quot; (15:39)
3237 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3239 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3238 <li> &quot;2006-12-6 13:18&quot;
3240 <li> &quot;2006-12-6 13:18&quot;
3239 <li> &quot;2006-12-6&quot;
3241 <li> &quot;2006-12-6&quot;
3240 <li> &quot;12-6&quot;
3242 <li> &quot;12-6&quot;
3241 <li> &quot;12/6&quot;
3243 <li> &quot;12/6&quot;
3242 <li> &quot;12/6/6&quot; (Dec 6 2006)
3244 <li> &quot;12/6/6&quot; (Dec 6 2006)
3243 <li> &quot;today&quot; (midnight)
3245 <li> &quot;today&quot; (midnight)
3244 <li> &quot;yesterday&quot; (midnight)
3246 <li> &quot;yesterday&quot; (midnight)
3245 <li> &quot;now&quot; - right now
3247 <li> &quot;now&quot; - right now
3246 </ul>
3248 </ul>
3247 <p>
3249 <p>
3248 Lastly, there is Mercurial's internal format:
3250 Lastly, there is Mercurial's internal format:
3249 </p>
3251 </p>
3250 <ul>
3252 <ul>
3251 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3253 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3252 </ul>
3254 </ul>
3253 <p>
3255 <p>
3254 This is the internal representation format for dates. The first number
3256 This is the internal representation format for dates. The first number
3255 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3257 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3256 second is the offset of the local timezone, in seconds west of UTC
3258 second is the offset of the local timezone, in seconds west of UTC
3257 (negative if the timezone is east of UTC).
3259 (negative if the timezone is east of UTC).
3258 </p>
3260 </p>
3259 <p>
3261 <p>
3260 The log command also accepts date ranges:
3262 The log command also accepts date ranges:
3261 </p>
3263 </p>
3262 <ul>
3264 <ul>
3263 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3265 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3264 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3266 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3265 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3267 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3266 <li> &quot;-DAYS&quot; - within a given number of days of today
3268 <li> &quot;-DAYS&quot; - within a given number of days of today
3267 </ul>
3269 </ul>
3268
3270
3269 </div>
3271 </div>
3270 </div>
3272 </div>
3271 </div>
3273 </div>
3272
3274
3273
3275
3274
3276
3275 </body>
3277 </body>
3276 </html>
3278 </html>
3277
3279
3278
3280
3279 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3281 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3280 200 Script output follows
3282 200 Script output follows
3281
3283
3282 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3284 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3283 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3285 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3284 <head>
3286 <head>
3285 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3287 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3286 <meta name="robots" content="index, nofollow" />
3288 <meta name="robots" content="index, nofollow" />
3287 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3289 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3288 <script type="text/javascript" src="/static/mercurial.js"></script>
3290 <script type="text/javascript" src="/static/mercurial.js"></script>
3289
3291
3290 <title>Help: pager</title>
3292 <title>Help: pager</title>
3291 </head>
3293 </head>
3292 <body>
3294 <body>
3293
3295
3294 <div class="container">
3296 <div class="container">
3295 <div class="menu">
3297 <div class="menu">
3296 <div class="logo">
3298 <div class="logo">
3297 <a href="https://mercurial-scm.org/">
3299 <a href="https://mercurial-scm.org/">
3298 <img src="/static/hglogo.png" alt="mercurial" /></a>
3300 <img src="/static/hglogo.png" alt="mercurial" /></a>
3299 </div>
3301 </div>
3300 <ul>
3302 <ul>
3301 <li><a href="/shortlog">log</a></li>
3303 <li><a href="/shortlog">log</a></li>
3302 <li><a href="/graph">graph</a></li>
3304 <li><a href="/graph">graph</a></li>
3303 <li><a href="/tags">tags</a></li>
3305 <li><a href="/tags">tags</a></li>
3304 <li><a href="/bookmarks">bookmarks</a></li>
3306 <li><a href="/bookmarks">bookmarks</a></li>
3305 <li><a href="/branches">branches</a></li>
3307 <li><a href="/branches">branches</a></li>
3306 </ul>
3308 </ul>
3307 <ul>
3309 <ul>
3308 <li class="active"><a href="/help">help</a></li>
3310 <li class="active"><a href="/help">help</a></li>
3309 </ul>
3311 </ul>
3310 </div>
3312 </div>
3311
3313
3312 <div class="main">
3314 <div class="main">
3313 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3315 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3314 <h3>Help: pager</h3>
3316 <h3>Help: pager</h3>
3315
3317
3316 <form class="search" action="/log">
3318 <form class="search" action="/log">
3317
3319
3318 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3320 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3319 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3321 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3320 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3322 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3321 </form>
3323 </form>
3322 <div id="doc">
3324 <div id="doc">
3323 <h1>Pager Support</h1>
3325 <h1>Pager Support</h1>
3324 <p>
3326 <p>
3325 Some Mercurial commands can produce a lot of output, and Mercurial will
3327 Some Mercurial commands can produce a lot of output, and Mercurial will
3326 attempt to use a pager to make those commands more pleasant.
3328 attempt to use a pager to make those commands more pleasant.
3327 </p>
3329 </p>
3328 <p>
3330 <p>
3329 To set the pager that should be used, set the application variable:
3331 To set the pager that should be used, set the application variable:
3330 </p>
3332 </p>
3331 <pre>
3333 <pre>
3332 [pager]
3334 [pager]
3333 pager = less -FRX
3335 pager = less -FRX
3334 </pre>
3336 </pre>
3335 <p>
3337 <p>
3336 If no pager is set in the user or repository configuration, Mercurial uses the
3338 If no pager is set in the user or repository configuration, Mercurial uses the
3337 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3339 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3338 or system configuration is used. If none of these are set, a default pager will
3340 or system configuration is used. If none of these are set, a default pager will
3339 be used, typically 'less' on Unix and 'more' on Windows.
3341 be used, typically 'less' on Unix and 'more' on Windows.
3340 </p>
3342 </p>
3341 <p>
3343 <p>
3342 You can disable the pager for certain commands by adding them to the
3344 You can disable the pager for certain commands by adding them to the
3343 pager.ignore list:
3345 pager.ignore list:
3344 </p>
3346 </p>
3345 <pre>
3347 <pre>
3346 [pager]
3348 [pager]
3347 ignore = version, help, update
3349 ignore = version, help, update
3348 </pre>
3350 </pre>
3349 <p>
3351 <p>
3350 To ignore global commands like 'hg version' or 'hg help', you have
3352 To ignore global commands like 'hg version' or 'hg help', you have
3351 to specify them in your user configuration file.
3353 to specify them in your user configuration file.
3352 </p>
3354 </p>
3353 <p>
3355 <p>
3354 To control whether the pager is used at all for an individual command,
3356 To control whether the pager is used at all for an individual command,
3355 you can use --pager=&lt;value&gt;:
3357 you can use --pager=&lt;value&gt;:
3356 </p>
3358 </p>
3357 <ul>
3359 <ul>
3358 <li> use as needed: 'auto'.
3360 <li> use as needed: 'auto'.
3359 <li> require the pager: 'yes' or 'on'.
3361 <li> require the pager: 'yes' or 'on'.
3360 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3362 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3361 </ul>
3363 </ul>
3362 <p>
3364 <p>
3363 To globally turn off all attempts to use a pager, set:
3365 To globally turn off all attempts to use a pager, set:
3364 </p>
3366 </p>
3365 <pre>
3367 <pre>
3366 [ui]
3368 [ui]
3367 paginate = never
3369 paginate = never
3368 </pre>
3370 </pre>
3369 <p>
3371 <p>
3370 which will prevent the pager from running.
3372 which will prevent the pager from running.
3371 </p>
3373 </p>
3372
3374
3373 </div>
3375 </div>
3374 </div>
3376 </div>
3375 </div>
3377 </div>
3376
3378
3377
3379
3378
3380
3379 </body>
3381 </body>
3380 </html>
3382 </html>
3381
3383
3382
3384
3383 Sub-topic indexes rendered properly
3385 Sub-topic indexes rendered properly
3384
3386
3385 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3387 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3386 200 Script output follows
3388 200 Script output follows
3387
3389
3388 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3390 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3389 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3391 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3390 <head>
3392 <head>
3391 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3393 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3392 <meta name="robots" content="index, nofollow" />
3394 <meta name="robots" content="index, nofollow" />
3393 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3395 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3394 <script type="text/javascript" src="/static/mercurial.js"></script>
3396 <script type="text/javascript" src="/static/mercurial.js"></script>
3395
3397
3396 <title>Help: internals</title>
3398 <title>Help: internals</title>
3397 </head>
3399 </head>
3398 <body>
3400 <body>
3399
3401
3400 <div class="container">
3402 <div class="container">
3401 <div class="menu">
3403 <div class="menu">
3402 <div class="logo">
3404 <div class="logo">
3403 <a href="https://mercurial-scm.org/">
3405 <a href="https://mercurial-scm.org/">
3404 <img src="/static/hglogo.png" alt="mercurial" /></a>
3406 <img src="/static/hglogo.png" alt="mercurial" /></a>
3405 </div>
3407 </div>
3406 <ul>
3408 <ul>
3407 <li><a href="/shortlog">log</a></li>
3409 <li><a href="/shortlog">log</a></li>
3408 <li><a href="/graph">graph</a></li>
3410 <li><a href="/graph">graph</a></li>
3409 <li><a href="/tags">tags</a></li>
3411 <li><a href="/tags">tags</a></li>
3410 <li><a href="/bookmarks">bookmarks</a></li>
3412 <li><a href="/bookmarks">bookmarks</a></li>
3411 <li><a href="/branches">branches</a></li>
3413 <li><a href="/branches">branches</a></li>
3412 </ul>
3414 </ul>
3413 <ul>
3415 <ul>
3414 <li><a href="/help">help</a></li>
3416 <li><a href="/help">help</a></li>
3415 </ul>
3417 </ul>
3416 </div>
3418 </div>
3417
3419
3418 <div class="main">
3420 <div class="main">
3419 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3421 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3420
3422
3421 <form class="search" action="/log">
3423 <form class="search" action="/log">
3422
3424
3423 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3425 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3424 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3426 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3425 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3427 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3426 </form>
3428 </form>
3427 <table class="bigtable">
3429 <table class="bigtable">
3428 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3430 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3429
3431
3430 <tr><td>
3432 <tr><td>
3431 <a href="/help/internals.bundle2">
3433 <a href="/help/internals.bundle2">
3432 bundle2
3434 bundle2
3433 </a>
3435 </a>
3434 </td><td>
3436 </td><td>
3435 Bundle2
3437 Bundle2
3436 </td></tr>
3438 </td></tr>
3437 <tr><td>
3439 <tr><td>
3438 <a href="/help/internals.bundles">
3440 <a href="/help/internals.bundles">
3439 bundles
3441 bundles
3440 </a>
3442 </a>
3441 </td><td>
3443 </td><td>
3442 Bundles
3444 Bundles
3443 </td></tr>
3445 </td></tr>
3444 <tr><td>
3446 <tr><td>
3445 <a href="/help/internals.cbor">
3447 <a href="/help/internals.cbor">
3446 cbor
3448 cbor
3447 </a>
3449 </a>
3448 </td><td>
3450 </td><td>
3449 CBOR
3451 CBOR
3450 </td></tr>
3452 </td></tr>
3451 <tr><td>
3453 <tr><td>
3452 <a href="/help/internals.censor">
3454 <a href="/help/internals.censor">
3453 censor
3455 censor
3454 </a>
3456 </a>
3455 </td><td>
3457 </td><td>
3456 Censor
3458 Censor
3457 </td></tr>
3459 </td></tr>
3458 <tr><td>
3460 <tr><td>
3459 <a href="/help/internals.changegroups">
3461 <a href="/help/internals.changegroups">
3460 changegroups
3462 changegroups
3461 </a>
3463 </a>
3462 </td><td>
3464 </td><td>
3463 Changegroups
3465 Changegroups
3464 </td></tr>
3466 </td></tr>
3465 <tr><td>
3467 <tr><td>
3466 <a href="/help/internals.config">
3468 <a href="/help/internals.config">
3467 config
3469 config
3468 </a>
3470 </a>
3469 </td><td>
3471 </td><td>
3470 Config Registrar
3472 Config Registrar
3471 </td></tr>
3473 </td></tr>
3472 <tr><td>
3474 <tr><td>
3473 <a href="/help/internals.extensions">
3475 <a href="/help/internals.extensions">
3474 extensions
3476 extensions
3475 </a>
3477 </a>
3476 </td><td>
3478 </td><td>
3477 Extension API
3479 Extension API
3478 </td></tr>
3480 </td></tr>
3479 <tr><td>
3481 <tr><td>
3480 <a href="/help/internals.mergestate">
3482 <a href="/help/internals.mergestate">
3481 mergestate
3483 mergestate
3482 </a>
3484 </a>
3483 </td><td>
3485 </td><td>
3484 Mergestate
3486 Mergestate
3485 </td></tr>
3487 </td></tr>
3486 <tr><td>
3488 <tr><td>
3487 <a href="/help/internals.requirements">
3489 <a href="/help/internals.requirements">
3488 requirements
3490 requirements
3489 </a>
3491 </a>
3490 </td><td>
3492 </td><td>
3491 Repository Requirements
3493 Repository Requirements
3492 </td></tr>
3494 </td></tr>
3493 <tr><td>
3495 <tr><td>
3494 <a href="/help/internals.revlogs">
3496 <a href="/help/internals.revlogs">
3495 revlogs
3497 revlogs
3496 </a>
3498 </a>
3497 </td><td>
3499 </td><td>
3498 Revision Logs
3500 Revision Logs
3499 </td></tr>
3501 </td></tr>
3500 <tr><td>
3502 <tr><td>
3501 <a href="/help/internals.wireprotocol">
3503 <a href="/help/internals.wireprotocol">
3502 wireprotocol
3504 wireprotocol
3503 </a>
3505 </a>
3504 </td><td>
3506 </td><td>
3505 Wire Protocol
3507 Wire Protocol
3506 </td></tr>
3508 </td></tr>
3507 <tr><td>
3509 <tr><td>
3508 <a href="/help/internals.wireprotocolrpc">
3510 <a href="/help/internals.wireprotocolrpc">
3509 wireprotocolrpc
3511 wireprotocolrpc
3510 </a>
3512 </a>
3511 </td><td>
3513 </td><td>
3512 Wire Protocol RPC
3514 Wire Protocol RPC
3513 </td></tr>
3515 </td></tr>
3514 <tr><td>
3516 <tr><td>
3515 <a href="/help/internals.wireprotocolv2">
3517 <a href="/help/internals.wireprotocolv2">
3516 wireprotocolv2
3518 wireprotocolv2
3517 </a>
3519 </a>
3518 </td><td>
3520 </td><td>
3519 Wire Protocol Version 2
3521 Wire Protocol Version 2
3520 </td></tr>
3522 </td></tr>
3521
3523
3522
3524
3523
3525
3524
3526
3525
3527
3526 </table>
3528 </table>
3527 </div>
3529 </div>
3528 </div>
3530 </div>
3529
3531
3530
3532
3531
3533
3532 </body>
3534 </body>
3533 </html>
3535 </html>
3534
3536
3535
3537
3536 Sub-topic topics rendered properly
3538 Sub-topic topics rendered properly
3537
3539
3538 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3540 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3539 200 Script output follows
3541 200 Script output follows
3540
3542
3541 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3543 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3542 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3544 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3543 <head>
3545 <head>
3544 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3546 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3545 <meta name="robots" content="index, nofollow" />
3547 <meta name="robots" content="index, nofollow" />
3546 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3548 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3547 <script type="text/javascript" src="/static/mercurial.js"></script>
3549 <script type="text/javascript" src="/static/mercurial.js"></script>
3548
3550
3549 <title>Help: internals.changegroups</title>
3551 <title>Help: internals.changegroups</title>
3550 </head>
3552 </head>
3551 <body>
3553 <body>
3552
3554
3553 <div class="container">
3555 <div class="container">
3554 <div class="menu">
3556 <div class="menu">
3555 <div class="logo">
3557 <div class="logo">
3556 <a href="https://mercurial-scm.org/">
3558 <a href="https://mercurial-scm.org/">
3557 <img src="/static/hglogo.png" alt="mercurial" /></a>
3559 <img src="/static/hglogo.png" alt="mercurial" /></a>
3558 </div>
3560 </div>
3559 <ul>
3561 <ul>
3560 <li><a href="/shortlog">log</a></li>
3562 <li><a href="/shortlog">log</a></li>
3561 <li><a href="/graph">graph</a></li>
3563 <li><a href="/graph">graph</a></li>
3562 <li><a href="/tags">tags</a></li>
3564 <li><a href="/tags">tags</a></li>
3563 <li><a href="/bookmarks">bookmarks</a></li>
3565 <li><a href="/bookmarks">bookmarks</a></li>
3564 <li><a href="/branches">branches</a></li>
3566 <li><a href="/branches">branches</a></li>
3565 </ul>
3567 </ul>
3566 <ul>
3568 <ul>
3567 <li class="active"><a href="/help">help</a></li>
3569 <li class="active"><a href="/help">help</a></li>
3568 </ul>
3570 </ul>
3569 </div>
3571 </div>
3570
3572
3571 <div class="main">
3573 <div class="main">
3572 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3574 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3573 <h3>Help: internals.changegroups</h3>
3575 <h3>Help: internals.changegroups</h3>
3574
3576
3575 <form class="search" action="/log">
3577 <form class="search" action="/log">
3576
3578
3577 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3579 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3578 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3580 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3579 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3581 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3580 </form>
3582 </form>
3581 <div id="doc">
3583 <div id="doc">
3582 <h1>Changegroups</h1>
3584 <h1>Changegroups</h1>
3583 <p>
3585 <p>
3584 Changegroups are representations of repository revlog data, specifically
3586 Changegroups are representations of repository revlog data, specifically
3585 the changelog data, root/flat manifest data, treemanifest data, and
3587 the changelog data, root/flat manifest data, treemanifest data, and
3586 filelogs.
3588 filelogs.
3587 </p>
3589 </p>
3588 <p>
3590 <p>
3589 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3591 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3590 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3592 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3591 only difference being an additional item in the *delta header*. Version
3593 only difference being an additional item in the *delta header*. Version
3592 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3594 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3593 exchanging treemanifests (enabled by setting an option on the
3595 exchanging treemanifests (enabled by setting an option on the
3594 &quot;changegroup&quot; part in the bundle2).
3596 &quot;changegroup&quot; part in the bundle2).
3595 </p>
3597 </p>
3596 <p>
3598 <p>
3597 Changegroups when not exchanging treemanifests consist of 3 logical
3599 Changegroups when not exchanging treemanifests consist of 3 logical
3598 segments:
3600 segments:
3599 </p>
3601 </p>
3600 <pre>
3602 <pre>
3601 +---------------------------------+
3603 +---------------------------------+
3602 | | | |
3604 | | | |
3603 | changeset | manifest | filelogs |
3605 | changeset | manifest | filelogs |
3604 | | | |
3606 | | | |
3605 | | | |
3607 | | | |
3606 +---------------------------------+
3608 +---------------------------------+
3607 </pre>
3609 </pre>
3608 <p>
3610 <p>
3609 When exchanging treemanifests, there are 4 logical segments:
3611 When exchanging treemanifests, there are 4 logical segments:
3610 </p>
3612 </p>
3611 <pre>
3613 <pre>
3612 +-------------------------------------------------+
3614 +-------------------------------------------------+
3613 | | | | |
3615 | | | | |
3614 | changeset | root | treemanifests | filelogs |
3616 | changeset | root | treemanifests | filelogs |
3615 | | manifest | | |
3617 | | manifest | | |
3616 | | | | |
3618 | | | | |
3617 +-------------------------------------------------+
3619 +-------------------------------------------------+
3618 </pre>
3620 </pre>
3619 <p>
3621 <p>
3620 The principle building block of each segment is a *chunk*. A *chunk*
3622 The principle building block of each segment is a *chunk*. A *chunk*
3621 is a framed piece of data:
3623 is a framed piece of data:
3622 </p>
3624 </p>
3623 <pre>
3625 <pre>
3624 +---------------------------------------+
3626 +---------------------------------------+
3625 | | |
3627 | | |
3626 | length | data |
3628 | length | data |
3627 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3629 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3628 | | |
3630 | | |
3629 +---------------------------------------+
3631 +---------------------------------------+
3630 </pre>
3632 </pre>
3631 <p>
3633 <p>
3632 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3634 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3633 integer indicating the length of the entire chunk (including the length field
3635 integer indicating the length of the entire chunk (including the length field
3634 itself).
3636 itself).
3635 </p>
3637 </p>
3636 <p>
3638 <p>
3637 There is a special case chunk that has a value of 0 for the length
3639 There is a special case chunk that has a value of 0 for the length
3638 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3640 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3639 </p>
3641 </p>
3640 <h2>Delta Groups</h2>
3642 <h2>Delta Groups</h2>
3641 <p>
3643 <p>
3642 A *delta group* expresses the content of a revlog as a series of deltas,
3644 A *delta group* expresses the content of a revlog as a series of deltas,
3643 or patches against previous revisions.
3645 or patches against previous revisions.
3644 </p>
3646 </p>
3645 <p>
3647 <p>
3646 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3648 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3647 to signal the end of the delta group:
3649 to signal the end of the delta group:
3648 </p>
3650 </p>
3649 <pre>
3651 <pre>
3650 +------------------------------------------------------------------------+
3652 +------------------------------------------------------------------------+
3651 | | | | | |
3653 | | | | | |
3652 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3654 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3653 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3655 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3654 | | | | | |
3656 | | | | | |
3655 +------------------------------------------------------------------------+
3657 +------------------------------------------------------------------------+
3656 </pre>
3658 </pre>
3657 <p>
3659 <p>
3658 Each *chunk*'s data consists of the following:
3660 Each *chunk*'s data consists of the following:
3659 </p>
3661 </p>
3660 <pre>
3662 <pre>
3661 +---------------------------------------+
3663 +---------------------------------------+
3662 | | |
3664 | | |
3663 | delta header | delta data |
3665 | delta header | delta data |
3664 | (various by version) | (various) |
3666 | (various by version) | (various) |
3665 | | |
3667 | | |
3666 +---------------------------------------+
3668 +---------------------------------------+
3667 </pre>
3669 </pre>
3668 <p>
3670 <p>
3669 The *delta data* is a series of *delta*s that describe a diff from an existing
3671 The *delta data* is a series of *delta*s that describe a diff from an existing
3670 entry (either that the recipient already has, or previously specified in the
3672 entry (either that the recipient already has, or previously specified in the
3671 bundle/changegroup).
3673 bundle/changegroup).
3672 </p>
3674 </p>
3673 <p>
3675 <p>
3674 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3676 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3675 &quot;3&quot; of the changegroup format.
3677 &quot;3&quot; of the changegroup format.
3676 </p>
3678 </p>
3677 <p>
3679 <p>
3678 Version 1 (headerlen=80):
3680 Version 1 (headerlen=80):
3679 </p>
3681 </p>
3680 <pre>
3682 <pre>
3681 +------------------------------------------------------+
3683 +------------------------------------------------------+
3682 | | | | |
3684 | | | | |
3683 | node | p1 node | p2 node | link node |
3685 | node | p1 node | p2 node | link node |
3684 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3686 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3685 | | | | |
3687 | | | | |
3686 +------------------------------------------------------+
3688 +------------------------------------------------------+
3687 </pre>
3689 </pre>
3688 <p>
3690 <p>
3689 Version 2 (headerlen=100):
3691 Version 2 (headerlen=100):
3690 </p>
3692 </p>
3691 <pre>
3693 <pre>
3692 +------------------------------------------------------------------+
3694 +------------------------------------------------------------------+
3693 | | | | | |
3695 | | | | | |
3694 | node | p1 node | p2 node | base node | link node |
3696 | node | p1 node | p2 node | base node | link node |
3695 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3697 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3696 | | | | | |
3698 | | | | | |
3697 +------------------------------------------------------------------+
3699 +------------------------------------------------------------------+
3698 </pre>
3700 </pre>
3699 <p>
3701 <p>
3700 Version 3 (headerlen=102):
3702 Version 3 (headerlen=102):
3701 </p>
3703 </p>
3702 <pre>
3704 <pre>
3703 +------------------------------------------------------------------------------+
3705 +------------------------------------------------------------------------------+
3704 | | | | | | |
3706 | | | | | | |
3705 | node | p1 node | p2 node | base node | link node | flags |
3707 | node | p1 node | p2 node | base node | link node | flags |
3706 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3708 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3707 | | | | | | |
3709 | | | | | | |
3708 +------------------------------------------------------------------------------+
3710 +------------------------------------------------------------------------------+
3709 </pre>
3711 </pre>
3710 <p>
3712 <p>
3711 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3713 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3712 series of *delta*s, densely packed (no separators). These deltas describe a diff
3714 series of *delta*s, densely packed (no separators). These deltas describe a diff
3713 from an existing entry (either that the recipient already has, or previously
3715 from an existing entry (either that the recipient already has, or previously
3714 specified in the bundle/changegroup). The format is described more fully in
3716 specified in the bundle/changegroup). The format is described more fully in
3715 &quot;hg help internals.bdiff&quot;, but briefly:
3717 &quot;hg help internals.bdiff&quot;, but briefly:
3716 </p>
3718 </p>
3717 <pre>
3719 <pre>
3718 +---------------------------------------------------------------+
3720 +---------------------------------------------------------------+
3719 | | | | |
3721 | | | | |
3720 | start offset | end offset | new length | content |
3722 | start offset | end offset | new length | content |
3721 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3723 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3722 | | | | |
3724 | | | | |
3723 +---------------------------------------------------------------+
3725 +---------------------------------------------------------------+
3724 </pre>
3726 </pre>
3725 <p>
3727 <p>
3726 Please note that the length field in the delta data does *not* include itself.
3728 Please note that the length field in the delta data does *not* include itself.
3727 </p>
3729 </p>
3728 <p>
3730 <p>
3729 In version 1, the delta is always applied against the previous node from
3731 In version 1, the delta is always applied against the previous node from
3730 the changegroup or the first parent if this is the first entry in the
3732 the changegroup or the first parent if this is the first entry in the
3731 changegroup.
3733 changegroup.
3732 </p>
3734 </p>
3733 <p>
3735 <p>
3734 In version 2 and up, the delta base node is encoded in the entry in the
3736 In version 2 and up, the delta base node is encoded in the entry in the
3735 changegroup. This allows the delta to be expressed against any parent,
3737 changegroup. This allows the delta to be expressed against any parent,
3736 which can result in smaller deltas and more efficient encoding of data.
3738 which can result in smaller deltas and more efficient encoding of data.
3737 </p>
3739 </p>
3738 <p>
3740 <p>
3739 The *flags* field holds bitwise flags affecting the processing of revision
3741 The *flags* field holds bitwise flags affecting the processing of revision
3740 data. The following flags are defined:
3742 data. The following flags are defined:
3741 </p>
3743 </p>
3742 <dl>
3744 <dl>
3743 <dt>32768
3745 <dt>32768
3744 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3746 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3745 <dt>16384
3747 <dt>16384
3746 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3748 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3747 <dt>8192
3749 <dt>8192
3748 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3750 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3749 </dl>
3751 </dl>
3750 <p>
3752 <p>
3751 For historical reasons, the integer values are identical to revlog version 1
3753 For historical reasons, the integer values are identical to revlog version 1
3752 per-revision storage flags and correspond to bits being set in this 2-byte
3754 per-revision storage flags and correspond to bits being set in this 2-byte
3753 field. Bits were allocated starting from the most-significant bit, hence the
3755 field. Bits were allocated starting from the most-significant bit, hence the
3754 reverse ordering and allocation of these flags.
3756 reverse ordering and allocation of these flags.
3755 </p>
3757 </p>
3756 <h2>Changeset Segment</h2>
3758 <h2>Changeset Segment</h2>
3757 <p>
3759 <p>
3758 The *changeset segment* consists of a single *delta group* holding
3760 The *changeset segment* consists of a single *delta group* holding
3759 changelog data. The *empty chunk* at the end of the *delta group* denotes
3761 changelog data. The *empty chunk* at the end of the *delta group* denotes
3760 the boundary to the *manifest segment*.
3762 the boundary to the *manifest segment*.
3761 </p>
3763 </p>
3762 <h2>Manifest Segment</h2>
3764 <h2>Manifest Segment</h2>
3763 <p>
3765 <p>
3764 The *manifest segment* consists of a single *delta group* holding manifest
3766 The *manifest segment* consists of a single *delta group* holding manifest
3765 data. If treemanifests are in use, it contains only the manifest for the
3767 data. If treemanifests are in use, it contains only the manifest for the
3766 root directory of the repository. Otherwise, it contains the entire
3768 root directory of the repository. Otherwise, it contains the entire
3767 manifest data. The *empty chunk* at the end of the *delta group* denotes
3769 manifest data. The *empty chunk* at the end of the *delta group* denotes
3768 the boundary to the next segment (either the *treemanifests segment* or the
3770 the boundary to the next segment (either the *treemanifests segment* or the
3769 *filelogs segment*, depending on version and the request options).
3771 *filelogs segment*, depending on version and the request options).
3770 </p>
3772 </p>
3771 <h3>Treemanifests Segment</h3>
3773 <h3>Treemanifests Segment</h3>
3772 <p>
3774 <p>
3773 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3775 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3774 only if the 'treemanifest' param is part of the bundle2 changegroup part
3776 only if the 'treemanifest' param is part of the bundle2 changegroup part
3775 (it is not possible to use changegroup version 3 outside of bundle2).
3777 (it is not possible to use changegroup version 3 outside of bundle2).
3776 Aside from the filenames in the *treemanifests segment* containing a
3778 Aside from the filenames in the *treemanifests segment* containing a
3777 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3779 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3778 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3780 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3779 a sub-segment with filename size 0). This denotes the boundary to the
3781 a sub-segment with filename size 0). This denotes the boundary to the
3780 *filelogs segment*.
3782 *filelogs segment*.
3781 </p>
3783 </p>
3782 <h2>Filelogs Segment</h2>
3784 <h2>Filelogs Segment</h2>
3783 <p>
3785 <p>
3784 The *filelogs segment* consists of multiple sub-segments, each
3786 The *filelogs segment* consists of multiple sub-segments, each
3785 corresponding to an individual file whose data is being described:
3787 corresponding to an individual file whose data is being described:
3786 </p>
3788 </p>
3787 <pre>
3789 <pre>
3788 +--------------------------------------------------+
3790 +--------------------------------------------------+
3789 | | | | | |
3791 | | | | | |
3790 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3792 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3791 | | | | | (4 bytes) |
3793 | | | | | (4 bytes) |
3792 | | | | | |
3794 | | | | | |
3793 +--------------------------------------------------+
3795 +--------------------------------------------------+
3794 </pre>
3796 </pre>
3795 <p>
3797 <p>
3796 The final filelog sub-segment is followed by an *empty chunk* (logically,
3798 The final filelog sub-segment is followed by an *empty chunk* (logically,
3797 a sub-segment with filename size 0). This denotes the end of the segment
3799 a sub-segment with filename size 0). This denotes the end of the segment
3798 and of the overall changegroup.
3800 and of the overall changegroup.
3799 </p>
3801 </p>
3800 <p>
3802 <p>
3801 Each filelog sub-segment consists of the following:
3803 Each filelog sub-segment consists of the following:
3802 </p>
3804 </p>
3803 <pre>
3805 <pre>
3804 +------------------------------------------------------+
3806 +------------------------------------------------------+
3805 | | | |
3807 | | | |
3806 | filename length | filename | delta group |
3808 | filename length | filename | delta group |
3807 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3809 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3808 | | | |
3810 | | | |
3809 +------------------------------------------------------+
3811 +------------------------------------------------------+
3810 </pre>
3812 </pre>
3811 <p>
3813 <p>
3812 That is, a *chunk* consisting of the filename (not terminated or padded)
3814 That is, a *chunk* consisting of the filename (not terminated or padded)
3813 followed by N chunks constituting the *delta group* for this file. The
3815 followed by N chunks constituting the *delta group* for this file. The
3814 *empty chunk* at the end of each *delta group* denotes the boundary to the
3816 *empty chunk* at the end of each *delta group* denotes the boundary to the
3815 next filelog sub-segment.
3817 next filelog sub-segment.
3816 </p>
3818 </p>
3817
3819
3818 </div>
3820 </div>
3819 </div>
3821 </div>
3820 </div>
3822 </div>
3821
3823
3822
3824
3823
3825
3824 </body>
3826 </body>
3825 </html>
3827 </html>
3826
3828
3827
3829
3828 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3830 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3829 404 Not Found
3831 404 Not Found
3830
3832
3831 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3833 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3832 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3834 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3833 <head>
3835 <head>
3834 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3836 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3835 <meta name="robots" content="index, nofollow" />
3837 <meta name="robots" content="index, nofollow" />
3836 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3838 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3837 <script type="text/javascript" src="/static/mercurial.js"></script>
3839 <script type="text/javascript" src="/static/mercurial.js"></script>
3838
3840
3839 <title>test: error</title>
3841 <title>test: error</title>
3840 </head>
3842 </head>
3841 <body>
3843 <body>
3842
3844
3843 <div class="container">
3845 <div class="container">
3844 <div class="menu">
3846 <div class="menu">
3845 <div class="logo">
3847 <div class="logo">
3846 <a href="https://mercurial-scm.org/">
3848 <a href="https://mercurial-scm.org/">
3847 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3849 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3848 </div>
3850 </div>
3849 <ul>
3851 <ul>
3850 <li><a href="/shortlog">log</a></li>
3852 <li><a href="/shortlog">log</a></li>
3851 <li><a href="/graph">graph</a></li>
3853 <li><a href="/graph">graph</a></li>
3852 <li><a href="/tags">tags</a></li>
3854 <li><a href="/tags">tags</a></li>
3853 <li><a href="/bookmarks">bookmarks</a></li>
3855 <li><a href="/bookmarks">bookmarks</a></li>
3854 <li><a href="/branches">branches</a></li>
3856 <li><a href="/branches">branches</a></li>
3855 </ul>
3857 </ul>
3856 <ul>
3858 <ul>
3857 <li><a href="/help">help</a></li>
3859 <li><a href="/help">help</a></li>
3858 </ul>
3860 </ul>
3859 </div>
3861 </div>
3860
3862
3861 <div class="main">
3863 <div class="main">
3862
3864
3863 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3865 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3864 <h3>error</h3>
3866 <h3>error</h3>
3865
3867
3866
3868
3867 <form class="search" action="/log">
3869 <form class="search" action="/log">
3868
3870
3869 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3871 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3870 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3872 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3871 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3873 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3872 </form>
3874 </form>
3873
3875
3874 <div class="description">
3876 <div class="description">
3875 <p>
3877 <p>
3876 An error occurred while processing your request:
3878 An error occurred while processing your request:
3877 </p>
3879 </p>
3878 <p>
3880 <p>
3879 Not Found
3881 Not Found
3880 </p>
3882 </p>
3881 </div>
3883 </div>
3882 </div>
3884 </div>
3883 </div>
3885 </div>
3884
3886
3885
3887
3886
3888
3887 </body>
3889 </body>
3888 </html>
3890 </html>
3889
3891
3890 [1]
3892 [1]
3891
3893
3892 $ killdaemons.py
3894 $ killdaemons.py
3893
3895
3894 #endif
3896 #endif
@@ -1,827 +1,830 b''
1 setup
1 setup
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > blackbox=
5 > blackbox=
6 > mock=$TESTDIR/mockblackbox.py
6 > mock=$TESTDIR/mockblackbox.py
7 > [blackbox]
7 > [blackbox]
8 > track = command, commandfinish, tagscache
8 > track = command, commandfinish, tagscache
9 > EOF
9 > EOF
10
10
11 Helper functions:
11 Helper functions:
12
12
13 $ cacheexists() {
13 $ cacheexists() {
14 > [ -f .hg/cache/tags2-visible ] && echo "tag cache exists" || echo "no tag cache"
14 > [ -f .hg/cache/tags2-visible ] && echo "tag cache exists" || echo "no tag cache"
15 > }
15 > }
16
16
17 $ fnodescacheexists() {
17 $ fnodescacheexists() {
18 > [ -f .hg/cache/hgtagsfnodes1 ] && echo "fnodes cache exists" || echo "no fnodes cache"
18 > [ -f .hg/cache/hgtagsfnodes1 ] && echo "fnodes cache exists" || echo "no fnodes cache"
19 > }
19 > }
20
20
21 $ dumptags() {
21 $ dumptags() {
22 > rev=$1
22 > rev=$1
23 > echo "rev $rev: .hgtags:"
23 > echo "rev $rev: .hgtags:"
24 > hg cat -r$rev .hgtags
24 > hg cat -r$rev .hgtags
25 > }
25 > }
26
26
27 # XXX need to test that the tag cache works when we strip an old head
27 # XXX need to test that the tag cache works when we strip an old head
28 # and add a new one rooted off non-tip: i.e. node and rev of tip are the
28 # and add a new one rooted off non-tip: i.e. node and rev of tip are the
29 # same, but stuff has changed behind tip.
29 # same, but stuff has changed behind tip.
30
30
31 Setup:
31 Setup:
32
32
33 $ hg init t
33 $ hg init t
34 $ cd t
34 $ cd t
35 $ cacheexists
35 $ cacheexists
36 no tag cache
36 no tag cache
37 $ fnodescacheexists
37 $ fnodescacheexists
38 no fnodes cache
38 no fnodes cache
39 $ hg id
39 $ hg id
40 000000000000 tip
40 000000000000 tip
41 $ cacheexists
41 $ cacheexists
42 no tag cache
42 no tag cache
43 $ fnodescacheexists
43 $ fnodescacheexists
44 no fnodes cache
44 no fnodes cache
45 $ echo a > a
45 $ echo a > a
46 $ hg add a
46 $ hg add a
47 $ hg commit -m "test"
47 $ hg commit -m "test"
48 $ hg co
48 $ hg co
49 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 $ hg identify
50 $ hg identify
51 acb14030fe0a tip
51 acb14030fe0a tip
52 $ hg identify -r 'wdir()'
52 $ hg identify -r 'wdir()'
53 acb14030fe0a tip
53 acb14030fe0a tip
54 $ cacheexists
54 $ cacheexists
55 tag cache exists
55 tag cache exists
56 No fnodes cache because .hgtags file doesn't exist
56 No fnodes cache because .hgtags file doesn't exist
57 (this is an implementation detail)
57 (this is an implementation detail)
58 $ fnodescacheexists
58 $ fnodescacheexists
59 no fnodes cache
59 no fnodes cache
60
60
61 Try corrupting the cache
61 Try corrupting the cache
62
62
63 $ printf 'a b' > .hg/cache/tags2-visible
63 $ printf 'a b' > .hg/cache/tags2-visible
64 $ hg identify
64 $ hg identify
65 acb14030fe0a tip
65 acb14030fe0a tip
66 $ cacheexists
66 $ cacheexists
67 tag cache exists
67 tag cache exists
68 $ fnodescacheexists
68 $ fnodescacheexists
69 no fnodes cache
69 no fnodes cache
70 $ hg identify
70 $ hg identify
71 acb14030fe0a tip
71 acb14030fe0a tip
72
72
73 Create local tag with long name:
73 Create local tag with long name:
74
74
75 $ T=`hg identify --debug --id`
75 $ T=`hg identify --debug --id`
76 $ hg tag -l "This is a local tag with a really long name!"
76 $ hg tag -l "This is a local tag with a really long name!"
77 $ hg tags
77 $ hg tags
78 tip 0:acb14030fe0a
78 tip 0:acb14030fe0a
79 This is a local tag with a really long name! 0:acb14030fe0a
79 This is a local tag with a really long name! 0:acb14030fe0a
80 $ rm .hg/localtags
80 $ rm .hg/localtags
81
81
82 Create a tag behind hg's back:
82 Create a tag behind hg's back:
83
83
84 $ echo "$T first" > .hgtags
84 $ echo "$T first" > .hgtags
85 $ cat .hgtags
85 $ cat .hgtags
86 acb14030fe0a21b60322c440ad2d20cf7685a376 first
86 acb14030fe0a21b60322c440ad2d20cf7685a376 first
87 $ hg add .hgtags
87 $ hg add .hgtags
88 $ hg commit -m "add tags"
88 $ hg commit -m "add tags"
89 $ hg tags
89 $ hg tags
90 tip 1:b9154636be93
90 tip 1:b9154636be93
91 first 0:acb14030fe0a
91 first 0:acb14030fe0a
92 $ hg identify
92 $ hg identify
93 b9154636be93 tip
93 b9154636be93 tip
94
94
95 We should have a fnodes cache now that we have a real tag
95 We should have a fnodes cache now that we have a real tag
96 The cache should have an empty entry for rev 0 and a valid entry for rev 1.
96 The cache should have an empty entry for rev 0 and a valid entry for rev 1.
97
97
98
98
99 $ fnodescacheexists
99 $ fnodescacheexists
100 fnodes cache exists
100 fnodes cache exists
101 $ f --size --hexdump .hg/cache/hgtagsfnodes1
101 $ f --size --hexdump .hg/cache/hgtagsfnodes1
102 .hg/cache/hgtagsfnodes1: size=48
102 .hg/cache/hgtagsfnodes1: size=48
103 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
103 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
104 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
104 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
105 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
105 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
106 $ hg debugtagscache
107 0 acb14030fe0a21b60322c440ad2d20cf7685a376 missing/invalid
108 1 b9154636be938d3d431e75a7c906504a079bfe07 26b7b4a773e09ee3c52f510e19e05e1ff966d859
106
109
107 Repeat with cold tag cache:
110 Repeat with cold tag cache:
108
111
109 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
112 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
110 $ hg identify
113 $ hg identify
111 b9154636be93 tip
114 b9154636be93 tip
112
115
113 $ fnodescacheexists
116 $ fnodescacheexists
114 fnodes cache exists
117 fnodes cache exists
115 $ f --size --hexdump .hg/cache/hgtagsfnodes1
118 $ f --size --hexdump .hg/cache/hgtagsfnodes1
116 .hg/cache/hgtagsfnodes1: size=48
119 .hg/cache/hgtagsfnodes1: size=48
117 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
120 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
118 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
121 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
119 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
122 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
120
123
121 And again, but now unable to write tag cache or lock file:
124 And again, but now unable to write tag cache or lock file:
122
125
123 #if unix-permissions no-fsmonitor
126 #if unix-permissions no-fsmonitor
124
127
125 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
128 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
126 $ chmod 555 .hg/cache
129 $ chmod 555 .hg/cache
127 $ hg identify
130 $ hg identify
128 b9154636be93 tip
131 b9154636be93 tip
129 $ chmod 755 .hg/cache
132 $ chmod 755 .hg/cache
130
133
131 (this block should be protected by no-fsmonitor, because "chmod 555 .hg"
134 (this block should be protected by no-fsmonitor, because "chmod 555 .hg"
132 makes watchman fail at accessing to files under .hg)
135 makes watchman fail at accessing to files under .hg)
133
136
134 $ chmod 555 .hg
137 $ chmod 555 .hg
135 $ hg identify
138 $ hg identify
136 b9154636be93 tip
139 b9154636be93 tip
137 $ chmod 755 .hg
140 $ chmod 755 .hg
138 #endif
141 #endif
139
142
140 Tag cache debug info written to blackbox log
143 Tag cache debug info written to blackbox log
141
144
142 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
145 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
143 $ hg identify
146 $ hg identify
144 b9154636be93 tip
147 b9154636be93 tip
145 $ hg blackbox -l 6
148 $ hg blackbox -l 6
146 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
149 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
147 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing 48 bytes to cache/hgtagsfnodes1
150 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing 48 bytes to cache/hgtagsfnodes1
148 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/2 cache hits/lookups in * seconds (glob)
151 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/2 cache hits/lookups in * seconds (glob)
149 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
152 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
150 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
153 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
151 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
154 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
152
155
153 Failure to acquire lock results in no write
156 Failure to acquire lock results in no write
154
157
155 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
158 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
156 $ echo 'foo:1' > .hg/wlock
159 $ echo 'foo:1' > .hg/wlock
157 $ hg identify
160 $ hg identify
158 b9154636be93 tip
161 b9154636be93 tip
159 $ hg blackbox -l 6
162 $ hg blackbox -l 6
160 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
163 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
161 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> not writing .hg/cache/hgtagsfnodes1 because lock cannot be acquired
164 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> not writing .hg/cache/hgtagsfnodes1 because lock cannot be acquired
162 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/2 cache hits/lookups in * seconds (glob)
165 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/2 cache hits/lookups in * seconds (glob)
163 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
166 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
164 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
167 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
165 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
168 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
166
169
167 $ fnodescacheexists
170 $ fnodescacheexists
168 no fnodes cache
171 no fnodes cache
169
172
170 $ rm .hg/wlock
173 $ rm .hg/wlock
171
174
172 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
175 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
173 $ hg identify
176 $ hg identify
174 b9154636be93 tip
177 b9154636be93 tip
175
178
176 Create a branch:
179 Create a branch:
177
180
178 $ echo bb > a
181 $ echo bb > a
179 $ hg status
182 $ hg status
180 M a
183 M a
181 $ hg identify
184 $ hg identify
182 b9154636be93+ tip
185 b9154636be93+ tip
183 $ hg co first
186 $ hg co first
184 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
187 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
185 $ hg id
188 $ hg id
186 acb14030fe0a+ first
189 acb14030fe0a+ first
187 $ hg id -r 'wdir()'
190 $ hg id -r 'wdir()'
188 acb14030fe0a+ first
191 acb14030fe0a+ first
189 $ hg -v id
192 $ hg -v id
190 acb14030fe0a+ first
193 acb14030fe0a+ first
191 $ hg status
194 $ hg status
192 M a
195 M a
193 $ echo 1 > b
196 $ echo 1 > b
194 $ hg add b
197 $ hg add b
195 $ hg commit -m "branch"
198 $ hg commit -m "branch"
196 created new head
199 created new head
197
200
198 Creating a new commit shouldn't append the .hgtags fnodes cache until
201 Creating a new commit shouldn't append the .hgtags fnodes cache until
199 tags info is accessed
202 tags info is accessed
200
203
201 $ f --size --hexdump .hg/cache/hgtagsfnodes1
204 $ f --size --hexdump .hg/cache/hgtagsfnodes1
202 .hg/cache/hgtagsfnodes1: size=48
205 .hg/cache/hgtagsfnodes1: size=48
203 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
206 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
204 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
207 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
205 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
208 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
206
209
207 $ hg id
210 $ hg id
208 c8edf04160c7 tip
211 c8edf04160c7 tip
209
212
210 First 4 bytes of record 3 are changeset fragment
213 First 4 bytes of record 3 are changeset fragment
211
214
212 $ f --size --hexdump .hg/cache/hgtagsfnodes1
215 $ f --size --hexdump .hg/cache/hgtagsfnodes1
213 .hg/cache/hgtagsfnodes1: size=72
216 .hg/cache/hgtagsfnodes1: size=72
214 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
217 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
215 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
218 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
216 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
219 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
217 0030: c8 ed f0 41 00 00 00 00 00 00 00 00 00 00 00 00 |...A............|
220 0030: c8 ed f0 41 00 00 00 00 00 00 00 00 00 00 00 00 |...A............|
218 0040: 00 00 00 00 00 00 00 00 |........|
221 0040: 00 00 00 00 00 00 00 00 |........|
219
222
220 Merge the two heads:
223 Merge the two heads:
221
224
222 $ hg merge 1
225 $ hg merge 1
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 (branch merge, don't forget to commit)
227 (branch merge, don't forget to commit)
225 $ hg blackbox -l3
228 $ hg blackbox -l3
226 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28 (5000)> merge 1
229 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28 (5000)> merge 1
227 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> merge 1 exited 0 after * seconds (glob)
230 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> merge 1 exited 0 after * seconds (glob)
228 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l3
231 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l3
229 $ hg id
232 $ hg id
230 c8edf04160c7+b9154636be93+ tip
233 c8edf04160c7+b9154636be93+ tip
231 $ hg status
234 $ hg status
232 M .hgtags
235 M .hgtags
233 $ hg commit -m "merge"
236 $ hg commit -m "merge"
234
237
235 Create a fake head, make sure tag not visible afterwards:
238 Create a fake head, make sure tag not visible afterwards:
236
239
237 $ cp .hgtags tags
240 $ cp .hgtags tags
238 $ hg tag last
241 $ hg tag last
239 $ hg rm .hgtags
242 $ hg rm .hgtags
240 $ hg commit -m "remove"
243 $ hg commit -m "remove"
241
244
242 $ mv tags .hgtags
245 $ mv tags .hgtags
243 $ hg add .hgtags
246 $ hg add .hgtags
244 $ hg commit -m "readd"
247 $ hg commit -m "readd"
245 $
248 $
246 $ hg tags
249 $ hg tags
247 tip 6:35ff301afafe
250 tip 6:35ff301afafe
248 first 0:acb14030fe0a
251 first 0:acb14030fe0a
249
252
250 Add invalid tags:
253 Add invalid tags:
251
254
252 $ echo "spam" >> .hgtags
255 $ echo "spam" >> .hgtags
253 $ echo >> .hgtags
256 $ echo >> .hgtags
254 $ echo "foo bar" >> .hgtags
257 $ echo "foo bar" >> .hgtags
255 $ echo "a5a5 invalid" >> .hg/localtags
258 $ echo "a5a5 invalid" >> .hg/localtags
256 $ cat .hgtags
259 $ cat .hgtags
257 acb14030fe0a21b60322c440ad2d20cf7685a376 first
260 acb14030fe0a21b60322c440ad2d20cf7685a376 first
258 spam
261 spam
259
262
260 foo bar
263 foo bar
261 $ hg commit -m "tags"
264 $ hg commit -m "tags"
262
265
263 Report tag parse error on other head:
266 Report tag parse error on other head:
264
267
265 $ hg up 3
268 $ hg up 3
266 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 $ echo 'x y' >> .hgtags
270 $ echo 'x y' >> .hgtags
268 $ hg commit -m "head"
271 $ hg commit -m "head"
269 created new head
272 created new head
270
273
271 $ hg tags --debug
274 $ hg tags --debug
272 .hgtags@75d9f02dfe28, line 2: cannot parse entry
275 .hgtags@75d9f02dfe28, line 2: cannot parse entry
273 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
276 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
274 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
277 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
275 tip 8:c4be69a18c11e8bc3a5fdbb576017c25f7d84663
278 tip 8:c4be69a18c11e8bc3a5fdbb576017c25f7d84663
276 first 0:acb14030fe0a21b60322c440ad2d20cf7685a376
279 first 0:acb14030fe0a21b60322c440ad2d20cf7685a376
277 $ hg tip
280 $ hg tip
278 changeset: 8:c4be69a18c11
281 changeset: 8:c4be69a18c11
279 tag: tip
282 tag: tip
280 parent: 3:ac5e980c4dc0
283 parent: 3:ac5e980c4dc0
281 user: test
284 user: test
282 date: Thu Jan 01 00:00:00 1970 +0000
285 date: Thu Jan 01 00:00:00 1970 +0000
283 summary: head
286 summary: head
284
287
285
288
286 Test tag precedence rules:
289 Test tag precedence rules:
287
290
288 $ cd ..
291 $ cd ..
289 $ hg init t2
292 $ hg init t2
290 $ cd t2
293 $ cd t2
291 $ echo foo > foo
294 $ echo foo > foo
292 $ hg add foo
295 $ hg add foo
293 $ hg ci -m 'add foo' # rev 0
296 $ hg ci -m 'add foo' # rev 0
294 $ hg tag bar # rev 1
297 $ hg tag bar # rev 1
295 $ echo >> foo
298 $ echo >> foo
296 $ hg ci -m 'change foo 1' # rev 2
299 $ hg ci -m 'change foo 1' # rev 2
297 $ hg up -C 1
300 $ hg up -C 1
298 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
299 $ hg tag -r 1 -f bar # rev 3
302 $ hg tag -r 1 -f bar # rev 3
300 $ hg up -C 1
303 $ hg up -C 1
301 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 $ echo >> foo
305 $ echo >> foo
303 $ hg ci -m 'change foo 2' # rev 4
306 $ hg ci -m 'change foo 2' # rev 4
304 created new head
307 created new head
305 $ hg tags
308 $ hg tags
306 tip 4:0c192d7d5e6b
309 tip 4:0c192d7d5e6b
307 bar 1:78391a272241
310 bar 1:78391a272241
308
311
309 Repeat in case of cache effects:
312 Repeat in case of cache effects:
310
313
311 $ hg tags
314 $ hg tags
312 tip 4:0c192d7d5e6b
315 tip 4:0c192d7d5e6b
313 bar 1:78391a272241
316 bar 1:78391a272241
314
317
315 Detailed dump of tag info:
318 Detailed dump of tag info:
316
319
317 $ hg heads -q # expect 4, 3, 2
320 $ hg heads -q # expect 4, 3, 2
318 4:0c192d7d5e6b
321 4:0c192d7d5e6b
319 3:6fa450212aeb
322 3:6fa450212aeb
320 2:7a94127795a3
323 2:7a94127795a3
321 $ dumptags 2
324 $ dumptags 2
322 rev 2: .hgtags:
325 rev 2: .hgtags:
323 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
326 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
324 $ dumptags 3
327 $ dumptags 3
325 rev 3: .hgtags:
328 rev 3: .hgtags:
326 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
329 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
327 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
330 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
328 78391a272241d70354aa14c874552cad6b51bb42 bar
331 78391a272241d70354aa14c874552cad6b51bb42 bar
329 $ dumptags 4
332 $ dumptags 4
330 rev 4: .hgtags:
333 rev 4: .hgtags:
331 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
334 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
332
335
333 Dump cache:
336 Dump cache:
334
337
335 $ cat .hg/cache/tags2-visible
338 $ cat .hg/cache/tags2-visible
336 4 0c192d7d5e6b78a714de54a2e9627952a877e25a
339 4 0c192d7d5e6b78a714de54a2e9627952a877e25a
337 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
340 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
338 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
341 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
339 78391a272241d70354aa14c874552cad6b51bb42 bar
342 78391a272241d70354aa14c874552cad6b51bb42 bar
340
343
341 $ f --size --hexdump .hg/cache/hgtagsfnodes1
344 $ f --size --hexdump .hg/cache/hgtagsfnodes1
342 .hg/cache/hgtagsfnodes1: size=120
345 .hg/cache/hgtagsfnodes1: size=120
343 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
346 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
344 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
347 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
345 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
348 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
346 0030: 7a 94 12 77 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |z..w.....1....B(|
349 0030: 7a 94 12 77 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |z..w.....1....B(|
347 0040: 78 ee 5a 2d ad bc 94 3d 6f a4 50 21 7d 3b 71 8c |x.Z-...=o.P!};q.|
350 0040: 78 ee 5a 2d ad bc 94 3d 6f a4 50 21 7d 3b 71 8c |x.Z-...=o.P!};q.|
348 0050: 96 4e f3 7b 89 e5 50 eb da fd 57 89 e7 6c e1 b0 |.N.{..P...W..l..|
351 0050: 96 4e f3 7b 89 e5 50 eb da fd 57 89 e7 6c e1 b0 |.N.{..P...W..l..|
349 0060: 0c 19 2d 7d 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |..-}.....1....B(|
352 0060: 0c 19 2d 7d 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |..-}.....1....B(|
350 0070: 78 ee 5a 2d ad bc 94 3d |x.Z-...=|
353 0070: 78 ee 5a 2d ad bc 94 3d |x.Z-...=|
351
354
352 Corrupt the .hgtags fnodes cache
355 Corrupt the .hgtags fnodes cache
353 Extra junk data at the end should get overwritten on next cache update
356 Extra junk data at the end should get overwritten on next cache update
354
357
355 $ echo extra >> .hg/cache/hgtagsfnodes1
358 $ echo extra >> .hg/cache/hgtagsfnodes1
356 $ echo dummy1 > foo
359 $ echo dummy1 > foo
357 $ hg commit -m throwaway1
360 $ hg commit -m throwaway1
358
361
359 $ hg tags
362 $ hg tags
360 tip 5:8dbfe60eff30
363 tip 5:8dbfe60eff30
361 bar 1:78391a272241
364 bar 1:78391a272241
362
365
363 $ hg blackbox -l 6
366 $ hg blackbox -l 6
364 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags
367 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags
365 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing 24 bytes to cache/hgtagsfnodes1
368 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing 24 bytes to cache/hgtagsfnodes1
366 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> 3/4 cache hits/lookups in * seconds (glob)
369 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> 3/4 cache hits/lookups in * seconds (glob)
367 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing .hg/cache/tags2-visible with 1 tags
370 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing .hg/cache/tags2-visible with 1 tags
368 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags exited 0 after * seconds (glob)
371 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags exited 0 after * seconds (glob)
369 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> blackbox -l 6
372 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> blackbox -l 6
370
373
371 #if unix-permissions no-root
374 #if unix-permissions no-root
372 Errors writing to .hgtags fnodes cache are silently ignored
375 Errors writing to .hgtags fnodes cache are silently ignored
373
376
374 $ echo dummy2 > foo
377 $ echo dummy2 > foo
375 $ hg commit -m throwaway2
378 $ hg commit -m throwaway2
376
379
377 $ chmod a-w .hg/cache/hgtagsfnodes1
380 $ chmod a-w .hg/cache/hgtagsfnodes1
378 $ rm -f .hg/cache/tags2-visible
381 $ rm -f .hg/cache/tags2-visible
379
382
380 $ hg tags
383 $ hg tags
381 tip 6:b968051b5cf3
384 tip 6:b968051b5cf3
382 bar 1:78391a272241
385 bar 1:78391a272241
383
386
384 $ hg blackbox -l 6
387 $ hg blackbox -l 6
385 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
388 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
386 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno *] * (glob)
389 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno *] * (glob)
387 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 3/4 cache hits/lookups in * seconds (glob)
390 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 3/4 cache hits/lookups in * seconds (glob)
388 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
391 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
389 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
392 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
390 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
393 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
391
394
392 $ chmod a+w .hg/cache/hgtagsfnodes1
395 $ chmod a+w .hg/cache/hgtagsfnodes1
393
396
394 $ rm -f .hg/cache/tags2-visible
397 $ rm -f .hg/cache/tags2-visible
395 $ hg tags
398 $ hg tags
396 tip 6:b968051b5cf3
399 tip 6:b968051b5cf3
397 bar 1:78391a272241
400 bar 1:78391a272241
398
401
399 $ hg blackbox -l 6
402 $ hg blackbox -l 6
400 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
403 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
401 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing 24 bytes to cache/hgtagsfnodes1
404 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing 24 bytes to cache/hgtagsfnodes1
402 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 3/4 cache hits/lookups in * seconds (glob)
405 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 3/4 cache hits/lookups in * seconds (glob)
403 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
406 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
404 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
407 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
405 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
408 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
406
409
407 $ f --size .hg/cache/hgtagsfnodes1
410 $ f --size .hg/cache/hgtagsfnodes1
408 .hg/cache/hgtagsfnodes1: size=168
411 .hg/cache/hgtagsfnodes1: size=168
409
412
410 $ hg -q --config extensions.strip= strip -r 6 --no-backup
413 $ hg -q --config extensions.strip= strip -r 6 --no-backup
411 #endif
414 #endif
412
415
413 Stripping doesn't truncate the tags cache until new data is available
416 Stripping doesn't truncate the tags cache until new data is available
414
417
415 $ rm -f .hg/cache/hgtagsfnodes1 .hg/cache/tags2-visible
418 $ rm -f .hg/cache/hgtagsfnodes1 .hg/cache/tags2-visible
416 $ hg tags
419 $ hg tags
417 tip 5:8dbfe60eff30
420 tip 5:8dbfe60eff30
418 bar 1:78391a272241
421 bar 1:78391a272241
419
422
420 $ f --size .hg/cache/hgtagsfnodes1
423 $ f --size .hg/cache/hgtagsfnodes1
421 .hg/cache/hgtagsfnodes1: size=144
424 .hg/cache/hgtagsfnodes1: size=144
422
425
423 $ hg -q --config extensions.strip= strip -r 5 --no-backup
426 $ hg -q --config extensions.strip= strip -r 5 --no-backup
424 $ hg tags
427 $ hg tags
425 tip 4:0c192d7d5e6b
428 tip 4:0c192d7d5e6b
426 bar 1:78391a272241
429 bar 1:78391a272241
427
430
428 $ hg blackbox -l 5
431 $ hg blackbox -l 5
429 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing 24 bytes to cache/hgtagsfnodes1
432 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing 24 bytes to cache/hgtagsfnodes1
430 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> 2/4 cache hits/lookups in * seconds (glob)
433 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> 2/4 cache hits/lookups in * seconds (glob)
431 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing .hg/cache/tags2-visible with 1 tags
434 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing .hg/cache/tags2-visible with 1 tags
432 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> tags exited 0 after * seconds (glob)
435 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> tags exited 0 after * seconds (glob)
433 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> blackbox -l 5
436 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> blackbox -l 5
434
437
435 $ f --size .hg/cache/hgtagsfnodes1
438 $ f --size .hg/cache/hgtagsfnodes1
436 .hg/cache/hgtagsfnodes1: size=120
439 .hg/cache/hgtagsfnodes1: size=120
437
440
438 $ echo dummy > foo
441 $ echo dummy > foo
439 $ hg commit -m throwaway3
442 $ hg commit -m throwaway3
440
443
441 $ hg tags
444 $ hg tags
442 tip 5:035f65efb448
445 tip 5:035f65efb448
443 bar 1:78391a272241
446 bar 1:78391a272241
444
447
445 $ hg blackbox -l 6
448 $ hg blackbox -l 6
446 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags
449 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags
447 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing 24 bytes to cache/hgtagsfnodes1
450 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing 24 bytes to cache/hgtagsfnodes1
448 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> 3/4 cache hits/lookups in * seconds (glob)
451 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> 3/4 cache hits/lookups in * seconds (glob)
449 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing .hg/cache/tags2-visible with 1 tags
452 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing .hg/cache/tags2-visible with 1 tags
450 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags exited 0 after * seconds (glob)
453 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags exited 0 after * seconds (glob)
451 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> blackbox -l 6
454 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> blackbox -l 6
452 $ f --size .hg/cache/hgtagsfnodes1
455 $ f --size .hg/cache/hgtagsfnodes1
453 .hg/cache/hgtagsfnodes1: size=144
456 .hg/cache/hgtagsfnodes1: size=144
454
457
455 $ hg -q --config extensions.strip= strip -r 5 --no-backup
458 $ hg -q --config extensions.strip= strip -r 5 --no-backup
456
459
457 Test tag removal:
460 Test tag removal:
458
461
459 $ hg tag --remove bar # rev 5
462 $ hg tag --remove bar # rev 5
460 $ hg tip -vp
463 $ hg tip -vp
461 changeset: 5:5f6e8655b1c7
464 changeset: 5:5f6e8655b1c7
462 tag: tip
465 tag: tip
463 user: test
466 user: test
464 date: Thu Jan 01 00:00:00 1970 +0000
467 date: Thu Jan 01 00:00:00 1970 +0000
465 files: .hgtags
468 files: .hgtags
466 description:
469 description:
467 Removed tag bar
470 Removed tag bar
468
471
469
472
470 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
473 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
471 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
474 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
472 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
475 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
473 @@ -1,1 +1,3 @@
476 @@ -1,1 +1,3 @@
474 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
477 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
475 +78391a272241d70354aa14c874552cad6b51bb42 bar
478 +78391a272241d70354aa14c874552cad6b51bb42 bar
476 +0000000000000000000000000000000000000000 bar
479 +0000000000000000000000000000000000000000 bar
477
480
478 $ hg tags
481 $ hg tags
479 tip 5:5f6e8655b1c7
482 tip 5:5f6e8655b1c7
480 $ hg tags # again, try to expose cache bugs
483 $ hg tags # again, try to expose cache bugs
481 tip 5:5f6e8655b1c7
484 tip 5:5f6e8655b1c7
482
485
483 Remove nonexistent tag:
486 Remove nonexistent tag:
484
487
485 $ hg tag --remove foobar
488 $ hg tag --remove foobar
486 abort: tag 'foobar' does not exist
489 abort: tag 'foobar' does not exist
487 [255]
490 [255]
488 $ hg tip
491 $ hg tip
489 changeset: 5:5f6e8655b1c7
492 changeset: 5:5f6e8655b1c7
490 tag: tip
493 tag: tip
491 user: test
494 user: test
492 date: Thu Jan 01 00:00:00 1970 +0000
495 date: Thu Jan 01 00:00:00 1970 +0000
493 summary: Removed tag bar
496 summary: Removed tag bar
494
497
495
498
496 Undo a tag with rollback:
499 Undo a tag with rollback:
497
500
498 $ hg rollback # destroy rev 5 (restore bar)
501 $ hg rollback # destroy rev 5 (restore bar)
499 repository tip rolled back to revision 4 (undo commit)
502 repository tip rolled back to revision 4 (undo commit)
500 working directory now based on revision 4
503 working directory now based on revision 4
501 $ hg tags
504 $ hg tags
502 tip 4:0c192d7d5e6b
505 tip 4:0c192d7d5e6b
503 bar 1:78391a272241
506 bar 1:78391a272241
504 $ hg tags
507 $ hg tags
505 tip 4:0c192d7d5e6b
508 tip 4:0c192d7d5e6b
506 bar 1:78391a272241
509 bar 1:78391a272241
507
510
508 Test tag rank:
511 Test tag rank:
509
512
510 $ cd ..
513 $ cd ..
511 $ hg init t3
514 $ hg init t3
512 $ cd t3
515 $ cd t3
513 $ echo foo > foo
516 $ echo foo > foo
514 $ hg add foo
517 $ hg add foo
515 $ hg ci -m 'add foo' # rev 0
518 $ hg ci -m 'add foo' # rev 0
516 $ hg tag -f bar # rev 1 bar -> 0
519 $ hg tag -f bar # rev 1 bar -> 0
517 $ hg tag -f bar # rev 2 bar -> 1
520 $ hg tag -f bar # rev 2 bar -> 1
518 $ hg tag -fr 0 bar # rev 3 bar -> 0
521 $ hg tag -fr 0 bar # rev 3 bar -> 0
519 $ hg tag -fr 1 bar # rev 4 bar -> 1
522 $ hg tag -fr 1 bar # rev 4 bar -> 1
520 $ hg tag -fr 0 bar # rev 5 bar -> 0
523 $ hg tag -fr 0 bar # rev 5 bar -> 0
521 $ hg tags
524 $ hg tags
522 tip 5:85f05169d91d
525 tip 5:85f05169d91d
523 bar 0:bbd179dfa0a7
526 bar 0:bbd179dfa0a7
524 $ hg co 3
527 $ hg co 3
525 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
526 $ echo barbar > foo
529 $ echo barbar > foo
527 $ hg ci -m 'change foo' # rev 6
530 $ hg ci -m 'change foo' # rev 6
528 created new head
531 created new head
529 $ hg tags
532 $ hg tags
530 tip 6:735c3ca72986
533 tip 6:735c3ca72986
531 bar 0:bbd179dfa0a7
534 bar 0:bbd179dfa0a7
532
535
533 Don't allow moving tag without -f:
536 Don't allow moving tag without -f:
534
537
535 $ hg tag -r 3 bar
538 $ hg tag -r 3 bar
536 abort: tag 'bar' already exists (use -f to force)
539 abort: tag 'bar' already exists (use -f to force)
537 [255]
540 [255]
538 $ hg tags
541 $ hg tags
539 tip 6:735c3ca72986
542 tip 6:735c3ca72986
540 bar 0:bbd179dfa0a7
543 bar 0:bbd179dfa0a7
541
544
542 Strip 1: expose an old head:
545 Strip 1: expose an old head:
543
546
544 $ hg --config extensions.mq= strip 5
547 $ hg --config extensions.mq= strip 5
545 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
548 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
546 $ hg tags # partly stale cache
549 $ hg tags # partly stale cache
547 tip 5:735c3ca72986
550 tip 5:735c3ca72986
548 bar 1:78391a272241
551 bar 1:78391a272241
549 $ hg tags # up-to-date cache
552 $ hg tags # up-to-date cache
550 tip 5:735c3ca72986
553 tip 5:735c3ca72986
551 bar 1:78391a272241
554 bar 1:78391a272241
552
555
553 Strip 2: destroy whole branch, no old head exposed
556 Strip 2: destroy whole branch, no old head exposed
554
557
555 $ hg --config extensions.mq= strip 4
558 $ hg --config extensions.mq= strip 4
556 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
559 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
557 $ hg tags # partly stale
560 $ hg tags # partly stale
558 tip 4:735c3ca72986
561 tip 4:735c3ca72986
559 bar 0:bbd179dfa0a7
562 bar 0:bbd179dfa0a7
560 $ rm -f .hg/cache/tags2-visible
563 $ rm -f .hg/cache/tags2-visible
561 $ hg tags # cold cache
564 $ hg tags # cold cache
562 tip 4:735c3ca72986
565 tip 4:735c3ca72986
563 bar 0:bbd179dfa0a7
566 bar 0:bbd179dfa0a7
564
567
565 Test tag rank with 3 heads:
568 Test tag rank with 3 heads:
566
569
567 $ cd ..
570 $ cd ..
568 $ hg init t4
571 $ hg init t4
569 $ cd t4
572 $ cd t4
570 $ echo foo > foo
573 $ echo foo > foo
571 $ hg add
574 $ hg add
572 adding foo
575 adding foo
573 $ hg ci -m 'add foo' # rev 0
576 $ hg ci -m 'add foo' # rev 0
574 $ hg tag bar # rev 1 bar -> 0
577 $ hg tag bar # rev 1 bar -> 0
575 $ hg tag -f bar # rev 2 bar -> 1
578 $ hg tag -f bar # rev 2 bar -> 1
576 $ hg up -qC 0
579 $ hg up -qC 0
577 $ hg tag -fr 2 bar # rev 3 bar -> 2
580 $ hg tag -fr 2 bar # rev 3 bar -> 2
578 $ hg tags
581 $ hg tags
579 tip 3:197c21bbbf2c
582 tip 3:197c21bbbf2c
580 bar 2:6fa450212aeb
583 bar 2:6fa450212aeb
581 $ hg up -qC 0
584 $ hg up -qC 0
582 $ hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2
585 $ hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2
583
586
584 Bar should still point to rev 2:
587 Bar should still point to rev 2:
585
588
586 $ hg tags
589 $ hg tags
587 tip 4:3b4b14ed0202
590 tip 4:3b4b14ed0202
588 bar 2:6fa450212aeb
591 bar 2:6fa450212aeb
589
592
590 Test that removing global/local tags does not get confused when trying
593 Test that removing global/local tags does not get confused when trying
591 to remove a tag of type X which actually only exists as a type Y:
594 to remove a tag of type X which actually only exists as a type Y:
592
595
593 $ cd ..
596 $ cd ..
594 $ hg init t5
597 $ hg init t5
595 $ cd t5
598 $ cd t5
596 $ echo foo > foo
599 $ echo foo > foo
597 $ hg add
600 $ hg add
598 adding foo
601 adding foo
599 $ hg ci -m 'add foo' # rev 0
602 $ hg ci -m 'add foo' # rev 0
600
603
601 $ hg tag -r 0 -l localtag
604 $ hg tag -r 0 -l localtag
602 $ hg tag --remove localtag
605 $ hg tag --remove localtag
603 abort: tag 'localtag' is not a global tag
606 abort: tag 'localtag' is not a global tag
604 [255]
607 [255]
605 $
608 $
606 $ hg tag -r 0 globaltag
609 $ hg tag -r 0 globaltag
607 $ hg tag --remove -l globaltag
610 $ hg tag --remove -l globaltag
608 abort: tag 'globaltag' is not a local tag
611 abort: tag 'globaltag' is not a local tag
609 [255]
612 [255]
610 $ hg tags -v
613 $ hg tags -v
611 tip 1:a0b6fe111088
614 tip 1:a0b6fe111088
612 localtag 0:bbd179dfa0a7 local
615 localtag 0:bbd179dfa0a7 local
613 globaltag 0:bbd179dfa0a7
616 globaltag 0:bbd179dfa0a7
614
617
615 Templated output:
618 Templated output:
616
619
617 (immediate values)
620 (immediate values)
618
621
619 $ hg tags -T '{pad(tag, 9)} {rev}:{node} ({type})\n'
622 $ hg tags -T '{pad(tag, 9)} {rev}:{node} ({type})\n'
620 tip 1:a0b6fe111088c8c29567d3876cc466aa02927cae ()
623 tip 1:a0b6fe111088c8c29567d3876cc466aa02927cae ()
621 localtag 0:bbd179dfa0a71671c253b3ae0aa1513b60d199fa (local)
624 localtag 0:bbd179dfa0a71671c253b3ae0aa1513b60d199fa (local)
622 globaltag 0:bbd179dfa0a71671c253b3ae0aa1513b60d199fa ()
625 globaltag 0:bbd179dfa0a71671c253b3ae0aa1513b60d199fa ()
623
626
624 (ctx/revcache dependent)
627 (ctx/revcache dependent)
625
628
626 $ hg tags -T '{pad(tag, 9)} {rev} {file_adds}\n'
629 $ hg tags -T '{pad(tag, 9)} {rev} {file_adds}\n'
627 tip 1 .hgtags
630 tip 1 .hgtags
628 localtag 0 foo
631 localtag 0 foo
629 globaltag 0 foo
632 globaltag 0 foo
630
633
631 $ hg tags -T '{pad(tag, 9)} {rev}:{node|shortest}\n'
634 $ hg tags -T '{pad(tag, 9)} {rev}:{node|shortest}\n'
632 tip 1:a0b6
635 tip 1:a0b6
633 localtag 0:bbd1
636 localtag 0:bbd1
634 globaltag 0:bbd1
637 globaltag 0:bbd1
635
638
636 Test for issue3911
639 Test for issue3911
637
640
638 $ hg tag -r 0 -l localtag2
641 $ hg tag -r 0 -l localtag2
639 $ hg tag -l --remove localtag2
642 $ hg tag -l --remove localtag2
640 $ hg tags -v
643 $ hg tags -v
641 tip 1:a0b6fe111088
644 tip 1:a0b6fe111088
642 localtag 0:bbd179dfa0a7 local
645 localtag 0:bbd179dfa0a7 local
643 globaltag 0:bbd179dfa0a7
646 globaltag 0:bbd179dfa0a7
644
647
645 $ hg tag -r 1 -f localtag
648 $ hg tag -r 1 -f localtag
646 $ hg tags -v
649 $ hg tags -v
647 tip 2:5c70a037bb37
650 tip 2:5c70a037bb37
648 localtag 1:a0b6fe111088
651 localtag 1:a0b6fe111088
649 globaltag 0:bbd179dfa0a7
652 globaltag 0:bbd179dfa0a7
650
653
651 $ hg tags -v
654 $ hg tags -v
652 tip 2:5c70a037bb37
655 tip 2:5c70a037bb37
653 localtag 1:a0b6fe111088
656 localtag 1:a0b6fe111088
654 globaltag 0:bbd179dfa0a7
657 globaltag 0:bbd179dfa0a7
655
658
656 $ hg tag -r 1 localtag2
659 $ hg tag -r 1 localtag2
657 $ hg tags -v
660 $ hg tags -v
658 tip 3:bbfb8cd42be2
661 tip 3:bbfb8cd42be2
659 localtag2 1:a0b6fe111088
662 localtag2 1:a0b6fe111088
660 localtag 1:a0b6fe111088
663 localtag 1:a0b6fe111088
661 globaltag 0:bbd179dfa0a7
664 globaltag 0:bbd179dfa0a7
662
665
663 $ hg tags -v
666 $ hg tags -v
664 tip 3:bbfb8cd42be2
667 tip 3:bbfb8cd42be2
665 localtag2 1:a0b6fe111088
668 localtag2 1:a0b6fe111088
666 localtag 1:a0b6fe111088
669 localtag 1:a0b6fe111088
667 globaltag 0:bbd179dfa0a7
670 globaltag 0:bbd179dfa0a7
668
671
669 $ cd ..
672 $ cd ..
670
673
671 Create a repository with tags data to test .hgtags fnodes transfer
674 Create a repository with tags data to test .hgtags fnodes transfer
672
675
673 $ hg init tagsserver
676 $ hg init tagsserver
674 $ cd tagsserver
677 $ cd tagsserver
675 $ touch foo
678 $ touch foo
676 $ hg -q commit -A -m initial
679 $ hg -q commit -A -m initial
677 $ hg tag -m 'tag 0.1' 0.1
680 $ hg tag -m 'tag 0.1' 0.1
678 $ echo second > foo
681 $ echo second > foo
679 $ hg commit -m second
682 $ hg commit -m second
680 $ hg tag -m 'tag 0.2' 0.2
683 $ hg tag -m 'tag 0.2' 0.2
681 $ hg tags
684 $ hg tags
682 tip 3:40f0358cb314
685 tip 3:40f0358cb314
683 0.2 2:f63cc8fe54e4
686 0.2 2:f63cc8fe54e4
684 0.1 0:96ee1d7354c4
687 0.1 0:96ee1d7354c4
685 $ cd ..
688 $ cd ..
686
689
687 Cloning should pull down hgtags fnodes mappings and write the cache file
690 Cloning should pull down hgtags fnodes mappings and write the cache file
688
691
689 $ hg clone --pull tagsserver tagsclient
692 $ hg clone --pull tagsserver tagsclient
690 requesting all changes
693 requesting all changes
691 adding changesets
694 adding changesets
692 adding manifests
695 adding manifests
693 adding file changes
696 adding file changes
694 added 4 changesets with 4 changes to 2 files
697 added 4 changesets with 4 changes to 2 files
695 new changesets 96ee1d7354c4:40f0358cb314
698 new changesets 96ee1d7354c4:40f0358cb314
696 updating to branch default
699 updating to branch default
697 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
700 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
698
701
699 Missing tags2* files means the cache wasn't written through the normal mechanism.
702 Missing tags2* files means the cache wasn't written through the normal mechanism.
700
703
701 $ ls tagsclient/.hg/cache
704 $ ls tagsclient/.hg/cache
702 branch2-base
705 branch2-base
703 hgtagsfnodes1
706 hgtagsfnodes1
704 rbc-names-v1
707 rbc-names-v1
705 rbc-revs-v1
708 rbc-revs-v1
706
709
707 Cache should contain the head only, even though other nodes have tags data
710 Cache should contain the head only, even though other nodes have tags data
708
711
709 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
712 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
710 tagsclient/.hg/cache/hgtagsfnodes1: size=96
713 tagsclient/.hg/cache/hgtagsfnodes1: size=96
711 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
714 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
712 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
715 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
713 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
716 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
714 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
717 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
715 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
718 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
716 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
719 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
717
720
718 Running hg tags should produce tags2* file and not change cache
721 Running hg tags should produce tags2* file and not change cache
719
722
720 $ hg -R tagsclient tags
723 $ hg -R tagsclient tags
721 tip 3:40f0358cb314
724 tip 3:40f0358cb314
722 0.2 2:f63cc8fe54e4
725 0.2 2:f63cc8fe54e4
723 0.1 0:96ee1d7354c4
726 0.1 0:96ee1d7354c4
724
727
725 $ ls tagsclient/.hg/cache
728 $ ls tagsclient/.hg/cache
726 branch2-base
729 branch2-base
727 hgtagsfnodes1
730 hgtagsfnodes1
728 rbc-names-v1
731 rbc-names-v1
729 rbc-revs-v1
732 rbc-revs-v1
730 tags2-visible
733 tags2-visible
731
734
732 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
735 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
733 tagsclient/.hg/cache/hgtagsfnodes1: size=96
736 tagsclient/.hg/cache/hgtagsfnodes1: size=96
734 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
737 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
735 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
738 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
736 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
739 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
737 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
740 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
738 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
741 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
739 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
742 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
740
743
741 Check that the bundle includes cache data
744 Check that the bundle includes cache data
742
745
743 $ hg -R tagsclient bundle --all ./test-cache-in-bundle-all-rev.hg
746 $ hg -R tagsclient bundle --all ./test-cache-in-bundle-all-rev.hg
744 4 changesets found
747 4 changesets found
745 $ hg debugbundle ./test-cache-in-bundle-all-rev.hg
748 $ hg debugbundle ./test-cache-in-bundle-all-rev.hg
746 Stream params: {Compression: BZ}
749 Stream params: {Compression: BZ}
747 changegroup -- {nbchanges: 4, version: 02} (mandatory: True)
750 changegroup -- {nbchanges: 4, version: 02} (mandatory: True)
748 96ee1d7354c4ad7372047672c36a1f561e3a6a4c
751 96ee1d7354c4ad7372047672c36a1f561e3a6a4c
749 c4dab0c2fd337eb9191f80c3024830a4889a8f34
752 c4dab0c2fd337eb9191f80c3024830a4889a8f34
750 f63cc8fe54e4d326f8d692805d70e092f851ddb1
753 f63cc8fe54e4d326f8d692805d70e092f851ddb1
751 40f0358cb314c824a5929ee527308d90e023bc10
754 40f0358cb314c824a5929ee527308d90e023bc10
752 hgtagsfnodes -- {} (mandatory: True)
755 hgtagsfnodes -- {} (mandatory: True)
753 cache:rev-branch-cache -- {} (mandatory: False)
756 cache:rev-branch-cache -- {} (mandatory: False)
754
757
755 Check that local clone includes cache data
758 Check that local clone includes cache data
756
759
757 $ hg clone tagsclient tags-local-clone
760 $ hg clone tagsclient tags-local-clone
758 updating to branch default
761 updating to branch default
759 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
762 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
760 $ (cd tags-local-clone/.hg/cache/; ls -1 tag*)
763 $ (cd tags-local-clone/.hg/cache/; ls -1 tag*)
761 tags2-visible
764 tags2-visible
762
765
763 Avoid writing logs on trying to delete an already deleted tag
766 Avoid writing logs on trying to delete an already deleted tag
764 $ hg init issue5752
767 $ hg init issue5752
765 $ cd issue5752
768 $ cd issue5752
766 $ echo > a
769 $ echo > a
767 $ hg commit -Am 'add a'
770 $ hg commit -Am 'add a'
768 adding a
771 adding a
769 $ hg tag a
772 $ hg tag a
770 $ hg tags
773 $ hg tags
771 tip 1:bd7ee4f3939b
774 tip 1:bd7ee4f3939b
772 a 0:a8a82d372bb3
775 a 0:a8a82d372bb3
773 $ hg log
776 $ hg log
774 changeset: 1:bd7ee4f3939b
777 changeset: 1:bd7ee4f3939b
775 tag: tip
778 tag: tip
776 user: test
779 user: test
777 date: Thu Jan 01 00:00:00 1970 +0000
780 date: Thu Jan 01 00:00:00 1970 +0000
778 summary: Added tag a for changeset a8a82d372bb3
781 summary: Added tag a for changeset a8a82d372bb3
779
782
780 changeset: 0:a8a82d372bb3
783 changeset: 0:a8a82d372bb3
781 tag: a
784 tag: a
782 user: test
785 user: test
783 date: Thu Jan 01 00:00:00 1970 +0000
786 date: Thu Jan 01 00:00:00 1970 +0000
784 summary: add a
787 summary: add a
785
788
786 $ hg tag --remove a
789 $ hg tag --remove a
787 $ hg log
790 $ hg log
788 changeset: 2:e7feacc7ec9e
791 changeset: 2:e7feacc7ec9e
789 tag: tip
792 tag: tip
790 user: test
793 user: test
791 date: Thu Jan 01 00:00:00 1970 +0000
794 date: Thu Jan 01 00:00:00 1970 +0000
792 summary: Removed tag a
795 summary: Removed tag a
793
796
794 changeset: 1:bd7ee4f3939b
797 changeset: 1:bd7ee4f3939b
795 user: test
798 user: test
796 date: Thu Jan 01 00:00:00 1970 +0000
799 date: Thu Jan 01 00:00:00 1970 +0000
797 summary: Added tag a for changeset a8a82d372bb3
800 summary: Added tag a for changeset a8a82d372bb3
798
801
799 changeset: 0:a8a82d372bb3
802 changeset: 0:a8a82d372bb3
800 user: test
803 user: test
801 date: Thu Jan 01 00:00:00 1970 +0000
804 date: Thu Jan 01 00:00:00 1970 +0000
802 summary: add a
805 summary: add a
803
806
804 $ hg tag --remove a
807 $ hg tag --remove a
805 abort: tag 'a' is already removed
808 abort: tag 'a' is already removed
806 [255]
809 [255]
807 $ hg log
810 $ hg log
808 changeset: 2:e7feacc7ec9e
811 changeset: 2:e7feacc7ec9e
809 tag: tip
812 tag: tip
810 user: test
813 user: test
811 date: Thu Jan 01 00:00:00 1970 +0000
814 date: Thu Jan 01 00:00:00 1970 +0000
812 summary: Removed tag a
815 summary: Removed tag a
813
816
814 changeset: 1:bd7ee4f3939b
817 changeset: 1:bd7ee4f3939b
815 user: test
818 user: test
816 date: Thu Jan 01 00:00:00 1970 +0000
819 date: Thu Jan 01 00:00:00 1970 +0000
817 summary: Added tag a for changeset a8a82d372bb3
820 summary: Added tag a for changeset a8a82d372bb3
818
821
819 changeset: 0:a8a82d372bb3
822 changeset: 0:a8a82d372bb3
820 user: test
823 user: test
821 date: Thu Jan 01 00:00:00 1970 +0000
824 date: Thu Jan 01 00:00:00 1970 +0000
822 summary: add a
825 summary: add a
823
826
824 $ cat .hgtags
827 $ cat .hgtags
825 a8a82d372bb35b42ff736e74f07c23bcd99c371f a
828 a8a82d372bb35b42ff736e74f07c23bcd99c371f a
826 a8a82d372bb35b42ff736e74f07c23bcd99c371f a
829 a8a82d372bb35b42ff736e74f07c23bcd99c371f a
827 0000000000000000000000000000000000000000 a
830 0000000000000000000000000000000000000000 a
General Comments 0
You need to be logged in to leave comments. Login now