##// END OF EJS Templates
debugcommands: add a debugindexstats command...
Martin von Zweigbergk -
r40016:d71e0ba3 default
parent child Browse files
Show More
@@ -1,3372 +1,3379 b''
1 1 # debugcommands.py - command processing for debug* commands
2 2 #
3 3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import codecs
11 11 import collections
12 12 import difflib
13 13 import errno
14 14 import operator
15 15 import os
16 16 import random
17 17 import re
18 18 import socket
19 19 import ssl
20 20 import stat
21 21 import string
22 22 import subprocess
23 23 import sys
24 24 import time
25 25
26 26 from .i18n import _
27 27 from .node import (
28 28 bin,
29 29 hex,
30 30 nullhex,
31 31 nullid,
32 32 nullrev,
33 33 short,
34 34 )
35 35 from . import (
36 36 bundle2,
37 37 changegroup,
38 38 cmdutil,
39 39 color,
40 40 context,
41 41 dagparser,
42 42 encoding,
43 43 error,
44 44 exchange,
45 45 extensions,
46 46 filemerge,
47 47 filesetlang,
48 48 formatter,
49 49 hg,
50 50 httppeer,
51 51 localrepo,
52 52 lock as lockmod,
53 53 logcmdutil,
54 54 merge as mergemod,
55 55 obsolete,
56 56 obsutil,
57 57 phases,
58 58 policy,
59 59 pvec,
60 60 pycompat,
61 61 registrar,
62 62 repair,
63 63 revlog,
64 64 revset,
65 65 revsetlang,
66 66 scmutil,
67 67 setdiscovery,
68 68 simplemerge,
69 69 sshpeer,
70 70 sslutil,
71 71 streamclone,
72 72 templater,
73 73 treediscovery,
74 74 upgrade,
75 75 url as urlmod,
76 76 util,
77 77 vfs as vfsmod,
78 78 wireprotoframing,
79 79 wireprotoserver,
80 80 wireprotov2peer,
81 81 )
82 82 from .utils import (
83 83 cborutil,
84 84 dateutil,
85 85 procutil,
86 86 stringutil,
87 87 )
88 88
89 89 from .revlogutils import (
90 90 deltas as deltautil
91 91 )
92 92
93 93 release = lockmod.release
94 94
95 95 command = registrar.command()
96 96
97 97 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
98 98 def debugancestor(ui, repo, *args):
99 99 """find the ancestor revision of two revisions in a given index"""
100 100 if len(args) == 3:
101 101 index, rev1, rev2 = args
102 102 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index)
103 103 lookup = r.lookup
104 104 elif len(args) == 2:
105 105 if not repo:
106 106 raise error.Abort(_('there is no Mercurial repository here '
107 107 '(.hg not found)'))
108 108 rev1, rev2 = args
109 109 r = repo.changelog
110 110 lookup = repo.lookup
111 111 else:
112 112 raise error.Abort(_('either two or three arguments required'))
113 113 a = r.ancestor(lookup(rev1), lookup(rev2))
114 114 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
115 115
116 116 @command('debugapplystreamclonebundle', [], 'FILE')
117 117 def debugapplystreamclonebundle(ui, repo, fname):
118 118 """apply a stream clone bundle file"""
119 119 f = hg.openpath(ui, fname)
120 120 gen = exchange.readbundle(ui, f, fname)
121 121 gen.apply(repo)
122 122
123 123 @command('debugbuilddag',
124 124 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
125 125 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
126 126 ('n', 'new-file', None, _('add new file at each rev'))],
127 127 _('[OPTION]... [TEXT]'))
128 128 def debugbuilddag(ui, repo, text=None,
129 129 mergeable_file=False,
130 130 overwritten_file=False,
131 131 new_file=False):
132 132 """builds a repo with a given DAG from scratch in the current empty repo
133 133
134 134 The description of the DAG is read from stdin if not given on the
135 135 command line.
136 136
137 137 Elements:
138 138
139 139 - "+n" is a linear run of n nodes based on the current default parent
140 140 - "." is a single node based on the current default parent
141 141 - "$" resets the default parent to null (implied at the start);
142 142 otherwise the default parent is always the last node created
143 143 - "<p" sets the default parent to the backref p
144 144 - "*p" is a fork at parent p, which is a backref
145 145 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
146 146 - "/p2" is a merge of the preceding node and p2
147 147 - ":tag" defines a local tag for the preceding node
148 148 - "@branch" sets the named branch for subsequent nodes
149 149 - "#...\\n" is a comment up to the end of the line
150 150
151 151 Whitespace between the above elements is ignored.
152 152
153 153 A backref is either
154 154
155 155 - a number n, which references the node curr-n, where curr is the current
156 156 node, or
157 157 - the name of a local tag you placed earlier using ":tag", or
158 158 - empty to denote the default parent.
159 159
160 160 All string valued-elements are either strictly alphanumeric, or must
161 161 be enclosed in double quotes ("..."), with "\\" as escape character.
162 162 """
163 163
164 164 if text is None:
165 165 ui.status(_("reading DAG from stdin\n"))
166 166 text = ui.fin.read()
167 167
168 168 cl = repo.changelog
169 169 if len(cl) > 0:
170 170 raise error.Abort(_('repository is not empty'))
171 171
172 172 # determine number of revs in DAG
173 173 total = 0
174 174 for type, data in dagparser.parsedag(text):
175 175 if type == 'n':
176 176 total += 1
177 177
178 178 if mergeable_file:
179 179 linesperrev = 2
180 180 # make a file with k lines per rev
181 181 initialmergedlines = ['%d' % i
182 182 for i in pycompat.xrange(0, total * linesperrev)]
183 183 initialmergedlines.append("")
184 184
185 185 tags = []
186 186 progress = ui.makeprogress(_('building'), unit=_('revisions'),
187 187 total=total)
188 188 with progress, repo.wlock(), repo.lock(), repo.transaction("builddag"):
189 189 at = -1
190 190 atbranch = 'default'
191 191 nodeids = []
192 192 id = 0
193 193 progress.update(id)
194 194 for type, data in dagparser.parsedag(text):
195 195 if type == 'n':
196 196 ui.note(('node %s\n' % pycompat.bytestr(data)))
197 197 id, ps = data
198 198
199 199 files = []
200 200 filecontent = {}
201 201
202 202 p2 = None
203 203 if mergeable_file:
204 204 fn = "mf"
205 205 p1 = repo[ps[0]]
206 206 if len(ps) > 1:
207 207 p2 = repo[ps[1]]
208 208 pa = p1.ancestor(p2)
209 209 base, local, other = [x[fn].data() for x in (pa, p1,
210 210 p2)]
211 211 m3 = simplemerge.Merge3Text(base, local, other)
212 212 ml = [l.strip() for l in m3.merge_lines()]
213 213 ml.append("")
214 214 elif at > 0:
215 215 ml = p1[fn].data().split("\n")
216 216 else:
217 217 ml = initialmergedlines
218 218 ml[id * linesperrev] += " r%i" % id
219 219 mergedtext = "\n".join(ml)
220 220 files.append(fn)
221 221 filecontent[fn] = mergedtext
222 222
223 223 if overwritten_file:
224 224 fn = "of"
225 225 files.append(fn)
226 226 filecontent[fn] = "r%i\n" % id
227 227
228 228 if new_file:
229 229 fn = "nf%i" % id
230 230 files.append(fn)
231 231 filecontent[fn] = "r%i\n" % id
232 232 if len(ps) > 1:
233 233 if not p2:
234 234 p2 = repo[ps[1]]
235 235 for fn in p2:
236 236 if fn.startswith("nf"):
237 237 files.append(fn)
238 238 filecontent[fn] = p2[fn].data()
239 239
240 240 def fctxfn(repo, cx, path):
241 241 if path in filecontent:
242 242 return context.memfilectx(repo, cx, path,
243 243 filecontent[path])
244 244 return None
245 245
246 246 if len(ps) == 0 or ps[0] < 0:
247 247 pars = [None, None]
248 248 elif len(ps) == 1:
249 249 pars = [nodeids[ps[0]], None]
250 250 else:
251 251 pars = [nodeids[p] for p in ps]
252 252 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
253 253 date=(id, 0),
254 254 user="debugbuilddag",
255 255 extra={'branch': atbranch})
256 256 nodeid = repo.commitctx(cx)
257 257 nodeids.append(nodeid)
258 258 at = id
259 259 elif type == 'l':
260 260 id, name = data
261 261 ui.note(('tag %s\n' % name))
262 262 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
263 263 elif type == 'a':
264 264 ui.note(('branch %s\n' % data))
265 265 atbranch = data
266 266 progress.update(id)
267 267
268 268 if tags:
269 269 repo.vfs.write("localtags", "".join(tags))
270 270
271 271 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
272 272 indent_string = ' ' * indent
273 273 if all:
274 274 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
275 275 % indent_string)
276 276
277 277 def showchunks(named):
278 278 ui.write("\n%s%s\n" % (indent_string, named))
279 279 for deltadata in gen.deltaiter():
280 280 node, p1, p2, cs, deltabase, delta, flags = deltadata
281 281 ui.write("%s%s %s %s %s %s %d\n" %
282 282 (indent_string, hex(node), hex(p1), hex(p2),
283 283 hex(cs), hex(deltabase), len(delta)))
284 284
285 285 chunkdata = gen.changelogheader()
286 286 showchunks("changelog")
287 287 chunkdata = gen.manifestheader()
288 288 showchunks("manifest")
289 289 for chunkdata in iter(gen.filelogheader, {}):
290 290 fname = chunkdata['filename']
291 291 showchunks(fname)
292 292 else:
293 293 if isinstance(gen, bundle2.unbundle20):
294 294 raise error.Abort(_('use debugbundle2 for this file'))
295 295 chunkdata = gen.changelogheader()
296 296 for deltadata in gen.deltaiter():
297 297 node, p1, p2, cs, deltabase, delta, flags = deltadata
298 298 ui.write("%s%s\n" % (indent_string, hex(node)))
299 299
300 300 def _debugobsmarkers(ui, part, indent=0, **opts):
301 301 """display version and markers contained in 'data'"""
302 302 opts = pycompat.byteskwargs(opts)
303 303 data = part.read()
304 304 indent_string = ' ' * indent
305 305 try:
306 306 version, markers = obsolete._readmarkers(data)
307 307 except error.UnknownVersion as exc:
308 308 msg = "%sunsupported version: %s (%d bytes)\n"
309 309 msg %= indent_string, exc.version, len(data)
310 310 ui.write(msg)
311 311 else:
312 312 msg = "%sversion: %d (%d bytes)\n"
313 313 msg %= indent_string, version, len(data)
314 314 ui.write(msg)
315 315 fm = ui.formatter('debugobsolete', opts)
316 316 for rawmarker in sorted(markers):
317 317 m = obsutil.marker(None, rawmarker)
318 318 fm.startitem()
319 319 fm.plain(indent_string)
320 320 cmdutil.showmarker(fm, m)
321 321 fm.end()
322 322
323 323 def _debugphaseheads(ui, data, indent=0):
324 324 """display version and markers contained in 'data'"""
325 325 indent_string = ' ' * indent
326 326 headsbyphase = phases.binarydecode(data)
327 327 for phase in phases.allphases:
328 328 for head in headsbyphase[phase]:
329 329 ui.write(indent_string)
330 330 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
331 331
332 332 def _quasirepr(thing):
333 333 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
334 334 return '{%s}' % (
335 335 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
336 336 return pycompat.bytestr(repr(thing))
337 337
338 338 def _debugbundle2(ui, gen, all=None, **opts):
339 339 """lists the contents of a bundle2"""
340 340 if not isinstance(gen, bundle2.unbundle20):
341 341 raise error.Abort(_('not a bundle2 file'))
342 342 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
343 343 parttypes = opts.get(r'part_type', [])
344 344 for part in gen.iterparts():
345 345 if parttypes and part.type not in parttypes:
346 346 continue
347 347 msg = '%s -- %s (mandatory: %r)\n'
348 348 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
349 349 if part.type == 'changegroup':
350 350 version = part.params.get('version', '01')
351 351 cg = changegroup.getunbundler(version, part, 'UN')
352 352 if not ui.quiet:
353 353 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
354 354 if part.type == 'obsmarkers':
355 355 if not ui.quiet:
356 356 _debugobsmarkers(ui, part, indent=4, **opts)
357 357 if part.type == 'phase-heads':
358 358 if not ui.quiet:
359 359 _debugphaseheads(ui, part, indent=4)
360 360
361 361 @command('debugbundle',
362 362 [('a', 'all', None, _('show all details')),
363 363 ('', 'part-type', [], _('show only the named part type')),
364 364 ('', 'spec', None, _('print the bundlespec of the bundle'))],
365 365 _('FILE'),
366 366 norepo=True)
367 367 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
368 368 """lists the contents of a bundle"""
369 369 with hg.openpath(ui, bundlepath) as f:
370 370 if spec:
371 371 spec = exchange.getbundlespec(ui, f)
372 372 ui.write('%s\n' % spec)
373 373 return
374 374
375 375 gen = exchange.readbundle(ui, f, bundlepath)
376 376 if isinstance(gen, bundle2.unbundle20):
377 377 return _debugbundle2(ui, gen, all=all, **opts)
378 378 _debugchangegroup(ui, gen, all=all, **opts)
379 379
380 380 @command('debugcapabilities',
381 381 [], _('PATH'),
382 382 norepo=True)
383 383 def debugcapabilities(ui, path, **opts):
384 384 """lists the capabilities of a remote peer"""
385 385 opts = pycompat.byteskwargs(opts)
386 386 peer = hg.peer(ui, opts, path)
387 387 caps = peer.capabilities()
388 388 ui.write(('Main capabilities:\n'))
389 389 for c in sorted(caps):
390 390 ui.write((' %s\n') % c)
391 391 b2caps = bundle2.bundle2caps(peer)
392 392 if b2caps:
393 393 ui.write(('Bundle2 capabilities:\n'))
394 394 for key, values in sorted(b2caps.iteritems()):
395 395 ui.write((' %s\n') % key)
396 396 for v in values:
397 397 ui.write((' %s\n') % v)
398 398
399 399 @command('debugcheckstate', [], '')
400 400 def debugcheckstate(ui, repo):
401 401 """validate the correctness of the current dirstate"""
402 402 parent1, parent2 = repo.dirstate.parents()
403 403 m1 = repo[parent1].manifest()
404 404 m2 = repo[parent2].manifest()
405 405 errors = 0
406 406 for f in repo.dirstate:
407 407 state = repo.dirstate[f]
408 408 if state in "nr" and f not in m1:
409 409 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
410 410 errors += 1
411 411 if state in "a" and f in m1:
412 412 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
413 413 errors += 1
414 414 if state in "m" and f not in m1 and f not in m2:
415 415 ui.warn(_("%s in state %s, but not in either manifest\n") %
416 416 (f, state))
417 417 errors += 1
418 418 for f in m1:
419 419 state = repo.dirstate[f]
420 420 if state not in "nrm":
421 421 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
422 422 errors += 1
423 423 if errors:
424 424 error = _(".hg/dirstate inconsistent with current parent's manifest")
425 425 raise error.Abort(error)
426 426
427 427 @command('debugcolor',
428 428 [('', 'style', None, _('show all configured styles'))],
429 429 'hg debugcolor')
430 430 def debugcolor(ui, repo, **opts):
431 431 """show available color, effects or style"""
432 432 ui.write(('color mode: %s\n') % stringutil.pprint(ui._colormode))
433 433 if opts.get(r'style'):
434 434 return _debugdisplaystyle(ui)
435 435 else:
436 436 return _debugdisplaycolor(ui)
437 437
438 438 def _debugdisplaycolor(ui):
439 439 ui = ui.copy()
440 440 ui._styles.clear()
441 441 for effect in color._activeeffects(ui).keys():
442 442 ui._styles[effect] = effect
443 443 if ui._terminfoparams:
444 444 for k, v in ui.configitems('color'):
445 445 if k.startswith('color.'):
446 446 ui._styles[k] = k[6:]
447 447 elif k.startswith('terminfo.'):
448 448 ui._styles[k] = k[9:]
449 449 ui.write(_('available colors:\n'))
450 450 # sort label with a '_' after the other to group '_background' entry.
451 451 items = sorted(ui._styles.items(),
452 452 key=lambda i: ('_' in i[0], i[0], i[1]))
453 453 for colorname, label in items:
454 454 ui.write(('%s\n') % colorname, label=label)
455 455
456 456 def _debugdisplaystyle(ui):
457 457 ui.write(_('available style:\n'))
458 458 if not ui._styles:
459 459 return
460 460 width = max(len(s) for s in ui._styles)
461 461 for label, effects in sorted(ui._styles.items()):
462 462 ui.write('%s' % label, label=label)
463 463 if effects:
464 464 # 50
465 465 ui.write(': ')
466 466 ui.write(' ' * (max(0, width - len(label))))
467 467 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
468 468 ui.write('\n')
469 469
470 470 @command('debugcreatestreamclonebundle', [], 'FILE')
471 471 def debugcreatestreamclonebundle(ui, repo, fname):
472 472 """create a stream clone bundle file
473 473
474 474 Stream bundles are special bundles that are essentially archives of
475 475 revlog files. They are commonly used for cloning very quickly.
476 476 """
477 477 # TODO we may want to turn this into an abort when this functionality
478 478 # is moved into `hg bundle`.
479 479 if phases.hassecret(repo):
480 480 ui.warn(_('(warning: stream clone bundle will contain secret '
481 481 'revisions)\n'))
482 482
483 483 requirements, gen = streamclone.generatebundlev1(repo)
484 484 changegroup.writechunks(ui, gen, fname)
485 485
486 486 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
487 487
488 488 @command('debugdag',
489 489 [('t', 'tags', None, _('use tags as labels')),
490 490 ('b', 'branches', None, _('annotate with branch names')),
491 491 ('', 'dots', None, _('use dots for runs')),
492 492 ('s', 'spaces', None, _('separate elements by spaces'))],
493 493 _('[OPTION]... [FILE [REV]...]'),
494 494 optionalrepo=True)
495 495 def debugdag(ui, repo, file_=None, *revs, **opts):
496 496 """format the changelog or an index DAG as a concise textual description
497 497
498 498 If you pass a revlog index, the revlog's DAG is emitted. If you list
499 499 revision numbers, they get labeled in the output as rN.
500 500
501 501 Otherwise, the changelog DAG of the current repo is emitted.
502 502 """
503 503 spaces = opts.get(r'spaces')
504 504 dots = opts.get(r'dots')
505 505 if file_:
506 506 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False),
507 507 file_)
508 508 revs = set((int(r) for r in revs))
509 509 def events():
510 510 for r in rlog:
511 511 yield 'n', (r, list(p for p in rlog.parentrevs(r)
512 512 if p != -1))
513 513 if r in revs:
514 514 yield 'l', (r, "r%i" % r)
515 515 elif repo:
516 516 cl = repo.changelog
517 517 tags = opts.get(r'tags')
518 518 branches = opts.get(r'branches')
519 519 if tags:
520 520 labels = {}
521 521 for l, n in repo.tags().items():
522 522 labels.setdefault(cl.rev(n), []).append(l)
523 523 def events():
524 524 b = "default"
525 525 for r in cl:
526 526 if branches:
527 527 newb = cl.read(cl.node(r))[5]['branch']
528 528 if newb != b:
529 529 yield 'a', newb
530 530 b = newb
531 531 yield 'n', (r, list(p for p in cl.parentrevs(r)
532 532 if p != -1))
533 533 if tags:
534 534 ls = labels.get(r)
535 535 if ls:
536 536 for l in ls:
537 537 yield 'l', (r, l)
538 538 else:
539 539 raise error.Abort(_('need repo for changelog dag'))
540 540
541 541 for line in dagparser.dagtextlines(events(),
542 542 addspaces=spaces,
543 543 wraplabels=True,
544 544 wrapannotations=True,
545 545 wrapnonlinear=dots,
546 546 usedots=dots,
547 547 maxlinewidth=70):
548 548 ui.write(line)
549 549 ui.write("\n")
550 550
551 551 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
552 552 def debugdata(ui, repo, file_, rev=None, **opts):
553 553 """dump the contents of a data file revision"""
554 554 opts = pycompat.byteskwargs(opts)
555 555 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
556 556 if rev is not None:
557 557 raise error.CommandError('debugdata', _('invalid arguments'))
558 558 file_, rev = None, file_
559 559 elif rev is None:
560 560 raise error.CommandError('debugdata', _('invalid arguments'))
561 561 r = cmdutil.openstorage(repo, 'debugdata', file_, opts)
562 562 try:
563 563 ui.write(r.revision(r.lookup(rev), raw=True))
564 564 except KeyError:
565 565 raise error.Abort(_('invalid revision identifier %s') % rev)
566 566
567 567 @command('debugdate',
568 568 [('e', 'extended', None, _('try extended date formats'))],
569 569 _('[-e] DATE [RANGE]'),
570 570 norepo=True, optionalrepo=True)
571 571 def debugdate(ui, date, range=None, **opts):
572 572 """parse and display a date"""
573 573 if opts[r"extended"]:
574 574 d = dateutil.parsedate(date, util.extendeddateformats)
575 575 else:
576 576 d = dateutil.parsedate(date)
577 577 ui.write(("internal: %d %d\n") % d)
578 578 ui.write(("standard: %s\n") % dateutil.datestr(d))
579 579 if range:
580 580 m = dateutil.matchdate(range)
581 581 ui.write(("match: %s\n") % m(d[0]))
582 582
583 583 @command('debugdeltachain',
584 584 cmdutil.debugrevlogopts + cmdutil.formatteropts,
585 585 _('-c|-m|FILE'),
586 586 optionalrepo=True)
587 587 def debugdeltachain(ui, repo, file_=None, **opts):
588 588 """dump information about delta chains in a revlog
589 589
590 590 Output can be templatized. Available template keywords are:
591 591
592 592 :``rev``: revision number
593 593 :``chainid``: delta chain identifier (numbered by unique base)
594 594 :``chainlen``: delta chain length to this revision
595 595 :``prevrev``: previous revision in delta chain
596 596 :``deltatype``: role of delta / how it was computed
597 597 :``compsize``: compressed size of revision
598 598 :``uncompsize``: uncompressed size of revision
599 599 :``chainsize``: total size of compressed revisions in chain
600 600 :``chainratio``: total chain size divided by uncompressed revision size
601 601 (new delta chains typically start at ratio 2.00)
602 602 :``lindist``: linear distance from base revision in delta chain to end
603 603 of this revision
604 604 :``extradist``: total size of revisions not part of this delta chain from
605 605 base of delta chain to end of this revision; a measurement
606 606 of how much extra data we need to read/seek across to read
607 607 the delta chain for this revision
608 608 :``extraratio``: extradist divided by chainsize; another representation of
609 609 how much unrelated data is needed to load this delta chain
610 610
611 611 If the repository is configured to use the sparse read, additional keywords
612 612 are available:
613 613
614 614 :``readsize``: total size of data read from the disk for a revision
615 615 (sum of the sizes of all the blocks)
616 616 :``largestblock``: size of the largest block of data read from the disk
617 617 :``readdensity``: density of useful bytes in the data read from the disk
618 618 :``srchunks``: in how many data hunks the whole revision would be read
619 619
620 620 The sparse read can be enabled with experimental.sparse-read = True
621 621 """
622 622 opts = pycompat.byteskwargs(opts)
623 623 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
624 624 index = r.index
625 625 start = r.start
626 626 length = r.length
627 627 generaldelta = r.version & revlog.FLAG_GENERALDELTA
628 628 withsparseread = getattr(r, '_withsparseread', False)
629 629
630 630 def revinfo(rev):
631 631 e = index[rev]
632 632 compsize = e[1]
633 633 uncompsize = e[2]
634 634 chainsize = 0
635 635
636 636 if generaldelta:
637 637 if e[3] == e[5]:
638 638 deltatype = 'p1'
639 639 elif e[3] == e[6]:
640 640 deltatype = 'p2'
641 641 elif e[3] == rev - 1:
642 642 deltatype = 'prev'
643 643 elif e[3] == rev:
644 644 deltatype = 'base'
645 645 else:
646 646 deltatype = 'other'
647 647 else:
648 648 if e[3] == rev:
649 649 deltatype = 'base'
650 650 else:
651 651 deltatype = 'prev'
652 652
653 653 chain = r._deltachain(rev)[0]
654 654 for iterrev in chain:
655 655 e = index[iterrev]
656 656 chainsize += e[1]
657 657
658 658 return compsize, uncompsize, deltatype, chain, chainsize
659 659
660 660 fm = ui.formatter('debugdeltachain', opts)
661 661
662 662 fm.plain(' rev chain# chainlen prev delta '
663 663 'size rawsize chainsize ratio lindist extradist '
664 664 'extraratio')
665 665 if withsparseread:
666 666 fm.plain(' readsize largestblk rddensity srchunks')
667 667 fm.plain('\n')
668 668
669 669 chainbases = {}
670 670 for rev in r:
671 671 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
672 672 chainbase = chain[0]
673 673 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
674 674 basestart = start(chainbase)
675 675 revstart = start(rev)
676 676 lineardist = revstart + comp - basestart
677 677 extradist = lineardist - chainsize
678 678 try:
679 679 prevrev = chain[-2]
680 680 except IndexError:
681 681 prevrev = -1
682 682
683 683 if uncomp != 0:
684 684 chainratio = float(chainsize) / float(uncomp)
685 685 else:
686 686 chainratio = chainsize
687 687
688 688 if chainsize != 0:
689 689 extraratio = float(extradist) / float(chainsize)
690 690 else:
691 691 extraratio = extradist
692 692
693 693 fm.startitem()
694 694 fm.write('rev chainid chainlen prevrev deltatype compsize '
695 695 'uncompsize chainsize chainratio lindist extradist '
696 696 'extraratio',
697 697 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
698 698 rev, chainid, len(chain), prevrev, deltatype, comp,
699 699 uncomp, chainsize, chainratio, lineardist, extradist,
700 700 extraratio,
701 701 rev=rev, chainid=chainid, chainlen=len(chain),
702 702 prevrev=prevrev, deltatype=deltatype, compsize=comp,
703 703 uncompsize=uncomp, chainsize=chainsize,
704 704 chainratio=chainratio, lindist=lineardist,
705 705 extradist=extradist, extraratio=extraratio)
706 706 if withsparseread:
707 707 readsize = 0
708 708 largestblock = 0
709 709 srchunks = 0
710 710
711 711 for revschunk in deltautil.slicechunk(r, chain):
712 712 srchunks += 1
713 713 blkend = start(revschunk[-1]) + length(revschunk[-1])
714 714 blksize = blkend - start(revschunk[0])
715 715
716 716 readsize += blksize
717 717 if largestblock < blksize:
718 718 largestblock = blksize
719 719
720 720 if readsize:
721 721 readdensity = float(chainsize) / float(readsize)
722 722 else:
723 723 readdensity = 1
724 724
725 725 fm.write('readsize largestblock readdensity srchunks',
726 726 ' %10d %10d %9.5f %8d',
727 727 readsize, largestblock, readdensity, srchunks,
728 728 readsize=readsize, largestblock=largestblock,
729 729 readdensity=readdensity, srchunks=srchunks)
730 730
731 731 fm.plain('\n')
732 732
733 733 fm.end()
734 734
735 735 @command('debugdirstate|debugstate',
736 736 [('', 'nodates', None, _('do not display the saved mtime (DEPRECATED)')),
737 737 ('', 'dates', True, _('display the saved mtime')),
738 738 ('', 'datesort', None, _('sort by saved mtime'))],
739 739 _('[OPTION]...'))
740 740 def debugstate(ui, repo, **opts):
741 741 """show the contents of the current dirstate"""
742 742
743 743 nodates = not opts[r'dates']
744 744 if opts.get(r'nodates') is not None:
745 745 nodates = True
746 746 datesort = opts.get(r'datesort')
747 747
748 748 timestr = ""
749 749 if datesort:
750 750 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
751 751 else:
752 752 keyfunc = None # sort by filename
753 753 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
754 754 if ent[3] == -1:
755 755 timestr = 'unset '
756 756 elif nodates:
757 757 timestr = 'set '
758 758 else:
759 759 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
760 760 time.localtime(ent[3]))
761 761 timestr = encoding.strtolocal(timestr)
762 762 if ent[1] & 0o20000:
763 763 mode = 'lnk'
764 764 else:
765 765 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
766 766 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
767 767 for f in repo.dirstate.copies():
768 768 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
769 769
770 770 @command('debugdiscovery',
771 771 [('', 'old', None, _('use old-style discovery')),
772 772 ('', 'nonheads', None,
773 773 _('use old-style discovery with non-heads included')),
774 774 ('', 'rev', [], 'restrict discovery to this set of revs'),
775 775 ] + cmdutil.remoteopts,
776 776 _('[--rev REV] [OTHER]'))
777 777 def debugdiscovery(ui, repo, remoteurl="default", **opts):
778 778 """runs the changeset discovery protocol in isolation"""
779 779 opts = pycompat.byteskwargs(opts)
780 780 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
781 781 remote = hg.peer(repo, opts, remoteurl)
782 782 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
783 783
784 784 # make sure tests are repeatable
785 785 random.seed(12323)
786 786
787 787 def doit(pushedrevs, remoteheads, remote=remote):
788 788 if opts.get('old'):
789 789 if not util.safehasattr(remote, 'branches'):
790 790 # enable in-client legacy support
791 791 remote = localrepo.locallegacypeer(remote.local())
792 792 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
793 793 force=True)
794 794 common = set(common)
795 795 if not opts.get('nonheads'):
796 796 ui.write(("unpruned common: %s\n") %
797 797 " ".join(sorted(short(n) for n in common)))
798 798
799 799 clnode = repo.changelog.node
800 800 common = repo.revs('heads(::%ln)', common)
801 801 common = {clnode(r) for r in common}
802 802 else:
803 803 nodes = None
804 804 if pushedrevs:
805 805 revs = scmutil.revrange(repo, pushedrevs)
806 806 nodes = [repo[r].node() for r in revs]
807 807 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
808 808 ancestorsof=nodes)
809 809 common = set(common)
810 810 rheads = set(hds)
811 811 lheads = set(repo.heads())
812 812 ui.write(("common heads: %s\n") %
813 813 " ".join(sorted(short(n) for n in common)))
814 814 if lheads <= common:
815 815 ui.write(("local is subset\n"))
816 816 elif rheads <= common:
817 817 ui.write(("remote is subset\n"))
818 818
819 819 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
820 820 localrevs = opts['rev']
821 821 doit(localrevs, remoterevs)
822 822
823 823 _chunksize = 4 << 10
824 824
825 825 @command('debugdownload',
826 826 [
827 827 ('o', 'output', '', _('path')),
828 828 ],
829 829 optionalrepo=True)
830 830 def debugdownload(ui, repo, url, output=None, **opts):
831 831 """download a resource using Mercurial logic and config
832 832 """
833 833 fh = urlmod.open(ui, url, output)
834 834
835 835 dest = ui
836 836 if output:
837 837 dest = open(output, "wb", _chunksize)
838 838 try:
839 839 data = fh.read(_chunksize)
840 840 while data:
841 841 dest.write(data)
842 842 data = fh.read(_chunksize)
843 843 finally:
844 844 if output:
845 845 dest.close()
846 846
847 847 @command('debugextensions', cmdutil.formatteropts, [], optionalrepo=True)
848 848 def debugextensions(ui, repo, **opts):
849 849 '''show information about active extensions'''
850 850 opts = pycompat.byteskwargs(opts)
851 851 exts = extensions.extensions(ui)
852 852 hgver = util.version()
853 853 fm = ui.formatter('debugextensions', opts)
854 854 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
855 855 isinternal = extensions.ismoduleinternal(extmod)
856 856 extsource = pycompat.fsencode(extmod.__file__)
857 857 if isinternal:
858 858 exttestedwith = [] # never expose magic string to users
859 859 else:
860 860 exttestedwith = getattr(extmod, 'testedwith', '').split()
861 861 extbuglink = getattr(extmod, 'buglink', None)
862 862
863 863 fm.startitem()
864 864
865 865 if ui.quiet or ui.verbose:
866 866 fm.write('name', '%s\n', extname)
867 867 else:
868 868 fm.write('name', '%s', extname)
869 869 if isinternal or hgver in exttestedwith:
870 870 fm.plain('\n')
871 871 elif not exttestedwith:
872 872 fm.plain(_(' (untested!)\n'))
873 873 else:
874 874 lasttestedversion = exttestedwith[-1]
875 875 fm.plain(' (%s!)\n' % lasttestedversion)
876 876
877 877 fm.condwrite(ui.verbose and extsource, 'source',
878 878 _(' location: %s\n'), extsource or "")
879 879
880 880 if ui.verbose:
881 881 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
882 882 fm.data(bundled=isinternal)
883 883
884 884 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
885 885 _(' tested with: %s\n'),
886 886 fm.formatlist(exttestedwith, name='ver'))
887 887
888 888 fm.condwrite(ui.verbose and extbuglink, 'buglink',
889 889 _(' bug reporting: %s\n'), extbuglink or "")
890 890
891 891 fm.end()
892 892
893 893 @command('debugfileset',
894 894 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')),
895 895 ('', 'all-files', False,
896 896 _('test files from all revisions and working directory')),
897 897 ('s', 'show-matcher', None,
898 898 _('print internal representation of matcher')),
899 899 ('p', 'show-stage', [],
900 900 _('print parsed tree at the given stage'), _('NAME'))],
901 901 _('[-r REV] [--all-files] [OPTION]... FILESPEC'))
902 902 def debugfileset(ui, repo, expr, **opts):
903 903 '''parse and apply a fileset specification'''
904 904 from . import fileset
905 905 fileset.symbols # force import of fileset so we have predicates to optimize
906 906 opts = pycompat.byteskwargs(opts)
907 907 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
908 908
909 909 stages = [
910 910 ('parsed', pycompat.identity),
911 911 ('analyzed', filesetlang.analyze),
912 912 ('optimized', filesetlang.optimize),
913 913 ]
914 914 stagenames = set(n for n, f in stages)
915 915
916 916 showalways = set()
917 917 if ui.verbose and not opts['show_stage']:
918 918 # show parsed tree by --verbose (deprecated)
919 919 showalways.add('parsed')
920 920 if opts['show_stage'] == ['all']:
921 921 showalways.update(stagenames)
922 922 else:
923 923 for n in opts['show_stage']:
924 924 if n not in stagenames:
925 925 raise error.Abort(_('invalid stage name: %s') % n)
926 926 showalways.update(opts['show_stage'])
927 927
928 928 tree = filesetlang.parse(expr)
929 929 for n, f in stages:
930 930 tree = f(tree)
931 931 if n in showalways:
932 932 if opts['show_stage'] or n != 'parsed':
933 933 ui.write(("* %s:\n") % n)
934 934 ui.write(filesetlang.prettyformat(tree), "\n")
935 935
936 936 files = set()
937 937 if opts['all_files']:
938 938 for r in repo:
939 939 c = repo[r]
940 940 files.update(c.files())
941 941 files.update(c.substate)
942 942 if opts['all_files'] or ctx.rev() is None:
943 943 wctx = repo[None]
944 944 files.update(repo.dirstate.walk(scmutil.matchall(repo),
945 945 subrepos=list(wctx.substate),
946 946 unknown=True, ignored=True))
947 947 files.update(wctx.substate)
948 948 else:
949 949 files.update(ctx.files())
950 950 files.update(ctx.substate)
951 951
952 952 m = ctx.matchfileset(expr)
953 953 if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose):
954 954 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
955 955 for f in sorted(files):
956 956 if not m(f):
957 957 continue
958 958 ui.write("%s\n" % f)
959 959
960 960 @command('debugformat',
961 961 [] + cmdutil.formatteropts)
962 962 def debugformat(ui, repo, **opts):
963 963 """display format information about the current repository
964 964
965 965 Use --verbose to get extra information about current config value and
966 966 Mercurial default."""
967 967 opts = pycompat.byteskwargs(opts)
968 968 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
969 969 maxvariantlength = max(len('format-variant'), maxvariantlength)
970 970
971 971 def makeformatname(name):
972 972 return '%s:' + (' ' * (maxvariantlength - len(name)))
973 973
974 974 fm = ui.formatter('debugformat', opts)
975 975 if fm.isplain():
976 976 def formatvalue(value):
977 977 if util.safehasattr(value, 'startswith'):
978 978 return value
979 979 if value:
980 980 return 'yes'
981 981 else:
982 982 return 'no'
983 983 else:
984 984 formatvalue = pycompat.identity
985 985
986 986 fm.plain('format-variant')
987 987 fm.plain(' ' * (maxvariantlength - len('format-variant')))
988 988 fm.plain(' repo')
989 989 if ui.verbose:
990 990 fm.plain(' config default')
991 991 fm.plain('\n')
992 992 for fv in upgrade.allformatvariant:
993 993 fm.startitem()
994 994 repovalue = fv.fromrepo(repo)
995 995 configvalue = fv.fromconfig(repo)
996 996
997 997 if repovalue != configvalue:
998 998 namelabel = 'formatvariant.name.mismatchconfig'
999 999 repolabel = 'formatvariant.repo.mismatchconfig'
1000 1000 elif repovalue != fv.default:
1001 1001 namelabel = 'formatvariant.name.mismatchdefault'
1002 1002 repolabel = 'formatvariant.repo.mismatchdefault'
1003 1003 else:
1004 1004 namelabel = 'formatvariant.name.uptodate'
1005 1005 repolabel = 'formatvariant.repo.uptodate'
1006 1006
1007 1007 fm.write('name', makeformatname(fv.name), fv.name,
1008 1008 label=namelabel)
1009 1009 fm.write('repo', ' %3s', formatvalue(repovalue),
1010 1010 label=repolabel)
1011 1011 if fv.default != configvalue:
1012 1012 configlabel = 'formatvariant.config.special'
1013 1013 else:
1014 1014 configlabel = 'formatvariant.config.default'
1015 1015 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
1016 1016 label=configlabel)
1017 1017 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
1018 1018 label='formatvariant.default')
1019 1019 fm.plain('\n')
1020 1020 fm.end()
1021 1021
1022 1022 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
1023 1023 def debugfsinfo(ui, path="."):
1024 1024 """show information detected about current filesystem"""
1025 1025 ui.write(('path: %s\n') % path)
1026 1026 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
1027 1027 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
1028 1028 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
1029 1029 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
1030 1030 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
1031 1031 casesensitive = '(unknown)'
1032 1032 try:
1033 1033 with pycompat.namedtempfile(prefix='.debugfsinfo', dir=path) as f:
1034 1034 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
1035 1035 except OSError:
1036 1036 pass
1037 1037 ui.write(('case-sensitive: %s\n') % casesensitive)
1038 1038
1039 1039 @command('debuggetbundle',
1040 1040 [('H', 'head', [], _('id of head node'), _('ID')),
1041 1041 ('C', 'common', [], _('id of common node'), _('ID')),
1042 1042 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1043 1043 _('REPO FILE [-H|-C ID]...'),
1044 1044 norepo=True)
1045 1045 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1046 1046 """retrieves a bundle from a repo
1047 1047
1048 1048 Every ID must be a full-length hex node id string. Saves the bundle to the
1049 1049 given file.
1050 1050 """
1051 1051 opts = pycompat.byteskwargs(opts)
1052 1052 repo = hg.peer(ui, opts, repopath)
1053 1053 if not repo.capable('getbundle'):
1054 1054 raise error.Abort("getbundle() not supported by target repository")
1055 1055 args = {}
1056 1056 if common:
1057 1057 args[r'common'] = [bin(s) for s in common]
1058 1058 if head:
1059 1059 args[r'heads'] = [bin(s) for s in head]
1060 1060 # TODO: get desired bundlecaps from command line.
1061 1061 args[r'bundlecaps'] = None
1062 1062 bundle = repo.getbundle('debug', **args)
1063 1063
1064 1064 bundletype = opts.get('type', 'bzip2').lower()
1065 1065 btypes = {'none': 'HG10UN',
1066 1066 'bzip2': 'HG10BZ',
1067 1067 'gzip': 'HG10GZ',
1068 1068 'bundle2': 'HG20'}
1069 1069 bundletype = btypes.get(bundletype)
1070 1070 if bundletype not in bundle2.bundletypes:
1071 1071 raise error.Abort(_('unknown bundle type specified with --type'))
1072 1072 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1073 1073
1074 1074 @command('debugignore', [], '[FILE]')
1075 1075 def debugignore(ui, repo, *files, **opts):
1076 1076 """display the combined ignore pattern and information about ignored files
1077 1077
1078 1078 With no argument display the combined ignore pattern.
1079 1079
1080 1080 Given space separated file names, shows if the given file is ignored and
1081 1081 if so, show the ignore rule (file and line number) that matched it.
1082 1082 """
1083 1083 ignore = repo.dirstate._ignore
1084 1084 if not files:
1085 1085 # Show all the patterns
1086 1086 ui.write("%s\n" % pycompat.byterepr(ignore))
1087 1087 else:
1088 1088 m = scmutil.match(repo[None], pats=files)
1089 1089 for f in m.files():
1090 1090 nf = util.normpath(f)
1091 1091 ignored = None
1092 1092 ignoredata = None
1093 1093 if nf != '.':
1094 1094 if ignore(nf):
1095 1095 ignored = nf
1096 1096 ignoredata = repo.dirstate._ignorefileandline(nf)
1097 1097 else:
1098 1098 for p in util.finddirs(nf):
1099 1099 if ignore(p):
1100 1100 ignored = p
1101 1101 ignoredata = repo.dirstate._ignorefileandline(p)
1102 1102 break
1103 1103 if ignored:
1104 1104 if ignored == nf:
1105 1105 ui.write(_("%s is ignored\n") % m.uipath(f))
1106 1106 else:
1107 1107 ui.write(_("%s is ignored because of "
1108 1108 "containing folder %s\n")
1109 1109 % (m.uipath(f), ignored))
1110 1110 ignorefile, lineno, line = ignoredata
1111 1111 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1112 1112 % (ignorefile, lineno, line))
1113 1113 else:
1114 1114 ui.write(_("%s is not ignored\n") % m.uipath(f))
1115 1115
1116 1116 @command('debugindex', cmdutil.debugrevlogopts + cmdutil.formatteropts,
1117 1117 _('-c|-m|FILE'))
1118 1118 def debugindex(ui, repo, file_=None, **opts):
1119 1119 """dump index data for a storage primitive"""
1120 1120 opts = pycompat.byteskwargs(opts)
1121 1121 store = cmdutil.openstorage(repo, 'debugindex', file_, opts)
1122 1122
1123 1123 if ui.debugflag:
1124 1124 shortfn = hex
1125 1125 else:
1126 1126 shortfn = short
1127 1127
1128 1128 idlen = 12
1129 1129 for i in store:
1130 1130 idlen = len(shortfn(store.node(i)))
1131 1131 break
1132 1132
1133 1133 fm = ui.formatter('debugindex', opts)
1134 1134 fm.plain(b' rev linkrev %s %s p2\n' % (
1135 1135 b'nodeid'.ljust(idlen),
1136 1136 b'p1'.ljust(idlen)))
1137 1137
1138 1138 for rev in store:
1139 1139 node = store.node(rev)
1140 1140 parents = store.parents(node)
1141 1141
1142 1142 fm.startitem()
1143 1143 fm.write(b'rev', b'%6d ', rev)
1144 1144 fm.write(b'linkrev', '%7d ', store.linkrev(rev))
1145 1145 fm.write(b'node', '%s ', shortfn(node))
1146 1146 fm.write(b'p1', '%s ', shortfn(parents[0]))
1147 1147 fm.write(b'p2', '%s', shortfn(parents[1]))
1148 1148 fm.plain(b'\n')
1149 1149
1150 1150 fm.end()
1151 1151
1152 1152 @command('debugindexdot', cmdutil.debugrevlogopts,
1153 1153 _('-c|-m|FILE'), optionalrepo=True)
1154 1154 def debugindexdot(ui, repo, file_=None, **opts):
1155 1155 """dump an index DAG as a graphviz dot file"""
1156 1156 opts = pycompat.byteskwargs(opts)
1157 1157 r = cmdutil.openstorage(repo, 'debugindexdot', file_, opts)
1158 1158 ui.write(("digraph G {\n"))
1159 1159 for i in r:
1160 1160 node = r.node(i)
1161 1161 pp = r.parents(node)
1162 1162 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1163 1163 if pp[1] != nullid:
1164 1164 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1165 1165 ui.write("}\n")
1166 1166
1167 @command('debugindexstats', [])
1168 def debugindexstats(ui, repo):
1169 """show stats related to the changelog index"""
1170 repo.changelog.shortest(nullid, 1)
1171 for k, v in sorted(repo.changelog.index.stats().items()):
1172 ui.write('%s: %s\n' % (k, v))
1173
1167 1174 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1168 1175 def debuginstall(ui, **opts):
1169 1176 '''test Mercurial installation
1170 1177
1171 1178 Returns 0 on success.
1172 1179 '''
1173 1180 opts = pycompat.byteskwargs(opts)
1174 1181
1175 1182 def writetemp(contents):
1176 1183 (fd, name) = pycompat.mkstemp(prefix="hg-debuginstall-")
1177 1184 f = os.fdopen(fd, r"wb")
1178 1185 f.write(contents)
1179 1186 f.close()
1180 1187 return name
1181 1188
1182 1189 problems = 0
1183 1190
1184 1191 fm = ui.formatter('debuginstall', opts)
1185 1192 fm.startitem()
1186 1193
1187 1194 # encoding
1188 1195 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1189 1196 err = None
1190 1197 try:
1191 1198 codecs.lookup(pycompat.sysstr(encoding.encoding))
1192 1199 except LookupError as inst:
1193 1200 err = stringutil.forcebytestr(inst)
1194 1201 problems += 1
1195 1202 fm.condwrite(err, 'encodingerror', _(" %s\n"
1196 1203 " (check that your locale is properly set)\n"), err)
1197 1204
1198 1205 # Python
1199 1206 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1200 1207 pycompat.sysexecutable)
1201 1208 fm.write('pythonver', _("checking Python version (%s)\n"),
1202 1209 ("%d.%d.%d" % sys.version_info[:3]))
1203 1210 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1204 1211 os.path.dirname(pycompat.fsencode(os.__file__)))
1205 1212
1206 1213 security = set(sslutil.supportedprotocols)
1207 1214 if sslutil.hassni:
1208 1215 security.add('sni')
1209 1216
1210 1217 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1211 1218 fm.formatlist(sorted(security), name='protocol',
1212 1219 fmt='%s', sep=','))
1213 1220
1214 1221 # These are warnings, not errors. So don't increment problem count. This
1215 1222 # may change in the future.
1216 1223 if 'tls1.2' not in security:
1217 1224 fm.plain(_(' TLS 1.2 not supported by Python install; '
1218 1225 'network connections lack modern security\n'))
1219 1226 if 'sni' not in security:
1220 1227 fm.plain(_(' SNI not supported by Python install; may have '
1221 1228 'connectivity issues with some servers\n'))
1222 1229
1223 1230 # TODO print CA cert info
1224 1231
1225 1232 # hg version
1226 1233 hgver = util.version()
1227 1234 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1228 1235 hgver.split('+')[0])
1229 1236 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1230 1237 '+'.join(hgver.split('+')[1:]))
1231 1238
1232 1239 # compiled modules
1233 1240 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1234 1241 policy.policy)
1235 1242 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1236 1243 os.path.dirname(pycompat.fsencode(__file__)))
1237 1244
1238 1245 if policy.policy in ('c', 'allow'):
1239 1246 err = None
1240 1247 try:
1241 1248 from .cext import (
1242 1249 base85,
1243 1250 bdiff,
1244 1251 mpatch,
1245 1252 osutil,
1246 1253 )
1247 1254 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1248 1255 except Exception as inst:
1249 1256 err = stringutil.forcebytestr(inst)
1250 1257 problems += 1
1251 1258 fm.condwrite(err, 'extensionserror', " %s\n", err)
1252 1259
1253 1260 compengines = util.compengines._engines.values()
1254 1261 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1255 1262 fm.formatlist(sorted(e.name() for e in compengines),
1256 1263 name='compengine', fmt='%s', sep=', '))
1257 1264 fm.write('compenginesavail', _('checking available compression engines '
1258 1265 '(%s)\n'),
1259 1266 fm.formatlist(sorted(e.name() for e in compengines
1260 1267 if e.available()),
1261 1268 name='compengine', fmt='%s', sep=', '))
1262 1269 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1263 1270 fm.write('compenginesserver', _('checking available compression engines '
1264 1271 'for wire protocol (%s)\n'),
1265 1272 fm.formatlist([e.name() for e in wirecompengines
1266 1273 if e.wireprotosupport()],
1267 1274 name='compengine', fmt='%s', sep=', '))
1268 1275 re2 = 'missing'
1269 1276 if util._re2:
1270 1277 re2 = 'available'
1271 1278 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1272 1279 fm.data(re2=bool(util._re2))
1273 1280
1274 1281 # templates
1275 1282 p = templater.templatepaths()
1276 1283 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1277 1284 fm.condwrite(not p, '', _(" no template directories found\n"))
1278 1285 if p:
1279 1286 m = templater.templatepath("map-cmdline.default")
1280 1287 if m:
1281 1288 # template found, check if it is working
1282 1289 err = None
1283 1290 try:
1284 1291 templater.templater.frommapfile(m)
1285 1292 except Exception as inst:
1286 1293 err = stringutil.forcebytestr(inst)
1287 1294 p = None
1288 1295 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1289 1296 else:
1290 1297 p = None
1291 1298 fm.condwrite(p, 'defaulttemplate',
1292 1299 _("checking default template (%s)\n"), m)
1293 1300 fm.condwrite(not m, 'defaulttemplatenotfound',
1294 1301 _(" template '%s' not found\n"), "default")
1295 1302 if not p:
1296 1303 problems += 1
1297 1304 fm.condwrite(not p, '',
1298 1305 _(" (templates seem to have been installed incorrectly)\n"))
1299 1306
1300 1307 # editor
1301 1308 editor = ui.geteditor()
1302 1309 editor = util.expandpath(editor)
1303 1310 editorbin = procutil.shellsplit(editor)[0]
1304 1311 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1305 1312 cmdpath = procutil.findexe(editorbin)
1306 1313 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1307 1314 _(" No commit editor set and can't find %s in PATH\n"
1308 1315 " (specify a commit editor in your configuration"
1309 1316 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1310 1317 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1311 1318 _(" Can't find editor '%s' in PATH\n"
1312 1319 " (specify a commit editor in your configuration"
1313 1320 " file)\n"), not cmdpath and editorbin)
1314 1321 if not cmdpath and editor != 'vi':
1315 1322 problems += 1
1316 1323
1317 1324 # check username
1318 1325 username = None
1319 1326 err = None
1320 1327 try:
1321 1328 username = ui.username()
1322 1329 except error.Abort as e:
1323 1330 err = stringutil.forcebytestr(e)
1324 1331 problems += 1
1325 1332
1326 1333 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1327 1334 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1328 1335 " (specify a username in your configuration file)\n"), err)
1329 1336
1330 1337 fm.condwrite(not problems, '',
1331 1338 _("no problems detected\n"))
1332 1339 if not problems:
1333 1340 fm.data(problems=problems)
1334 1341 fm.condwrite(problems, 'problems',
1335 1342 _("%d problems detected,"
1336 1343 " please check your install!\n"), problems)
1337 1344 fm.end()
1338 1345
1339 1346 return problems
1340 1347
1341 1348 @command('debugknown', [], _('REPO ID...'), norepo=True)
1342 1349 def debugknown(ui, repopath, *ids, **opts):
1343 1350 """test whether node ids are known to a repo
1344 1351
1345 1352 Every ID must be a full-length hex node id string. Returns a list of 0s
1346 1353 and 1s indicating unknown/known.
1347 1354 """
1348 1355 opts = pycompat.byteskwargs(opts)
1349 1356 repo = hg.peer(ui, opts, repopath)
1350 1357 if not repo.capable('known'):
1351 1358 raise error.Abort("known() not supported by target repository")
1352 1359 flags = repo.known([bin(s) for s in ids])
1353 1360 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1354 1361
1355 1362 @command('debuglabelcomplete', [], _('LABEL...'))
1356 1363 def debuglabelcomplete(ui, repo, *args):
1357 1364 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1358 1365 debugnamecomplete(ui, repo, *args)
1359 1366
1360 1367 @command('debuglocks',
1361 1368 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1362 1369 ('W', 'force-wlock', None,
1363 1370 _('free the working state lock (DANGEROUS)')),
1364 1371 ('s', 'set-lock', None, _('set the store lock until stopped')),
1365 1372 ('S', 'set-wlock', None,
1366 1373 _('set the working state lock until stopped'))],
1367 1374 _('[OPTION]...'))
1368 1375 def debuglocks(ui, repo, **opts):
1369 1376 """show or modify state of locks
1370 1377
1371 1378 By default, this command will show which locks are held. This
1372 1379 includes the user and process holding the lock, the amount of time
1373 1380 the lock has been held, and the machine name where the process is
1374 1381 running if it's not local.
1375 1382
1376 1383 Locks protect the integrity of Mercurial's data, so should be
1377 1384 treated with care. System crashes or other interruptions may cause
1378 1385 locks to not be properly released, though Mercurial will usually
1379 1386 detect and remove such stale locks automatically.
1380 1387
1381 1388 However, detecting stale locks may not always be possible (for
1382 1389 instance, on a shared filesystem). Removing locks may also be
1383 1390 blocked by filesystem permissions.
1384 1391
1385 1392 Setting a lock will prevent other commands from changing the data.
1386 1393 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1387 1394 The set locks are removed when the command exits.
1388 1395
1389 1396 Returns 0 if no locks are held.
1390 1397
1391 1398 """
1392 1399
1393 1400 if opts.get(r'force_lock'):
1394 1401 repo.svfs.unlink('lock')
1395 1402 if opts.get(r'force_wlock'):
1396 1403 repo.vfs.unlink('wlock')
1397 1404 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1398 1405 return 0
1399 1406
1400 1407 locks = []
1401 1408 try:
1402 1409 if opts.get(r'set_wlock'):
1403 1410 try:
1404 1411 locks.append(repo.wlock(False))
1405 1412 except error.LockHeld:
1406 1413 raise error.Abort(_('wlock is already held'))
1407 1414 if opts.get(r'set_lock'):
1408 1415 try:
1409 1416 locks.append(repo.lock(False))
1410 1417 except error.LockHeld:
1411 1418 raise error.Abort(_('lock is already held'))
1412 1419 if len(locks):
1413 1420 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1414 1421 return 0
1415 1422 finally:
1416 1423 release(*locks)
1417 1424
1418 1425 now = time.time()
1419 1426 held = 0
1420 1427
1421 1428 def report(vfs, name, method):
1422 1429 # this causes stale locks to get reaped for more accurate reporting
1423 1430 try:
1424 1431 l = method(False)
1425 1432 except error.LockHeld:
1426 1433 l = None
1427 1434
1428 1435 if l:
1429 1436 l.release()
1430 1437 else:
1431 1438 try:
1432 1439 st = vfs.lstat(name)
1433 1440 age = now - st[stat.ST_MTIME]
1434 1441 user = util.username(st.st_uid)
1435 1442 locker = vfs.readlock(name)
1436 1443 if ":" in locker:
1437 1444 host, pid = locker.split(':')
1438 1445 if host == socket.gethostname():
1439 1446 locker = 'user %s, process %s' % (user or b'None', pid)
1440 1447 else:
1441 1448 locker = 'user %s, process %s, host %s' \
1442 1449 % (user or b'None', pid, host)
1443 1450 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1444 1451 return 1
1445 1452 except OSError as e:
1446 1453 if e.errno != errno.ENOENT:
1447 1454 raise
1448 1455
1449 1456 ui.write(("%-6s free\n") % (name + ":"))
1450 1457 return 0
1451 1458
1452 1459 held += report(repo.svfs, "lock", repo.lock)
1453 1460 held += report(repo.vfs, "wlock", repo.wlock)
1454 1461
1455 1462 return held
1456 1463
1457 1464 @command('debugmanifestfulltextcache', [
1458 1465 ('', 'clear', False, _('clear the cache')),
1459 1466 ('a', 'add', '', _('add the given manifest node to the cache'),
1460 1467 _('NODE'))
1461 1468 ], '')
1462 1469 def debugmanifestfulltextcache(ui, repo, add=None, **opts):
1463 1470 """show, clear or amend the contents of the manifest fulltext cache"""
1464 1471 with repo.lock():
1465 1472 r = repo.manifestlog.getstorage(b'')
1466 1473 try:
1467 1474 cache = r._fulltextcache
1468 1475 except AttributeError:
1469 1476 ui.warn(_(
1470 1477 "Current revlog implementation doesn't appear to have a "
1471 1478 'manifest fulltext cache\n'))
1472 1479 return
1473 1480
1474 1481 if opts.get(r'clear'):
1475 1482 cache.clear()
1476 1483
1477 1484 if add:
1478 1485 try:
1479 1486 manifest = repo.manifestlog[r.lookup(add)]
1480 1487 except error.LookupError as e:
1481 1488 raise error.Abort(e, hint="Check your manifest node id")
1482 1489 manifest.read() # stores revisision in cache too
1483 1490
1484 1491 if not len(cache):
1485 1492 ui.write(_('Cache empty'))
1486 1493 else:
1487 1494 ui.write(
1488 1495 _('Cache contains %d manifest entries, in order of most to '
1489 1496 'least recent:\n') % (len(cache),))
1490 1497 totalsize = 0
1491 1498 for nodeid in cache:
1492 1499 # Use cache.get to not update the LRU order
1493 1500 data = cache.get(nodeid)
1494 1501 size = len(data)
1495 1502 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size
1496 1503 ui.write(_('id: %s, size %s\n') % (
1497 1504 hex(nodeid), util.bytecount(size)))
1498 1505 ondisk = cache._opener.stat('manifestfulltextcache').st_size
1499 1506 ui.write(
1500 1507 _('Total cache data size %s, on-disk %s\n') % (
1501 1508 util.bytecount(totalsize), util.bytecount(ondisk))
1502 1509 )
1503 1510
1504 1511 @command('debugmergestate', [], '')
1505 1512 def debugmergestate(ui, repo, *args):
1506 1513 """print merge state
1507 1514
1508 1515 Use --verbose to print out information about whether v1 or v2 merge state
1509 1516 was chosen."""
1510 1517 def _hashornull(h):
1511 1518 if h == nullhex:
1512 1519 return 'null'
1513 1520 else:
1514 1521 return h
1515 1522
1516 1523 def printrecords(version):
1517 1524 ui.write(('* version %d records\n') % version)
1518 1525 if version == 1:
1519 1526 records = v1records
1520 1527 else:
1521 1528 records = v2records
1522 1529
1523 1530 for rtype, record in records:
1524 1531 # pretty print some record types
1525 1532 if rtype == 'L':
1526 1533 ui.write(('local: %s\n') % record)
1527 1534 elif rtype == 'O':
1528 1535 ui.write(('other: %s\n') % record)
1529 1536 elif rtype == 'm':
1530 1537 driver, mdstate = record.split('\0', 1)
1531 1538 ui.write(('merge driver: %s (state "%s")\n')
1532 1539 % (driver, mdstate))
1533 1540 elif rtype in 'FDC':
1534 1541 r = record.split('\0')
1535 1542 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1536 1543 if version == 1:
1537 1544 onode = 'not stored in v1 format'
1538 1545 flags = r[7]
1539 1546 else:
1540 1547 onode, flags = r[7:9]
1541 1548 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1542 1549 % (f, rtype, state, _hashornull(hash)))
1543 1550 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1544 1551 ui.write((' ancestor path: %s (node %s)\n')
1545 1552 % (afile, _hashornull(anode)))
1546 1553 ui.write((' other path: %s (node %s)\n')
1547 1554 % (ofile, _hashornull(onode)))
1548 1555 elif rtype == 'f':
1549 1556 filename, rawextras = record.split('\0', 1)
1550 1557 extras = rawextras.split('\0')
1551 1558 i = 0
1552 1559 extrastrings = []
1553 1560 while i < len(extras):
1554 1561 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1555 1562 i += 2
1556 1563
1557 1564 ui.write(('file extras: %s (%s)\n')
1558 1565 % (filename, ', '.join(extrastrings)))
1559 1566 elif rtype == 'l':
1560 1567 labels = record.split('\0', 2)
1561 1568 labels = [l for l in labels if len(l) > 0]
1562 1569 ui.write(('labels:\n'))
1563 1570 ui.write((' local: %s\n' % labels[0]))
1564 1571 ui.write((' other: %s\n' % labels[1]))
1565 1572 if len(labels) > 2:
1566 1573 ui.write((' base: %s\n' % labels[2]))
1567 1574 else:
1568 1575 ui.write(('unrecognized entry: %s\t%s\n')
1569 1576 % (rtype, record.replace('\0', '\t')))
1570 1577
1571 1578 # Avoid mergestate.read() since it may raise an exception for unsupported
1572 1579 # merge state records. We shouldn't be doing this, but this is OK since this
1573 1580 # command is pretty low-level.
1574 1581 ms = mergemod.mergestate(repo)
1575 1582
1576 1583 # sort so that reasonable information is on top
1577 1584 v1records = ms._readrecordsv1()
1578 1585 v2records = ms._readrecordsv2()
1579 1586 order = 'LOml'
1580 1587 def key(r):
1581 1588 idx = order.find(r[0])
1582 1589 if idx == -1:
1583 1590 return (1, r[1])
1584 1591 else:
1585 1592 return (0, idx)
1586 1593 v1records.sort(key=key)
1587 1594 v2records.sort(key=key)
1588 1595
1589 1596 if not v1records and not v2records:
1590 1597 ui.write(('no merge state found\n'))
1591 1598 elif not v2records:
1592 1599 ui.note(('no version 2 merge state\n'))
1593 1600 printrecords(1)
1594 1601 elif ms._v1v2match(v1records, v2records):
1595 1602 ui.note(('v1 and v2 states match: using v2\n'))
1596 1603 printrecords(2)
1597 1604 else:
1598 1605 ui.note(('v1 and v2 states mismatch: using v1\n'))
1599 1606 printrecords(1)
1600 1607 if ui.verbose:
1601 1608 printrecords(2)
1602 1609
1603 1610 @command('debugnamecomplete', [], _('NAME...'))
1604 1611 def debugnamecomplete(ui, repo, *args):
1605 1612 '''complete "names" - tags, open branch names, bookmark names'''
1606 1613
1607 1614 names = set()
1608 1615 # since we previously only listed open branches, we will handle that
1609 1616 # specially (after this for loop)
1610 1617 for name, ns in repo.names.iteritems():
1611 1618 if name != 'branches':
1612 1619 names.update(ns.listnames(repo))
1613 1620 names.update(tag for (tag, heads, tip, closed)
1614 1621 in repo.branchmap().iterbranches() if not closed)
1615 1622 completions = set()
1616 1623 if not args:
1617 1624 args = ['']
1618 1625 for a in args:
1619 1626 completions.update(n for n in names if n.startswith(a))
1620 1627 ui.write('\n'.join(sorted(completions)))
1621 1628 ui.write('\n')
1622 1629
1623 1630 @command('debugobsolete',
1624 1631 [('', 'flags', 0, _('markers flag')),
1625 1632 ('', 'record-parents', False,
1626 1633 _('record parent information for the precursor')),
1627 1634 ('r', 'rev', [], _('display markers relevant to REV')),
1628 1635 ('', 'exclusive', False, _('restrict display to markers only '
1629 1636 'relevant to REV')),
1630 1637 ('', 'index', False, _('display index of the marker')),
1631 1638 ('', 'delete', [], _('delete markers specified by indices')),
1632 1639 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1633 1640 _('[OBSOLETED [REPLACEMENT ...]]'))
1634 1641 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1635 1642 """create arbitrary obsolete marker
1636 1643
1637 1644 With no arguments, displays the list of obsolescence markers."""
1638 1645
1639 1646 opts = pycompat.byteskwargs(opts)
1640 1647
1641 1648 def parsenodeid(s):
1642 1649 try:
1643 1650 # We do not use revsingle/revrange functions here to accept
1644 1651 # arbitrary node identifiers, possibly not present in the
1645 1652 # local repository.
1646 1653 n = bin(s)
1647 1654 if len(n) != len(nullid):
1648 1655 raise TypeError()
1649 1656 return n
1650 1657 except TypeError:
1651 1658 raise error.Abort('changeset references must be full hexadecimal '
1652 1659 'node identifiers')
1653 1660
1654 1661 if opts.get('delete'):
1655 1662 indices = []
1656 1663 for v in opts.get('delete'):
1657 1664 try:
1658 1665 indices.append(int(v))
1659 1666 except ValueError:
1660 1667 raise error.Abort(_('invalid index value: %r') % v,
1661 1668 hint=_('use integers for indices'))
1662 1669
1663 1670 if repo.currenttransaction():
1664 1671 raise error.Abort(_('cannot delete obsmarkers in the middle '
1665 1672 'of transaction.'))
1666 1673
1667 1674 with repo.lock():
1668 1675 n = repair.deleteobsmarkers(repo.obsstore, indices)
1669 1676 ui.write(_('deleted %i obsolescence markers\n') % n)
1670 1677
1671 1678 return
1672 1679
1673 1680 if precursor is not None:
1674 1681 if opts['rev']:
1675 1682 raise error.Abort('cannot select revision when creating marker')
1676 1683 metadata = {}
1677 1684 metadata['user'] = encoding.fromlocal(opts['user'] or ui.username())
1678 1685 succs = tuple(parsenodeid(succ) for succ in successors)
1679 1686 l = repo.lock()
1680 1687 try:
1681 1688 tr = repo.transaction('debugobsolete')
1682 1689 try:
1683 1690 date = opts.get('date')
1684 1691 if date:
1685 1692 date = dateutil.parsedate(date)
1686 1693 else:
1687 1694 date = None
1688 1695 prec = parsenodeid(precursor)
1689 1696 parents = None
1690 1697 if opts['record_parents']:
1691 1698 if prec not in repo.unfiltered():
1692 1699 raise error.Abort('cannot used --record-parents on '
1693 1700 'unknown changesets')
1694 1701 parents = repo.unfiltered()[prec].parents()
1695 1702 parents = tuple(p.node() for p in parents)
1696 1703 repo.obsstore.create(tr, prec, succs, opts['flags'],
1697 1704 parents=parents, date=date,
1698 1705 metadata=metadata, ui=ui)
1699 1706 tr.close()
1700 1707 except ValueError as exc:
1701 1708 raise error.Abort(_('bad obsmarker input: %s') %
1702 1709 pycompat.bytestr(exc))
1703 1710 finally:
1704 1711 tr.release()
1705 1712 finally:
1706 1713 l.release()
1707 1714 else:
1708 1715 if opts['rev']:
1709 1716 revs = scmutil.revrange(repo, opts['rev'])
1710 1717 nodes = [repo[r].node() for r in revs]
1711 1718 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1712 1719 exclusive=opts['exclusive']))
1713 1720 markers.sort(key=lambda x: x._data)
1714 1721 else:
1715 1722 markers = obsutil.getmarkers(repo)
1716 1723
1717 1724 markerstoiter = markers
1718 1725 isrelevant = lambda m: True
1719 1726 if opts.get('rev') and opts.get('index'):
1720 1727 markerstoiter = obsutil.getmarkers(repo)
1721 1728 markerset = set(markers)
1722 1729 isrelevant = lambda m: m in markerset
1723 1730
1724 1731 fm = ui.formatter('debugobsolete', opts)
1725 1732 for i, m in enumerate(markerstoiter):
1726 1733 if not isrelevant(m):
1727 1734 # marker can be irrelevant when we're iterating over a set
1728 1735 # of markers (markerstoiter) which is bigger than the set
1729 1736 # of markers we want to display (markers)
1730 1737 # this can happen if both --index and --rev options are
1731 1738 # provided and thus we need to iterate over all of the markers
1732 1739 # to get the correct indices, but only display the ones that
1733 1740 # are relevant to --rev value
1734 1741 continue
1735 1742 fm.startitem()
1736 1743 ind = i if opts.get('index') else None
1737 1744 cmdutil.showmarker(fm, m, index=ind)
1738 1745 fm.end()
1739 1746
1740 1747 @command('debugpathcomplete',
1741 1748 [('f', 'full', None, _('complete an entire path')),
1742 1749 ('n', 'normal', None, _('show only normal files')),
1743 1750 ('a', 'added', None, _('show only added files')),
1744 1751 ('r', 'removed', None, _('show only removed files'))],
1745 1752 _('FILESPEC...'))
1746 1753 def debugpathcomplete(ui, repo, *specs, **opts):
1747 1754 '''complete part or all of a tracked path
1748 1755
1749 1756 This command supports shells that offer path name completion. It
1750 1757 currently completes only files already known to the dirstate.
1751 1758
1752 1759 Completion extends only to the next path segment unless
1753 1760 --full is specified, in which case entire paths are used.'''
1754 1761
1755 1762 def complete(path, acceptable):
1756 1763 dirstate = repo.dirstate
1757 1764 spec = os.path.normpath(os.path.join(encoding.getcwd(), path))
1758 1765 rootdir = repo.root + pycompat.ossep
1759 1766 if spec != repo.root and not spec.startswith(rootdir):
1760 1767 return [], []
1761 1768 if os.path.isdir(spec):
1762 1769 spec += '/'
1763 1770 spec = spec[len(rootdir):]
1764 1771 fixpaths = pycompat.ossep != '/'
1765 1772 if fixpaths:
1766 1773 spec = spec.replace(pycompat.ossep, '/')
1767 1774 speclen = len(spec)
1768 1775 fullpaths = opts[r'full']
1769 1776 files, dirs = set(), set()
1770 1777 adddir, addfile = dirs.add, files.add
1771 1778 for f, st in dirstate.iteritems():
1772 1779 if f.startswith(spec) and st[0] in acceptable:
1773 1780 if fixpaths:
1774 1781 f = f.replace('/', pycompat.ossep)
1775 1782 if fullpaths:
1776 1783 addfile(f)
1777 1784 continue
1778 1785 s = f.find(pycompat.ossep, speclen)
1779 1786 if s >= 0:
1780 1787 adddir(f[:s])
1781 1788 else:
1782 1789 addfile(f)
1783 1790 return files, dirs
1784 1791
1785 1792 acceptable = ''
1786 1793 if opts[r'normal']:
1787 1794 acceptable += 'nm'
1788 1795 if opts[r'added']:
1789 1796 acceptable += 'a'
1790 1797 if opts[r'removed']:
1791 1798 acceptable += 'r'
1792 1799 cwd = repo.getcwd()
1793 1800 if not specs:
1794 1801 specs = ['.']
1795 1802
1796 1803 files, dirs = set(), set()
1797 1804 for spec in specs:
1798 1805 f, d = complete(spec, acceptable or 'nmar')
1799 1806 files.update(f)
1800 1807 dirs.update(d)
1801 1808 files.update(dirs)
1802 1809 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1803 1810 ui.write('\n')
1804 1811
1805 1812 @command('debugpeer', [], _('PATH'), norepo=True)
1806 1813 def debugpeer(ui, path):
1807 1814 """establish a connection to a peer repository"""
1808 1815 # Always enable peer request logging. Requires --debug to display
1809 1816 # though.
1810 1817 overrides = {
1811 1818 ('devel', 'debug.peer-request'): True,
1812 1819 }
1813 1820
1814 1821 with ui.configoverride(overrides):
1815 1822 peer = hg.peer(ui, {}, path)
1816 1823
1817 1824 local = peer.local() is not None
1818 1825 canpush = peer.canpush()
1819 1826
1820 1827 ui.write(_('url: %s\n') % peer.url())
1821 1828 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1822 1829 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1823 1830
1824 1831 @command('debugpickmergetool',
1825 1832 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1826 1833 ('', 'changedelete', None, _('emulate merging change and delete')),
1827 1834 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1828 1835 _('[PATTERN]...'),
1829 1836 inferrepo=True)
1830 1837 def debugpickmergetool(ui, repo, *pats, **opts):
1831 1838 """examine which merge tool is chosen for specified file
1832 1839
1833 1840 As described in :hg:`help merge-tools`, Mercurial examines
1834 1841 configurations below in this order to decide which merge tool is
1835 1842 chosen for specified file.
1836 1843
1837 1844 1. ``--tool`` option
1838 1845 2. ``HGMERGE`` environment variable
1839 1846 3. configurations in ``merge-patterns`` section
1840 1847 4. configuration of ``ui.merge``
1841 1848 5. configurations in ``merge-tools`` section
1842 1849 6. ``hgmerge`` tool (for historical reason only)
1843 1850 7. default tool for fallback (``:merge`` or ``:prompt``)
1844 1851
1845 1852 This command writes out examination result in the style below::
1846 1853
1847 1854 FILE = MERGETOOL
1848 1855
1849 1856 By default, all files known in the first parent context of the
1850 1857 working directory are examined. Use file patterns and/or -I/-X
1851 1858 options to limit target files. -r/--rev is also useful to examine
1852 1859 files in another context without actual updating to it.
1853 1860
1854 1861 With --debug, this command shows warning messages while matching
1855 1862 against ``merge-patterns`` and so on, too. It is recommended to
1856 1863 use this option with explicit file patterns and/or -I/-X options,
1857 1864 because this option increases amount of output per file according
1858 1865 to configurations in hgrc.
1859 1866
1860 1867 With -v/--verbose, this command shows configurations below at
1861 1868 first (only if specified).
1862 1869
1863 1870 - ``--tool`` option
1864 1871 - ``HGMERGE`` environment variable
1865 1872 - configuration of ``ui.merge``
1866 1873
1867 1874 If merge tool is chosen before matching against
1868 1875 ``merge-patterns``, this command can't show any helpful
1869 1876 information, even with --debug. In such case, information above is
1870 1877 useful to know why a merge tool is chosen.
1871 1878 """
1872 1879 opts = pycompat.byteskwargs(opts)
1873 1880 overrides = {}
1874 1881 if opts['tool']:
1875 1882 overrides[('ui', 'forcemerge')] = opts['tool']
1876 1883 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1877 1884
1878 1885 with ui.configoverride(overrides, 'debugmergepatterns'):
1879 1886 hgmerge = encoding.environ.get("HGMERGE")
1880 1887 if hgmerge is not None:
1881 1888 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1882 1889 uimerge = ui.config("ui", "merge")
1883 1890 if uimerge:
1884 1891 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1885 1892
1886 1893 ctx = scmutil.revsingle(repo, opts.get('rev'))
1887 1894 m = scmutil.match(ctx, pats, opts)
1888 1895 changedelete = opts['changedelete']
1889 1896 for path in ctx.walk(m):
1890 1897 fctx = ctx[path]
1891 1898 try:
1892 1899 if not ui.debugflag:
1893 1900 ui.pushbuffer(error=True)
1894 1901 tool, toolpath = filemerge._picktool(repo, ui, path,
1895 1902 fctx.isbinary(),
1896 1903 'l' in fctx.flags(),
1897 1904 changedelete)
1898 1905 finally:
1899 1906 if not ui.debugflag:
1900 1907 ui.popbuffer()
1901 1908 ui.write(('%s = %s\n') % (path, tool))
1902 1909
1903 1910 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1904 1911 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1905 1912 '''access the pushkey key/value protocol
1906 1913
1907 1914 With two args, list the keys in the given namespace.
1908 1915
1909 1916 With five args, set a key to new if it currently is set to old.
1910 1917 Reports success or failure.
1911 1918 '''
1912 1919
1913 1920 target = hg.peer(ui, {}, repopath)
1914 1921 if keyinfo:
1915 1922 key, old, new = keyinfo
1916 1923 with target.commandexecutor() as e:
1917 1924 r = e.callcommand('pushkey', {
1918 1925 'namespace': namespace,
1919 1926 'key': key,
1920 1927 'old': old,
1921 1928 'new': new,
1922 1929 }).result()
1923 1930
1924 1931 ui.status(pycompat.bytestr(r) + '\n')
1925 1932 return not r
1926 1933 else:
1927 1934 for k, v in sorted(target.listkeys(namespace).iteritems()):
1928 1935 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1929 1936 stringutil.escapestr(v)))
1930 1937
1931 1938 @command('debugpvec', [], _('A B'))
1932 1939 def debugpvec(ui, repo, a, b=None):
1933 1940 ca = scmutil.revsingle(repo, a)
1934 1941 cb = scmutil.revsingle(repo, b)
1935 1942 pa = pvec.ctxpvec(ca)
1936 1943 pb = pvec.ctxpvec(cb)
1937 1944 if pa == pb:
1938 1945 rel = "="
1939 1946 elif pa > pb:
1940 1947 rel = ">"
1941 1948 elif pa < pb:
1942 1949 rel = "<"
1943 1950 elif pa | pb:
1944 1951 rel = "|"
1945 1952 ui.write(_("a: %s\n") % pa)
1946 1953 ui.write(_("b: %s\n") % pb)
1947 1954 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1948 1955 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1949 1956 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1950 1957 pa.distance(pb), rel))
1951 1958
1952 1959 @command('debugrebuilddirstate|debugrebuildstate',
1953 1960 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1954 1961 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1955 1962 'the working copy parent')),
1956 1963 ],
1957 1964 _('[-r REV]'))
1958 1965 def debugrebuilddirstate(ui, repo, rev, **opts):
1959 1966 """rebuild the dirstate as it would look like for the given revision
1960 1967
1961 1968 If no revision is specified the first current parent will be used.
1962 1969
1963 1970 The dirstate will be set to the files of the given revision.
1964 1971 The actual working directory content or existing dirstate
1965 1972 information such as adds or removes is not considered.
1966 1973
1967 1974 ``minimal`` will only rebuild the dirstate status for files that claim to be
1968 1975 tracked but are not in the parent manifest, or that exist in the parent
1969 1976 manifest but are not in the dirstate. It will not change adds, removes, or
1970 1977 modified files that are in the working copy parent.
1971 1978
1972 1979 One use of this command is to make the next :hg:`status` invocation
1973 1980 check the actual file content.
1974 1981 """
1975 1982 ctx = scmutil.revsingle(repo, rev)
1976 1983 with repo.wlock():
1977 1984 dirstate = repo.dirstate
1978 1985 changedfiles = None
1979 1986 # See command doc for what minimal does.
1980 1987 if opts.get(r'minimal'):
1981 1988 manifestfiles = set(ctx.manifest().keys())
1982 1989 dirstatefiles = set(dirstate)
1983 1990 manifestonly = manifestfiles - dirstatefiles
1984 1991 dsonly = dirstatefiles - manifestfiles
1985 1992 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1986 1993 changedfiles = manifestonly | dsnotadded
1987 1994
1988 1995 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1989 1996
1990 1997 @command('debugrebuildfncache', [], '')
1991 1998 def debugrebuildfncache(ui, repo):
1992 1999 """rebuild the fncache file"""
1993 2000 repair.rebuildfncache(ui, repo)
1994 2001
1995 2002 @command('debugrename',
1996 2003 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1997 2004 _('[-r REV] FILE'))
1998 2005 def debugrename(ui, repo, file1, *pats, **opts):
1999 2006 """dump rename information"""
2000 2007
2001 2008 opts = pycompat.byteskwargs(opts)
2002 2009 ctx = scmutil.revsingle(repo, opts.get('rev'))
2003 2010 m = scmutil.match(ctx, (file1,) + pats, opts)
2004 2011 for abs in ctx.walk(m):
2005 2012 fctx = ctx[abs]
2006 2013 o = fctx.filelog().renamed(fctx.filenode())
2007 2014 rel = m.rel(abs)
2008 2015 if o:
2009 2016 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2010 2017 else:
2011 2018 ui.write(_("%s not renamed\n") % rel)
2012 2019
2013 2020 @command('debugrevlog', cmdutil.debugrevlogopts +
2014 2021 [('d', 'dump', False, _('dump index data'))],
2015 2022 _('-c|-m|FILE'),
2016 2023 optionalrepo=True)
2017 2024 def debugrevlog(ui, repo, file_=None, **opts):
2018 2025 """show data and statistics about a revlog"""
2019 2026 opts = pycompat.byteskwargs(opts)
2020 2027 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2021 2028
2022 2029 if opts.get("dump"):
2023 2030 numrevs = len(r)
2024 2031 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
2025 2032 " rawsize totalsize compression heads chainlen\n"))
2026 2033 ts = 0
2027 2034 heads = set()
2028 2035
2029 2036 for rev in pycompat.xrange(numrevs):
2030 2037 dbase = r.deltaparent(rev)
2031 2038 if dbase == -1:
2032 2039 dbase = rev
2033 2040 cbase = r.chainbase(rev)
2034 2041 clen = r.chainlen(rev)
2035 2042 p1, p2 = r.parentrevs(rev)
2036 2043 rs = r.rawsize(rev)
2037 2044 ts = ts + rs
2038 2045 heads -= set(r.parentrevs(rev))
2039 2046 heads.add(rev)
2040 2047 try:
2041 2048 compression = ts / r.end(rev)
2042 2049 except ZeroDivisionError:
2043 2050 compression = 0
2044 2051 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2045 2052 "%11d %5d %8d\n" %
2046 2053 (rev, p1, p2, r.start(rev), r.end(rev),
2047 2054 r.start(dbase), r.start(cbase),
2048 2055 r.start(p1), r.start(p2),
2049 2056 rs, ts, compression, len(heads), clen))
2050 2057 return 0
2051 2058
2052 2059 v = r.version
2053 2060 format = v & 0xFFFF
2054 2061 flags = []
2055 2062 gdelta = False
2056 2063 if v & revlog.FLAG_INLINE_DATA:
2057 2064 flags.append('inline')
2058 2065 if v & revlog.FLAG_GENERALDELTA:
2059 2066 gdelta = True
2060 2067 flags.append('generaldelta')
2061 2068 if not flags:
2062 2069 flags = ['(none)']
2063 2070
2064 2071 ### tracks merge vs single parent
2065 2072 nummerges = 0
2066 2073
2067 2074 ### tracks ways the "delta" are build
2068 2075 # nodelta
2069 2076 numempty = 0
2070 2077 numemptytext = 0
2071 2078 numemptydelta = 0
2072 2079 # full file content
2073 2080 numfull = 0
2074 2081 # intermediate snapshot against a prior snapshot
2075 2082 numsemi = 0
2076 2083 # snapshot count per depth
2077 2084 numsnapdepth = collections.defaultdict(lambda: 0)
2078 2085 # delta against previous revision
2079 2086 numprev = 0
2080 2087 # delta against first or second parent (not prev)
2081 2088 nump1 = 0
2082 2089 nump2 = 0
2083 2090 # delta against neither prev nor parents
2084 2091 numother = 0
2085 2092 # delta against prev that are also first or second parent
2086 2093 # (details of `numprev`)
2087 2094 nump1prev = 0
2088 2095 nump2prev = 0
2089 2096
2090 2097 # data about delta chain of each revs
2091 2098 chainlengths = []
2092 2099 chainbases = []
2093 2100 chainspans = []
2094 2101
2095 2102 # data about each revision
2096 2103 datasize = [None, 0, 0]
2097 2104 fullsize = [None, 0, 0]
2098 2105 semisize = [None, 0, 0]
2099 2106 # snapshot count per depth
2100 2107 snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
2101 2108 deltasize = [None, 0, 0]
2102 2109 chunktypecounts = {}
2103 2110 chunktypesizes = {}
2104 2111
2105 2112 def addsize(size, l):
2106 2113 if l[0] is None or size < l[0]:
2107 2114 l[0] = size
2108 2115 if size > l[1]:
2109 2116 l[1] = size
2110 2117 l[2] += size
2111 2118
2112 2119 numrevs = len(r)
2113 2120 for rev in pycompat.xrange(numrevs):
2114 2121 p1, p2 = r.parentrevs(rev)
2115 2122 delta = r.deltaparent(rev)
2116 2123 if format > 0:
2117 2124 addsize(r.rawsize(rev), datasize)
2118 2125 if p2 != nullrev:
2119 2126 nummerges += 1
2120 2127 size = r.length(rev)
2121 2128 if delta == nullrev:
2122 2129 chainlengths.append(0)
2123 2130 chainbases.append(r.start(rev))
2124 2131 chainspans.append(size)
2125 2132 if size == 0:
2126 2133 numempty += 1
2127 2134 numemptytext += 1
2128 2135 else:
2129 2136 numfull += 1
2130 2137 numsnapdepth[0] += 1
2131 2138 addsize(size, fullsize)
2132 2139 addsize(size, snapsizedepth[0])
2133 2140 else:
2134 2141 chainlengths.append(chainlengths[delta] + 1)
2135 2142 baseaddr = chainbases[delta]
2136 2143 revaddr = r.start(rev)
2137 2144 chainbases.append(baseaddr)
2138 2145 chainspans.append((revaddr - baseaddr) + size)
2139 2146 if size == 0:
2140 2147 numempty += 1
2141 2148 numemptydelta += 1
2142 2149 elif r.issnapshot(rev):
2143 2150 addsize(size, semisize)
2144 2151 numsemi += 1
2145 2152 depth = r.snapshotdepth(rev)
2146 2153 numsnapdepth[depth] += 1
2147 2154 addsize(size, snapsizedepth[depth])
2148 2155 else:
2149 2156 addsize(size, deltasize)
2150 2157 if delta == rev - 1:
2151 2158 numprev += 1
2152 2159 if delta == p1:
2153 2160 nump1prev += 1
2154 2161 elif delta == p2:
2155 2162 nump2prev += 1
2156 2163 elif delta == p1:
2157 2164 nump1 += 1
2158 2165 elif delta == p2:
2159 2166 nump2 += 1
2160 2167 elif delta != nullrev:
2161 2168 numother += 1
2162 2169
2163 2170 # Obtain data on the raw chunks in the revlog.
2164 2171 if util.safehasattr(r, '_getsegmentforrevs'):
2165 2172 segment = r._getsegmentforrevs(rev, rev)[1]
2166 2173 else:
2167 2174 segment = r._revlog._getsegmentforrevs(rev, rev)[1]
2168 2175 if segment:
2169 2176 chunktype = bytes(segment[0:1])
2170 2177 else:
2171 2178 chunktype = 'empty'
2172 2179
2173 2180 if chunktype not in chunktypecounts:
2174 2181 chunktypecounts[chunktype] = 0
2175 2182 chunktypesizes[chunktype] = 0
2176 2183
2177 2184 chunktypecounts[chunktype] += 1
2178 2185 chunktypesizes[chunktype] += size
2179 2186
2180 2187 # Adjust size min value for empty cases
2181 2188 for size in (datasize, fullsize, semisize, deltasize):
2182 2189 if size[0] is None:
2183 2190 size[0] = 0
2184 2191
2185 2192 numdeltas = numrevs - numfull - numempty - numsemi
2186 2193 numoprev = numprev - nump1prev - nump2prev
2187 2194 totalrawsize = datasize[2]
2188 2195 datasize[2] /= numrevs
2189 2196 fulltotal = fullsize[2]
2190 2197 fullsize[2] /= numfull
2191 2198 semitotal = semisize[2]
2192 2199 snaptotal = {}
2193 2200 if 0 < numsemi:
2194 2201 semisize[2] /= numsemi
2195 2202 for depth in snapsizedepth:
2196 2203 snaptotal[depth] = snapsizedepth[depth][2]
2197 2204 snapsizedepth[depth][2] /= numsnapdepth[depth]
2198 2205
2199 2206 deltatotal = deltasize[2]
2200 2207 if numdeltas > 0:
2201 2208 deltasize[2] /= numdeltas
2202 2209 totalsize = fulltotal + semitotal + deltatotal
2203 2210 avgchainlen = sum(chainlengths) / numrevs
2204 2211 maxchainlen = max(chainlengths)
2205 2212 maxchainspan = max(chainspans)
2206 2213 compratio = 1
2207 2214 if totalsize:
2208 2215 compratio = totalrawsize / totalsize
2209 2216
2210 2217 basedfmtstr = '%%%dd\n'
2211 2218 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2212 2219
2213 2220 def dfmtstr(max):
2214 2221 return basedfmtstr % len(str(max))
2215 2222 def pcfmtstr(max, padding=0):
2216 2223 return basepcfmtstr % (len(str(max)), ' ' * padding)
2217 2224
2218 2225 def pcfmt(value, total):
2219 2226 if total:
2220 2227 return (value, 100 * float(value) / total)
2221 2228 else:
2222 2229 return value, 100.0
2223 2230
2224 2231 ui.write(('format : %d\n') % format)
2225 2232 ui.write(('flags : %s\n') % ', '.join(flags))
2226 2233
2227 2234 ui.write('\n')
2228 2235 fmt = pcfmtstr(totalsize)
2229 2236 fmt2 = dfmtstr(totalsize)
2230 2237 ui.write(('revisions : ') + fmt2 % numrevs)
2231 2238 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2232 2239 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2233 2240 ui.write(('revisions : ') + fmt2 % numrevs)
2234 2241 ui.write((' empty : ') + fmt % pcfmt(numempty, numrevs))
2235 2242 ui.write((' text : ')
2236 2243 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta))
2237 2244 ui.write((' delta : ')
2238 2245 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta))
2239 2246 ui.write((' snapshot : ') + fmt % pcfmt(numfull + numsemi, numrevs))
2240 2247 for depth in sorted(numsnapdepth):
2241 2248 ui.write((' lvl-%-3d : ' % depth)
2242 2249 + fmt % pcfmt(numsnapdepth[depth], numrevs))
2243 2250 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2244 2251 ui.write(('revision size : ') + fmt2 % totalsize)
2245 2252 ui.write((' snapshot : ')
2246 2253 + fmt % pcfmt(fulltotal + semitotal, totalsize))
2247 2254 for depth in sorted(numsnapdepth):
2248 2255 ui.write((' lvl-%-3d : ' % depth)
2249 2256 + fmt % pcfmt(snaptotal[depth], totalsize))
2250 2257 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2251 2258
2252 2259 def fmtchunktype(chunktype):
2253 2260 if chunktype == 'empty':
2254 2261 return ' %s : ' % chunktype
2255 2262 elif chunktype in pycompat.bytestr(string.ascii_letters):
2256 2263 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2257 2264 else:
2258 2265 return ' 0x%s : ' % hex(chunktype)
2259 2266
2260 2267 ui.write('\n')
2261 2268 ui.write(('chunks : ') + fmt2 % numrevs)
2262 2269 for chunktype in sorted(chunktypecounts):
2263 2270 ui.write(fmtchunktype(chunktype))
2264 2271 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2265 2272 ui.write(('chunks size : ') + fmt2 % totalsize)
2266 2273 for chunktype in sorted(chunktypecounts):
2267 2274 ui.write(fmtchunktype(chunktype))
2268 2275 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2269 2276
2270 2277 ui.write('\n')
2271 2278 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2272 2279 ui.write(('avg chain length : ') + fmt % avgchainlen)
2273 2280 ui.write(('max chain length : ') + fmt % maxchainlen)
2274 2281 ui.write(('max chain reach : ') + fmt % maxchainspan)
2275 2282 ui.write(('compression ratio : ') + fmt % compratio)
2276 2283
2277 2284 if format > 0:
2278 2285 ui.write('\n')
2279 2286 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2280 2287 % tuple(datasize))
2281 2288 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2282 2289 % tuple(fullsize))
2283 2290 ui.write(('inter-snapshot size (min/max/avg) : %d / %d / %d\n')
2284 2291 % tuple(semisize))
2285 2292 for depth in sorted(snapsizedepth):
2286 2293 if depth == 0:
2287 2294 continue
2288 2295 ui.write((' level-%-3d (min/max/avg) : %d / %d / %d\n')
2289 2296 % ((depth,) + tuple(snapsizedepth[depth])))
2290 2297 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2291 2298 % tuple(deltasize))
2292 2299
2293 2300 if numdeltas > 0:
2294 2301 ui.write('\n')
2295 2302 fmt = pcfmtstr(numdeltas)
2296 2303 fmt2 = pcfmtstr(numdeltas, 4)
2297 2304 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2298 2305 if numprev > 0:
2299 2306 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2300 2307 numprev))
2301 2308 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2302 2309 numprev))
2303 2310 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2304 2311 numprev))
2305 2312 if gdelta:
2306 2313 ui.write(('deltas against p1 : ')
2307 2314 + fmt % pcfmt(nump1, numdeltas))
2308 2315 ui.write(('deltas against p2 : ')
2309 2316 + fmt % pcfmt(nump2, numdeltas))
2310 2317 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2311 2318 numdeltas))
2312 2319
2313 2320 @command('debugrevlogindex', cmdutil.debugrevlogopts +
2314 2321 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2315 2322 _('[-f FORMAT] -c|-m|FILE'),
2316 2323 optionalrepo=True)
2317 2324 def debugrevlogindex(ui, repo, file_=None, **opts):
2318 2325 """dump the contents of a revlog index"""
2319 2326 opts = pycompat.byteskwargs(opts)
2320 2327 r = cmdutil.openrevlog(repo, 'debugrevlogindex', file_, opts)
2321 2328 format = opts.get('format', 0)
2322 2329 if format not in (0, 1):
2323 2330 raise error.Abort(_("unknown format %d") % format)
2324 2331
2325 2332 if ui.debugflag:
2326 2333 shortfn = hex
2327 2334 else:
2328 2335 shortfn = short
2329 2336
2330 2337 # There might not be anything in r, so have a sane default
2331 2338 idlen = 12
2332 2339 for i in r:
2333 2340 idlen = len(shortfn(r.node(i)))
2334 2341 break
2335 2342
2336 2343 if format == 0:
2337 2344 if ui.verbose:
2338 2345 ui.write((" rev offset length linkrev"
2339 2346 " %s %s p2\n") % ("nodeid".ljust(idlen),
2340 2347 "p1".ljust(idlen)))
2341 2348 else:
2342 2349 ui.write((" rev linkrev %s %s p2\n") % (
2343 2350 "nodeid".ljust(idlen), "p1".ljust(idlen)))
2344 2351 elif format == 1:
2345 2352 if ui.verbose:
2346 2353 ui.write((" rev flag offset length size link p1"
2347 2354 " p2 %s\n") % "nodeid".rjust(idlen))
2348 2355 else:
2349 2356 ui.write((" rev flag size link p1 p2 %s\n") %
2350 2357 "nodeid".rjust(idlen))
2351 2358
2352 2359 for i in r:
2353 2360 node = r.node(i)
2354 2361 if format == 0:
2355 2362 try:
2356 2363 pp = r.parents(node)
2357 2364 except Exception:
2358 2365 pp = [nullid, nullid]
2359 2366 if ui.verbose:
2360 2367 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
2361 2368 i, r.start(i), r.length(i), r.linkrev(i),
2362 2369 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2363 2370 else:
2364 2371 ui.write("% 6d % 7d %s %s %s\n" % (
2365 2372 i, r.linkrev(i), shortfn(node), shortfn(pp[0]),
2366 2373 shortfn(pp[1])))
2367 2374 elif format == 1:
2368 2375 pr = r.parentrevs(i)
2369 2376 if ui.verbose:
2370 2377 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
2371 2378 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2372 2379 r.linkrev(i), pr[0], pr[1], shortfn(node)))
2373 2380 else:
2374 2381 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % (
2375 2382 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1],
2376 2383 shortfn(node)))
2377 2384
2378 2385 @command('debugrevspec',
2379 2386 [('', 'optimize', None,
2380 2387 _('print parsed tree after optimizing (DEPRECATED)')),
2381 2388 ('', 'show-revs', True, _('print list of result revisions (default)')),
2382 2389 ('s', 'show-set', None, _('print internal representation of result set')),
2383 2390 ('p', 'show-stage', [],
2384 2391 _('print parsed tree at the given stage'), _('NAME')),
2385 2392 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2386 2393 ('', 'verify-optimized', False, _('verify optimized result')),
2387 2394 ],
2388 2395 ('REVSPEC'))
2389 2396 def debugrevspec(ui, repo, expr, **opts):
2390 2397 """parse and apply a revision specification
2391 2398
2392 2399 Use -p/--show-stage option to print the parsed tree at the given stages.
2393 2400 Use -p all to print tree at every stage.
2394 2401
2395 2402 Use --no-show-revs option with -s or -p to print only the set
2396 2403 representation or the parsed tree respectively.
2397 2404
2398 2405 Use --verify-optimized to compare the optimized result with the unoptimized
2399 2406 one. Returns 1 if the optimized result differs.
2400 2407 """
2401 2408 opts = pycompat.byteskwargs(opts)
2402 2409 aliases = ui.configitems('revsetalias')
2403 2410 stages = [
2404 2411 ('parsed', lambda tree: tree),
2405 2412 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2406 2413 ui.warn)),
2407 2414 ('concatenated', revsetlang.foldconcat),
2408 2415 ('analyzed', revsetlang.analyze),
2409 2416 ('optimized', revsetlang.optimize),
2410 2417 ]
2411 2418 if opts['no_optimized']:
2412 2419 stages = stages[:-1]
2413 2420 if opts['verify_optimized'] and opts['no_optimized']:
2414 2421 raise error.Abort(_('cannot use --verify-optimized with '
2415 2422 '--no-optimized'))
2416 2423 stagenames = set(n for n, f in stages)
2417 2424
2418 2425 showalways = set()
2419 2426 showchanged = set()
2420 2427 if ui.verbose and not opts['show_stage']:
2421 2428 # show parsed tree by --verbose (deprecated)
2422 2429 showalways.add('parsed')
2423 2430 showchanged.update(['expanded', 'concatenated'])
2424 2431 if opts['optimize']:
2425 2432 showalways.add('optimized')
2426 2433 if opts['show_stage'] and opts['optimize']:
2427 2434 raise error.Abort(_('cannot use --optimize with --show-stage'))
2428 2435 if opts['show_stage'] == ['all']:
2429 2436 showalways.update(stagenames)
2430 2437 else:
2431 2438 for n in opts['show_stage']:
2432 2439 if n not in stagenames:
2433 2440 raise error.Abort(_('invalid stage name: %s') % n)
2434 2441 showalways.update(opts['show_stage'])
2435 2442
2436 2443 treebystage = {}
2437 2444 printedtree = None
2438 2445 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
2439 2446 for n, f in stages:
2440 2447 treebystage[n] = tree = f(tree)
2441 2448 if n in showalways or (n in showchanged and tree != printedtree):
2442 2449 if opts['show_stage'] or n != 'parsed':
2443 2450 ui.write(("* %s:\n") % n)
2444 2451 ui.write(revsetlang.prettyformat(tree), "\n")
2445 2452 printedtree = tree
2446 2453
2447 2454 if opts['verify_optimized']:
2448 2455 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2449 2456 brevs = revset.makematcher(treebystage['optimized'])(repo)
2450 2457 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2451 2458 ui.write(("* analyzed set:\n"), stringutil.prettyrepr(arevs), "\n")
2452 2459 ui.write(("* optimized set:\n"), stringutil.prettyrepr(brevs), "\n")
2453 2460 arevs = list(arevs)
2454 2461 brevs = list(brevs)
2455 2462 if arevs == brevs:
2456 2463 return 0
2457 2464 ui.write(('--- analyzed\n'), label='diff.file_a')
2458 2465 ui.write(('+++ optimized\n'), label='diff.file_b')
2459 2466 sm = difflib.SequenceMatcher(None, arevs, brevs)
2460 2467 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2461 2468 if tag in ('delete', 'replace'):
2462 2469 for c in arevs[alo:ahi]:
2463 2470 ui.write('-%s\n' % c, label='diff.deleted')
2464 2471 if tag in ('insert', 'replace'):
2465 2472 for c in brevs[blo:bhi]:
2466 2473 ui.write('+%s\n' % c, label='diff.inserted')
2467 2474 if tag == 'equal':
2468 2475 for c in arevs[alo:ahi]:
2469 2476 ui.write(' %s\n' % c)
2470 2477 return 1
2471 2478
2472 2479 func = revset.makematcher(tree)
2473 2480 revs = func(repo)
2474 2481 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2475 2482 ui.write(("* set:\n"), stringutil.prettyrepr(revs), "\n")
2476 2483 if not opts['show_revs']:
2477 2484 return
2478 2485 for c in revs:
2479 2486 ui.write("%d\n" % c)
2480 2487
2481 2488 @command('debugserve', [
2482 2489 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2483 2490 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2484 2491 ('', 'logiofile', '', _('file to log server I/O to')),
2485 2492 ], '')
2486 2493 def debugserve(ui, repo, **opts):
2487 2494 """run a server with advanced settings
2488 2495
2489 2496 This command is similar to :hg:`serve`. It exists partially as a
2490 2497 workaround to the fact that ``hg serve --stdio`` must have specific
2491 2498 arguments for security reasons.
2492 2499 """
2493 2500 opts = pycompat.byteskwargs(opts)
2494 2501
2495 2502 if not opts['sshstdio']:
2496 2503 raise error.Abort(_('only --sshstdio is currently supported'))
2497 2504
2498 2505 logfh = None
2499 2506
2500 2507 if opts['logiofd'] and opts['logiofile']:
2501 2508 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2502 2509
2503 2510 if opts['logiofd']:
2504 2511 # Line buffered because output is line based.
2505 2512 try:
2506 2513 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2507 2514 except OSError as e:
2508 2515 if e.errno != errno.ESPIPE:
2509 2516 raise
2510 2517 # can't seek a pipe, so `ab` mode fails on py3
2511 2518 logfh = os.fdopen(int(opts['logiofd']), r'wb', 1)
2512 2519 elif opts['logiofile']:
2513 2520 logfh = open(opts['logiofile'], 'ab', 1)
2514 2521
2515 2522 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2516 2523 s.serve_forever()
2517 2524
2518 2525 @command('debugsetparents', [], _('REV1 [REV2]'))
2519 2526 def debugsetparents(ui, repo, rev1, rev2=None):
2520 2527 """manually set the parents of the current working directory
2521 2528
2522 2529 This is useful for writing repository conversion tools, but should
2523 2530 be used with care. For example, neither the working directory nor the
2524 2531 dirstate is updated, so file status may be incorrect after running this
2525 2532 command.
2526 2533
2527 2534 Returns 0 on success.
2528 2535 """
2529 2536
2530 2537 node1 = scmutil.revsingle(repo, rev1).node()
2531 2538 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2532 2539
2533 2540 with repo.wlock():
2534 2541 repo.setparents(node1, node2)
2535 2542
2536 2543 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2537 2544 def debugssl(ui, repo, source=None, **opts):
2538 2545 '''test a secure connection to a server
2539 2546
2540 2547 This builds the certificate chain for the server on Windows, installing the
2541 2548 missing intermediates and trusted root via Windows Update if necessary. It
2542 2549 does nothing on other platforms.
2543 2550
2544 2551 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2545 2552 that server is used. See :hg:`help urls` for more information.
2546 2553
2547 2554 If the update succeeds, retry the original operation. Otherwise, the cause
2548 2555 of the SSL error is likely another issue.
2549 2556 '''
2550 2557 if not pycompat.iswindows:
2551 2558 raise error.Abort(_('certificate chain building is only possible on '
2552 2559 'Windows'))
2553 2560
2554 2561 if not source:
2555 2562 if not repo:
2556 2563 raise error.Abort(_("there is no Mercurial repository here, and no "
2557 2564 "server specified"))
2558 2565 source = "default"
2559 2566
2560 2567 source, branches = hg.parseurl(ui.expandpath(source))
2561 2568 url = util.url(source)
2562 2569 addr = None
2563 2570
2564 2571 defaultport = {'https': 443, 'ssh': 22}
2565 2572 if url.scheme in defaultport:
2566 2573 try:
2567 2574 addr = (url.host, int(url.port or defaultport[url.scheme]))
2568 2575 except ValueError:
2569 2576 raise error.Abort(_("malformed port number in URL"))
2570 2577 else:
2571 2578 raise error.Abort(_("only https and ssh connections are supported"))
2572 2579
2573 2580 from . import win32
2574 2581
2575 2582 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2576 2583 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2577 2584
2578 2585 try:
2579 2586 s.connect(addr)
2580 2587 cert = s.getpeercert(True)
2581 2588
2582 2589 ui.status(_('checking the certificate chain for %s\n') % url.host)
2583 2590
2584 2591 complete = win32.checkcertificatechain(cert, build=False)
2585 2592
2586 2593 if not complete:
2587 2594 ui.status(_('certificate chain is incomplete, updating... '))
2588 2595
2589 2596 if not win32.checkcertificatechain(cert):
2590 2597 ui.status(_('failed.\n'))
2591 2598 else:
2592 2599 ui.status(_('done.\n'))
2593 2600 else:
2594 2601 ui.status(_('full certificate chain is available\n'))
2595 2602 finally:
2596 2603 s.close()
2597 2604
2598 2605 @command('debugsub',
2599 2606 [('r', 'rev', '',
2600 2607 _('revision to check'), _('REV'))],
2601 2608 _('[-r REV] [REV]'))
2602 2609 def debugsub(ui, repo, rev=None):
2603 2610 ctx = scmutil.revsingle(repo, rev, None)
2604 2611 for k, v in sorted(ctx.substate.items()):
2605 2612 ui.write(('path %s\n') % k)
2606 2613 ui.write((' source %s\n') % v[0])
2607 2614 ui.write((' revision %s\n') % v[1])
2608 2615
2609 2616 @command('debugsuccessorssets',
2610 2617 [('', 'closest', False, _('return closest successors sets only'))],
2611 2618 _('[REV]'))
2612 2619 def debugsuccessorssets(ui, repo, *revs, **opts):
2613 2620 """show set of successors for revision
2614 2621
2615 2622 A successors set of changeset A is a consistent group of revisions that
2616 2623 succeed A. It contains non-obsolete changesets only unless closests
2617 2624 successors set is set.
2618 2625
2619 2626 In most cases a changeset A has a single successors set containing a single
2620 2627 successor (changeset A replaced by A').
2621 2628
2622 2629 A changeset that is made obsolete with no successors are called "pruned".
2623 2630 Such changesets have no successors sets at all.
2624 2631
2625 2632 A changeset that has been "split" will have a successors set containing
2626 2633 more than one successor.
2627 2634
2628 2635 A changeset that has been rewritten in multiple different ways is called
2629 2636 "divergent". Such changesets have multiple successor sets (each of which
2630 2637 may also be split, i.e. have multiple successors).
2631 2638
2632 2639 Results are displayed as follows::
2633 2640
2634 2641 <rev1>
2635 2642 <successors-1A>
2636 2643 <rev2>
2637 2644 <successors-2A>
2638 2645 <successors-2B1> <successors-2B2> <successors-2B3>
2639 2646
2640 2647 Here rev2 has two possible (i.e. divergent) successors sets. The first
2641 2648 holds one element, whereas the second holds three (i.e. the changeset has
2642 2649 been split).
2643 2650 """
2644 2651 # passed to successorssets caching computation from one call to another
2645 2652 cache = {}
2646 2653 ctx2str = bytes
2647 2654 node2str = short
2648 2655 for rev in scmutil.revrange(repo, revs):
2649 2656 ctx = repo[rev]
2650 2657 ui.write('%s\n'% ctx2str(ctx))
2651 2658 for succsset in obsutil.successorssets(repo, ctx.node(),
2652 2659 closest=opts[r'closest'],
2653 2660 cache=cache):
2654 2661 if succsset:
2655 2662 ui.write(' ')
2656 2663 ui.write(node2str(succsset[0]))
2657 2664 for node in succsset[1:]:
2658 2665 ui.write(' ')
2659 2666 ui.write(node2str(node))
2660 2667 ui.write('\n')
2661 2668
2662 2669 @command('debugtemplate',
2663 2670 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2664 2671 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2665 2672 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2666 2673 optionalrepo=True)
2667 2674 def debugtemplate(ui, repo, tmpl, **opts):
2668 2675 """parse and apply a template
2669 2676
2670 2677 If -r/--rev is given, the template is processed as a log template and
2671 2678 applied to the given changesets. Otherwise, it is processed as a generic
2672 2679 template.
2673 2680
2674 2681 Use --verbose to print the parsed tree.
2675 2682 """
2676 2683 revs = None
2677 2684 if opts[r'rev']:
2678 2685 if repo is None:
2679 2686 raise error.RepoError(_('there is no Mercurial repository here '
2680 2687 '(.hg not found)'))
2681 2688 revs = scmutil.revrange(repo, opts[r'rev'])
2682 2689
2683 2690 props = {}
2684 2691 for d in opts[r'define']:
2685 2692 try:
2686 2693 k, v = (e.strip() for e in d.split('=', 1))
2687 2694 if not k or k == 'ui':
2688 2695 raise ValueError
2689 2696 props[k] = v
2690 2697 except ValueError:
2691 2698 raise error.Abort(_('malformed keyword definition: %s') % d)
2692 2699
2693 2700 if ui.verbose:
2694 2701 aliases = ui.configitems('templatealias')
2695 2702 tree = templater.parse(tmpl)
2696 2703 ui.note(templater.prettyformat(tree), '\n')
2697 2704 newtree = templater.expandaliases(tree, aliases)
2698 2705 if newtree != tree:
2699 2706 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2700 2707
2701 2708 if revs is None:
2702 2709 tres = formatter.templateresources(ui, repo)
2703 2710 t = formatter.maketemplater(ui, tmpl, resources=tres)
2704 2711 if ui.verbose:
2705 2712 kwds, funcs = t.symbolsuseddefault()
2706 2713 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2707 2714 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2708 2715 ui.write(t.renderdefault(props))
2709 2716 else:
2710 2717 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2711 2718 if ui.verbose:
2712 2719 kwds, funcs = displayer.t.symbolsuseddefault()
2713 2720 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds)))
2714 2721 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs)))
2715 2722 for r in revs:
2716 2723 displayer.show(repo[r], **pycompat.strkwargs(props))
2717 2724 displayer.close()
2718 2725
2719 2726 @command('debuguigetpass', [
2720 2727 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2721 2728 ], _('[-p TEXT]'), norepo=True)
2722 2729 def debuguigetpass(ui, prompt=''):
2723 2730 """show prompt to type password"""
2724 2731 r = ui.getpass(prompt)
2725 2732 ui.write(('respose: %s\n') % r)
2726 2733
2727 2734 @command('debuguiprompt', [
2728 2735 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2729 2736 ], _('[-p TEXT]'), norepo=True)
2730 2737 def debuguiprompt(ui, prompt=''):
2731 2738 """show plain prompt"""
2732 2739 r = ui.prompt(prompt)
2733 2740 ui.write(('response: %s\n') % r)
2734 2741
2735 2742 @command('debugupdatecaches', [])
2736 2743 def debugupdatecaches(ui, repo, *pats, **opts):
2737 2744 """warm all known caches in the repository"""
2738 2745 with repo.wlock(), repo.lock():
2739 2746 repo.updatecaches(full=True)
2740 2747
2741 2748 @command('debugupgraderepo', [
2742 2749 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2743 2750 ('', 'run', False, _('performs an upgrade')),
2744 2751 ])
2745 2752 def debugupgraderepo(ui, repo, run=False, optimize=None):
2746 2753 """upgrade a repository to use different features
2747 2754
2748 2755 If no arguments are specified, the repository is evaluated for upgrade
2749 2756 and a list of problems and potential optimizations is printed.
2750 2757
2751 2758 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2752 2759 can be influenced via additional arguments. More details will be provided
2753 2760 by the command output when run without ``--run``.
2754 2761
2755 2762 During the upgrade, the repository will be locked and no writes will be
2756 2763 allowed.
2757 2764
2758 2765 At the end of the upgrade, the repository may not be readable while new
2759 2766 repository data is swapped in. This window will be as long as it takes to
2760 2767 rename some directories inside the ``.hg`` directory. On most machines, this
2761 2768 should complete almost instantaneously and the chances of a consumer being
2762 2769 unable to access the repository should be low.
2763 2770 """
2764 2771 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2765 2772
2766 2773 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2767 2774 inferrepo=True)
2768 2775 def debugwalk(ui, repo, *pats, **opts):
2769 2776 """show how files match on given patterns"""
2770 2777 opts = pycompat.byteskwargs(opts)
2771 2778 m = scmutil.match(repo[None], pats, opts)
2772 2779 if ui.verbose:
2773 2780 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n')
2774 2781 items = list(repo[None].walk(m))
2775 2782 if not items:
2776 2783 return
2777 2784 f = lambda fn: fn
2778 2785 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2779 2786 f = lambda fn: util.normpath(fn)
2780 2787 fmt = 'f %%-%ds %%-%ds %%s' % (
2781 2788 max([len(abs) for abs in items]),
2782 2789 max([len(m.rel(abs)) for abs in items]))
2783 2790 for abs in items:
2784 2791 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2785 2792 ui.write("%s\n" % line.rstrip())
2786 2793
2787 2794 @command('debugwhyunstable', [], _('REV'))
2788 2795 def debugwhyunstable(ui, repo, rev):
2789 2796 """explain instabilities of a changeset"""
2790 2797 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
2791 2798 dnodes = ''
2792 2799 if entry.get('divergentnodes'):
2793 2800 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2794 2801 for ctx in entry['divergentnodes']) + ' '
2795 2802 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2796 2803 entry['reason'], entry['node']))
2797 2804
2798 2805 @command('debugwireargs',
2799 2806 [('', 'three', '', 'three'),
2800 2807 ('', 'four', '', 'four'),
2801 2808 ('', 'five', '', 'five'),
2802 2809 ] + cmdutil.remoteopts,
2803 2810 _('REPO [OPTIONS]... [ONE [TWO]]'),
2804 2811 norepo=True)
2805 2812 def debugwireargs(ui, repopath, *vals, **opts):
2806 2813 opts = pycompat.byteskwargs(opts)
2807 2814 repo = hg.peer(ui, opts, repopath)
2808 2815 for opt in cmdutil.remoteopts:
2809 2816 del opts[opt[1]]
2810 2817 args = {}
2811 2818 for k, v in opts.iteritems():
2812 2819 if v:
2813 2820 args[k] = v
2814 2821 args = pycompat.strkwargs(args)
2815 2822 # run twice to check that we don't mess up the stream for the next command
2816 2823 res1 = repo.debugwireargs(*vals, **args)
2817 2824 res2 = repo.debugwireargs(*vals, **args)
2818 2825 ui.write("%s\n" % res1)
2819 2826 if res1 != res2:
2820 2827 ui.warn("%s\n" % res2)
2821 2828
2822 2829 def _parsewirelangblocks(fh):
2823 2830 activeaction = None
2824 2831 blocklines = []
2825 2832
2826 2833 for line in fh:
2827 2834 line = line.rstrip()
2828 2835 if not line:
2829 2836 continue
2830 2837
2831 2838 if line.startswith(b'#'):
2832 2839 continue
2833 2840
2834 2841 if not line.startswith(b' '):
2835 2842 # New block. Flush previous one.
2836 2843 if activeaction:
2837 2844 yield activeaction, blocklines
2838 2845
2839 2846 activeaction = line
2840 2847 blocklines = []
2841 2848 continue
2842 2849
2843 2850 # Else we start with an indent.
2844 2851
2845 2852 if not activeaction:
2846 2853 raise error.Abort(_('indented line outside of block'))
2847 2854
2848 2855 blocklines.append(line)
2849 2856
2850 2857 # Flush last block.
2851 2858 if activeaction:
2852 2859 yield activeaction, blocklines
2853 2860
2854 2861 @command('debugwireproto',
2855 2862 [
2856 2863 ('', 'localssh', False, _('start an SSH server for this repo')),
2857 2864 ('', 'peer', '', _('construct a specific version of the peer')),
2858 2865 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2859 2866 ('', 'nologhandshake', False,
2860 2867 _('do not log I/O related to the peer handshake')),
2861 2868 ] + cmdutil.remoteopts,
2862 2869 _('[PATH]'),
2863 2870 optionalrepo=True)
2864 2871 def debugwireproto(ui, repo, path=None, **opts):
2865 2872 """send wire protocol commands to a server
2866 2873
2867 2874 This command can be used to issue wire protocol commands to remote
2868 2875 peers and to debug the raw data being exchanged.
2869 2876
2870 2877 ``--localssh`` will start an SSH server against the current repository
2871 2878 and connect to that. By default, the connection will perform a handshake
2872 2879 and establish an appropriate peer instance.
2873 2880
2874 2881 ``--peer`` can be used to bypass the handshake protocol and construct a
2875 2882 peer instance using the specified class type. Valid values are ``raw``,
2876 2883 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
2877 2884 raw data payloads and don't support higher-level command actions.
2878 2885
2879 2886 ``--noreadstderr`` can be used to disable automatic reading from stderr
2880 2887 of the peer (for SSH connections only). Disabling automatic reading of
2881 2888 stderr is useful for making output more deterministic.
2882 2889
2883 2890 Commands are issued via a mini language which is specified via stdin.
2884 2891 The language consists of individual actions to perform. An action is
2885 2892 defined by a block. A block is defined as a line with no leading
2886 2893 space followed by 0 or more lines with leading space. Blocks are
2887 2894 effectively a high-level command with additional metadata.
2888 2895
2889 2896 Lines beginning with ``#`` are ignored.
2890 2897
2891 2898 The following sections denote available actions.
2892 2899
2893 2900 raw
2894 2901 ---
2895 2902
2896 2903 Send raw data to the server.
2897 2904
2898 2905 The block payload contains the raw data to send as one atomic send
2899 2906 operation. The data may not actually be delivered in a single system
2900 2907 call: it depends on the abilities of the transport being used.
2901 2908
2902 2909 Each line in the block is de-indented and concatenated. Then, that
2903 2910 value is evaluated as a Python b'' literal. This allows the use of
2904 2911 backslash escaping, etc.
2905 2912
2906 2913 raw+
2907 2914 ----
2908 2915
2909 2916 Behaves like ``raw`` except flushes output afterwards.
2910 2917
2911 2918 command <X>
2912 2919 -----------
2913 2920
2914 2921 Send a request to run a named command, whose name follows the ``command``
2915 2922 string.
2916 2923
2917 2924 Arguments to the command are defined as lines in this block. The format of
2918 2925 each line is ``<key> <value>``. e.g.::
2919 2926
2920 2927 command listkeys
2921 2928 namespace bookmarks
2922 2929
2923 2930 If the value begins with ``eval:``, it will be interpreted as a Python
2924 2931 literal expression. Otherwise values are interpreted as Python b'' literals.
2925 2932 This allows sending complex types and encoding special byte sequences via
2926 2933 backslash escaping.
2927 2934
2928 2935 The following arguments have special meaning:
2929 2936
2930 2937 ``PUSHFILE``
2931 2938 When defined, the *push* mechanism of the peer will be used instead
2932 2939 of the static request-response mechanism and the content of the
2933 2940 file specified in the value of this argument will be sent as the
2934 2941 command payload.
2935 2942
2936 2943 This can be used to submit a local bundle file to the remote.
2937 2944
2938 2945 batchbegin
2939 2946 ----------
2940 2947
2941 2948 Instruct the peer to begin a batched send.
2942 2949
2943 2950 All ``command`` blocks are queued for execution until the next
2944 2951 ``batchsubmit`` block.
2945 2952
2946 2953 batchsubmit
2947 2954 -----------
2948 2955
2949 2956 Submit previously queued ``command`` blocks as a batch request.
2950 2957
2951 2958 This action MUST be paired with a ``batchbegin`` action.
2952 2959
2953 2960 httprequest <method> <path>
2954 2961 ---------------------------
2955 2962
2956 2963 (HTTP peer only)
2957 2964
2958 2965 Send an HTTP request to the peer.
2959 2966
2960 2967 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2961 2968
2962 2969 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2963 2970 headers to add to the request. e.g. ``Accept: foo``.
2964 2971
2965 2972 The following arguments are special:
2966 2973
2967 2974 ``BODYFILE``
2968 2975 The content of the file defined as the value to this argument will be
2969 2976 transferred verbatim as the HTTP request body.
2970 2977
2971 2978 ``frame <type> <flags> <payload>``
2972 2979 Send a unified protocol frame as part of the request body.
2973 2980
2974 2981 All frames will be collected and sent as the body to the HTTP
2975 2982 request.
2976 2983
2977 2984 close
2978 2985 -----
2979 2986
2980 2987 Close the connection to the server.
2981 2988
2982 2989 flush
2983 2990 -----
2984 2991
2985 2992 Flush data written to the server.
2986 2993
2987 2994 readavailable
2988 2995 -------------
2989 2996
2990 2997 Close the write end of the connection and read all available data from
2991 2998 the server.
2992 2999
2993 3000 If the connection to the server encompasses multiple pipes, we poll both
2994 3001 pipes and read available data.
2995 3002
2996 3003 readline
2997 3004 --------
2998 3005
2999 3006 Read a line of output from the server. If there are multiple output
3000 3007 pipes, reads only the main pipe.
3001 3008
3002 3009 ereadline
3003 3010 ---------
3004 3011
3005 3012 Like ``readline``, but read from the stderr pipe, if available.
3006 3013
3007 3014 read <X>
3008 3015 --------
3009 3016
3010 3017 ``read()`` N bytes from the server's main output pipe.
3011 3018
3012 3019 eread <X>
3013 3020 ---------
3014 3021
3015 3022 ``read()`` N bytes from the server's stderr pipe, if available.
3016 3023
3017 3024 Specifying Unified Frame-Based Protocol Frames
3018 3025 ----------------------------------------------
3019 3026
3020 3027 It is possible to emit a *Unified Frame-Based Protocol* by using special
3021 3028 syntax.
3022 3029
3023 3030 A frame is composed as a type, flags, and payload. These can be parsed
3024 3031 from a string of the form:
3025 3032
3026 3033 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
3027 3034
3028 3035 ``request-id`` and ``stream-id`` are integers defining the request and
3029 3036 stream identifiers.
3030 3037
3031 3038 ``type`` can be an integer value for the frame type or the string name
3032 3039 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
3033 3040 ``command-name``.
3034 3041
3035 3042 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
3036 3043 components. Each component (and there can be just one) can be an integer
3037 3044 or a flag name for stream flags or frame flags, respectively. Values are
3038 3045 resolved to integers and then bitwise OR'd together.
3039 3046
3040 3047 ``payload`` represents the raw frame payload. If it begins with
3041 3048 ``cbor:``, the following string is evaluated as Python code and the
3042 3049 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
3043 3050 as a Python byte string literal.
3044 3051 """
3045 3052 opts = pycompat.byteskwargs(opts)
3046 3053
3047 3054 if opts['localssh'] and not repo:
3048 3055 raise error.Abort(_('--localssh requires a repository'))
3049 3056
3050 3057 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'):
3051 3058 raise error.Abort(_('invalid value for --peer'),
3052 3059 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
3053 3060
3054 3061 if path and opts['localssh']:
3055 3062 raise error.Abort(_('cannot specify --localssh with an explicit '
3056 3063 'path'))
3057 3064
3058 3065 if ui.interactive():
3059 3066 ui.write(_('(waiting for commands on stdin)\n'))
3060 3067
3061 3068 blocks = list(_parsewirelangblocks(ui.fin))
3062 3069
3063 3070 proc = None
3064 3071 stdin = None
3065 3072 stdout = None
3066 3073 stderr = None
3067 3074 opener = None
3068 3075
3069 3076 if opts['localssh']:
3070 3077 # We start the SSH server in its own process so there is process
3071 3078 # separation. This prevents a whole class of potential bugs around
3072 3079 # shared state from interfering with server operation.
3073 3080 args = procutil.hgcmd() + [
3074 3081 '-R', repo.root,
3075 3082 'debugserve', '--sshstdio',
3076 3083 ]
3077 3084 proc = subprocess.Popen(pycompat.rapply(procutil.tonativestr, args),
3078 3085 stdin=subprocess.PIPE,
3079 3086 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
3080 3087 bufsize=0)
3081 3088
3082 3089 stdin = proc.stdin
3083 3090 stdout = proc.stdout
3084 3091 stderr = proc.stderr
3085 3092
3086 3093 # We turn the pipes into observers so we can log I/O.
3087 3094 if ui.verbose or opts['peer'] == 'raw':
3088 3095 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
3089 3096 logdata=True)
3090 3097 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
3091 3098 logdata=True)
3092 3099 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
3093 3100 logdata=True)
3094 3101
3095 3102 # --localssh also implies the peer connection settings.
3096 3103
3097 3104 url = 'ssh://localserver'
3098 3105 autoreadstderr = not opts['noreadstderr']
3099 3106
3100 3107 if opts['peer'] == 'ssh1':
3101 3108 ui.write(_('creating ssh peer for wire protocol version 1\n'))
3102 3109 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
3103 3110 None, autoreadstderr=autoreadstderr)
3104 3111 elif opts['peer'] == 'ssh2':
3105 3112 ui.write(_('creating ssh peer for wire protocol version 2\n'))
3106 3113 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
3107 3114 None, autoreadstderr=autoreadstderr)
3108 3115 elif opts['peer'] == 'raw':
3109 3116 ui.write(_('using raw connection to peer\n'))
3110 3117 peer = None
3111 3118 else:
3112 3119 ui.write(_('creating ssh peer from handshake results\n'))
3113 3120 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
3114 3121 autoreadstderr=autoreadstderr)
3115 3122
3116 3123 elif path:
3117 3124 # We bypass hg.peer() so we can proxy the sockets.
3118 3125 # TODO consider not doing this because we skip
3119 3126 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
3120 3127 u = util.url(path)
3121 3128 if u.scheme != 'http':
3122 3129 raise error.Abort(_('only http:// paths are currently supported'))
3123 3130
3124 3131 url, authinfo = u.authinfo()
3125 3132 openerargs = {
3126 3133 r'useragent': b'Mercurial debugwireproto',
3127 3134 }
3128 3135
3129 3136 # Turn pipes/sockets into observers so we can log I/O.
3130 3137 if ui.verbose:
3131 3138 openerargs.update({
3132 3139 r'loggingfh': ui,
3133 3140 r'loggingname': b's',
3134 3141 r'loggingopts': {
3135 3142 r'logdata': True,
3136 3143 r'logdataapis': False,
3137 3144 },
3138 3145 })
3139 3146
3140 3147 if ui.debugflag:
3141 3148 openerargs[r'loggingopts'][r'logdataapis'] = True
3142 3149
3143 3150 # Don't send default headers when in raw mode. This allows us to
3144 3151 # bypass most of the behavior of our URL handling code so we can
3145 3152 # have near complete control over what's sent on the wire.
3146 3153 if opts['peer'] == 'raw':
3147 3154 openerargs[r'sendaccept'] = False
3148 3155
3149 3156 opener = urlmod.opener(ui, authinfo, **openerargs)
3150 3157
3151 3158 if opts['peer'] == 'http2':
3152 3159 ui.write(_('creating http peer for wire protocol version 2\n'))
3153 3160 # We go through makepeer() because we need an API descriptor for
3154 3161 # the peer instance to be useful.
3155 3162 with ui.configoverride({
3156 3163 ('experimental', 'httppeer.advertise-v2'): True}):
3157 3164 if opts['nologhandshake']:
3158 3165 ui.pushbuffer()
3159 3166
3160 3167 peer = httppeer.makepeer(ui, path, opener=opener)
3161 3168
3162 3169 if opts['nologhandshake']:
3163 3170 ui.popbuffer()
3164 3171
3165 3172 if not isinstance(peer, httppeer.httpv2peer):
3166 3173 raise error.Abort(_('could not instantiate HTTP peer for '
3167 3174 'wire protocol version 2'),
3168 3175 hint=_('the server may not have the feature '
3169 3176 'enabled or is not allowing this '
3170 3177 'client version'))
3171 3178
3172 3179 elif opts['peer'] == 'raw':
3173 3180 ui.write(_('using raw connection to peer\n'))
3174 3181 peer = None
3175 3182 elif opts['peer']:
3176 3183 raise error.Abort(_('--peer %s not supported with HTTP peers') %
3177 3184 opts['peer'])
3178 3185 else:
3179 3186 peer = httppeer.makepeer(ui, path, opener=opener)
3180 3187
3181 3188 # We /could/ populate stdin/stdout with sock.makefile()...
3182 3189 else:
3183 3190 raise error.Abort(_('unsupported connection configuration'))
3184 3191
3185 3192 batchedcommands = None
3186 3193
3187 3194 # Now perform actions based on the parsed wire language instructions.
3188 3195 for action, lines in blocks:
3189 3196 if action in ('raw', 'raw+'):
3190 3197 if not stdin:
3191 3198 raise error.Abort(_('cannot call raw/raw+ on this peer'))
3192 3199
3193 3200 # Concatenate the data together.
3194 3201 data = ''.join(l.lstrip() for l in lines)
3195 3202 data = stringutil.unescapestr(data)
3196 3203 stdin.write(data)
3197 3204
3198 3205 if action == 'raw+':
3199 3206 stdin.flush()
3200 3207 elif action == 'flush':
3201 3208 if not stdin:
3202 3209 raise error.Abort(_('cannot call flush on this peer'))
3203 3210 stdin.flush()
3204 3211 elif action.startswith('command'):
3205 3212 if not peer:
3206 3213 raise error.Abort(_('cannot send commands unless peer instance '
3207 3214 'is available'))
3208 3215
3209 3216 command = action.split(' ', 1)[1]
3210 3217
3211 3218 args = {}
3212 3219 for line in lines:
3213 3220 # We need to allow empty values.
3214 3221 fields = line.lstrip().split(' ', 1)
3215 3222 if len(fields) == 1:
3216 3223 key = fields[0]
3217 3224 value = ''
3218 3225 else:
3219 3226 key, value = fields
3220 3227
3221 3228 if value.startswith('eval:'):
3222 3229 value = stringutil.evalpythonliteral(value[5:])
3223 3230 else:
3224 3231 value = stringutil.unescapestr(value)
3225 3232
3226 3233 args[key] = value
3227 3234
3228 3235 if batchedcommands is not None:
3229 3236 batchedcommands.append((command, args))
3230 3237 continue
3231 3238
3232 3239 ui.status(_('sending %s command\n') % command)
3233 3240
3234 3241 if 'PUSHFILE' in args:
3235 3242 with open(args['PUSHFILE'], r'rb') as fh:
3236 3243 del args['PUSHFILE']
3237 3244 res, output = peer._callpush(command, fh,
3238 3245 **pycompat.strkwargs(args))
3239 3246 ui.status(_('result: %s\n') % stringutil.escapestr(res))
3240 3247 ui.status(_('remote output: %s\n') %
3241 3248 stringutil.escapestr(output))
3242 3249 else:
3243 3250 with peer.commandexecutor() as e:
3244 3251 res = e.callcommand(command, args).result()
3245 3252
3246 3253 if isinstance(res, wireprotov2peer.commandresponse):
3247 3254 val = res.objects()
3248 3255 ui.status(_('response: %s\n') %
3249 3256 stringutil.pprint(val, bprefix=True, indent=2))
3250 3257 else:
3251 3258 ui.status(_('response: %s\n') %
3252 3259 stringutil.pprint(res, bprefix=True, indent=2))
3253 3260
3254 3261 elif action == 'batchbegin':
3255 3262 if batchedcommands is not None:
3256 3263 raise error.Abort(_('nested batchbegin not allowed'))
3257 3264
3258 3265 batchedcommands = []
3259 3266 elif action == 'batchsubmit':
3260 3267 # There is a batching API we could go through. But it would be
3261 3268 # difficult to normalize requests into function calls. It is easier
3262 3269 # to bypass this layer and normalize to commands + args.
3263 3270 ui.status(_('sending batch with %d sub-commands\n') %
3264 3271 len(batchedcommands))
3265 3272 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
3266 3273 ui.status(_('response #%d: %s\n') %
3267 3274 (i, stringutil.escapestr(chunk)))
3268 3275
3269 3276 batchedcommands = None
3270 3277
3271 3278 elif action.startswith('httprequest '):
3272 3279 if not opener:
3273 3280 raise error.Abort(_('cannot use httprequest without an HTTP '
3274 3281 'peer'))
3275 3282
3276 3283 request = action.split(' ', 2)
3277 3284 if len(request) != 3:
3278 3285 raise error.Abort(_('invalid httprequest: expected format is '
3279 3286 '"httprequest <method> <path>'))
3280 3287
3281 3288 method, httppath = request[1:]
3282 3289 headers = {}
3283 3290 body = None
3284 3291 frames = []
3285 3292 for line in lines:
3286 3293 line = line.lstrip()
3287 3294 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
3288 3295 if m:
3289 3296 # Headers need to use native strings.
3290 3297 key = pycompat.strurl(m.group(1))
3291 3298 value = pycompat.strurl(m.group(2))
3292 3299 headers[key] = value
3293 3300 continue
3294 3301
3295 3302 if line.startswith(b'BODYFILE '):
3296 3303 with open(line.split(b' ', 1), 'rb') as fh:
3297 3304 body = fh.read()
3298 3305 elif line.startswith(b'frame '):
3299 3306 frame = wireprotoframing.makeframefromhumanstring(
3300 3307 line[len(b'frame '):])
3301 3308
3302 3309 frames.append(frame)
3303 3310 else:
3304 3311 raise error.Abort(_('unknown argument to httprequest: %s') %
3305 3312 line)
3306 3313
3307 3314 url = path + httppath
3308 3315
3309 3316 if frames:
3310 3317 body = b''.join(bytes(f) for f in frames)
3311 3318
3312 3319 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3313 3320
3314 3321 # urllib.Request insists on using has_data() as a proxy for
3315 3322 # determining the request method. Override that to use our
3316 3323 # explicitly requested method.
3317 3324 req.get_method = lambda: pycompat.sysstr(method)
3318 3325
3319 3326 try:
3320 3327 res = opener.open(req)
3321 3328 body = res.read()
3322 3329 except util.urlerr.urlerror as e:
3323 3330 # read() method must be called, but only exists in Python 2
3324 3331 getattr(e, 'read', lambda: None)()
3325 3332 continue
3326 3333
3327 3334 ct = res.headers.get(r'Content-Type')
3328 3335 if ct == r'application/mercurial-cbor':
3329 3336 ui.write(_('cbor> %s\n') %
3330 3337 stringutil.pprint(cborutil.decodeall(body)[0],
3331 3338 bprefix=True,
3332 3339 indent=2))
3333 3340
3334 3341 elif action == 'close':
3335 3342 peer.close()
3336 3343 elif action == 'readavailable':
3337 3344 if not stdout or not stderr:
3338 3345 raise error.Abort(_('readavailable not available on this peer'))
3339 3346
3340 3347 stdin.close()
3341 3348 stdout.read()
3342 3349 stderr.read()
3343 3350
3344 3351 elif action == 'readline':
3345 3352 if not stdout:
3346 3353 raise error.Abort(_('readline not available on this peer'))
3347 3354 stdout.readline()
3348 3355 elif action == 'ereadline':
3349 3356 if not stderr:
3350 3357 raise error.Abort(_('ereadline not available on this peer'))
3351 3358 stderr.readline()
3352 3359 elif action.startswith('read '):
3353 3360 count = int(action.split(' ', 1)[1])
3354 3361 if not stdout:
3355 3362 raise error.Abort(_('read not available on this peer'))
3356 3363 stdout.read(count)
3357 3364 elif action.startswith('eread '):
3358 3365 count = int(action.split(' ', 1)[1])
3359 3366 if not stderr:
3360 3367 raise error.Abort(_('eread not available on this peer'))
3361 3368 stderr.read(count)
3362 3369 else:
3363 3370 raise error.Abort(_('unknown action: %s') % action)
3364 3371
3365 3372 if batchedcommands is not None:
3366 3373 raise error.Abort(_('unclosed "batchbegin" request'))
3367 3374
3368 3375 if peer:
3369 3376 peer.close()
3370 3377
3371 3378 if proc:
3372 3379 proc.kill()
@@ -1,406 +1,408 b''
1 1 Show all commands except debug commands
2 2 $ hg debugcomplete
3 3 add
4 4 addremove
5 5 annotate
6 6 archive
7 7 backout
8 8 bisect
9 9 bookmarks
10 10 branch
11 11 branches
12 12 bundle
13 13 cat
14 14 clone
15 15 commit
16 16 config
17 17 copy
18 18 diff
19 19 export
20 20 files
21 21 forget
22 22 graft
23 23 grep
24 24 heads
25 25 help
26 26 identify
27 27 import
28 28 incoming
29 29 init
30 30 locate
31 31 log
32 32 manifest
33 33 merge
34 34 outgoing
35 35 parents
36 36 paths
37 37 phase
38 38 pull
39 39 push
40 40 recover
41 41 remove
42 42 rename
43 43 resolve
44 44 revert
45 45 rollback
46 46 root
47 47 serve
48 48 status
49 49 summary
50 50 tag
51 51 tags
52 52 tip
53 53 unbundle
54 54 update
55 55 verify
56 56 version
57 57
58 58 Show all commands that start with "a"
59 59 $ hg debugcomplete a
60 60 add
61 61 addremove
62 62 annotate
63 63 archive
64 64
65 65 Do not show debug commands if there are other candidates
66 66 $ hg debugcomplete d
67 67 diff
68 68
69 69 Show debug commands if there are no other candidates
70 70 $ hg debugcomplete debug
71 71 debugancestor
72 72 debugapplystreamclonebundle
73 73 debugbuilddag
74 74 debugbundle
75 75 debugcapabilities
76 76 debugcheckstate
77 77 debugcolor
78 78 debugcommands
79 79 debugcomplete
80 80 debugconfig
81 81 debugcreatestreamclonebundle
82 82 debugdag
83 83 debugdata
84 84 debugdate
85 85 debugdeltachain
86 86 debugdirstate
87 87 debugdiscovery
88 88 debugdownload
89 89 debugextensions
90 90 debugfileset
91 91 debugformat
92 92 debugfsinfo
93 93 debuggetbundle
94 94 debugignore
95 95 debugindex
96 96 debugindexdot
97 debugindexstats
97 98 debuginstall
98 99 debugknown
99 100 debuglabelcomplete
100 101 debuglocks
101 102 debugmanifestfulltextcache
102 103 debugmergestate
103 104 debugnamecomplete
104 105 debugobsolete
105 106 debugpathcomplete
106 107 debugpeer
107 108 debugpickmergetool
108 109 debugpushkey
109 110 debugpvec
110 111 debugrebuilddirstate
111 112 debugrebuildfncache
112 113 debugrename
113 114 debugrevlog
114 115 debugrevlogindex
115 116 debugrevspec
116 117 debugserve
117 118 debugsetparents
118 119 debugssl
119 120 debugsub
120 121 debugsuccessorssets
121 122 debugtemplate
122 123 debuguigetpass
123 124 debuguiprompt
124 125 debugupdatecaches
125 126 debugupgraderepo
126 127 debugwalk
127 128 debugwhyunstable
128 129 debugwireargs
129 130 debugwireproto
130 131
131 132 Do not show the alias of a debug command if there are other candidates
132 133 (this should hide rawcommit)
133 134 $ hg debugcomplete r
134 135 recover
135 136 remove
136 137 rename
137 138 resolve
138 139 revert
139 140 rollback
140 141 root
141 142 Show the alias of a debug command if there are no other candidates
142 143 $ hg debugcomplete rawc
143 144
144 145
145 146 Show the global options
146 147 $ hg debugcomplete --options | sort
147 148 --color
148 149 --config
149 150 --cwd
150 151 --debug
151 152 --debugger
152 153 --encoding
153 154 --encodingmode
154 155 --help
155 156 --hidden
156 157 --noninteractive
157 158 --pager
158 159 --profile
159 160 --quiet
160 161 --repository
161 162 --time
162 163 --traceback
163 164 --verbose
164 165 --version
165 166 -R
166 167 -h
167 168 -q
168 169 -v
169 170 -y
170 171
171 172 Show the options for the "serve" command
172 173 $ hg debugcomplete --options serve | sort
173 174 --accesslog
174 175 --address
175 176 --certificate
176 177 --cmdserver
177 178 --color
178 179 --config
179 180 --cwd
180 181 --daemon
181 182 --daemon-postexec
182 183 --debug
183 184 --debugger
184 185 --encoding
185 186 --encodingmode
186 187 --errorlog
187 188 --help
188 189 --hidden
189 190 --ipv6
190 191 --name
191 192 --noninteractive
192 193 --pager
193 194 --pid-file
194 195 --port
195 196 --prefix
196 197 --print-url
197 198 --profile
198 199 --quiet
199 200 --repository
200 201 --stdio
201 202 --style
202 203 --subrepos
203 204 --templates
204 205 --time
205 206 --traceback
206 207 --verbose
207 208 --version
208 209 --web-conf
209 210 -6
210 211 -A
211 212 -E
212 213 -R
213 214 -S
214 215 -a
215 216 -d
216 217 -h
217 218 -n
218 219 -p
219 220 -q
220 221 -t
221 222 -v
222 223 -y
223 224
224 225 Show an error if we use --options with an ambiguous abbreviation
225 226 $ hg debugcomplete --options s
226 227 hg: command 's' is ambiguous:
227 228 serve showconfig status summary
228 229 [255]
229 230
230 231 Show all commands + options
231 232 $ hg debugcommands
232 233 add: include, exclude, subrepos, dry-run
233 234 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
234 235 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
235 236 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
236 237 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
237 238 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
238 239 forget: interactive, include, exclude, dry-run
239 240 init: ssh, remotecmd, insecure
240 241 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
241 242 merge: force, rev, preview, abort, tool
242 243 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
243 244 push: force, rev, bookmark, branch, new-branch, pushvars, ssh, remotecmd, insecure
244 245 remove: after, force, subrepos, include, exclude, dry-run
245 246 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
246 247 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
247 248 summary: remote
248 249 update: clean, check, merge, date, rev, tool
249 250 addremove: similarity, subrepos, include, exclude, dry-run
250 251 archive: no-decode, prefix, rev, type, subrepos, include, exclude
251 252 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
252 253 bisect: reset, good, bad, skip, extend, command, noupdate
253 254 bookmarks: force, rev, delete, rename, inactive, list, template
254 255 branch: force, clean, rev
255 256 branches: active, closed, template
256 257 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
257 258 cat: output, rev, decode, include, exclude, template
258 259 config: untrusted, edit, local, global, template
259 260 copy: after, force, include, exclude, dry-run
260 261 debugancestor:
261 262 debugapplystreamclonebundle:
262 263 debugbuilddag: mergeable-file, overwritten-file, new-file
263 264 debugbundle: all, part-type, spec
264 265 debugcapabilities:
265 266 debugcheckstate:
266 267 debugcolor: style
267 268 debugcommands:
268 269 debugcomplete: options
269 270 debugcreatestreamclonebundle:
270 271 debugdag: tags, branches, dots, spaces
271 272 debugdata: changelog, manifest, dir
272 273 debugdate: extended
273 274 debugdeltachain: changelog, manifest, dir, template
274 275 debugdirstate: nodates, dates, datesort
275 276 debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure
276 277 debugdownload: output
277 278 debugextensions: template
278 279 debugfileset: rev, all-files, show-matcher, show-stage
279 280 debugformat: template
280 281 debugfsinfo:
281 282 debuggetbundle: head, common, type
282 283 debugignore:
283 284 debugindex: changelog, manifest, dir, template
284 285 debugindexdot: changelog, manifest, dir
286 debugindexstats:
285 287 debuginstall: template
286 288 debugknown:
287 289 debuglabelcomplete:
288 290 debuglocks: force-lock, force-wlock, set-lock, set-wlock
289 291 debugmanifestfulltextcache: clear, add
290 292 debugmergestate:
291 293 debugnamecomplete:
292 294 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
293 295 debugpathcomplete: full, normal, added, removed
294 296 debugpeer:
295 297 debugpickmergetool: rev, changedelete, include, exclude, tool
296 298 debugpushkey:
297 299 debugpvec:
298 300 debugrebuilddirstate: rev, minimal
299 301 debugrebuildfncache:
300 302 debugrename: rev
301 303 debugrevlog: changelog, manifest, dir, dump
302 304 debugrevlogindex: changelog, manifest, dir, format
303 305 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
304 306 debugserve: sshstdio, logiofd, logiofile
305 307 debugsetparents:
306 308 debugssl:
307 309 debugsub: rev
308 310 debugsuccessorssets: closest
309 311 debugtemplate: rev, define
310 312 debuguigetpass: prompt
311 313 debuguiprompt: prompt
312 314 debugupdatecaches:
313 315 debugupgraderepo: optimize, run
314 316 debugwalk: include, exclude
315 317 debugwhyunstable:
316 318 debugwireargs: three, four, five, ssh, remotecmd, insecure
317 319 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
318 320 files: rev, print0, include, exclude, template, subrepos
319 321 graft: rev, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
320 322 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
321 323 heads: rev, topo, active, closed, style, template
322 324 help: extension, command, keyword, system
323 325 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
324 326 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
325 327 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
326 328 locate: rev, print0, fullpath, include, exclude
327 329 manifest: rev, all, template
328 330 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
329 331 parents: rev, style, template
330 332 paths: template
331 333 phase: public, draft, secret, force, rev
332 334 recover:
333 335 rename: after, force, include, exclude, dry-run
334 336 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
335 337 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
336 338 rollback: dry-run, force
337 339 root:
338 340 tag: force, local, rev, remove, edit, message, date, user
339 341 tags: template
340 342 tip: patch, git, style, template
341 343 unbundle: update
342 344 verify:
343 345 version: template
344 346
345 347 $ hg init a
346 348 $ cd a
347 349 $ echo fee > fee
348 350 $ hg ci -q -Amfee
349 351 $ hg tag fee
350 352 $ mkdir fie
351 353 $ echo dead > fie/dead
352 354 $ echo live > fie/live
353 355 $ hg bookmark fo
354 356 $ hg branch -q fie
355 357 $ hg ci -q -Amfie
356 358 $ echo fo > fo
357 359 $ hg branch -qf default
358 360 $ hg ci -q -Amfo
359 361 $ echo Fum > Fum
360 362 $ hg ci -q -AmFum
361 363 $ hg bookmark Fum
362 364
363 365 Test debugpathcomplete
364 366
365 367 $ hg debugpathcomplete f
366 368 fee
367 369 fie
368 370 fo
369 371 $ hg debugpathcomplete -f f
370 372 fee
371 373 fie/dead
372 374 fie/live
373 375 fo
374 376
375 377 $ hg rm Fum
376 378 $ hg debugpathcomplete -r F
377 379 Fum
378 380
379 381 Test debugnamecomplete
380 382
381 383 $ hg debugnamecomplete
382 384 Fum
383 385 default
384 386 fee
385 387 fie
386 388 fo
387 389 tip
388 390 $ hg debugnamecomplete f
389 391 fee
390 392 fie
391 393 fo
392 394
393 395 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
394 396 used for completions in some shells.
395 397
396 398 $ hg debuglabelcomplete
397 399 Fum
398 400 default
399 401 fee
400 402 fie
401 403 fo
402 404 tip
403 405 $ hg debuglabelcomplete f
404 406 fee
405 407 fie
406 408 fo
@@ -1,625 +1,635 b''
1 1 $ cat << EOF >> $HGRCPATH
2 2 > [ui]
3 3 > interactive=yes
4 4 > EOF
5 5
6 6 $ hg init debugrevlog
7 7 $ cd debugrevlog
8 8 $ echo a > a
9 9 $ hg ci -Am adda
10 10 adding a
11 11 $ hg rm .
12 12 removing a
13 13 $ hg ci -Am make-it-empty
14 14 $ hg revert --all -r 0
15 15 adding a
16 16 $ hg ci -Am make-it-full
17 17 #if reporevlogstore
18 18 $ hg debugrevlog -c
19 19 format : 1
20 20 flags : inline
21 21
22 22 revisions : 3
23 23 merges : 0 ( 0.00%)
24 24 normal : 3 (100.00%)
25 25 revisions : 3
26 26 empty : 0 ( 0.00%)
27 27 text : 0 (100.00%)
28 28 delta : 0 (100.00%)
29 29 snapshot : 3 (100.00%)
30 30 lvl-0 : 3 (100.00%)
31 31 deltas : 0 ( 0.00%)
32 32 revision size : 191
33 33 snapshot : 191 (100.00%)
34 34 lvl-0 : 191 (100.00%)
35 35 deltas : 0 ( 0.00%)
36 36
37 37 chunks : 3
38 38 0x75 (u) : 3 (100.00%)
39 39 chunks size : 191
40 40 0x75 (u) : 191 (100.00%)
41 41
42 42 avg chain length : 0
43 43 max chain length : 0
44 44 max chain reach : 67
45 45 compression ratio : 0
46 46
47 47 uncompressed data size (min/max/avg) : 57 / 66 / 62
48 48 full revision size (min/max/avg) : 58 / 67 / 63
49 49 inter-snapshot size (min/max/avg) : 0 / 0 / 0
50 50 delta size (min/max/avg) : 0 / 0 / 0
51 51 $ hg debugrevlog -m
52 52 format : 1
53 53 flags : inline, generaldelta
54 54
55 55 revisions : 3
56 56 merges : 0 ( 0.00%)
57 57 normal : 3 (100.00%)
58 58 revisions : 3
59 59 empty : 1 (33.33%)
60 60 text : 1 (100.00%)
61 61 delta : 0 ( 0.00%)
62 62 snapshot : 2 (66.67%)
63 63 lvl-0 : 2 (66.67%)
64 64 deltas : 0 ( 0.00%)
65 65 revision size : 88
66 66 snapshot : 88 (100.00%)
67 67 lvl-0 : 88 (100.00%)
68 68 deltas : 0 ( 0.00%)
69 69
70 70 chunks : 3
71 71 empty : 1 (33.33%)
72 72 0x75 (u) : 2 (66.67%)
73 73 chunks size : 88
74 74 empty : 0 ( 0.00%)
75 75 0x75 (u) : 88 (100.00%)
76 76
77 77 avg chain length : 0
78 78 max chain length : 0
79 79 max chain reach : 44
80 80 compression ratio : 0
81 81
82 82 uncompressed data size (min/max/avg) : 0 / 43 / 28
83 83 full revision size (min/max/avg) : 44 / 44 / 44
84 84 inter-snapshot size (min/max/avg) : 0 / 0 / 0
85 85 delta size (min/max/avg) : 0 / 0 / 0
86 86 $ hg debugrevlog a
87 87 format : 1
88 88 flags : inline, generaldelta
89 89
90 90 revisions : 1
91 91 merges : 0 ( 0.00%)
92 92 normal : 1 (100.00%)
93 93 revisions : 1
94 94 empty : 0 ( 0.00%)
95 95 text : 0 (100.00%)
96 96 delta : 0 (100.00%)
97 97 snapshot : 1 (100.00%)
98 98 lvl-0 : 1 (100.00%)
99 99 deltas : 0 ( 0.00%)
100 100 revision size : 3
101 101 snapshot : 3 (100.00%)
102 102 lvl-0 : 3 (100.00%)
103 103 deltas : 0 ( 0.00%)
104 104
105 105 chunks : 1
106 106 0x75 (u) : 1 (100.00%)
107 107 chunks size : 3
108 108 0x75 (u) : 3 (100.00%)
109 109
110 110 avg chain length : 0
111 111 max chain length : 0
112 112 max chain reach : 3
113 113 compression ratio : 0
114 114
115 115 uncompressed data size (min/max/avg) : 2 / 2 / 2
116 116 full revision size (min/max/avg) : 3 / 3 / 3
117 117 inter-snapshot size (min/max/avg) : 0 / 0 / 0
118 118 delta size (min/max/avg) : 0 / 0 / 0
119 119 #endif
120 120
121 121 Test debugindex, with and without the --verbose/--debug flag
122 122 $ hg debugrevlogindex a
123 123 rev linkrev nodeid p1 p2
124 124 0 0 b789fdd96dc2 000000000000 000000000000
125 125
126 126 #if no-reposimplestore
127 127 $ hg --verbose debugrevlogindex a
128 128 rev offset length linkrev nodeid p1 p2
129 129 0 0 3 0 b789fdd96dc2 000000000000 000000000000
130 130
131 131 $ hg --debug debugrevlogindex a
132 132 rev offset length linkrev nodeid p1 p2
133 133 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
134 134 #endif
135 135
136 136 $ hg debugrevlogindex -f 1 a
137 137 rev flag size link p1 p2 nodeid
138 138 0 0000 2 0 -1 -1 b789fdd96dc2
139 139
140 140 #if no-reposimplestore
141 141 $ hg --verbose debugrevlogindex -f 1 a
142 142 rev flag offset length size link p1 p2 nodeid
143 143 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
144 144
145 145 $ hg --debug debugrevlogindex -f 1 a
146 146 rev flag offset length size link p1 p2 nodeid
147 147 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
148 148 #endif
149 149
150 150 $ hg debugindex -c
151 151 rev linkrev nodeid p1 p2
152 152 0 0 07f494440405 000000000000 000000000000
153 153 1 1 8cccb4b5fec2 07f494440405 000000000000
154 154 2 2 b1e228c512c5 8cccb4b5fec2 000000000000
155 155 $ hg debugindex -c --debug
156 156 rev linkrev nodeid p1 p2
157 157 0 0 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
158 158 1 1 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000
159 159 2 2 b1e228c512c5d7066d70562ed839c3323a62d6d2 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 0000000000000000000000000000000000000000
160 160 $ hg debugindex -m
161 161 rev linkrev nodeid p1 p2
162 162 0 0 a0c8bcbbb45c 000000000000 000000000000
163 163 1 1 57faf8a737ae a0c8bcbbb45c 000000000000
164 164 2 2 a35b10320954 57faf8a737ae 000000000000
165 165 $ hg debugindex -m --debug
166 166 rev linkrev nodeid p1 p2
167 167 0 0 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
168 168 1 1 57faf8a737ae7faf490582941a82319ba6529dca a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000
169 169 2 2 a35b103209548032201c16c7688cb2657f037a38 57faf8a737ae7faf490582941a82319ba6529dca 0000000000000000000000000000000000000000
170 170 $ hg debugindex a
171 171 rev linkrev nodeid p1 p2
172 172 0 0 b789fdd96dc2 000000000000 000000000000
173 173 $ hg debugindex --debug a
174 174 rev linkrev nodeid p1 p2
175 175 0 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
176 176
177 177 debugdelta chain basic output
178 178
179 179 #if reporevlogstore
180 $ hg debugindexstats
181 node trie capacity: 4
182 node trie count: 2
183 node trie depth: 1
184 node trie last rev scanned: -1
185 node trie lookups: 4
186 node trie misses: 1
187 node trie splits: 1
188 revs in memory: 3
189
180 190 $ hg debugdeltachain -m
181 191 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
182 192 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000
183 193 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000
184 194 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000
185 195
186 196 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
187 197 0 1 1
188 198 1 2 1
189 199 2 3 1
190 200
191 201 $ hg debugdeltachain -m -Tjson
192 202 [
193 203 {
194 204 "chainid": 1,
195 205 "chainlen": 1,
196 206 "chainratio": 1.02325581395, (no-py3k !)
197 207 "chainratio": 1.0232558139534884, (py3k !)
198 208 "chainsize": 44,
199 209 "compsize": 44,
200 210 "deltatype": "base",
201 211 "extradist": 0,
202 212 "extraratio": 0.0,
203 213 "lindist": 44,
204 214 "prevrev": -1,
205 215 "rev": 0,
206 216 "uncompsize": 43
207 217 },
208 218 {
209 219 "chainid": 2,
210 220 "chainlen": 1,
211 221 "chainratio": 0,
212 222 "chainsize": 0,
213 223 "compsize": 0,
214 224 "deltatype": "base",
215 225 "extradist": 0,
216 226 "extraratio": 0,
217 227 "lindist": 0,
218 228 "prevrev": -1,
219 229 "rev": 1,
220 230 "uncompsize": 0
221 231 },
222 232 {
223 233 "chainid": 3,
224 234 "chainlen": 1,
225 235 "chainratio": 1.02325581395, (no-py3k !)
226 236 "chainratio": 1.0232558139534884, (py3k !)
227 237 "chainsize": 44,
228 238 "compsize": 44,
229 239 "deltatype": "base",
230 240 "extradist": 0,
231 241 "extraratio": 0.0,
232 242 "lindist": 44,
233 243 "prevrev": -1,
234 244 "rev": 2,
235 245 "uncompsize": 43
236 246 }
237 247 ]
238 248
239 249 debugdelta chain with sparse read enabled
240 250
241 251 $ cat >> $HGRCPATH <<EOF
242 252 > [experimental]
243 253 > sparse-read = True
244 254 > EOF
245 255 $ hg debugdeltachain -m
246 256 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
247 257 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
248 258 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
249 259 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
250 260
251 261 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
252 262 0 1 1 44 44 1.0
253 263 1 2 1 0 0 1
254 264 2 3 1 44 44 1.0
255 265
256 266 $ hg debugdeltachain -m -Tjson
257 267 [
258 268 {
259 269 "chainid": 1,
260 270 "chainlen": 1,
261 271 "chainratio": 1.02325581395, (no-py3k !)
262 272 "chainratio": 1.0232558139534884, (py3k !)
263 273 "chainsize": 44,
264 274 "compsize": 44,
265 275 "deltatype": "base",
266 276 "extradist": 0,
267 277 "extraratio": 0.0,
268 278 "largestblock": 44,
269 279 "lindist": 44,
270 280 "prevrev": -1,
271 281 "readdensity": 1.0,
272 282 "readsize": 44,
273 283 "rev": 0,
274 284 "srchunks": 1,
275 285 "uncompsize": 43
276 286 },
277 287 {
278 288 "chainid": 2,
279 289 "chainlen": 1,
280 290 "chainratio": 0,
281 291 "chainsize": 0,
282 292 "compsize": 0,
283 293 "deltatype": "base",
284 294 "extradist": 0,
285 295 "extraratio": 0,
286 296 "largestblock": 0,
287 297 "lindist": 0,
288 298 "prevrev": -1,
289 299 "readdensity": 1,
290 300 "readsize": 0,
291 301 "rev": 1,
292 302 "srchunks": 1,
293 303 "uncompsize": 0
294 304 },
295 305 {
296 306 "chainid": 3,
297 307 "chainlen": 1,
298 308 "chainratio": 1.02325581395, (no-py3k !)
299 309 "chainratio": 1.0232558139534884, (py3k !)
300 310 "chainsize": 44,
301 311 "compsize": 44,
302 312 "deltatype": "base",
303 313 "extradist": 0,
304 314 "extraratio": 0.0,
305 315 "largestblock": 44,
306 316 "lindist": 44,
307 317 "prevrev": -1,
308 318 "readdensity": 1.0,
309 319 "readsize": 44,
310 320 "rev": 2,
311 321 "srchunks": 1,
312 322 "uncompsize": 43
313 323 }
314 324 ]
315 325
316 326 $ printf "This test checks things.\n" >> a
317 327 $ hg ci -m a
318 328 $ hg branch other
319 329 marked working directory as branch other
320 330 (branches are permanent and global, did you want a bookmark?)
321 331 $ for i in `$TESTDIR/seq.py 5`; do
322 332 > printf "shorter ${i}" >> a
323 333 > hg ci -m "a other:$i"
324 334 > hg up -q default
325 335 > printf "for the branch default we want longer chains: ${i}" >> a
326 336 > hg ci -m "a default:$i"
327 337 > hg up -q other
328 338 > done
329 339 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
330 340 > --config experimental.sparse-read.density-threshold=0.50 \
331 341 > --config experimental.sparse-read.min-gap-size=0
332 342 0 1
333 343 1 1
334 344 2 1
335 345 3 1
336 346 4 1
337 347 5 1
338 348 6 1
339 349 7 1
340 350 8 1
341 351 9 1
342 352 10 2
343 353 11 1
344 354 $ hg --config extensions.strip= strip --no-backup -r 1
345 355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 356
347 357 Test max chain len
348 358 $ cat >> $HGRCPATH << EOF
349 359 > [format]
350 360 > maxchainlen=4
351 361 > EOF
352 362
353 363 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
354 364 $ hg ci -m a
355 365 $ printf "b\n" >> a
356 366 $ hg ci -m a
357 367 $ printf "c\n" >> a
358 368 $ hg ci -m a
359 369 $ printf "d\n" >> a
360 370 $ hg ci -m a
361 371 $ printf "e\n" >> a
362 372 $ hg ci -m a
363 373 $ printf "f\n" >> a
364 374 $ hg ci -m a
365 375 $ printf 'g\n' >> a
366 376 $ hg ci -m a
367 377 $ printf 'h\n' >> a
368 378 $ hg ci -m a
369 379
370 380 $ hg debugrevlog -d a
371 381 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
372 382 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
373 383 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
374 384 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
375 385 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
376 386 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
377 387 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
378 388 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
379 389 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
380 390 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
381 391 #endif
382 392
383 393 Test debuglocks command:
384 394
385 395 $ hg debuglocks
386 396 lock: free
387 397 wlock: free
388 398
389 399 * Test setting the lock
390 400
391 401 waitlock <file> will wait for file to be created. If it isn't in a reasonable
392 402 amount of time, displays error message and returns 1
393 403 $ waitlock() {
394 404 > start=`date +%s`
395 405 > timeout=5
396 406 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
397 407 > now=`date +%s`
398 408 > if [ "`expr $now - $start`" -gt $timeout ]; then
399 409 > echo "timeout: $1 was not created in $timeout seconds"
400 410 > return 1
401 411 > fi
402 412 > sleep 0.1
403 413 > done
404 414 > }
405 415 $ dolock() {
406 416 > {
407 417 > waitlock .hg/unlock
408 418 > rm -f .hg/unlock
409 419 > echo y
410 420 > } | hg debuglocks "$@" > /dev/null
411 421 > }
412 422 $ dolock -s &
413 423 $ waitlock .hg/store/lock
414 424
415 425 $ hg debuglocks
416 426 lock: user *, process * (*s) (glob)
417 427 wlock: free
418 428 [1]
419 429 $ touch .hg/unlock
420 430 $ wait
421 431 $ [ -f .hg/store/lock ] || echo "There is no lock"
422 432 There is no lock
423 433
424 434 * Test setting the wlock
425 435
426 436 $ dolock -S &
427 437 $ waitlock .hg/wlock
428 438
429 439 $ hg debuglocks
430 440 lock: free
431 441 wlock: user *, process * (*s) (glob)
432 442 [1]
433 443 $ touch .hg/unlock
434 444 $ wait
435 445 $ [ -f .hg/wlock ] || echo "There is no wlock"
436 446 There is no wlock
437 447
438 448 * Test setting both locks
439 449
440 450 $ dolock -Ss &
441 451 $ waitlock .hg/wlock && waitlock .hg/store/lock
442 452
443 453 $ hg debuglocks
444 454 lock: user *, process * (*s) (glob)
445 455 wlock: user *, process * (*s) (glob)
446 456 [2]
447 457
448 458 * Test failing to set a lock
449 459
450 460 $ hg debuglocks -s
451 461 abort: lock is already held
452 462 [255]
453 463
454 464 $ hg debuglocks -S
455 465 abort: wlock is already held
456 466 [255]
457 467
458 468 $ touch .hg/unlock
459 469 $ wait
460 470
461 471 $ hg debuglocks
462 472 lock: free
463 473 wlock: free
464 474
465 475 * Test forcing the lock
466 476
467 477 $ dolock -s &
468 478 $ waitlock .hg/store/lock
469 479
470 480 $ hg debuglocks
471 481 lock: user *, process * (*s) (glob)
472 482 wlock: free
473 483 [1]
474 484
475 485 $ hg debuglocks -L
476 486
477 487 $ hg debuglocks
478 488 lock: free
479 489 wlock: free
480 490
481 491 $ touch .hg/unlock
482 492 $ wait
483 493
484 494 * Test forcing the wlock
485 495
486 496 $ dolock -S &
487 497 $ waitlock .hg/wlock
488 498
489 499 $ hg debuglocks
490 500 lock: free
491 501 wlock: user *, process * (*s) (glob)
492 502 [1]
493 503
494 504 $ hg debuglocks -W
495 505
496 506 $ hg debuglocks
497 507 lock: free
498 508 wlock: free
499 509
500 510 $ touch .hg/unlock
501 511 $ wait
502 512
503 513 Test WdirUnsupported exception
504 514
505 515 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
506 516 abort: working directory revision cannot be specified
507 517 [255]
508 518
509 519 Test cache warming command
510 520
511 521 $ rm -rf .hg/cache/
512 522 $ hg debugupdatecaches --debug
513 523 updating the branch cache
514 524 $ ls -r .hg/cache/*
515 525 .hg/cache/rbc-revs-v1
516 526 .hg/cache/rbc-names-v1
517 527 .hg/cache/manifestfulltextcache (reporevlogstore !)
518 528 .hg/cache/branch2-served
519 529
520 530 Test debugcolor
521 531
522 532 #if no-windows
523 533 $ hg debugcolor --style --color always | egrep 'mode|style|log\.'
524 534 color mode: 'ansi'
525 535 available style:
526 536 \x1b[0;33mlog.changeset\x1b[0m: \x1b[0;33myellow\x1b[0m (esc)
527 537 #endif
528 538
529 539 $ hg debugcolor --style --color never
530 540 color mode: None
531 541 available style:
532 542
533 543 $ cd ..
534 544
535 545 Test internal debugstacktrace command
536 546
537 547 $ cat > debugstacktrace.py << EOF
538 548 > from __future__ import absolute_import
539 549 > from mercurial import (
540 550 > pycompat,
541 551 > util,
542 552 > )
543 553 > def f():
544 554 > util.debugstacktrace(f=pycompat.stdout)
545 555 > g()
546 556 > def g():
547 557 > util.dst(b'hello from g\\n', skip=1)
548 558 > h()
549 559 > def h():
550 560 > util.dst(b'hi ...\\nfrom h hidden in g', 1, depth=2)
551 561 > f()
552 562 > EOF
553 563 $ "$PYTHON" debugstacktrace.py
554 564 stacktrace at:
555 565 debugstacktrace.py:14 in * (glob)
556 566 debugstacktrace.py:7 in f
557 567 hello from g at:
558 568 debugstacktrace.py:14 in * (glob)
559 569 debugstacktrace.py:8 in f
560 570 hi ...
561 571 from h hidden in g at:
562 572 debugstacktrace.py:8 in f
563 573 debugstacktrace.py:11 in g
564 574
565 575 Test debugcapabilities command:
566 576
567 577 $ hg debugcapabilities ./debugrevlog/
568 578 Main capabilities:
569 579 branchmap
570 580 $USUAL_BUNDLE2_CAPS$
571 581 getbundle
572 582 known
573 583 lookup
574 584 pushkey
575 585 unbundle
576 586 Bundle2 capabilities:
577 587 HG20
578 588 bookmarks
579 589 changegroup
580 590 01
581 591 02
582 592 digests
583 593 md5
584 594 sha1
585 595 sha512
586 596 error
587 597 abort
588 598 unsupportedcontent
589 599 pushraced
590 600 pushkey
591 601 hgtagsfnodes
592 602 listkeys
593 603 phases
594 604 heads
595 605 pushkey
596 606 remote-changegroup
597 607 http
598 608 https
599 609 rev-branch-cache
600 610 stream
601 611 v2
602 612
603 613 Test debugpeer
604 614
605 615 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
606 616 url: ssh://user@dummy/debugrevlog
607 617 local: no
608 618 pushable: yes
609 619
610 620 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
611 621 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
612 622 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
613 623 devel-peer-request: hello+between
614 624 devel-peer-request: pairs: 81 bytes
615 625 sending hello command
616 626 sending between command
617 627 remote: 427
618 628 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
619 629 remote: 1
620 630 devel-peer-request: protocaps
621 631 devel-peer-request: caps: * bytes (glob)
622 632 sending protocaps command
623 633 url: ssh://user@dummy/debugrevlog
624 634 local: no
625 635 pushable: yes
@@ -1,3720 +1,3722 b''
1 1 Short help:
2 2
3 3 $ hg
4 4 Mercurial Distributed SCM
5 5
6 6 basic commands:
7 7
8 8 add add the specified files on the next commit
9 9 annotate show changeset information by line for each file
10 10 clone make a copy of an existing repository
11 11 commit commit the specified files or all outstanding changes
12 12 diff diff repository (or selected files)
13 13 export dump the header and diffs for one or more changesets
14 14 forget forget the specified files on the next commit
15 15 init create a new repository in the given directory
16 16 log show revision history of entire repository or files
17 17 merge merge another revision into working directory
18 18 pull pull changes from the specified source
19 19 push push changes to the specified destination
20 20 remove remove the specified files on the next commit
21 21 serve start stand-alone webserver
22 22 status show changed files in the working directory
23 23 summary summarize working directory state
24 24 update update working directory (or switch revisions)
25 25
26 26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27 27
28 28 $ hg -q
29 29 add add the specified files on the next commit
30 30 annotate show changeset information by line for each file
31 31 clone make a copy of an existing repository
32 32 commit commit the specified files or all outstanding changes
33 33 diff diff repository (or selected files)
34 34 export dump the header and diffs for one or more changesets
35 35 forget forget the specified files on the next commit
36 36 init create a new repository in the given directory
37 37 log show revision history of entire repository or files
38 38 merge merge another revision into working directory
39 39 pull pull changes from the specified source
40 40 push push changes to the specified destination
41 41 remove remove the specified files on the next commit
42 42 serve start stand-alone webserver
43 43 status show changed files in the working directory
44 44 summary summarize working directory state
45 45 update update working directory (or switch revisions)
46 46
47 47 Extra extensions will be printed in help output in a non-reliable order since
48 48 the extension is unknown.
49 49 #if no-extraextensions
50 50
51 51 $ hg help
52 52 Mercurial Distributed SCM
53 53
54 54 list of commands:
55 55
56 56 add add the specified files on the next commit
57 57 addremove add all new files, delete all missing files
58 58 annotate show changeset information by line for each file
59 59 archive create an unversioned archive of a repository revision
60 60 backout reverse effect of earlier changeset
61 61 bisect subdivision search of changesets
62 62 bookmarks create a new bookmark or list existing bookmarks
63 63 branch set or show the current branch name
64 64 branches list repository named branches
65 65 bundle create a bundle file
66 66 cat output the current or given revision of files
67 67 clone make a copy of an existing repository
68 68 commit commit the specified files or all outstanding changes
69 69 config show combined config settings from all hgrc files
70 70 copy mark files as copied for the next commit
71 71 diff diff repository (or selected files)
72 72 export dump the header and diffs for one or more changesets
73 73 files list tracked files
74 74 forget forget the specified files on the next commit
75 75 graft copy changes from other branches onto the current branch
76 76 grep search revision history for a pattern in specified files
77 77 heads show branch heads
78 78 help show help for a given topic or a help overview
79 79 identify identify the working directory or specified revision
80 80 import import an ordered set of patches
81 81 incoming show new changesets found in source
82 82 init create a new repository in the given directory
83 83 log show revision history of entire repository or files
84 84 manifest output the current or given revision of the project manifest
85 85 merge merge another revision into working directory
86 86 outgoing show changesets not found in the destination
87 87 paths show aliases for remote repositories
88 88 phase set or show the current phase name
89 89 pull pull changes from the specified source
90 90 push push changes to the specified destination
91 91 recover roll back an interrupted transaction
92 92 remove remove the specified files on the next commit
93 93 rename rename files; equivalent of copy + remove
94 94 resolve redo merges or set/view the merge status of files
95 95 revert restore files to their checkout state
96 96 root print the root (top) of the current working directory
97 97 serve start stand-alone webserver
98 98 status show changed files in the working directory
99 99 summary summarize working directory state
100 100 tag add one or more tags for the current or given revision
101 101 tags list repository tags
102 102 unbundle apply one or more bundle files
103 103 update update working directory (or switch revisions)
104 104 verify verify the integrity of the repository
105 105 version output version and copyright information
106 106
107 107 additional help topics:
108 108
109 109 bundlespec Bundle File Formats
110 110 color Colorizing Outputs
111 111 config Configuration Files
112 112 dates Date Formats
113 113 deprecated Deprecated Features
114 114 diffs Diff Formats
115 115 environment Environment Variables
116 116 extensions Using Additional Features
117 117 filesets Specifying File Sets
118 118 flags Command-line flags
119 119 glossary Glossary
120 120 hgignore Syntax for Mercurial Ignore Files
121 121 hgweb Configuring hgweb
122 122 internals Technical implementation topics
123 123 merge-tools Merge Tools
124 124 pager Pager Support
125 125 patterns File Name Patterns
126 126 phases Working with Phases
127 127 revisions Specifying Revisions
128 128 scripting Using Mercurial from scripts and automation
129 129 subrepos Subrepositories
130 130 templating Template Usage
131 131 urls URL Paths
132 132
133 133 (use 'hg help -v' to show built-in aliases and global options)
134 134
135 135 $ hg -q help
136 136 add add the specified files on the next commit
137 137 addremove add all new files, delete all missing files
138 138 annotate show changeset information by line for each file
139 139 archive create an unversioned archive of a repository revision
140 140 backout reverse effect of earlier changeset
141 141 bisect subdivision search of changesets
142 142 bookmarks create a new bookmark or list existing bookmarks
143 143 branch set or show the current branch name
144 144 branches list repository named branches
145 145 bundle create a bundle file
146 146 cat output the current or given revision of files
147 147 clone make a copy of an existing repository
148 148 commit commit the specified files or all outstanding changes
149 149 config show combined config settings from all hgrc files
150 150 copy mark files as copied for the next commit
151 151 diff diff repository (or selected files)
152 152 export dump the header and diffs for one or more changesets
153 153 files list tracked files
154 154 forget forget the specified files on the next commit
155 155 graft copy changes from other branches onto the current branch
156 156 grep search revision history for a pattern in specified files
157 157 heads show branch heads
158 158 help show help for a given topic or a help overview
159 159 identify identify the working directory or specified revision
160 160 import import an ordered set of patches
161 161 incoming show new changesets found in source
162 162 init create a new repository in the given directory
163 163 log show revision history of entire repository or files
164 164 manifest output the current or given revision of the project manifest
165 165 merge merge another revision into working directory
166 166 outgoing show changesets not found in the destination
167 167 paths show aliases for remote repositories
168 168 phase set or show the current phase name
169 169 pull pull changes from the specified source
170 170 push push changes to the specified destination
171 171 recover roll back an interrupted transaction
172 172 remove remove the specified files on the next commit
173 173 rename rename files; equivalent of copy + remove
174 174 resolve redo merges or set/view the merge status of files
175 175 revert restore files to their checkout state
176 176 root print the root (top) of the current working directory
177 177 serve start stand-alone webserver
178 178 status show changed files in the working directory
179 179 summary summarize working directory state
180 180 tag add one or more tags for the current or given revision
181 181 tags list repository tags
182 182 unbundle apply one or more bundle files
183 183 update update working directory (or switch revisions)
184 184 verify verify the integrity of the repository
185 185 version output version and copyright information
186 186
187 187 additional help topics:
188 188
189 189 bundlespec Bundle File Formats
190 190 color Colorizing Outputs
191 191 config Configuration Files
192 192 dates Date Formats
193 193 deprecated Deprecated Features
194 194 diffs Diff Formats
195 195 environment Environment Variables
196 196 extensions Using Additional Features
197 197 filesets Specifying File Sets
198 198 flags Command-line flags
199 199 glossary Glossary
200 200 hgignore Syntax for Mercurial Ignore Files
201 201 hgweb Configuring hgweb
202 202 internals Technical implementation topics
203 203 merge-tools Merge Tools
204 204 pager Pager Support
205 205 patterns File Name Patterns
206 206 phases Working with Phases
207 207 revisions Specifying Revisions
208 208 scripting Using Mercurial from scripts and automation
209 209 subrepos Subrepositories
210 210 templating Template Usage
211 211 urls URL Paths
212 212
213 213 Test extension help:
214 214 $ hg help extensions --config extensions.rebase= --config extensions.children=
215 215 Using Additional Features
216 216 """""""""""""""""""""""""
217 217
218 218 Mercurial has the ability to add new features through the use of
219 219 extensions. Extensions may add new commands, add options to existing
220 220 commands, change the default behavior of commands, or implement hooks.
221 221
222 222 To enable the "foo" extension, either shipped with Mercurial or in the
223 223 Python search path, create an entry for it in your configuration file,
224 224 like this:
225 225
226 226 [extensions]
227 227 foo =
228 228
229 229 You may also specify the full path to an extension:
230 230
231 231 [extensions]
232 232 myfeature = ~/.hgext/myfeature.py
233 233
234 234 See 'hg help config' for more information on configuration files.
235 235
236 236 Extensions are not loaded by default for a variety of reasons: they can
237 237 increase startup overhead; they may be meant for advanced usage only; they
238 238 may provide potentially dangerous abilities (such as letting you destroy
239 239 or modify history); they might not be ready for prime time; or they may
240 240 alter some usual behaviors of stock Mercurial. It is thus up to the user
241 241 to activate extensions as needed.
242 242
243 243 To explicitly disable an extension enabled in a configuration file of
244 244 broader scope, prepend its path with !:
245 245
246 246 [extensions]
247 247 # disabling extension bar residing in /path/to/extension/bar.py
248 248 bar = !/path/to/extension/bar.py
249 249 # ditto, but no path was supplied for extension baz
250 250 baz = !
251 251
252 252 enabled extensions:
253 253
254 254 children command to display child changesets (DEPRECATED)
255 255 rebase command to move sets of revisions to a different ancestor
256 256
257 257 disabled extensions:
258 258
259 259 acl hooks for controlling repository access
260 260 blackbox log repository events to a blackbox for debugging
261 261 bugzilla hooks for integrating with the Bugzilla bug tracker
262 262 censor erase file content at a given revision
263 263 churn command to display statistics about repository history
264 264 clonebundles advertise pre-generated bundles to seed clones
265 265 convert import revisions from foreign VCS repositories into
266 266 Mercurial
267 267 eol automatically manage newlines in repository files
268 268 extdiff command to allow external programs to compare revisions
269 269 factotum http authentication with factotum
270 270 githelp try mapping git commands to Mercurial commands
271 271 gpg commands to sign and verify changesets
272 272 hgk browse the repository in a graphical way
273 273 highlight syntax highlighting for hgweb (requires Pygments)
274 274 histedit interactive history editing
275 275 keyword expand keywords in tracked files
276 276 largefiles track large binary files
277 277 mq manage a stack of patches
278 278 notify hooks for sending email push notifications
279 279 patchbomb command to send changesets as (a series of) patch emails
280 280 purge command to delete untracked files from the working
281 281 directory
282 282 relink recreates hardlinks between repository clones
283 283 schemes extend schemes with shortcuts to repository swarms
284 284 share share a common history between several working directories
285 285 shelve save and restore changes to the working directory
286 286 strip strip changesets and their descendants from history
287 287 transplant command to transplant changesets from another branch
288 288 win32mbcs allow the use of MBCS paths with problematic encodings
289 289 zeroconf discover and advertise repositories on the local network
290 290
291 291 #endif
292 292
293 293 Verify that deprecated extensions are included if --verbose:
294 294
295 295 $ hg -v help extensions | grep children
296 296 children command to display child changesets (DEPRECATED)
297 297
298 298 Verify that extension keywords appear in help templates
299 299
300 300 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
301 301
302 302 Test short command list with verbose option
303 303
304 304 $ hg -v help shortlist
305 305 Mercurial Distributed SCM
306 306
307 307 basic commands:
308 308
309 309 add add the specified files on the next commit
310 310 annotate, blame
311 311 show changeset information by line for each file
312 312 clone make a copy of an existing repository
313 313 commit, ci commit the specified files or all outstanding changes
314 314 diff diff repository (or selected files)
315 315 export dump the header and diffs for one or more changesets
316 316 forget forget the specified files on the next commit
317 317 init create a new repository in the given directory
318 318 log, history show revision history of entire repository or files
319 319 merge merge another revision into working directory
320 320 pull pull changes from the specified source
321 321 push push changes to the specified destination
322 322 remove, rm remove the specified files on the next commit
323 323 serve start stand-alone webserver
324 324 status, st show changed files in the working directory
325 325 summary, sum summarize working directory state
326 326 update, up, checkout, co
327 327 update working directory (or switch revisions)
328 328
329 329 global options ([+] can be repeated):
330 330
331 331 -R --repository REPO repository root directory or name of overlay bundle
332 332 file
333 333 --cwd DIR change working directory
334 334 -y --noninteractive do not prompt, automatically pick the first choice for
335 335 all prompts
336 336 -q --quiet suppress output
337 337 -v --verbose enable additional output
338 338 --color TYPE when to colorize (boolean, always, auto, never, or
339 339 debug)
340 340 --config CONFIG [+] set/override config option (use 'section.name=value')
341 341 --debug enable debugging output
342 342 --debugger start debugger
343 343 --encoding ENCODE set the charset encoding (default: ascii)
344 344 --encodingmode MODE set the charset encoding mode (default: strict)
345 345 --traceback always print a traceback on exception
346 346 --time time how long the command takes
347 347 --profile print command execution profile
348 348 --version output version information and exit
349 349 -h --help display help and exit
350 350 --hidden consider hidden changesets
351 351 --pager TYPE when to paginate (boolean, always, auto, or never)
352 352 (default: auto)
353 353
354 354 (use 'hg help' for the full list of commands)
355 355
356 356 $ hg add -h
357 357 hg add [OPTION]... [FILE]...
358 358
359 359 add the specified files on the next commit
360 360
361 361 Schedule files to be version controlled and added to the repository.
362 362
363 363 The files will be added to the repository at the next commit. To undo an
364 364 add before that, see 'hg forget'.
365 365
366 366 If no names are given, add all files to the repository (except files
367 367 matching ".hgignore").
368 368
369 369 Returns 0 if all files are successfully added.
370 370
371 371 options ([+] can be repeated):
372 372
373 373 -I --include PATTERN [+] include names matching the given patterns
374 374 -X --exclude PATTERN [+] exclude names matching the given patterns
375 375 -S --subrepos recurse into subrepositories
376 376 -n --dry-run do not perform actions, just print output
377 377
378 378 (some details hidden, use --verbose to show complete help)
379 379
380 380 Verbose help for add
381 381
382 382 $ hg add -hv
383 383 hg add [OPTION]... [FILE]...
384 384
385 385 add the specified files on the next commit
386 386
387 387 Schedule files to be version controlled and added to the repository.
388 388
389 389 The files will be added to the repository at the next commit. To undo an
390 390 add before that, see 'hg forget'.
391 391
392 392 If no names are given, add all files to the repository (except files
393 393 matching ".hgignore").
394 394
395 395 Examples:
396 396
397 397 - New (unknown) files are added automatically by 'hg add':
398 398
399 399 $ ls
400 400 foo.c
401 401 $ hg status
402 402 ? foo.c
403 403 $ hg add
404 404 adding foo.c
405 405 $ hg status
406 406 A foo.c
407 407
408 408 - Specific files to be added can be specified:
409 409
410 410 $ ls
411 411 bar.c foo.c
412 412 $ hg status
413 413 ? bar.c
414 414 ? foo.c
415 415 $ hg add bar.c
416 416 $ hg status
417 417 A bar.c
418 418 ? foo.c
419 419
420 420 Returns 0 if all files are successfully added.
421 421
422 422 options ([+] can be repeated):
423 423
424 424 -I --include PATTERN [+] include names matching the given patterns
425 425 -X --exclude PATTERN [+] exclude names matching the given patterns
426 426 -S --subrepos recurse into subrepositories
427 427 -n --dry-run do not perform actions, just print output
428 428
429 429 global options ([+] can be repeated):
430 430
431 431 -R --repository REPO repository root directory or name of overlay bundle
432 432 file
433 433 --cwd DIR change working directory
434 434 -y --noninteractive do not prompt, automatically pick the first choice for
435 435 all prompts
436 436 -q --quiet suppress output
437 437 -v --verbose enable additional output
438 438 --color TYPE when to colorize (boolean, always, auto, never, or
439 439 debug)
440 440 --config CONFIG [+] set/override config option (use 'section.name=value')
441 441 --debug enable debugging output
442 442 --debugger start debugger
443 443 --encoding ENCODE set the charset encoding (default: ascii)
444 444 --encodingmode MODE set the charset encoding mode (default: strict)
445 445 --traceback always print a traceback on exception
446 446 --time time how long the command takes
447 447 --profile print command execution profile
448 448 --version output version information and exit
449 449 -h --help display help and exit
450 450 --hidden consider hidden changesets
451 451 --pager TYPE when to paginate (boolean, always, auto, or never)
452 452 (default: auto)
453 453
454 454 Test the textwidth config option
455 455
456 456 $ hg root -h --config ui.textwidth=50
457 457 hg root
458 458
459 459 print the root (top) of the current working
460 460 directory
461 461
462 462 Print the root directory of the current
463 463 repository.
464 464
465 465 Returns 0 on success.
466 466
467 467 (some details hidden, use --verbose to show
468 468 complete help)
469 469
470 470 Test help option with version option
471 471
472 472 $ hg add -h --version
473 473 Mercurial Distributed SCM (version *) (glob)
474 474 (see https://mercurial-scm.org for more information)
475 475
476 476 Copyright (C) 2005-* Matt Mackall and others (glob)
477 477 This is free software; see the source for copying conditions. There is NO
478 478 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
479 479
480 480 $ hg add --skjdfks
481 481 hg add: option --skjdfks not recognized
482 482 hg add [OPTION]... [FILE]...
483 483
484 484 add the specified files on the next commit
485 485
486 486 options ([+] can be repeated):
487 487
488 488 -I --include PATTERN [+] include names matching the given patterns
489 489 -X --exclude PATTERN [+] exclude names matching the given patterns
490 490 -S --subrepos recurse into subrepositories
491 491 -n --dry-run do not perform actions, just print output
492 492
493 493 (use 'hg add -h' to show more help)
494 494 [255]
495 495
496 496 Test ambiguous command help
497 497
498 498 $ hg help ad
499 499 list of commands:
500 500
501 501 add add the specified files on the next commit
502 502 addremove add all new files, delete all missing files
503 503
504 504 (use 'hg help -v ad' to show built-in aliases and global options)
505 505
506 506 Test command without options
507 507
508 508 $ hg help verify
509 509 hg verify
510 510
511 511 verify the integrity of the repository
512 512
513 513 Verify the integrity of the current repository.
514 514
515 515 This will perform an extensive check of the repository's integrity,
516 516 validating the hashes and checksums of each entry in the changelog,
517 517 manifest, and tracked files, as well as the integrity of their crosslinks
518 518 and indices.
519 519
520 520 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
521 521 information about recovery from corruption of the repository.
522 522
523 523 Returns 0 on success, 1 if errors are encountered.
524 524
525 525 (some details hidden, use --verbose to show complete help)
526 526
527 527 $ hg help diff
528 528 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
529 529
530 530 diff repository (or selected files)
531 531
532 532 Show differences between revisions for the specified files.
533 533
534 534 Differences between files are shown using the unified diff format.
535 535
536 536 Note:
537 537 'hg diff' may generate unexpected results for merges, as it will
538 538 default to comparing against the working directory's first parent
539 539 changeset if no revisions are specified.
540 540
541 541 When two revision arguments are given, then changes are shown between
542 542 those revisions. If only one revision is specified then that revision is
543 543 compared to the working directory, and, when no revisions are specified,
544 544 the working directory files are compared to its first parent.
545 545
546 546 Alternatively you can specify -c/--change with a revision to see the
547 547 changes in that changeset relative to its first parent.
548 548
549 549 Without the -a/--text option, diff will avoid generating diffs of files it
550 550 detects as binary. With -a, diff will generate a diff anyway, probably
551 551 with undesirable results.
552 552
553 553 Use the -g/--git option to generate diffs in the git extended diff format.
554 554 For more information, read 'hg help diffs'.
555 555
556 556 Returns 0 on success.
557 557
558 558 options ([+] can be repeated):
559 559
560 560 -r --rev REV [+] revision
561 561 -c --change REV change made by revision
562 562 -a --text treat all files as text
563 563 -g --git use git extended diff format
564 564 --binary generate binary diffs in git mode (default)
565 565 --nodates omit dates from diff headers
566 566 --noprefix omit a/ and b/ prefixes from filenames
567 567 -p --show-function show which function each change is in
568 568 --reverse produce a diff that undoes the changes
569 569 -w --ignore-all-space ignore white space when comparing lines
570 570 -b --ignore-space-change ignore changes in the amount of white space
571 571 -B --ignore-blank-lines ignore changes whose lines are all blank
572 572 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
573 573 -U --unified NUM number of lines of context to show
574 574 --stat output diffstat-style summary of changes
575 575 --root DIR produce diffs relative to subdirectory
576 576 -I --include PATTERN [+] include names matching the given patterns
577 577 -X --exclude PATTERN [+] exclude names matching the given patterns
578 578 -S --subrepos recurse into subrepositories
579 579
580 580 (some details hidden, use --verbose to show complete help)
581 581
582 582 $ hg help status
583 583 hg status [OPTION]... [FILE]...
584 584
585 585 aliases: st
586 586
587 587 show changed files in the working directory
588 588
589 589 Show status of files in the repository. If names are given, only files
590 590 that match are shown. Files that are clean or ignored or the source of a
591 591 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
592 592 -C/--copies or -A/--all are given. Unless options described with "show
593 593 only ..." are given, the options -mardu are used.
594 594
595 595 Option -q/--quiet hides untracked (unknown and ignored) files unless
596 596 explicitly requested with -u/--unknown or -i/--ignored.
597 597
598 598 Note:
599 599 'hg status' may appear to disagree with diff if permissions have
600 600 changed or a merge has occurred. The standard diff format does not
601 601 report permission changes and diff only reports changes relative to one
602 602 merge parent.
603 603
604 604 If one revision is given, it is used as the base revision. If two
605 605 revisions are given, the differences between them are shown. The --change
606 606 option can also be used as a shortcut to list the changed files of a
607 607 revision from its first parent.
608 608
609 609 The codes used to show the status of files are:
610 610
611 611 M = modified
612 612 A = added
613 613 R = removed
614 614 C = clean
615 615 ! = missing (deleted by non-hg command, but still tracked)
616 616 ? = not tracked
617 617 I = ignored
618 618 = origin of the previous file (with --copies)
619 619
620 620 Returns 0 on success.
621 621
622 622 options ([+] can be repeated):
623 623
624 624 -A --all show status of all files
625 625 -m --modified show only modified files
626 626 -a --added show only added files
627 627 -r --removed show only removed files
628 628 -d --deleted show only deleted (but tracked) files
629 629 -c --clean show only files without changes
630 630 -u --unknown show only unknown (not tracked) files
631 631 -i --ignored show only ignored files
632 632 -n --no-status hide status prefix
633 633 -C --copies show source of copied files
634 634 -0 --print0 end filenames with NUL, for use with xargs
635 635 --rev REV [+] show difference from revision
636 636 --change REV list the changed files of a revision
637 637 -I --include PATTERN [+] include names matching the given patterns
638 638 -X --exclude PATTERN [+] exclude names matching the given patterns
639 639 -S --subrepos recurse into subrepositories
640 640 -T --template TEMPLATE display with template
641 641
642 642 (some details hidden, use --verbose to show complete help)
643 643
644 644 $ hg -q help status
645 645 hg status [OPTION]... [FILE]...
646 646
647 647 show changed files in the working directory
648 648
649 649 $ hg help foo
650 650 abort: no such help topic: foo
651 651 (try 'hg help --keyword foo')
652 652 [255]
653 653
654 654 $ hg skjdfks
655 655 hg: unknown command 'skjdfks'
656 656 (use 'hg help' for a list of commands)
657 657 [255]
658 658
659 659 Typoed command gives suggestion
660 660 $ hg puls
661 661 hg: unknown command 'puls'
662 662 (did you mean one of pull, push?)
663 663 [255]
664 664
665 665 Not enabled extension gets suggested
666 666
667 667 $ hg rebase
668 668 hg: unknown command 'rebase'
669 669 'rebase' is provided by the following extension:
670 670
671 671 rebase command to move sets of revisions to a different ancestor
672 672
673 673 (use 'hg help extensions' for information on enabling extensions)
674 674 [255]
675 675
676 676 Disabled extension gets suggested
677 677 $ hg --config extensions.rebase=! rebase
678 678 hg: unknown command 'rebase'
679 679 'rebase' is provided by the following extension:
680 680
681 681 rebase command to move sets of revisions to a different ancestor
682 682
683 683 (use 'hg help extensions' for information on enabling extensions)
684 684 [255]
685 685
686 686 Make sure that we don't run afoul of the help system thinking that
687 687 this is a section and erroring out weirdly.
688 688
689 689 $ hg .log
690 690 hg: unknown command '.log'
691 691 (did you mean log?)
692 692 [255]
693 693
694 694 $ hg log.
695 695 hg: unknown command 'log.'
696 696 (did you mean log?)
697 697 [255]
698 698 $ hg pu.lh
699 699 hg: unknown command 'pu.lh'
700 700 (did you mean one of pull, push?)
701 701 [255]
702 702
703 703 $ cat > helpext.py <<EOF
704 704 > import os
705 705 > from mercurial import commands, fancyopts, registrar
706 706 >
707 707 > def func(arg):
708 708 > return '%sfoo' % arg
709 709 > class customopt(fancyopts.customopt):
710 710 > def newstate(self, oldstate, newparam, abort):
711 711 > return '%sbar' % oldstate
712 712 > cmdtable = {}
713 713 > command = registrar.command(cmdtable)
714 714 >
715 715 > @command(b'nohelp',
716 716 > [(b'', b'longdesc', 3, b'x'*67),
717 717 > (b'n', b'', None, b'normal desc'),
718 718 > (b'', b'newline', b'', b'line1\nline2'),
719 719 > (b'', b'callableopt', func, b'adds foo'),
720 720 > (b'', b'customopt', customopt(''), b'adds bar'),
721 721 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
722 722 > b'hg nohelp',
723 723 > norepo=True)
724 724 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
725 725 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
726 726 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
727 727 > def nohelp(ui, *args, **kwargs):
728 728 > pass
729 729 >
730 730 > def uisetup(ui):
731 731 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
732 732 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
733 733 >
734 734 > EOF
735 735 $ echo '[extensions]' >> $HGRCPATH
736 736 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
737 737
738 738 Test for aliases
739 739
740 740 $ hg help hgalias
741 741 hg hgalias [--remote]
742 742
743 743 alias for: hg summary
744 744
745 745 summarize working directory state
746 746
747 747 This generates a brief summary of the working directory state, including
748 748 parents, branch, commit status, phase and available updates.
749 749
750 750 With the --remote option, this will check the default paths for incoming
751 751 and outgoing changes. This can be time-consuming.
752 752
753 753 Returns 0 on success.
754 754
755 755 defined by: helpext
756 756
757 757 options:
758 758
759 759 --remote check for push and pull
760 760
761 761 (some details hidden, use --verbose to show complete help)
762 762
763 763 $ hg help shellalias
764 764 hg shellalias
765 765
766 766 shell alias for: echo hi
767 767
768 768 (no help text available)
769 769
770 770 defined by: helpext
771 771
772 772 (some details hidden, use --verbose to show complete help)
773 773
774 774 Test command with no help text
775 775
776 776 $ hg help nohelp
777 777 hg nohelp
778 778
779 779 (no help text available)
780 780
781 781 options:
782 782
783 783 --longdesc VALUE
784 784 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
785 785 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
786 786 -n -- normal desc
787 787 --newline VALUE line1 line2
788 788 --callableopt VALUE adds foo
789 789 --customopt VALUE adds bar
790 790 --customopt-withdefault VALUE adds bar (default: foo)
791 791
792 792 (some details hidden, use --verbose to show complete help)
793 793
794 794 $ hg help -k nohelp
795 795 Commands:
796 796
797 797 nohelp hg nohelp
798 798
799 799 Extension Commands:
800 800
801 801 nohelp (no help text available)
802 802
803 803 Test that default list of commands omits extension commands
804 804
805 805 #if no-extraextensions
806 806
807 807 $ hg help
808 808 Mercurial Distributed SCM
809 809
810 810 list of commands:
811 811
812 812 add add the specified files on the next commit
813 813 addremove add all new files, delete all missing files
814 814 annotate show changeset information by line for each file
815 815 archive create an unversioned archive of a repository revision
816 816 backout reverse effect of earlier changeset
817 817 bisect subdivision search of changesets
818 818 bookmarks create a new bookmark or list existing bookmarks
819 819 branch set or show the current branch name
820 820 branches list repository named branches
821 821 bundle create a bundle file
822 822 cat output the current or given revision of files
823 823 clone make a copy of an existing repository
824 824 commit commit the specified files or all outstanding changes
825 825 config show combined config settings from all hgrc files
826 826 copy mark files as copied for the next commit
827 827 diff diff repository (or selected files)
828 828 export dump the header and diffs for one or more changesets
829 829 files list tracked files
830 830 forget forget the specified files on the next commit
831 831 graft copy changes from other branches onto the current branch
832 832 grep search revision history for a pattern in specified files
833 833 heads show branch heads
834 834 help show help for a given topic or a help overview
835 835 identify identify the working directory or specified revision
836 836 import import an ordered set of patches
837 837 incoming show new changesets found in source
838 838 init create a new repository in the given directory
839 839 log show revision history of entire repository or files
840 840 manifest output the current or given revision of the project manifest
841 841 merge merge another revision into working directory
842 842 outgoing show changesets not found in the destination
843 843 paths show aliases for remote repositories
844 844 phase set or show the current phase name
845 845 pull pull changes from the specified source
846 846 push push changes to the specified destination
847 847 recover roll back an interrupted transaction
848 848 remove remove the specified files on the next commit
849 849 rename rename files; equivalent of copy + remove
850 850 resolve redo merges or set/view the merge status of files
851 851 revert restore files to their checkout state
852 852 root print the root (top) of the current working directory
853 853 serve start stand-alone webserver
854 854 status show changed files in the working directory
855 855 summary summarize working directory state
856 856 tag add one or more tags for the current or given revision
857 857 tags list repository tags
858 858 unbundle apply one or more bundle files
859 859 update update working directory (or switch revisions)
860 860 verify verify the integrity of the repository
861 861 version output version and copyright information
862 862
863 863 enabled extensions:
864 864
865 865 helpext (no help text available)
866 866
867 867 additional help topics:
868 868
869 869 bundlespec Bundle File Formats
870 870 color Colorizing Outputs
871 871 config Configuration Files
872 872 dates Date Formats
873 873 deprecated Deprecated Features
874 874 diffs Diff Formats
875 875 environment Environment Variables
876 876 extensions Using Additional Features
877 877 filesets Specifying File Sets
878 878 flags Command-line flags
879 879 glossary Glossary
880 880 hgignore Syntax for Mercurial Ignore Files
881 881 hgweb Configuring hgweb
882 882 internals Technical implementation topics
883 883 merge-tools Merge Tools
884 884 pager Pager Support
885 885 patterns File Name Patterns
886 886 phases Working with Phases
887 887 revisions Specifying Revisions
888 888 scripting Using Mercurial from scripts and automation
889 889 subrepos Subrepositories
890 890 templating Template Usage
891 891 urls URL Paths
892 892
893 893 (use 'hg help -v' to show built-in aliases and global options)
894 894
895 895 #endif
896 896
897 897 Test list of internal help commands
898 898
899 899 $ hg help debug
900 900 debug commands (internal and unsupported):
901 901
902 902 debugancestor
903 903 find the ancestor revision of two revisions in a given index
904 904 debugapplystreamclonebundle
905 905 apply a stream clone bundle file
906 906 debugbuilddag
907 907 builds a repo with a given DAG from scratch in the current
908 908 empty repo
909 909 debugbundle lists the contents of a bundle
910 910 debugcapabilities
911 911 lists the capabilities of a remote peer
912 912 debugcheckstate
913 913 validate the correctness of the current dirstate
914 914 debugcolor show available color, effects or style
915 915 debugcommands
916 916 list all available commands and options
917 917 debugcomplete
918 918 returns the completion list associated with the given command
919 919 debugcreatestreamclonebundle
920 920 create a stream clone bundle file
921 921 debugdag format the changelog or an index DAG as a concise textual
922 922 description
923 923 debugdata dump the contents of a data file revision
924 924 debugdate parse and display a date
925 925 debugdeltachain
926 926 dump information about delta chains in a revlog
927 927 debugdirstate
928 928 show the contents of the current dirstate
929 929 debugdiscovery
930 930 runs the changeset discovery protocol in isolation
931 931 debugdownload
932 932 download a resource using Mercurial logic and config
933 933 debugextensions
934 934 show information about active extensions
935 935 debugfileset parse and apply a fileset specification
936 936 debugformat display format information about the current repository
937 937 debugfsinfo show information detected about current filesystem
938 938 debuggetbundle
939 939 retrieves a bundle from a repo
940 940 debugignore display the combined ignore pattern and information about
941 941 ignored files
942 942 debugindex dump index data for a storage primitive
943 943 debugindexdot
944 944 dump an index DAG as a graphviz dot file
945 debugindexstats
946 show stats related to the changelog index
945 947 debuginstall test Mercurial installation
946 948 debugknown test whether node ids are known to a repo
947 949 debuglocks show or modify state of locks
948 950 debugmanifestfulltextcache
949 951 show, clear or amend the contents of the manifest fulltext
950 952 cache
951 953 debugmergestate
952 954 print merge state
953 955 debugnamecomplete
954 956 complete "names" - tags, open branch names, bookmark names
955 957 debugobsolete
956 958 create arbitrary obsolete marker
957 959 debugoptADV (no help text available)
958 960 debugoptDEP (no help text available)
959 961 debugoptEXP (no help text available)
960 962 debugpathcomplete
961 963 complete part or all of a tracked path
962 964 debugpeer establish a connection to a peer repository
963 965 debugpickmergetool
964 966 examine which merge tool is chosen for specified file
965 967 debugpushkey access the pushkey key/value protocol
966 968 debugpvec (no help text available)
967 969 debugrebuilddirstate
968 970 rebuild the dirstate as it would look like for the given
969 971 revision
970 972 debugrebuildfncache
971 973 rebuild the fncache file
972 974 debugrename dump rename information
973 975 debugrevlog show data and statistics about a revlog
974 976 debugrevlogindex
975 977 dump the contents of a revlog index
976 978 debugrevspec parse and apply a revision specification
977 979 debugserve run a server with advanced settings
978 980 debugsetparents
979 981 manually set the parents of the current working directory
980 982 debugssl test a secure connection to a server
981 983 debugsub (no help text available)
982 984 debugsuccessorssets
983 985 show set of successors for revision
984 986 debugtemplate
985 987 parse and apply a template
986 988 debuguigetpass
987 989 show prompt to type password
988 990 debuguiprompt
989 991 show plain prompt
990 992 debugupdatecaches
991 993 warm all known caches in the repository
992 994 debugupgraderepo
993 995 upgrade a repository to use different features
994 996 debugwalk show how files match on given patterns
995 997 debugwhyunstable
996 998 explain instabilities of a changeset
997 999 debugwireargs
998 1000 (no help text available)
999 1001 debugwireproto
1000 1002 send wire protocol commands to a server
1001 1003
1002 1004 (use 'hg help -v debug' to show built-in aliases and global options)
1003 1005
1004 1006 internals topic renders index of available sub-topics
1005 1007
1006 1008 $ hg help internals
1007 1009 Technical implementation topics
1008 1010 """""""""""""""""""""""""""""""
1009 1011
1010 1012 To access a subtopic, use "hg help internals.{subtopic-name}"
1011 1013
1012 1014 bundle2 Bundle2
1013 1015 bundles Bundles
1014 1016 cbor CBOR
1015 1017 censor Censor
1016 1018 changegroups Changegroups
1017 1019 config Config Registrar
1018 1020 requirements Repository Requirements
1019 1021 revlogs Revision Logs
1020 1022 wireprotocol Wire Protocol
1021 1023 wireprotocolrpc
1022 1024 Wire Protocol RPC
1023 1025 wireprotocolv2
1024 1026 Wire Protocol Version 2
1025 1027
1026 1028 sub-topics can be accessed
1027 1029
1028 1030 $ hg help internals.changegroups
1029 1031 Changegroups
1030 1032 """"""""""""
1031 1033
1032 1034 Changegroups are representations of repository revlog data, specifically
1033 1035 the changelog data, root/flat manifest data, treemanifest data, and
1034 1036 filelogs.
1035 1037
1036 1038 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1037 1039 level, versions "1" and "2" are almost exactly the same, with the only
1038 1040 difference being an additional item in the *delta header*. Version "3"
1039 1041 adds support for revlog flags in the *delta header* and optionally
1040 1042 exchanging treemanifests (enabled by setting an option on the
1041 1043 "changegroup" part in the bundle2).
1042 1044
1043 1045 Changegroups when not exchanging treemanifests consist of 3 logical
1044 1046 segments:
1045 1047
1046 1048 +---------------------------------+
1047 1049 | | | |
1048 1050 | changeset | manifest | filelogs |
1049 1051 | | | |
1050 1052 | | | |
1051 1053 +---------------------------------+
1052 1054
1053 1055 When exchanging treemanifests, there are 4 logical segments:
1054 1056
1055 1057 +-------------------------------------------------+
1056 1058 | | | | |
1057 1059 | changeset | root | treemanifests | filelogs |
1058 1060 | | manifest | | |
1059 1061 | | | | |
1060 1062 +-------------------------------------------------+
1061 1063
1062 1064 The principle building block of each segment is a *chunk*. A *chunk* is a
1063 1065 framed piece of data:
1064 1066
1065 1067 +---------------------------------------+
1066 1068 | | |
1067 1069 | length | data |
1068 1070 | (4 bytes) | (<length - 4> bytes) |
1069 1071 | | |
1070 1072 +---------------------------------------+
1071 1073
1072 1074 All integers are big-endian signed integers. Each chunk starts with a
1073 1075 32-bit integer indicating the length of the entire chunk (including the
1074 1076 length field itself).
1075 1077
1076 1078 There is a special case chunk that has a value of 0 for the length
1077 1079 ("0x00000000"). We call this an *empty chunk*.
1078 1080
1079 1081 Delta Groups
1080 1082 ============
1081 1083
1082 1084 A *delta group* expresses the content of a revlog as a series of deltas,
1083 1085 or patches against previous revisions.
1084 1086
1085 1087 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1086 1088 to signal the end of the delta group:
1087 1089
1088 1090 +------------------------------------------------------------------------+
1089 1091 | | | | | |
1090 1092 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1091 1093 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1092 1094 | | | | | |
1093 1095 +------------------------------------------------------------------------+
1094 1096
1095 1097 Each *chunk*'s data consists of the following:
1096 1098
1097 1099 +---------------------------------------+
1098 1100 | | |
1099 1101 | delta header | delta data |
1100 1102 | (various by version) | (various) |
1101 1103 | | |
1102 1104 +---------------------------------------+
1103 1105
1104 1106 The *delta data* is a series of *delta*s that describe a diff from an
1105 1107 existing entry (either that the recipient already has, or previously
1106 1108 specified in the bundle/changegroup).
1107 1109
1108 1110 The *delta header* is different between versions "1", "2", and "3" of the
1109 1111 changegroup format.
1110 1112
1111 1113 Version 1 (headerlen=80):
1112 1114
1113 1115 +------------------------------------------------------+
1114 1116 | | | | |
1115 1117 | node | p1 node | p2 node | link node |
1116 1118 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1117 1119 | | | | |
1118 1120 +------------------------------------------------------+
1119 1121
1120 1122 Version 2 (headerlen=100):
1121 1123
1122 1124 +------------------------------------------------------------------+
1123 1125 | | | | | |
1124 1126 | node | p1 node | p2 node | base node | link node |
1125 1127 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1126 1128 | | | | | |
1127 1129 +------------------------------------------------------------------+
1128 1130
1129 1131 Version 3 (headerlen=102):
1130 1132
1131 1133 +------------------------------------------------------------------------------+
1132 1134 | | | | | | |
1133 1135 | node | p1 node | p2 node | base node | link node | flags |
1134 1136 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1135 1137 | | | | | | |
1136 1138 +------------------------------------------------------------------------------+
1137 1139
1138 1140 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1139 1141 contain a series of *delta*s, densely packed (no separators). These deltas
1140 1142 describe a diff from an existing entry (either that the recipient already
1141 1143 has, or previously specified in the bundle/changegroup). The format is
1142 1144 described more fully in "hg help internals.bdiff", but briefly:
1143 1145
1144 1146 +---------------------------------------------------------------+
1145 1147 | | | | |
1146 1148 | start offset | end offset | new length | content |
1147 1149 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1148 1150 | | | | |
1149 1151 +---------------------------------------------------------------+
1150 1152
1151 1153 Please note that the length field in the delta data does *not* include
1152 1154 itself.
1153 1155
1154 1156 In version 1, the delta is always applied against the previous node from
1155 1157 the changegroup or the first parent if this is the first entry in the
1156 1158 changegroup.
1157 1159
1158 1160 In version 2 and up, the delta base node is encoded in the entry in the
1159 1161 changegroup. This allows the delta to be expressed against any parent,
1160 1162 which can result in smaller deltas and more efficient encoding of data.
1161 1163
1162 1164 Changeset Segment
1163 1165 =================
1164 1166
1165 1167 The *changeset segment* consists of a single *delta group* holding
1166 1168 changelog data. The *empty chunk* at the end of the *delta group* denotes
1167 1169 the boundary to the *manifest segment*.
1168 1170
1169 1171 Manifest Segment
1170 1172 ================
1171 1173
1172 1174 The *manifest segment* consists of a single *delta group* holding manifest
1173 1175 data. If treemanifests are in use, it contains only the manifest for the
1174 1176 root directory of the repository. Otherwise, it contains the entire
1175 1177 manifest data. The *empty chunk* at the end of the *delta group* denotes
1176 1178 the boundary to the next segment (either the *treemanifests segment* or
1177 1179 the *filelogs segment*, depending on version and the request options).
1178 1180
1179 1181 Treemanifests Segment
1180 1182 ---------------------
1181 1183
1182 1184 The *treemanifests segment* only exists in changegroup version "3", and
1183 1185 only if the 'treemanifest' param is part of the bundle2 changegroup part
1184 1186 (it is not possible to use changegroup version 3 outside of bundle2).
1185 1187 Aside from the filenames in the *treemanifests segment* containing a
1186 1188 trailing "/" character, it behaves identically to the *filelogs segment*
1187 1189 (see below). The final sub-segment is followed by an *empty chunk*
1188 1190 (logically, a sub-segment with filename size 0). This denotes the boundary
1189 1191 to the *filelogs segment*.
1190 1192
1191 1193 Filelogs Segment
1192 1194 ================
1193 1195
1194 1196 The *filelogs segment* consists of multiple sub-segments, each
1195 1197 corresponding to an individual file whose data is being described:
1196 1198
1197 1199 +--------------------------------------------------+
1198 1200 | | | | | |
1199 1201 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1200 1202 | | | | | (4 bytes) |
1201 1203 | | | | | |
1202 1204 +--------------------------------------------------+
1203 1205
1204 1206 The final filelog sub-segment is followed by an *empty chunk* (logically,
1205 1207 a sub-segment with filename size 0). This denotes the end of the segment
1206 1208 and of the overall changegroup.
1207 1209
1208 1210 Each filelog sub-segment consists of the following:
1209 1211
1210 1212 +------------------------------------------------------+
1211 1213 | | | |
1212 1214 | filename length | filename | delta group |
1213 1215 | (4 bytes) | (<length - 4> bytes) | (various) |
1214 1216 | | | |
1215 1217 +------------------------------------------------------+
1216 1218
1217 1219 That is, a *chunk* consisting of the filename (not terminated or padded)
1218 1220 followed by N chunks constituting the *delta group* for this file. The
1219 1221 *empty chunk* at the end of each *delta group* denotes the boundary to the
1220 1222 next filelog sub-segment.
1221 1223
1222 1224 Test list of commands with command with no help text
1223 1225
1224 1226 $ hg help helpext
1225 1227 helpext extension - no help text available
1226 1228
1227 1229 list of commands:
1228 1230
1229 1231 nohelp (no help text available)
1230 1232
1231 1233 (use 'hg help -v helpext' to show built-in aliases and global options)
1232 1234
1233 1235
1234 1236 test advanced, deprecated and experimental options are hidden in command help
1235 1237 $ hg help debugoptADV
1236 1238 hg debugoptADV
1237 1239
1238 1240 (no help text available)
1239 1241
1240 1242 options:
1241 1243
1242 1244 (some details hidden, use --verbose to show complete help)
1243 1245 $ hg help debugoptDEP
1244 1246 hg debugoptDEP
1245 1247
1246 1248 (no help text available)
1247 1249
1248 1250 options:
1249 1251
1250 1252 (some details hidden, use --verbose to show complete help)
1251 1253
1252 1254 $ hg help debugoptEXP
1253 1255 hg debugoptEXP
1254 1256
1255 1257 (no help text available)
1256 1258
1257 1259 options:
1258 1260
1259 1261 (some details hidden, use --verbose to show complete help)
1260 1262
1261 1263 test advanced, deprecated and experimental options are shown with -v
1262 1264 $ hg help -v debugoptADV | grep aopt
1263 1265 --aopt option is (ADVANCED)
1264 1266 $ hg help -v debugoptDEP | grep dopt
1265 1267 --dopt option is (DEPRECATED)
1266 1268 $ hg help -v debugoptEXP | grep eopt
1267 1269 --eopt option is (EXPERIMENTAL)
1268 1270
1269 1271 #if gettext
1270 1272 test deprecated option is hidden with translation with untranslated description
1271 1273 (use many globy for not failing on changed transaction)
1272 1274 $ LANGUAGE=sv hg help debugoptDEP
1273 1275 hg debugoptDEP
1274 1276
1275 1277 (*) (glob)
1276 1278
1277 1279 options:
1278 1280
1279 1281 (some details hidden, use --verbose to show complete help)
1280 1282 #endif
1281 1283
1282 1284 Test commands that collide with topics (issue4240)
1283 1285
1284 1286 $ hg config -hq
1285 1287 hg config [-u] [NAME]...
1286 1288
1287 1289 show combined config settings from all hgrc files
1288 1290 $ hg showconfig -hq
1289 1291 hg config [-u] [NAME]...
1290 1292
1291 1293 show combined config settings from all hgrc files
1292 1294
1293 1295 Test a help topic
1294 1296
1295 1297 $ hg help dates
1296 1298 Date Formats
1297 1299 """"""""""""
1298 1300
1299 1301 Some commands allow the user to specify a date, e.g.:
1300 1302
1301 1303 - backout, commit, import, tag: Specify the commit date.
1302 1304 - log, revert, update: Select revision(s) by date.
1303 1305
1304 1306 Many date formats are valid. Here are some examples:
1305 1307
1306 1308 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1307 1309 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1308 1310 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1309 1311 - "Dec 6" (midnight)
1310 1312 - "13:18" (today assumed)
1311 1313 - "3:39" (3:39AM assumed)
1312 1314 - "3:39pm" (15:39)
1313 1315 - "2006-12-06 13:18:29" (ISO 8601 format)
1314 1316 - "2006-12-6 13:18"
1315 1317 - "2006-12-6"
1316 1318 - "12-6"
1317 1319 - "12/6"
1318 1320 - "12/6/6" (Dec 6 2006)
1319 1321 - "today" (midnight)
1320 1322 - "yesterday" (midnight)
1321 1323 - "now" - right now
1322 1324
1323 1325 Lastly, there is Mercurial's internal format:
1324 1326
1325 1327 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1326 1328
1327 1329 This is the internal representation format for dates. The first number is
1328 1330 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1329 1331 is the offset of the local timezone, in seconds west of UTC (negative if
1330 1332 the timezone is east of UTC).
1331 1333
1332 1334 The log command also accepts date ranges:
1333 1335
1334 1336 - "<DATE" - at or before a given date/time
1335 1337 - ">DATE" - on or after a given date/time
1336 1338 - "DATE to DATE" - a date range, inclusive
1337 1339 - "-DAYS" - within a given number of days of today
1338 1340
1339 1341 Test repeated config section name
1340 1342
1341 1343 $ hg help config.host
1342 1344 "http_proxy.host"
1343 1345 Host name and (optional) port of the proxy server, for example
1344 1346 "myproxy:8000".
1345 1347
1346 1348 "smtp.host"
1347 1349 Host name of mail server, e.g. "mail.example.com".
1348 1350
1349 1351
1350 1352 Test section name with dot
1351 1353
1352 1354 $ hg help config.ui.username
1353 1355 "ui.username"
1354 1356 The committer of a changeset created when running "commit". Typically
1355 1357 a person's name and email address, e.g. "Fred Widget
1356 1358 <fred@example.com>". Environment variables in the username are
1357 1359 expanded.
1358 1360
1359 1361 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1360 1362 empty, e.g. if the system admin set "username =" in the system hgrc,
1361 1363 it has to be specified manually or in a different hgrc file)
1362 1364
1363 1365
1364 1366 $ hg help config.annotate.git
1365 1367 abort: help section not found: config.annotate.git
1366 1368 [255]
1367 1369
1368 1370 $ hg help config.update.check
1369 1371 "commands.update.check"
1370 1372 Determines what level of checking 'hg update' will perform before
1371 1373 moving to a destination revision. Valid values are "abort", "none",
1372 1374 "linear", and "noconflict". "abort" always fails if the working
1373 1375 directory has uncommitted changes. "none" performs no checking, and
1374 1376 may result in a merge with uncommitted changes. "linear" allows any
1375 1377 update as long as it follows a straight line in the revision history,
1376 1378 and may trigger a merge with uncommitted changes. "noconflict" will
1377 1379 allow any update which would not trigger a merge with uncommitted
1378 1380 changes, if any are present. (default: "linear")
1379 1381
1380 1382
1381 1383 $ hg help config.commands.update.check
1382 1384 "commands.update.check"
1383 1385 Determines what level of checking 'hg update' will perform before
1384 1386 moving to a destination revision. Valid values are "abort", "none",
1385 1387 "linear", and "noconflict". "abort" always fails if the working
1386 1388 directory has uncommitted changes. "none" performs no checking, and
1387 1389 may result in a merge with uncommitted changes. "linear" allows any
1388 1390 update as long as it follows a straight line in the revision history,
1389 1391 and may trigger a merge with uncommitted changes. "noconflict" will
1390 1392 allow any update which would not trigger a merge with uncommitted
1391 1393 changes, if any are present. (default: "linear")
1392 1394
1393 1395
1394 1396 $ hg help config.ommands.update.check
1395 1397 abort: help section not found: config.ommands.update.check
1396 1398 [255]
1397 1399
1398 1400 Unrelated trailing paragraphs shouldn't be included
1399 1401
1400 1402 $ hg help config.extramsg | grep '^$'
1401 1403
1402 1404
1403 1405 Test capitalized section name
1404 1406
1405 1407 $ hg help scripting.HGPLAIN > /dev/null
1406 1408
1407 1409 Help subsection:
1408 1410
1409 1411 $ hg help config.charsets |grep "Email example:" > /dev/null
1410 1412 [1]
1411 1413
1412 1414 Show nested definitions
1413 1415 ("profiling.type"[break]"ls"[break]"stat"[break])
1414 1416
1415 1417 $ hg help config.type | egrep '^$'|wc -l
1416 1418 \s*3 (re)
1417 1419
1418 1420 $ hg help config.profiling.type.ls
1419 1421 "profiling.type.ls"
1420 1422 Use Python's built-in instrumenting profiler. This profiler works on
1421 1423 all platforms, but each line number it reports is the first line of
1422 1424 a function. This restriction makes it difficult to identify the
1423 1425 expensive parts of a non-trivial function.
1424 1426
1425 1427
1426 1428 Separate sections from subsections
1427 1429
1428 1430 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1429 1431 "format"
1430 1432 --------
1431 1433
1432 1434 "usegeneraldelta"
1433 1435
1434 1436 "dotencode"
1435 1437
1436 1438 "usefncache"
1437 1439
1438 1440 "usestore"
1439 1441
1440 1442 "profiling"
1441 1443 -----------
1442 1444
1443 1445 "format"
1444 1446
1445 1447 "progress"
1446 1448 ----------
1447 1449
1448 1450 "format"
1449 1451
1450 1452
1451 1453 Last item in help config.*:
1452 1454
1453 1455 $ hg help config.`hg help config|grep '^ "'| \
1454 1456 > tail -1|sed 's![ "]*!!g'`| \
1455 1457 > grep 'hg help -c config' > /dev/null
1456 1458 [1]
1457 1459
1458 1460 note to use help -c for general hg help config:
1459 1461
1460 1462 $ hg help config |grep 'hg help -c config' > /dev/null
1461 1463
1462 1464 Test templating help
1463 1465
1464 1466 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1465 1467 desc String. The text of the changeset description.
1466 1468 diffstat String. Statistics of changes with the following format:
1467 1469 firstline Any text. Returns the first line of text.
1468 1470 nonempty Any text. Returns '(none)' if the string is empty.
1469 1471
1470 1472 Test deprecated items
1471 1473
1472 1474 $ hg help -v templating | grep currentbookmark
1473 1475 currentbookmark
1474 1476 $ hg help templating | (grep currentbookmark || true)
1475 1477
1476 1478 Test help hooks
1477 1479
1478 1480 $ cat > helphook1.py <<EOF
1479 1481 > from mercurial import help
1480 1482 >
1481 1483 > def rewrite(ui, topic, doc):
1482 1484 > return doc + '\nhelphook1\n'
1483 1485 >
1484 1486 > def extsetup(ui):
1485 1487 > help.addtopichook('revisions', rewrite)
1486 1488 > EOF
1487 1489 $ cat > helphook2.py <<EOF
1488 1490 > from mercurial import help
1489 1491 >
1490 1492 > def rewrite(ui, topic, doc):
1491 1493 > return doc + '\nhelphook2\n'
1492 1494 >
1493 1495 > def extsetup(ui):
1494 1496 > help.addtopichook('revisions', rewrite)
1495 1497 > EOF
1496 1498 $ echo '[extensions]' >> $HGRCPATH
1497 1499 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1498 1500 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1499 1501 $ hg help revsets | grep helphook
1500 1502 helphook1
1501 1503 helphook2
1502 1504
1503 1505 help -c should only show debug --debug
1504 1506
1505 1507 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1506 1508 [1]
1507 1509
1508 1510 help -c should only show deprecated for -v
1509 1511
1510 1512 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1511 1513 [1]
1512 1514
1513 1515 Test -s / --system
1514 1516
1515 1517 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1516 1518 > wc -l | sed -e 's/ //g'
1517 1519 0
1518 1520 $ hg help config.files --system unix | grep 'USER' | \
1519 1521 > wc -l | sed -e 's/ //g'
1520 1522 0
1521 1523
1522 1524 Test -e / -c / -k combinations
1523 1525
1524 1526 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1525 1527 Commands:
1526 1528 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1527 1529 Extensions:
1528 1530 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1529 1531 Topics:
1530 1532 Commands:
1531 1533 Extensions:
1532 1534 Extension Commands:
1533 1535 $ hg help -c schemes
1534 1536 abort: no such help topic: schemes
1535 1537 (try 'hg help --keyword schemes')
1536 1538 [255]
1537 1539 $ hg help -e schemes |head -1
1538 1540 schemes extension - extend schemes with shortcuts to repository swarms
1539 1541 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1540 1542 Commands:
1541 1543 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1542 1544 Extensions:
1543 1545 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1544 1546 Extensions:
1545 1547 Commands:
1546 1548 $ hg help -c commit > /dev/null
1547 1549 $ hg help -e -c commit > /dev/null
1548 1550 $ hg help -e commit
1549 1551 abort: no such help topic: commit
1550 1552 (try 'hg help --keyword commit')
1551 1553 [255]
1552 1554
1553 1555 Test keyword search help
1554 1556
1555 1557 $ cat > prefixedname.py <<EOF
1556 1558 > '''matched against word "clone"
1557 1559 > '''
1558 1560 > EOF
1559 1561 $ echo '[extensions]' >> $HGRCPATH
1560 1562 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1561 1563 $ hg help -k clone
1562 1564 Topics:
1563 1565
1564 1566 config Configuration Files
1565 1567 extensions Using Additional Features
1566 1568 glossary Glossary
1567 1569 phases Working with Phases
1568 1570 subrepos Subrepositories
1569 1571 urls URL Paths
1570 1572
1571 1573 Commands:
1572 1574
1573 1575 bookmarks create a new bookmark or list existing bookmarks
1574 1576 clone make a copy of an existing repository
1575 1577 paths show aliases for remote repositories
1576 1578 pull pull changes from the specified source
1577 1579 update update working directory (or switch revisions)
1578 1580
1579 1581 Extensions:
1580 1582
1581 1583 clonebundles advertise pre-generated bundles to seed clones
1582 1584 narrow create clones which fetch history data for subset of files
1583 1585 (EXPERIMENTAL)
1584 1586 prefixedname matched against word "clone"
1585 1587 relink recreates hardlinks between repository clones
1586 1588
1587 1589 Extension Commands:
1588 1590
1589 1591 qclone clone main and patch repository at same time
1590 1592
1591 1593 Test unfound topic
1592 1594
1593 1595 $ hg help nonexistingtopicthatwillneverexisteverever
1594 1596 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1595 1597 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1596 1598 [255]
1597 1599
1598 1600 Test unfound keyword
1599 1601
1600 1602 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1601 1603 abort: no matches
1602 1604 (try 'hg help' for a list of topics)
1603 1605 [255]
1604 1606
1605 1607 Test omit indicating for help
1606 1608
1607 1609 $ cat > addverboseitems.py <<EOF
1608 1610 > '''extension to test omit indicating.
1609 1611 >
1610 1612 > This paragraph is never omitted (for extension)
1611 1613 >
1612 1614 > .. container:: verbose
1613 1615 >
1614 1616 > This paragraph is omitted,
1615 1617 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1616 1618 >
1617 1619 > This paragraph is never omitted, too (for extension)
1618 1620 > '''
1619 1621 > from __future__ import absolute_import
1620 1622 > from mercurial import commands, help
1621 1623 > testtopic = """This paragraph is never omitted (for topic).
1622 1624 >
1623 1625 > .. container:: verbose
1624 1626 >
1625 1627 > This paragraph is omitted,
1626 1628 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1627 1629 >
1628 1630 > This paragraph is never omitted, too (for topic)
1629 1631 > """
1630 1632 > def extsetup(ui):
1631 1633 > help.helptable.append((["topic-containing-verbose"],
1632 1634 > "This is the topic to test omit indicating.",
1633 1635 > lambda ui: testtopic))
1634 1636 > EOF
1635 1637 $ echo '[extensions]' >> $HGRCPATH
1636 1638 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1637 1639 $ hg help addverboseitems
1638 1640 addverboseitems extension - extension to test omit indicating.
1639 1641
1640 1642 This paragraph is never omitted (for extension)
1641 1643
1642 1644 This paragraph is never omitted, too (for extension)
1643 1645
1644 1646 (some details hidden, use --verbose to show complete help)
1645 1647
1646 1648 no commands defined
1647 1649 $ hg help -v addverboseitems
1648 1650 addverboseitems extension - extension to test omit indicating.
1649 1651
1650 1652 This paragraph is never omitted (for extension)
1651 1653
1652 1654 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1653 1655 extension)
1654 1656
1655 1657 This paragraph is never omitted, too (for extension)
1656 1658
1657 1659 no commands defined
1658 1660 $ hg help topic-containing-verbose
1659 1661 This is the topic to test omit indicating.
1660 1662 """"""""""""""""""""""""""""""""""""""""""
1661 1663
1662 1664 This paragraph is never omitted (for topic).
1663 1665
1664 1666 This paragraph is never omitted, too (for topic)
1665 1667
1666 1668 (some details hidden, use --verbose to show complete help)
1667 1669 $ hg help -v topic-containing-verbose
1668 1670 This is the topic to test omit indicating.
1669 1671 """"""""""""""""""""""""""""""""""""""""""
1670 1672
1671 1673 This paragraph is never omitted (for topic).
1672 1674
1673 1675 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1674 1676 topic)
1675 1677
1676 1678 This paragraph is never omitted, too (for topic)
1677 1679
1678 1680 Test section lookup
1679 1681
1680 1682 $ hg help revset.merge
1681 1683 "merge()"
1682 1684 Changeset is a merge changeset.
1683 1685
1684 1686 $ hg help glossary.dag
1685 1687 DAG
1686 1688 The repository of changesets of a distributed version control system
1687 1689 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1688 1690 of nodes and edges, where nodes correspond to changesets and edges
1689 1691 imply a parent -> child relation. This graph can be visualized by
1690 1692 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1691 1693 limited by the requirement for children to have at most two parents.
1692 1694
1693 1695
1694 1696 $ hg help hgrc.paths
1695 1697 "paths"
1696 1698 -------
1697 1699
1698 1700 Assigns symbolic names and behavior to repositories.
1699 1701
1700 1702 Options are symbolic names defining the URL or directory that is the
1701 1703 location of the repository. Example:
1702 1704
1703 1705 [paths]
1704 1706 my_server = https://example.com/my_repo
1705 1707 local_path = /home/me/repo
1706 1708
1707 1709 These symbolic names can be used from the command line. To pull from
1708 1710 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1709 1711 local_path'.
1710 1712
1711 1713 Options containing colons (":") denote sub-options that can influence
1712 1714 behavior for that specific path. Example:
1713 1715
1714 1716 [paths]
1715 1717 my_server = https://example.com/my_path
1716 1718 my_server:pushurl = ssh://example.com/my_path
1717 1719
1718 1720 The following sub-options can be defined:
1719 1721
1720 1722 "pushurl"
1721 1723 The URL to use for push operations. If not defined, the location
1722 1724 defined by the path's main entry is used.
1723 1725
1724 1726 "pushrev"
1725 1727 A revset defining which revisions to push by default.
1726 1728
1727 1729 When 'hg push' is executed without a "-r" argument, the revset defined
1728 1730 by this sub-option is evaluated to determine what to push.
1729 1731
1730 1732 For example, a value of "." will push the working directory's revision
1731 1733 by default.
1732 1734
1733 1735 Revsets specifying bookmarks will not result in the bookmark being
1734 1736 pushed.
1735 1737
1736 1738 The following special named paths exist:
1737 1739
1738 1740 "default"
1739 1741 The URL or directory to use when no source or remote is specified.
1740 1742
1741 1743 'hg clone' will automatically define this path to the location the
1742 1744 repository was cloned from.
1743 1745
1744 1746 "default-push"
1745 1747 (deprecated) The URL or directory for the default 'hg push' location.
1746 1748 "default:pushurl" should be used instead.
1747 1749
1748 1750 $ hg help glossary.mcguffin
1749 1751 abort: help section not found: glossary.mcguffin
1750 1752 [255]
1751 1753
1752 1754 $ hg help glossary.mc.guffin
1753 1755 abort: help section not found: glossary.mc.guffin
1754 1756 [255]
1755 1757
1756 1758 $ hg help template.files
1757 1759 files List of strings. All files modified, added, or removed by
1758 1760 this changeset.
1759 1761 files(pattern)
1760 1762 All files of the current changeset matching the pattern. See
1761 1763 'hg help patterns'.
1762 1764
1763 1765 Test section lookup by translated message
1764 1766
1765 1767 str.lower() instead of encoding.lower(str) on translated message might
1766 1768 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1767 1769 as the second or later byte of multi-byte character.
1768 1770
1769 1771 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1770 1772 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1771 1773 replacement makes message meaningless.
1772 1774
1773 1775 This tests that section lookup by translated string isn't broken by
1774 1776 such str.lower().
1775 1777
1776 1778 $ "$PYTHON" <<EOF
1777 1779 > def escape(s):
1778 1780 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1779 1781 > # translation of "record" in ja_JP.cp932
1780 1782 > upper = "\x8bL\x98^"
1781 1783 > # str.lower()-ed section name should be treated as different one
1782 1784 > lower = "\x8bl\x98^"
1783 1785 > with open('ambiguous.py', 'w') as fp:
1784 1786 > fp.write("""# ambiguous section names in ja_JP.cp932
1785 1787 > u'''summary of extension
1786 1788 >
1787 1789 > %s
1788 1790 > ----
1789 1791 >
1790 1792 > Upper name should show only this message
1791 1793 >
1792 1794 > %s
1793 1795 > ----
1794 1796 >
1795 1797 > Lower name should show only this message
1796 1798 >
1797 1799 > subsequent section
1798 1800 > ------------------
1799 1801 >
1800 1802 > This should be hidden at 'hg help ambiguous' with section name.
1801 1803 > '''
1802 1804 > """ % (escape(upper), escape(lower)))
1803 1805 > EOF
1804 1806
1805 1807 $ cat >> $HGRCPATH <<EOF
1806 1808 > [extensions]
1807 1809 > ambiguous = ./ambiguous.py
1808 1810 > EOF
1809 1811
1810 1812 $ "$PYTHON" <<EOF | sh
1811 1813 > upper = "\x8bL\x98^"
1812 1814 > print("hg --encoding cp932 help -e ambiguous.%s" % upper)
1813 1815 > EOF
1814 1816 \x8bL\x98^ (esc)
1815 1817 ----
1816 1818
1817 1819 Upper name should show only this message
1818 1820
1819 1821
1820 1822 $ "$PYTHON" <<EOF | sh
1821 1823 > lower = "\x8bl\x98^"
1822 1824 > print("hg --encoding cp932 help -e ambiguous.%s" % lower)
1823 1825 > EOF
1824 1826 \x8bl\x98^ (esc)
1825 1827 ----
1826 1828
1827 1829 Lower name should show only this message
1828 1830
1829 1831
1830 1832 $ cat >> $HGRCPATH <<EOF
1831 1833 > [extensions]
1832 1834 > ambiguous = !
1833 1835 > EOF
1834 1836
1835 1837 Show help content of disabled extensions
1836 1838
1837 1839 $ cat >> $HGRCPATH <<EOF
1838 1840 > [extensions]
1839 1841 > ambiguous = !./ambiguous.py
1840 1842 > EOF
1841 1843 $ hg help -e ambiguous
1842 1844 ambiguous extension - (no help text available)
1843 1845
1844 1846 (use 'hg help extensions' for information on enabling extensions)
1845 1847
1846 1848 Test dynamic list of merge tools only shows up once
1847 1849 $ hg help merge-tools
1848 1850 Merge Tools
1849 1851 """""""""""
1850 1852
1851 1853 To merge files Mercurial uses merge tools.
1852 1854
1853 1855 A merge tool combines two different versions of a file into a merged file.
1854 1856 Merge tools are given the two files and the greatest common ancestor of
1855 1857 the two file versions, so they can determine the changes made on both
1856 1858 branches.
1857 1859
1858 1860 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1859 1861 backout' and in several extensions.
1860 1862
1861 1863 Usually, the merge tool tries to automatically reconcile the files by
1862 1864 combining all non-overlapping changes that occurred separately in the two
1863 1865 different evolutions of the same initial base file. Furthermore, some
1864 1866 interactive merge programs make it easier to manually resolve conflicting
1865 1867 merges, either in a graphical way, or by inserting some conflict markers.
1866 1868 Mercurial does not include any interactive merge programs but relies on
1867 1869 external tools for that.
1868 1870
1869 1871 Available merge tools
1870 1872 =====================
1871 1873
1872 1874 External merge tools and their properties are configured in the merge-
1873 1875 tools configuration section - see hgrc(5) - but they can often just be
1874 1876 named by their executable.
1875 1877
1876 1878 A merge tool is generally usable if its executable can be found on the
1877 1879 system and if it can handle the merge. The executable is found if it is an
1878 1880 absolute or relative executable path or the name of an application in the
1879 1881 executable search path. The tool is assumed to be able to handle the merge
1880 1882 if it can handle symlinks if the file is a symlink, if it can handle
1881 1883 binary files if the file is binary, and if a GUI is available if the tool
1882 1884 requires a GUI.
1883 1885
1884 1886 There are some internal merge tools which can be used. The internal merge
1885 1887 tools are:
1886 1888
1887 1889 ":dump"
1888 1890 Creates three versions of the files to merge, containing the contents of
1889 1891 local, other and base. These files can then be used to perform a merge
1890 1892 manually. If the file to be merged is named "a.txt", these files will
1891 1893 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1892 1894 they will be placed in the same directory as "a.txt".
1893 1895
1894 1896 This implies premerge. Therefore, files aren't dumped, if premerge runs
1895 1897 successfully. Use :forcedump to forcibly write files out.
1896 1898
1897 1899 (actual capabilities: binary, symlink)
1898 1900
1899 1901 ":fail"
1900 1902 Rather than attempting to merge files that were modified on both
1901 1903 branches, it marks them as unresolved. The resolve command must be used
1902 1904 to resolve these conflicts.
1903 1905
1904 1906 (actual capabilities: binary, symlink)
1905 1907
1906 1908 ":forcedump"
1907 1909 Creates three versions of the files as same as :dump, but omits
1908 1910 premerge.
1909 1911
1910 1912 (actual capabilities: binary, symlink)
1911 1913
1912 1914 ":local"
1913 1915 Uses the local 'p1()' version of files as the merged version.
1914 1916
1915 1917 (actual capabilities: binary, symlink)
1916 1918
1917 1919 ":merge"
1918 1920 Uses the internal non-interactive simple merge algorithm for merging
1919 1921 files. It will fail if there are any conflicts and leave markers in the
1920 1922 partially merged file. Markers will have two sections, one for each side
1921 1923 of merge.
1922 1924
1923 1925 ":merge-local"
1924 1926 Like :merge, but resolve all conflicts non-interactively in favor of the
1925 1927 local 'p1()' changes.
1926 1928
1927 1929 ":merge-other"
1928 1930 Like :merge, but resolve all conflicts non-interactively in favor of the
1929 1931 other 'p2()' changes.
1930 1932
1931 1933 ":merge3"
1932 1934 Uses the internal non-interactive simple merge algorithm for merging
1933 1935 files. It will fail if there are any conflicts and leave markers in the
1934 1936 partially merged file. Marker will have three sections, one from each
1935 1937 side of the merge and one for the base content.
1936 1938
1937 1939 ":other"
1938 1940 Uses the other 'p2()' version of files as the merged version.
1939 1941
1940 1942 (actual capabilities: binary, symlink)
1941 1943
1942 1944 ":prompt"
1943 1945 Asks the user which of the local 'p1()' or the other 'p2()' version to
1944 1946 keep as the merged version.
1945 1947
1946 1948 (actual capabilities: binary, symlink)
1947 1949
1948 1950 ":tagmerge"
1949 1951 Uses the internal tag merge algorithm (experimental).
1950 1952
1951 1953 ":union"
1952 1954 Uses the internal non-interactive simple merge algorithm for merging
1953 1955 files. It will use both left and right sides for conflict regions. No
1954 1956 markers are inserted.
1955 1957
1956 1958 Internal tools are always available and do not require a GUI but will by
1957 1959 default not handle symlinks or binary files. See next section for detail
1958 1960 about "actual capabilities" described above.
1959 1961
1960 1962 Choosing a merge tool
1961 1963 =====================
1962 1964
1963 1965 Mercurial uses these rules when deciding which merge tool to use:
1964 1966
1965 1967 1. If a tool has been specified with the --tool option to merge or
1966 1968 resolve, it is used. If it is the name of a tool in the merge-tools
1967 1969 configuration, its configuration is used. Otherwise the specified tool
1968 1970 must be executable by the shell.
1969 1971 2. If the "HGMERGE" environment variable is present, its value is used and
1970 1972 must be executable by the shell.
1971 1973 3. If the filename of the file to be merged matches any of the patterns in
1972 1974 the merge-patterns configuration section, the first usable merge tool
1973 1975 corresponding to a matching pattern is used.
1974 1976 4. If ui.merge is set it will be considered next. If the value is not the
1975 1977 name of a configured tool, the specified value is used and must be
1976 1978 executable by the shell. Otherwise the named tool is used if it is
1977 1979 usable.
1978 1980 5. If any usable merge tools are present in the merge-tools configuration
1979 1981 section, the one with the highest priority is used.
1980 1982 6. If a program named "hgmerge" can be found on the system, it is used -
1981 1983 but it will by default not be used for symlinks and binary files.
1982 1984 7. If the file to be merged is not binary and is not a symlink, then
1983 1985 internal ":merge" is used.
1984 1986 8. Otherwise, ":prompt" is used.
1985 1987
1986 1988 For historical reason, Mercurial treats merge tools as below while
1987 1989 examining rules above.
1988 1990
1989 1991 step specified via binary symlink
1990 1992 ----------------------------------
1991 1993 1. --tool o/o o/o
1992 1994 2. HGMERGE o/o o/o
1993 1995 3. merge-patterns o/o(*) x/?(*)
1994 1996 4. ui.merge x/?(*) x/?(*)
1995 1997
1996 1998 Each capability column indicates Mercurial behavior for internal/external
1997 1999 merge tools at examining each rule.
1998 2000
1999 2001 - "o": "assume that a tool has capability"
2000 2002 - "x": "assume that a tool does not have capability"
2001 2003 - "?": "check actual capability of a tool"
2002 2004
2003 2005 If "merge.strict-capability-check" configuration is true, Mercurial checks
2004 2006 capabilities of merge tools strictly in (*) cases above (= each capability
2005 2007 column becomes "?/?"). It is false by default for backward compatibility.
2006 2008
2007 2009 Note:
2008 2010 After selecting a merge program, Mercurial will by default attempt to
2009 2011 merge the files using a simple merge algorithm first. Only if it
2010 2012 doesn't succeed because of conflicting changes will Mercurial actually
2011 2013 execute the merge program. Whether to use the simple merge algorithm
2012 2014 first can be controlled by the premerge setting of the merge tool.
2013 2015 Premerge is enabled by default unless the file is binary or a symlink.
2014 2016
2015 2017 See the merge-tools and ui sections of hgrc(5) for details on the
2016 2018 configuration of merge tools.
2017 2019
2018 2020 Compression engines listed in `hg help bundlespec`
2019 2021
2020 2022 $ hg help bundlespec | grep gzip
2021 2023 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2022 2024 An algorithm that produces smaller bundles than "gzip".
2023 2025 This engine will likely produce smaller bundles than "gzip" but will be
2024 2026 "gzip"
2025 2027 better compression than "gzip". It also frequently yields better (?)
2026 2028
2027 2029 Test usage of section marks in help documents
2028 2030
2029 2031 $ cd "$TESTDIR"/../doc
2030 2032 $ "$PYTHON" check-seclevel.py
2031 2033 $ cd $TESTTMP
2032 2034
2033 2035 #if serve
2034 2036
2035 2037 Test the help pages in hgweb.
2036 2038
2037 2039 Dish up an empty repo; serve it cold.
2038 2040
2039 2041 $ hg init "$TESTTMP/test"
2040 2042 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2041 2043 $ cat hg.pid >> $DAEMON_PIDS
2042 2044
2043 2045 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2044 2046 200 Script output follows
2045 2047
2046 2048 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2047 2049 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2048 2050 <head>
2049 2051 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2050 2052 <meta name="robots" content="index, nofollow" />
2051 2053 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2052 2054 <script type="text/javascript" src="/static/mercurial.js"></script>
2053 2055
2054 2056 <title>Help: Index</title>
2055 2057 </head>
2056 2058 <body>
2057 2059
2058 2060 <div class="container">
2059 2061 <div class="menu">
2060 2062 <div class="logo">
2061 2063 <a href="https://mercurial-scm.org/">
2062 2064 <img src="/static/hglogo.png" alt="mercurial" /></a>
2063 2065 </div>
2064 2066 <ul>
2065 2067 <li><a href="/shortlog">log</a></li>
2066 2068 <li><a href="/graph">graph</a></li>
2067 2069 <li><a href="/tags">tags</a></li>
2068 2070 <li><a href="/bookmarks">bookmarks</a></li>
2069 2071 <li><a href="/branches">branches</a></li>
2070 2072 </ul>
2071 2073 <ul>
2072 2074 <li class="active">help</li>
2073 2075 </ul>
2074 2076 </div>
2075 2077
2076 2078 <div class="main">
2077 2079 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2078 2080
2079 2081 <form class="search" action="/log">
2080 2082
2081 2083 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2082 2084 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2083 2085 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2084 2086 </form>
2085 2087 <table class="bigtable">
2086 2088 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2087 2089
2088 2090 <tr><td>
2089 2091 <a href="/help/bundlespec">
2090 2092 bundlespec
2091 2093 </a>
2092 2094 </td><td>
2093 2095 Bundle File Formats
2094 2096 </td></tr>
2095 2097 <tr><td>
2096 2098 <a href="/help/color">
2097 2099 color
2098 2100 </a>
2099 2101 </td><td>
2100 2102 Colorizing Outputs
2101 2103 </td></tr>
2102 2104 <tr><td>
2103 2105 <a href="/help/config">
2104 2106 config
2105 2107 </a>
2106 2108 </td><td>
2107 2109 Configuration Files
2108 2110 </td></tr>
2109 2111 <tr><td>
2110 2112 <a href="/help/dates">
2111 2113 dates
2112 2114 </a>
2113 2115 </td><td>
2114 2116 Date Formats
2115 2117 </td></tr>
2116 2118 <tr><td>
2117 2119 <a href="/help/deprecated">
2118 2120 deprecated
2119 2121 </a>
2120 2122 </td><td>
2121 2123 Deprecated Features
2122 2124 </td></tr>
2123 2125 <tr><td>
2124 2126 <a href="/help/diffs">
2125 2127 diffs
2126 2128 </a>
2127 2129 </td><td>
2128 2130 Diff Formats
2129 2131 </td></tr>
2130 2132 <tr><td>
2131 2133 <a href="/help/environment">
2132 2134 environment
2133 2135 </a>
2134 2136 </td><td>
2135 2137 Environment Variables
2136 2138 </td></tr>
2137 2139 <tr><td>
2138 2140 <a href="/help/extensions">
2139 2141 extensions
2140 2142 </a>
2141 2143 </td><td>
2142 2144 Using Additional Features
2143 2145 </td></tr>
2144 2146 <tr><td>
2145 2147 <a href="/help/filesets">
2146 2148 filesets
2147 2149 </a>
2148 2150 </td><td>
2149 2151 Specifying File Sets
2150 2152 </td></tr>
2151 2153 <tr><td>
2152 2154 <a href="/help/flags">
2153 2155 flags
2154 2156 </a>
2155 2157 </td><td>
2156 2158 Command-line flags
2157 2159 </td></tr>
2158 2160 <tr><td>
2159 2161 <a href="/help/glossary">
2160 2162 glossary
2161 2163 </a>
2162 2164 </td><td>
2163 2165 Glossary
2164 2166 </td></tr>
2165 2167 <tr><td>
2166 2168 <a href="/help/hgignore">
2167 2169 hgignore
2168 2170 </a>
2169 2171 </td><td>
2170 2172 Syntax for Mercurial Ignore Files
2171 2173 </td></tr>
2172 2174 <tr><td>
2173 2175 <a href="/help/hgweb">
2174 2176 hgweb
2175 2177 </a>
2176 2178 </td><td>
2177 2179 Configuring hgweb
2178 2180 </td></tr>
2179 2181 <tr><td>
2180 2182 <a href="/help/internals">
2181 2183 internals
2182 2184 </a>
2183 2185 </td><td>
2184 2186 Technical implementation topics
2185 2187 </td></tr>
2186 2188 <tr><td>
2187 2189 <a href="/help/merge-tools">
2188 2190 merge-tools
2189 2191 </a>
2190 2192 </td><td>
2191 2193 Merge Tools
2192 2194 </td></tr>
2193 2195 <tr><td>
2194 2196 <a href="/help/pager">
2195 2197 pager
2196 2198 </a>
2197 2199 </td><td>
2198 2200 Pager Support
2199 2201 </td></tr>
2200 2202 <tr><td>
2201 2203 <a href="/help/patterns">
2202 2204 patterns
2203 2205 </a>
2204 2206 </td><td>
2205 2207 File Name Patterns
2206 2208 </td></tr>
2207 2209 <tr><td>
2208 2210 <a href="/help/phases">
2209 2211 phases
2210 2212 </a>
2211 2213 </td><td>
2212 2214 Working with Phases
2213 2215 </td></tr>
2214 2216 <tr><td>
2215 2217 <a href="/help/revisions">
2216 2218 revisions
2217 2219 </a>
2218 2220 </td><td>
2219 2221 Specifying Revisions
2220 2222 </td></tr>
2221 2223 <tr><td>
2222 2224 <a href="/help/scripting">
2223 2225 scripting
2224 2226 </a>
2225 2227 </td><td>
2226 2228 Using Mercurial from scripts and automation
2227 2229 </td></tr>
2228 2230 <tr><td>
2229 2231 <a href="/help/subrepos">
2230 2232 subrepos
2231 2233 </a>
2232 2234 </td><td>
2233 2235 Subrepositories
2234 2236 </td></tr>
2235 2237 <tr><td>
2236 2238 <a href="/help/templating">
2237 2239 templating
2238 2240 </a>
2239 2241 </td><td>
2240 2242 Template Usage
2241 2243 </td></tr>
2242 2244 <tr><td>
2243 2245 <a href="/help/urls">
2244 2246 urls
2245 2247 </a>
2246 2248 </td><td>
2247 2249 URL Paths
2248 2250 </td></tr>
2249 2251 <tr><td>
2250 2252 <a href="/help/topic-containing-verbose">
2251 2253 topic-containing-verbose
2252 2254 </a>
2253 2255 </td><td>
2254 2256 This is the topic to test omit indicating.
2255 2257 </td></tr>
2256 2258
2257 2259
2258 2260 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2259 2261
2260 2262 <tr><td>
2261 2263 <a href="/help/add">
2262 2264 add
2263 2265 </a>
2264 2266 </td><td>
2265 2267 add the specified files on the next commit
2266 2268 </td></tr>
2267 2269 <tr><td>
2268 2270 <a href="/help/annotate">
2269 2271 annotate
2270 2272 </a>
2271 2273 </td><td>
2272 2274 show changeset information by line for each file
2273 2275 </td></tr>
2274 2276 <tr><td>
2275 2277 <a href="/help/clone">
2276 2278 clone
2277 2279 </a>
2278 2280 </td><td>
2279 2281 make a copy of an existing repository
2280 2282 </td></tr>
2281 2283 <tr><td>
2282 2284 <a href="/help/commit">
2283 2285 commit
2284 2286 </a>
2285 2287 </td><td>
2286 2288 commit the specified files or all outstanding changes
2287 2289 </td></tr>
2288 2290 <tr><td>
2289 2291 <a href="/help/diff">
2290 2292 diff
2291 2293 </a>
2292 2294 </td><td>
2293 2295 diff repository (or selected files)
2294 2296 </td></tr>
2295 2297 <tr><td>
2296 2298 <a href="/help/export">
2297 2299 export
2298 2300 </a>
2299 2301 </td><td>
2300 2302 dump the header and diffs for one or more changesets
2301 2303 </td></tr>
2302 2304 <tr><td>
2303 2305 <a href="/help/forget">
2304 2306 forget
2305 2307 </a>
2306 2308 </td><td>
2307 2309 forget the specified files on the next commit
2308 2310 </td></tr>
2309 2311 <tr><td>
2310 2312 <a href="/help/init">
2311 2313 init
2312 2314 </a>
2313 2315 </td><td>
2314 2316 create a new repository in the given directory
2315 2317 </td></tr>
2316 2318 <tr><td>
2317 2319 <a href="/help/log">
2318 2320 log
2319 2321 </a>
2320 2322 </td><td>
2321 2323 show revision history of entire repository or files
2322 2324 </td></tr>
2323 2325 <tr><td>
2324 2326 <a href="/help/merge">
2325 2327 merge
2326 2328 </a>
2327 2329 </td><td>
2328 2330 merge another revision into working directory
2329 2331 </td></tr>
2330 2332 <tr><td>
2331 2333 <a href="/help/pull">
2332 2334 pull
2333 2335 </a>
2334 2336 </td><td>
2335 2337 pull changes from the specified source
2336 2338 </td></tr>
2337 2339 <tr><td>
2338 2340 <a href="/help/push">
2339 2341 push
2340 2342 </a>
2341 2343 </td><td>
2342 2344 push changes to the specified destination
2343 2345 </td></tr>
2344 2346 <tr><td>
2345 2347 <a href="/help/remove">
2346 2348 remove
2347 2349 </a>
2348 2350 </td><td>
2349 2351 remove the specified files on the next commit
2350 2352 </td></tr>
2351 2353 <tr><td>
2352 2354 <a href="/help/serve">
2353 2355 serve
2354 2356 </a>
2355 2357 </td><td>
2356 2358 start stand-alone webserver
2357 2359 </td></tr>
2358 2360 <tr><td>
2359 2361 <a href="/help/status">
2360 2362 status
2361 2363 </a>
2362 2364 </td><td>
2363 2365 show changed files in the working directory
2364 2366 </td></tr>
2365 2367 <tr><td>
2366 2368 <a href="/help/summary">
2367 2369 summary
2368 2370 </a>
2369 2371 </td><td>
2370 2372 summarize working directory state
2371 2373 </td></tr>
2372 2374 <tr><td>
2373 2375 <a href="/help/update">
2374 2376 update
2375 2377 </a>
2376 2378 </td><td>
2377 2379 update working directory (or switch revisions)
2378 2380 </td></tr>
2379 2381
2380 2382
2381 2383
2382 2384 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2383 2385
2384 2386 <tr><td>
2385 2387 <a href="/help/addremove">
2386 2388 addremove
2387 2389 </a>
2388 2390 </td><td>
2389 2391 add all new files, delete all missing files
2390 2392 </td></tr>
2391 2393 <tr><td>
2392 2394 <a href="/help/archive">
2393 2395 archive
2394 2396 </a>
2395 2397 </td><td>
2396 2398 create an unversioned archive of a repository revision
2397 2399 </td></tr>
2398 2400 <tr><td>
2399 2401 <a href="/help/backout">
2400 2402 backout
2401 2403 </a>
2402 2404 </td><td>
2403 2405 reverse effect of earlier changeset
2404 2406 </td></tr>
2405 2407 <tr><td>
2406 2408 <a href="/help/bisect">
2407 2409 bisect
2408 2410 </a>
2409 2411 </td><td>
2410 2412 subdivision search of changesets
2411 2413 </td></tr>
2412 2414 <tr><td>
2413 2415 <a href="/help/bookmarks">
2414 2416 bookmarks
2415 2417 </a>
2416 2418 </td><td>
2417 2419 create a new bookmark or list existing bookmarks
2418 2420 </td></tr>
2419 2421 <tr><td>
2420 2422 <a href="/help/branch">
2421 2423 branch
2422 2424 </a>
2423 2425 </td><td>
2424 2426 set or show the current branch name
2425 2427 </td></tr>
2426 2428 <tr><td>
2427 2429 <a href="/help/branches">
2428 2430 branches
2429 2431 </a>
2430 2432 </td><td>
2431 2433 list repository named branches
2432 2434 </td></tr>
2433 2435 <tr><td>
2434 2436 <a href="/help/bundle">
2435 2437 bundle
2436 2438 </a>
2437 2439 </td><td>
2438 2440 create a bundle file
2439 2441 </td></tr>
2440 2442 <tr><td>
2441 2443 <a href="/help/cat">
2442 2444 cat
2443 2445 </a>
2444 2446 </td><td>
2445 2447 output the current or given revision of files
2446 2448 </td></tr>
2447 2449 <tr><td>
2448 2450 <a href="/help/config">
2449 2451 config
2450 2452 </a>
2451 2453 </td><td>
2452 2454 show combined config settings from all hgrc files
2453 2455 </td></tr>
2454 2456 <tr><td>
2455 2457 <a href="/help/copy">
2456 2458 copy
2457 2459 </a>
2458 2460 </td><td>
2459 2461 mark files as copied for the next commit
2460 2462 </td></tr>
2461 2463 <tr><td>
2462 2464 <a href="/help/files">
2463 2465 files
2464 2466 </a>
2465 2467 </td><td>
2466 2468 list tracked files
2467 2469 </td></tr>
2468 2470 <tr><td>
2469 2471 <a href="/help/graft">
2470 2472 graft
2471 2473 </a>
2472 2474 </td><td>
2473 2475 copy changes from other branches onto the current branch
2474 2476 </td></tr>
2475 2477 <tr><td>
2476 2478 <a href="/help/grep">
2477 2479 grep
2478 2480 </a>
2479 2481 </td><td>
2480 2482 search revision history for a pattern in specified files
2481 2483 </td></tr>
2482 2484 <tr><td>
2483 2485 <a href="/help/heads">
2484 2486 heads
2485 2487 </a>
2486 2488 </td><td>
2487 2489 show branch heads
2488 2490 </td></tr>
2489 2491 <tr><td>
2490 2492 <a href="/help/help">
2491 2493 help
2492 2494 </a>
2493 2495 </td><td>
2494 2496 show help for a given topic or a help overview
2495 2497 </td></tr>
2496 2498 <tr><td>
2497 2499 <a href="/help/hgalias">
2498 2500 hgalias
2499 2501 </a>
2500 2502 </td><td>
2501 2503 summarize working directory state
2502 2504 </td></tr>
2503 2505 <tr><td>
2504 2506 <a href="/help/identify">
2505 2507 identify
2506 2508 </a>
2507 2509 </td><td>
2508 2510 identify the working directory or specified revision
2509 2511 </td></tr>
2510 2512 <tr><td>
2511 2513 <a href="/help/import">
2512 2514 import
2513 2515 </a>
2514 2516 </td><td>
2515 2517 import an ordered set of patches
2516 2518 </td></tr>
2517 2519 <tr><td>
2518 2520 <a href="/help/incoming">
2519 2521 incoming
2520 2522 </a>
2521 2523 </td><td>
2522 2524 show new changesets found in source
2523 2525 </td></tr>
2524 2526 <tr><td>
2525 2527 <a href="/help/manifest">
2526 2528 manifest
2527 2529 </a>
2528 2530 </td><td>
2529 2531 output the current or given revision of the project manifest
2530 2532 </td></tr>
2531 2533 <tr><td>
2532 2534 <a href="/help/nohelp">
2533 2535 nohelp
2534 2536 </a>
2535 2537 </td><td>
2536 2538 (no help text available)
2537 2539 </td></tr>
2538 2540 <tr><td>
2539 2541 <a href="/help/outgoing">
2540 2542 outgoing
2541 2543 </a>
2542 2544 </td><td>
2543 2545 show changesets not found in the destination
2544 2546 </td></tr>
2545 2547 <tr><td>
2546 2548 <a href="/help/paths">
2547 2549 paths
2548 2550 </a>
2549 2551 </td><td>
2550 2552 show aliases for remote repositories
2551 2553 </td></tr>
2552 2554 <tr><td>
2553 2555 <a href="/help/phase">
2554 2556 phase
2555 2557 </a>
2556 2558 </td><td>
2557 2559 set or show the current phase name
2558 2560 </td></tr>
2559 2561 <tr><td>
2560 2562 <a href="/help/recover">
2561 2563 recover
2562 2564 </a>
2563 2565 </td><td>
2564 2566 roll back an interrupted transaction
2565 2567 </td></tr>
2566 2568 <tr><td>
2567 2569 <a href="/help/rename">
2568 2570 rename
2569 2571 </a>
2570 2572 </td><td>
2571 2573 rename files; equivalent of copy + remove
2572 2574 </td></tr>
2573 2575 <tr><td>
2574 2576 <a href="/help/resolve">
2575 2577 resolve
2576 2578 </a>
2577 2579 </td><td>
2578 2580 redo merges or set/view the merge status of files
2579 2581 </td></tr>
2580 2582 <tr><td>
2581 2583 <a href="/help/revert">
2582 2584 revert
2583 2585 </a>
2584 2586 </td><td>
2585 2587 restore files to their checkout state
2586 2588 </td></tr>
2587 2589 <tr><td>
2588 2590 <a href="/help/root">
2589 2591 root
2590 2592 </a>
2591 2593 </td><td>
2592 2594 print the root (top) of the current working directory
2593 2595 </td></tr>
2594 2596 <tr><td>
2595 2597 <a href="/help/shellalias">
2596 2598 shellalias
2597 2599 </a>
2598 2600 </td><td>
2599 2601 (no help text available)
2600 2602 </td></tr>
2601 2603 <tr><td>
2602 2604 <a href="/help/tag">
2603 2605 tag
2604 2606 </a>
2605 2607 </td><td>
2606 2608 add one or more tags for the current or given revision
2607 2609 </td></tr>
2608 2610 <tr><td>
2609 2611 <a href="/help/tags">
2610 2612 tags
2611 2613 </a>
2612 2614 </td><td>
2613 2615 list repository tags
2614 2616 </td></tr>
2615 2617 <tr><td>
2616 2618 <a href="/help/unbundle">
2617 2619 unbundle
2618 2620 </a>
2619 2621 </td><td>
2620 2622 apply one or more bundle files
2621 2623 </td></tr>
2622 2624 <tr><td>
2623 2625 <a href="/help/verify">
2624 2626 verify
2625 2627 </a>
2626 2628 </td><td>
2627 2629 verify the integrity of the repository
2628 2630 </td></tr>
2629 2631 <tr><td>
2630 2632 <a href="/help/version">
2631 2633 version
2632 2634 </a>
2633 2635 </td><td>
2634 2636 output version and copyright information
2635 2637 </td></tr>
2636 2638
2637 2639
2638 2640 </table>
2639 2641 </div>
2640 2642 </div>
2641 2643
2642 2644
2643 2645
2644 2646 </body>
2645 2647 </html>
2646 2648
2647 2649
2648 2650 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2649 2651 200 Script output follows
2650 2652
2651 2653 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2652 2654 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2653 2655 <head>
2654 2656 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2655 2657 <meta name="robots" content="index, nofollow" />
2656 2658 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2657 2659 <script type="text/javascript" src="/static/mercurial.js"></script>
2658 2660
2659 2661 <title>Help: add</title>
2660 2662 </head>
2661 2663 <body>
2662 2664
2663 2665 <div class="container">
2664 2666 <div class="menu">
2665 2667 <div class="logo">
2666 2668 <a href="https://mercurial-scm.org/">
2667 2669 <img src="/static/hglogo.png" alt="mercurial" /></a>
2668 2670 </div>
2669 2671 <ul>
2670 2672 <li><a href="/shortlog">log</a></li>
2671 2673 <li><a href="/graph">graph</a></li>
2672 2674 <li><a href="/tags">tags</a></li>
2673 2675 <li><a href="/bookmarks">bookmarks</a></li>
2674 2676 <li><a href="/branches">branches</a></li>
2675 2677 </ul>
2676 2678 <ul>
2677 2679 <li class="active"><a href="/help">help</a></li>
2678 2680 </ul>
2679 2681 </div>
2680 2682
2681 2683 <div class="main">
2682 2684 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2683 2685 <h3>Help: add</h3>
2684 2686
2685 2687 <form class="search" action="/log">
2686 2688
2687 2689 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2688 2690 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2689 2691 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2690 2692 </form>
2691 2693 <div id="doc">
2692 2694 <p>
2693 2695 hg add [OPTION]... [FILE]...
2694 2696 </p>
2695 2697 <p>
2696 2698 add the specified files on the next commit
2697 2699 </p>
2698 2700 <p>
2699 2701 Schedule files to be version controlled and added to the
2700 2702 repository.
2701 2703 </p>
2702 2704 <p>
2703 2705 The files will be added to the repository at the next commit. To
2704 2706 undo an add before that, see 'hg forget'.
2705 2707 </p>
2706 2708 <p>
2707 2709 If no names are given, add all files to the repository (except
2708 2710 files matching &quot;.hgignore&quot;).
2709 2711 </p>
2710 2712 <p>
2711 2713 Examples:
2712 2714 </p>
2713 2715 <ul>
2714 2716 <li> New (unknown) files are added automatically by 'hg add':
2715 2717 <pre>
2716 2718 \$ ls (re)
2717 2719 foo.c
2718 2720 \$ hg status (re)
2719 2721 ? foo.c
2720 2722 \$ hg add (re)
2721 2723 adding foo.c
2722 2724 \$ hg status (re)
2723 2725 A foo.c
2724 2726 </pre>
2725 2727 <li> Specific files to be added can be specified:
2726 2728 <pre>
2727 2729 \$ ls (re)
2728 2730 bar.c foo.c
2729 2731 \$ hg status (re)
2730 2732 ? bar.c
2731 2733 ? foo.c
2732 2734 \$ hg add bar.c (re)
2733 2735 \$ hg status (re)
2734 2736 A bar.c
2735 2737 ? foo.c
2736 2738 </pre>
2737 2739 </ul>
2738 2740 <p>
2739 2741 Returns 0 if all files are successfully added.
2740 2742 </p>
2741 2743 <p>
2742 2744 options ([+] can be repeated):
2743 2745 </p>
2744 2746 <table>
2745 2747 <tr><td>-I</td>
2746 2748 <td>--include PATTERN [+]</td>
2747 2749 <td>include names matching the given patterns</td></tr>
2748 2750 <tr><td>-X</td>
2749 2751 <td>--exclude PATTERN [+]</td>
2750 2752 <td>exclude names matching the given patterns</td></tr>
2751 2753 <tr><td>-S</td>
2752 2754 <td>--subrepos</td>
2753 2755 <td>recurse into subrepositories</td></tr>
2754 2756 <tr><td>-n</td>
2755 2757 <td>--dry-run</td>
2756 2758 <td>do not perform actions, just print output</td></tr>
2757 2759 </table>
2758 2760 <p>
2759 2761 global options ([+] can be repeated):
2760 2762 </p>
2761 2763 <table>
2762 2764 <tr><td>-R</td>
2763 2765 <td>--repository REPO</td>
2764 2766 <td>repository root directory or name of overlay bundle file</td></tr>
2765 2767 <tr><td></td>
2766 2768 <td>--cwd DIR</td>
2767 2769 <td>change working directory</td></tr>
2768 2770 <tr><td>-y</td>
2769 2771 <td>--noninteractive</td>
2770 2772 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2771 2773 <tr><td>-q</td>
2772 2774 <td>--quiet</td>
2773 2775 <td>suppress output</td></tr>
2774 2776 <tr><td>-v</td>
2775 2777 <td>--verbose</td>
2776 2778 <td>enable additional output</td></tr>
2777 2779 <tr><td></td>
2778 2780 <td>--color TYPE</td>
2779 2781 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2780 2782 <tr><td></td>
2781 2783 <td>--config CONFIG [+]</td>
2782 2784 <td>set/override config option (use 'section.name=value')</td></tr>
2783 2785 <tr><td></td>
2784 2786 <td>--debug</td>
2785 2787 <td>enable debugging output</td></tr>
2786 2788 <tr><td></td>
2787 2789 <td>--debugger</td>
2788 2790 <td>start debugger</td></tr>
2789 2791 <tr><td></td>
2790 2792 <td>--encoding ENCODE</td>
2791 2793 <td>set the charset encoding (default: ascii)</td></tr>
2792 2794 <tr><td></td>
2793 2795 <td>--encodingmode MODE</td>
2794 2796 <td>set the charset encoding mode (default: strict)</td></tr>
2795 2797 <tr><td></td>
2796 2798 <td>--traceback</td>
2797 2799 <td>always print a traceback on exception</td></tr>
2798 2800 <tr><td></td>
2799 2801 <td>--time</td>
2800 2802 <td>time how long the command takes</td></tr>
2801 2803 <tr><td></td>
2802 2804 <td>--profile</td>
2803 2805 <td>print command execution profile</td></tr>
2804 2806 <tr><td></td>
2805 2807 <td>--version</td>
2806 2808 <td>output version information and exit</td></tr>
2807 2809 <tr><td>-h</td>
2808 2810 <td>--help</td>
2809 2811 <td>display help and exit</td></tr>
2810 2812 <tr><td></td>
2811 2813 <td>--hidden</td>
2812 2814 <td>consider hidden changesets</td></tr>
2813 2815 <tr><td></td>
2814 2816 <td>--pager TYPE</td>
2815 2817 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2816 2818 </table>
2817 2819
2818 2820 </div>
2819 2821 </div>
2820 2822 </div>
2821 2823
2822 2824
2823 2825
2824 2826 </body>
2825 2827 </html>
2826 2828
2827 2829
2828 2830 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2829 2831 200 Script output follows
2830 2832
2831 2833 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2832 2834 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2833 2835 <head>
2834 2836 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2835 2837 <meta name="robots" content="index, nofollow" />
2836 2838 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2837 2839 <script type="text/javascript" src="/static/mercurial.js"></script>
2838 2840
2839 2841 <title>Help: remove</title>
2840 2842 </head>
2841 2843 <body>
2842 2844
2843 2845 <div class="container">
2844 2846 <div class="menu">
2845 2847 <div class="logo">
2846 2848 <a href="https://mercurial-scm.org/">
2847 2849 <img src="/static/hglogo.png" alt="mercurial" /></a>
2848 2850 </div>
2849 2851 <ul>
2850 2852 <li><a href="/shortlog">log</a></li>
2851 2853 <li><a href="/graph">graph</a></li>
2852 2854 <li><a href="/tags">tags</a></li>
2853 2855 <li><a href="/bookmarks">bookmarks</a></li>
2854 2856 <li><a href="/branches">branches</a></li>
2855 2857 </ul>
2856 2858 <ul>
2857 2859 <li class="active"><a href="/help">help</a></li>
2858 2860 </ul>
2859 2861 </div>
2860 2862
2861 2863 <div class="main">
2862 2864 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2863 2865 <h3>Help: remove</h3>
2864 2866
2865 2867 <form class="search" action="/log">
2866 2868
2867 2869 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2868 2870 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2869 2871 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2870 2872 </form>
2871 2873 <div id="doc">
2872 2874 <p>
2873 2875 hg remove [OPTION]... FILE...
2874 2876 </p>
2875 2877 <p>
2876 2878 aliases: rm
2877 2879 </p>
2878 2880 <p>
2879 2881 remove the specified files on the next commit
2880 2882 </p>
2881 2883 <p>
2882 2884 Schedule the indicated files for removal from the current branch.
2883 2885 </p>
2884 2886 <p>
2885 2887 This command schedules the files to be removed at the next commit.
2886 2888 To undo a remove before that, see 'hg revert'. To undo added
2887 2889 files, see 'hg forget'.
2888 2890 </p>
2889 2891 <p>
2890 2892 -A/--after can be used to remove only files that have already
2891 2893 been deleted, -f/--force can be used to force deletion, and -Af
2892 2894 can be used to remove files from the next revision without
2893 2895 deleting them from the working directory.
2894 2896 </p>
2895 2897 <p>
2896 2898 The following table details the behavior of remove for different
2897 2899 file states (columns) and option combinations (rows). The file
2898 2900 states are Added [A], Clean [C], Modified [M] and Missing [!]
2899 2901 (as reported by 'hg status'). The actions are Warn, Remove
2900 2902 (from branch) and Delete (from disk):
2901 2903 </p>
2902 2904 <table>
2903 2905 <tr><td>opt/state</td>
2904 2906 <td>A</td>
2905 2907 <td>C</td>
2906 2908 <td>M</td>
2907 2909 <td>!</td></tr>
2908 2910 <tr><td>none</td>
2909 2911 <td>W</td>
2910 2912 <td>RD</td>
2911 2913 <td>W</td>
2912 2914 <td>R</td></tr>
2913 2915 <tr><td>-f</td>
2914 2916 <td>R</td>
2915 2917 <td>RD</td>
2916 2918 <td>RD</td>
2917 2919 <td>R</td></tr>
2918 2920 <tr><td>-A</td>
2919 2921 <td>W</td>
2920 2922 <td>W</td>
2921 2923 <td>W</td>
2922 2924 <td>R</td></tr>
2923 2925 <tr><td>-Af</td>
2924 2926 <td>R</td>
2925 2927 <td>R</td>
2926 2928 <td>R</td>
2927 2929 <td>R</td></tr>
2928 2930 </table>
2929 2931 <p>
2930 2932 <b>Note:</b>
2931 2933 </p>
2932 2934 <p>
2933 2935 'hg remove' never deletes files in Added [A] state from the
2934 2936 working directory, not even if &quot;--force&quot; is specified.
2935 2937 </p>
2936 2938 <p>
2937 2939 Returns 0 on success, 1 if any warnings encountered.
2938 2940 </p>
2939 2941 <p>
2940 2942 options ([+] can be repeated):
2941 2943 </p>
2942 2944 <table>
2943 2945 <tr><td>-A</td>
2944 2946 <td>--after</td>
2945 2947 <td>record delete for missing files</td></tr>
2946 2948 <tr><td>-f</td>
2947 2949 <td>--force</td>
2948 2950 <td>forget added files, delete modified files</td></tr>
2949 2951 <tr><td>-S</td>
2950 2952 <td>--subrepos</td>
2951 2953 <td>recurse into subrepositories</td></tr>
2952 2954 <tr><td>-I</td>
2953 2955 <td>--include PATTERN [+]</td>
2954 2956 <td>include names matching the given patterns</td></tr>
2955 2957 <tr><td>-X</td>
2956 2958 <td>--exclude PATTERN [+]</td>
2957 2959 <td>exclude names matching the given patterns</td></tr>
2958 2960 <tr><td>-n</td>
2959 2961 <td>--dry-run</td>
2960 2962 <td>do not perform actions, just print output</td></tr>
2961 2963 </table>
2962 2964 <p>
2963 2965 global options ([+] can be repeated):
2964 2966 </p>
2965 2967 <table>
2966 2968 <tr><td>-R</td>
2967 2969 <td>--repository REPO</td>
2968 2970 <td>repository root directory or name of overlay bundle file</td></tr>
2969 2971 <tr><td></td>
2970 2972 <td>--cwd DIR</td>
2971 2973 <td>change working directory</td></tr>
2972 2974 <tr><td>-y</td>
2973 2975 <td>--noninteractive</td>
2974 2976 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2975 2977 <tr><td>-q</td>
2976 2978 <td>--quiet</td>
2977 2979 <td>suppress output</td></tr>
2978 2980 <tr><td>-v</td>
2979 2981 <td>--verbose</td>
2980 2982 <td>enable additional output</td></tr>
2981 2983 <tr><td></td>
2982 2984 <td>--color TYPE</td>
2983 2985 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2984 2986 <tr><td></td>
2985 2987 <td>--config CONFIG [+]</td>
2986 2988 <td>set/override config option (use 'section.name=value')</td></tr>
2987 2989 <tr><td></td>
2988 2990 <td>--debug</td>
2989 2991 <td>enable debugging output</td></tr>
2990 2992 <tr><td></td>
2991 2993 <td>--debugger</td>
2992 2994 <td>start debugger</td></tr>
2993 2995 <tr><td></td>
2994 2996 <td>--encoding ENCODE</td>
2995 2997 <td>set the charset encoding (default: ascii)</td></tr>
2996 2998 <tr><td></td>
2997 2999 <td>--encodingmode MODE</td>
2998 3000 <td>set the charset encoding mode (default: strict)</td></tr>
2999 3001 <tr><td></td>
3000 3002 <td>--traceback</td>
3001 3003 <td>always print a traceback on exception</td></tr>
3002 3004 <tr><td></td>
3003 3005 <td>--time</td>
3004 3006 <td>time how long the command takes</td></tr>
3005 3007 <tr><td></td>
3006 3008 <td>--profile</td>
3007 3009 <td>print command execution profile</td></tr>
3008 3010 <tr><td></td>
3009 3011 <td>--version</td>
3010 3012 <td>output version information and exit</td></tr>
3011 3013 <tr><td>-h</td>
3012 3014 <td>--help</td>
3013 3015 <td>display help and exit</td></tr>
3014 3016 <tr><td></td>
3015 3017 <td>--hidden</td>
3016 3018 <td>consider hidden changesets</td></tr>
3017 3019 <tr><td></td>
3018 3020 <td>--pager TYPE</td>
3019 3021 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3020 3022 </table>
3021 3023
3022 3024 </div>
3023 3025 </div>
3024 3026 </div>
3025 3027
3026 3028
3027 3029
3028 3030 </body>
3029 3031 </html>
3030 3032
3031 3033
3032 3034 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3033 3035 200 Script output follows
3034 3036
3035 3037 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3036 3038 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3037 3039 <head>
3038 3040 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3039 3041 <meta name="robots" content="index, nofollow" />
3040 3042 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3041 3043 <script type="text/javascript" src="/static/mercurial.js"></script>
3042 3044
3043 3045 <title>Help: dates</title>
3044 3046 </head>
3045 3047 <body>
3046 3048
3047 3049 <div class="container">
3048 3050 <div class="menu">
3049 3051 <div class="logo">
3050 3052 <a href="https://mercurial-scm.org/">
3051 3053 <img src="/static/hglogo.png" alt="mercurial" /></a>
3052 3054 </div>
3053 3055 <ul>
3054 3056 <li><a href="/shortlog">log</a></li>
3055 3057 <li><a href="/graph">graph</a></li>
3056 3058 <li><a href="/tags">tags</a></li>
3057 3059 <li><a href="/bookmarks">bookmarks</a></li>
3058 3060 <li><a href="/branches">branches</a></li>
3059 3061 </ul>
3060 3062 <ul>
3061 3063 <li class="active"><a href="/help">help</a></li>
3062 3064 </ul>
3063 3065 </div>
3064 3066
3065 3067 <div class="main">
3066 3068 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3067 3069 <h3>Help: dates</h3>
3068 3070
3069 3071 <form class="search" action="/log">
3070 3072
3071 3073 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3072 3074 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3073 3075 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3074 3076 </form>
3075 3077 <div id="doc">
3076 3078 <h1>Date Formats</h1>
3077 3079 <p>
3078 3080 Some commands allow the user to specify a date, e.g.:
3079 3081 </p>
3080 3082 <ul>
3081 3083 <li> backout, commit, import, tag: Specify the commit date.
3082 3084 <li> log, revert, update: Select revision(s) by date.
3083 3085 </ul>
3084 3086 <p>
3085 3087 Many date formats are valid. Here are some examples:
3086 3088 </p>
3087 3089 <ul>
3088 3090 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3089 3091 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3090 3092 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3091 3093 <li> &quot;Dec 6&quot; (midnight)
3092 3094 <li> &quot;13:18&quot; (today assumed)
3093 3095 <li> &quot;3:39&quot; (3:39AM assumed)
3094 3096 <li> &quot;3:39pm&quot; (15:39)
3095 3097 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3096 3098 <li> &quot;2006-12-6 13:18&quot;
3097 3099 <li> &quot;2006-12-6&quot;
3098 3100 <li> &quot;12-6&quot;
3099 3101 <li> &quot;12/6&quot;
3100 3102 <li> &quot;12/6/6&quot; (Dec 6 2006)
3101 3103 <li> &quot;today&quot; (midnight)
3102 3104 <li> &quot;yesterday&quot; (midnight)
3103 3105 <li> &quot;now&quot; - right now
3104 3106 </ul>
3105 3107 <p>
3106 3108 Lastly, there is Mercurial's internal format:
3107 3109 </p>
3108 3110 <ul>
3109 3111 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3110 3112 </ul>
3111 3113 <p>
3112 3114 This is the internal representation format for dates. The first number
3113 3115 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3114 3116 second is the offset of the local timezone, in seconds west of UTC
3115 3117 (negative if the timezone is east of UTC).
3116 3118 </p>
3117 3119 <p>
3118 3120 The log command also accepts date ranges:
3119 3121 </p>
3120 3122 <ul>
3121 3123 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3122 3124 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3123 3125 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3124 3126 <li> &quot;-DAYS&quot; - within a given number of days of today
3125 3127 </ul>
3126 3128
3127 3129 </div>
3128 3130 </div>
3129 3131 </div>
3130 3132
3131 3133
3132 3134
3133 3135 </body>
3134 3136 </html>
3135 3137
3136 3138
3137 3139 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3138 3140 200 Script output follows
3139 3141
3140 3142 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3141 3143 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3142 3144 <head>
3143 3145 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3144 3146 <meta name="robots" content="index, nofollow" />
3145 3147 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3146 3148 <script type="text/javascript" src="/static/mercurial.js"></script>
3147 3149
3148 3150 <title>Help: pager</title>
3149 3151 </head>
3150 3152 <body>
3151 3153
3152 3154 <div class="container">
3153 3155 <div class="menu">
3154 3156 <div class="logo">
3155 3157 <a href="https://mercurial-scm.org/">
3156 3158 <img src="/static/hglogo.png" alt="mercurial" /></a>
3157 3159 </div>
3158 3160 <ul>
3159 3161 <li><a href="/shortlog">log</a></li>
3160 3162 <li><a href="/graph">graph</a></li>
3161 3163 <li><a href="/tags">tags</a></li>
3162 3164 <li><a href="/bookmarks">bookmarks</a></li>
3163 3165 <li><a href="/branches">branches</a></li>
3164 3166 </ul>
3165 3167 <ul>
3166 3168 <li class="active"><a href="/help">help</a></li>
3167 3169 </ul>
3168 3170 </div>
3169 3171
3170 3172 <div class="main">
3171 3173 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3172 3174 <h3>Help: pager</h3>
3173 3175
3174 3176 <form class="search" action="/log">
3175 3177
3176 3178 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3177 3179 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3178 3180 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3179 3181 </form>
3180 3182 <div id="doc">
3181 3183 <h1>Pager Support</h1>
3182 3184 <p>
3183 3185 Some Mercurial commands can produce a lot of output, and Mercurial will
3184 3186 attempt to use a pager to make those commands more pleasant.
3185 3187 </p>
3186 3188 <p>
3187 3189 To set the pager that should be used, set the application variable:
3188 3190 </p>
3189 3191 <pre>
3190 3192 [pager]
3191 3193 pager = less -FRX
3192 3194 </pre>
3193 3195 <p>
3194 3196 If no pager is set in the user or repository configuration, Mercurial uses the
3195 3197 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3196 3198 or system configuration is used. If none of these are set, a default pager will
3197 3199 be used, typically 'less' on Unix and 'more' on Windows.
3198 3200 </p>
3199 3201 <p>
3200 3202 You can disable the pager for certain commands by adding them to the
3201 3203 pager.ignore list:
3202 3204 </p>
3203 3205 <pre>
3204 3206 [pager]
3205 3207 ignore = version, help, update
3206 3208 </pre>
3207 3209 <p>
3208 3210 To ignore global commands like 'hg version' or 'hg help', you have
3209 3211 to specify them in your user configuration file.
3210 3212 </p>
3211 3213 <p>
3212 3214 To control whether the pager is used at all for an individual command,
3213 3215 you can use --pager=&lt;value&gt;:
3214 3216 </p>
3215 3217 <ul>
3216 3218 <li> use as needed: 'auto'.
3217 3219 <li> require the pager: 'yes' or 'on'.
3218 3220 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3219 3221 </ul>
3220 3222 <p>
3221 3223 To globally turn off all attempts to use a pager, set:
3222 3224 </p>
3223 3225 <pre>
3224 3226 [ui]
3225 3227 paginate = never
3226 3228 </pre>
3227 3229 <p>
3228 3230 which will prevent the pager from running.
3229 3231 </p>
3230 3232
3231 3233 </div>
3232 3234 </div>
3233 3235 </div>
3234 3236
3235 3237
3236 3238
3237 3239 </body>
3238 3240 </html>
3239 3241
3240 3242
3241 3243 Sub-topic indexes rendered properly
3242 3244
3243 3245 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3244 3246 200 Script output follows
3245 3247
3246 3248 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3247 3249 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3248 3250 <head>
3249 3251 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3250 3252 <meta name="robots" content="index, nofollow" />
3251 3253 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3252 3254 <script type="text/javascript" src="/static/mercurial.js"></script>
3253 3255
3254 3256 <title>Help: internals</title>
3255 3257 </head>
3256 3258 <body>
3257 3259
3258 3260 <div class="container">
3259 3261 <div class="menu">
3260 3262 <div class="logo">
3261 3263 <a href="https://mercurial-scm.org/">
3262 3264 <img src="/static/hglogo.png" alt="mercurial" /></a>
3263 3265 </div>
3264 3266 <ul>
3265 3267 <li><a href="/shortlog">log</a></li>
3266 3268 <li><a href="/graph">graph</a></li>
3267 3269 <li><a href="/tags">tags</a></li>
3268 3270 <li><a href="/bookmarks">bookmarks</a></li>
3269 3271 <li><a href="/branches">branches</a></li>
3270 3272 </ul>
3271 3273 <ul>
3272 3274 <li><a href="/help">help</a></li>
3273 3275 </ul>
3274 3276 </div>
3275 3277
3276 3278 <div class="main">
3277 3279 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3278 3280
3279 3281 <form class="search" action="/log">
3280 3282
3281 3283 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3282 3284 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3283 3285 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3284 3286 </form>
3285 3287 <table class="bigtable">
3286 3288 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3287 3289
3288 3290 <tr><td>
3289 3291 <a href="/help/internals.bundle2">
3290 3292 bundle2
3291 3293 </a>
3292 3294 </td><td>
3293 3295 Bundle2
3294 3296 </td></tr>
3295 3297 <tr><td>
3296 3298 <a href="/help/internals.bundles">
3297 3299 bundles
3298 3300 </a>
3299 3301 </td><td>
3300 3302 Bundles
3301 3303 </td></tr>
3302 3304 <tr><td>
3303 3305 <a href="/help/internals.cbor">
3304 3306 cbor
3305 3307 </a>
3306 3308 </td><td>
3307 3309 CBOR
3308 3310 </td></tr>
3309 3311 <tr><td>
3310 3312 <a href="/help/internals.censor">
3311 3313 censor
3312 3314 </a>
3313 3315 </td><td>
3314 3316 Censor
3315 3317 </td></tr>
3316 3318 <tr><td>
3317 3319 <a href="/help/internals.changegroups">
3318 3320 changegroups
3319 3321 </a>
3320 3322 </td><td>
3321 3323 Changegroups
3322 3324 </td></tr>
3323 3325 <tr><td>
3324 3326 <a href="/help/internals.config">
3325 3327 config
3326 3328 </a>
3327 3329 </td><td>
3328 3330 Config Registrar
3329 3331 </td></tr>
3330 3332 <tr><td>
3331 3333 <a href="/help/internals.requirements">
3332 3334 requirements
3333 3335 </a>
3334 3336 </td><td>
3335 3337 Repository Requirements
3336 3338 </td></tr>
3337 3339 <tr><td>
3338 3340 <a href="/help/internals.revlogs">
3339 3341 revlogs
3340 3342 </a>
3341 3343 </td><td>
3342 3344 Revision Logs
3343 3345 </td></tr>
3344 3346 <tr><td>
3345 3347 <a href="/help/internals.wireprotocol">
3346 3348 wireprotocol
3347 3349 </a>
3348 3350 </td><td>
3349 3351 Wire Protocol
3350 3352 </td></tr>
3351 3353 <tr><td>
3352 3354 <a href="/help/internals.wireprotocolrpc">
3353 3355 wireprotocolrpc
3354 3356 </a>
3355 3357 </td><td>
3356 3358 Wire Protocol RPC
3357 3359 </td></tr>
3358 3360 <tr><td>
3359 3361 <a href="/help/internals.wireprotocolv2">
3360 3362 wireprotocolv2
3361 3363 </a>
3362 3364 </td><td>
3363 3365 Wire Protocol Version 2
3364 3366 </td></tr>
3365 3367
3366 3368
3367 3369
3368 3370
3369 3371
3370 3372 </table>
3371 3373 </div>
3372 3374 </div>
3373 3375
3374 3376
3375 3377
3376 3378 </body>
3377 3379 </html>
3378 3380
3379 3381
3380 3382 Sub-topic topics rendered properly
3381 3383
3382 3384 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3383 3385 200 Script output follows
3384 3386
3385 3387 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3386 3388 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3387 3389 <head>
3388 3390 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3389 3391 <meta name="robots" content="index, nofollow" />
3390 3392 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3391 3393 <script type="text/javascript" src="/static/mercurial.js"></script>
3392 3394
3393 3395 <title>Help: internals.changegroups</title>
3394 3396 </head>
3395 3397 <body>
3396 3398
3397 3399 <div class="container">
3398 3400 <div class="menu">
3399 3401 <div class="logo">
3400 3402 <a href="https://mercurial-scm.org/">
3401 3403 <img src="/static/hglogo.png" alt="mercurial" /></a>
3402 3404 </div>
3403 3405 <ul>
3404 3406 <li><a href="/shortlog">log</a></li>
3405 3407 <li><a href="/graph">graph</a></li>
3406 3408 <li><a href="/tags">tags</a></li>
3407 3409 <li><a href="/bookmarks">bookmarks</a></li>
3408 3410 <li><a href="/branches">branches</a></li>
3409 3411 </ul>
3410 3412 <ul>
3411 3413 <li class="active"><a href="/help">help</a></li>
3412 3414 </ul>
3413 3415 </div>
3414 3416
3415 3417 <div class="main">
3416 3418 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3417 3419 <h3>Help: internals.changegroups</h3>
3418 3420
3419 3421 <form class="search" action="/log">
3420 3422
3421 3423 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3422 3424 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3423 3425 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3424 3426 </form>
3425 3427 <div id="doc">
3426 3428 <h1>Changegroups</h1>
3427 3429 <p>
3428 3430 Changegroups are representations of repository revlog data, specifically
3429 3431 the changelog data, root/flat manifest data, treemanifest data, and
3430 3432 filelogs.
3431 3433 </p>
3432 3434 <p>
3433 3435 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3434 3436 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3435 3437 only difference being an additional item in the *delta header*. Version
3436 3438 &quot;3&quot; adds support for revlog flags in the *delta header* and optionally
3437 3439 exchanging treemanifests (enabled by setting an option on the
3438 3440 &quot;changegroup&quot; part in the bundle2).
3439 3441 </p>
3440 3442 <p>
3441 3443 Changegroups when not exchanging treemanifests consist of 3 logical
3442 3444 segments:
3443 3445 </p>
3444 3446 <pre>
3445 3447 +---------------------------------+
3446 3448 | | | |
3447 3449 | changeset | manifest | filelogs |
3448 3450 | | | |
3449 3451 | | | |
3450 3452 +---------------------------------+
3451 3453 </pre>
3452 3454 <p>
3453 3455 When exchanging treemanifests, there are 4 logical segments:
3454 3456 </p>
3455 3457 <pre>
3456 3458 +-------------------------------------------------+
3457 3459 | | | | |
3458 3460 | changeset | root | treemanifests | filelogs |
3459 3461 | | manifest | | |
3460 3462 | | | | |
3461 3463 +-------------------------------------------------+
3462 3464 </pre>
3463 3465 <p>
3464 3466 The principle building block of each segment is a *chunk*. A *chunk*
3465 3467 is a framed piece of data:
3466 3468 </p>
3467 3469 <pre>
3468 3470 +---------------------------------------+
3469 3471 | | |
3470 3472 | length | data |
3471 3473 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3472 3474 | | |
3473 3475 +---------------------------------------+
3474 3476 </pre>
3475 3477 <p>
3476 3478 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3477 3479 integer indicating the length of the entire chunk (including the length field
3478 3480 itself).
3479 3481 </p>
3480 3482 <p>
3481 3483 There is a special case chunk that has a value of 0 for the length
3482 3484 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3483 3485 </p>
3484 3486 <h2>Delta Groups</h2>
3485 3487 <p>
3486 3488 A *delta group* expresses the content of a revlog as a series of deltas,
3487 3489 or patches against previous revisions.
3488 3490 </p>
3489 3491 <p>
3490 3492 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3491 3493 to signal the end of the delta group:
3492 3494 </p>
3493 3495 <pre>
3494 3496 +------------------------------------------------------------------------+
3495 3497 | | | | | |
3496 3498 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3497 3499 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3498 3500 | | | | | |
3499 3501 +------------------------------------------------------------------------+
3500 3502 </pre>
3501 3503 <p>
3502 3504 Each *chunk*'s data consists of the following:
3503 3505 </p>
3504 3506 <pre>
3505 3507 +---------------------------------------+
3506 3508 | | |
3507 3509 | delta header | delta data |
3508 3510 | (various by version) | (various) |
3509 3511 | | |
3510 3512 +---------------------------------------+
3511 3513 </pre>
3512 3514 <p>
3513 3515 The *delta data* is a series of *delta*s that describe a diff from an existing
3514 3516 entry (either that the recipient already has, or previously specified in the
3515 3517 bundle/changegroup).
3516 3518 </p>
3517 3519 <p>
3518 3520 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3519 3521 &quot;3&quot; of the changegroup format.
3520 3522 </p>
3521 3523 <p>
3522 3524 Version 1 (headerlen=80):
3523 3525 </p>
3524 3526 <pre>
3525 3527 +------------------------------------------------------+
3526 3528 | | | | |
3527 3529 | node | p1 node | p2 node | link node |
3528 3530 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3529 3531 | | | | |
3530 3532 +------------------------------------------------------+
3531 3533 </pre>
3532 3534 <p>
3533 3535 Version 2 (headerlen=100):
3534 3536 </p>
3535 3537 <pre>
3536 3538 +------------------------------------------------------------------+
3537 3539 | | | | | |
3538 3540 | node | p1 node | p2 node | base node | link node |
3539 3541 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3540 3542 | | | | | |
3541 3543 +------------------------------------------------------------------+
3542 3544 </pre>
3543 3545 <p>
3544 3546 Version 3 (headerlen=102):
3545 3547 </p>
3546 3548 <pre>
3547 3549 +------------------------------------------------------------------------------+
3548 3550 | | | | | | |
3549 3551 | node | p1 node | p2 node | base node | link node | flags |
3550 3552 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3551 3553 | | | | | | |
3552 3554 +------------------------------------------------------------------------------+
3553 3555 </pre>
3554 3556 <p>
3555 3557 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3556 3558 series of *delta*s, densely packed (no separators). These deltas describe a diff
3557 3559 from an existing entry (either that the recipient already has, or previously
3558 3560 specified in the bundle/changegroup). The format is described more fully in
3559 3561 &quot;hg help internals.bdiff&quot;, but briefly:
3560 3562 </p>
3561 3563 <pre>
3562 3564 +---------------------------------------------------------------+
3563 3565 | | | | |
3564 3566 | start offset | end offset | new length | content |
3565 3567 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3566 3568 | | | | |
3567 3569 +---------------------------------------------------------------+
3568 3570 </pre>
3569 3571 <p>
3570 3572 Please note that the length field in the delta data does *not* include itself.
3571 3573 </p>
3572 3574 <p>
3573 3575 In version 1, the delta is always applied against the previous node from
3574 3576 the changegroup or the first parent if this is the first entry in the
3575 3577 changegroup.
3576 3578 </p>
3577 3579 <p>
3578 3580 In version 2 and up, the delta base node is encoded in the entry in the
3579 3581 changegroup. This allows the delta to be expressed against any parent,
3580 3582 which can result in smaller deltas and more efficient encoding of data.
3581 3583 </p>
3582 3584 <h2>Changeset Segment</h2>
3583 3585 <p>
3584 3586 The *changeset segment* consists of a single *delta group* holding
3585 3587 changelog data. The *empty chunk* at the end of the *delta group* denotes
3586 3588 the boundary to the *manifest segment*.
3587 3589 </p>
3588 3590 <h2>Manifest Segment</h2>
3589 3591 <p>
3590 3592 The *manifest segment* consists of a single *delta group* holding manifest
3591 3593 data. If treemanifests are in use, it contains only the manifest for the
3592 3594 root directory of the repository. Otherwise, it contains the entire
3593 3595 manifest data. The *empty chunk* at the end of the *delta group* denotes
3594 3596 the boundary to the next segment (either the *treemanifests segment* or the
3595 3597 *filelogs segment*, depending on version and the request options).
3596 3598 </p>
3597 3599 <h3>Treemanifests Segment</h3>
3598 3600 <p>
3599 3601 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3600 3602 only if the 'treemanifest' param is part of the bundle2 changegroup part
3601 3603 (it is not possible to use changegroup version 3 outside of bundle2).
3602 3604 Aside from the filenames in the *treemanifests segment* containing a
3603 3605 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3604 3606 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3605 3607 a sub-segment with filename size 0). This denotes the boundary to the
3606 3608 *filelogs segment*.
3607 3609 </p>
3608 3610 <h2>Filelogs Segment</h2>
3609 3611 <p>
3610 3612 The *filelogs segment* consists of multiple sub-segments, each
3611 3613 corresponding to an individual file whose data is being described:
3612 3614 </p>
3613 3615 <pre>
3614 3616 +--------------------------------------------------+
3615 3617 | | | | | |
3616 3618 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3617 3619 | | | | | (4 bytes) |
3618 3620 | | | | | |
3619 3621 +--------------------------------------------------+
3620 3622 </pre>
3621 3623 <p>
3622 3624 The final filelog sub-segment is followed by an *empty chunk* (logically,
3623 3625 a sub-segment with filename size 0). This denotes the end of the segment
3624 3626 and of the overall changegroup.
3625 3627 </p>
3626 3628 <p>
3627 3629 Each filelog sub-segment consists of the following:
3628 3630 </p>
3629 3631 <pre>
3630 3632 +------------------------------------------------------+
3631 3633 | | | |
3632 3634 | filename length | filename | delta group |
3633 3635 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3634 3636 | | | |
3635 3637 +------------------------------------------------------+
3636 3638 </pre>
3637 3639 <p>
3638 3640 That is, a *chunk* consisting of the filename (not terminated or padded)
3639 3641 followed by N chunks constituting the *delta group* for this file. The
3640 3642 *empty chunk* at the end of each *delta group* denotes the boundary to the
3641 3643 next filelog sub-segment.
3642 3644 </p>
3643 3645
3644 3646 </div>
3645 3647 </div>
3646 3648 </div>
3647 3649
3648 3650
3649 3651
3650 3652 </body>
3651 3653 </html>
3652 3654
3653 3655
3654 3656 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3655 3657 404 Not Found
3656 3658
3657 3659 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3658 3660 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3659 3661 <head>
3660 3662 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3661 3663 <meta name="robots" content="index, nofollow" />
3662 3664 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3663 3665 <script type="text/javascript" src="/static/mercurial.js"></script>
3664 3666
3665 3667 <title>test: error</title>
3666 3668 </head>
3667 3669 <body>
3668 3670
3669 3671 <div class="container">
3670 3672 <div class="menu">
3671 3673 <div class="logo">
3672 3674 <a href="https://mercurial-scm.org/">
3673 3675 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3674 3676 </div>
3675 3677 <ul>
3676 3678 <li><a href="/shortlog">log</a></li>
3677 3679 <li><a href="/graph">graph</a></li>
3678 3680 <li><a href="/tags">tags</a></li>
3679 3681 <li><a href="/bookmarks">bookmarks</a></li>
3680 3682 <li><a href="/branches">branches</a></li>
3681 3683 </ul>
3682 3684 <ul>
3683 3685 <li><a href="/help">help</a></li>
3684 3686 </ul>
3685 3687 </div>
3686 3688
3687 3689 <div class="main">
3688 3690
3689 3691 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3690 3692 <h3>error</h3>
3691 3693
3692 3694
3693 3695 <form class="search" action="/log">
3694 3696
3695 3697 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3696 3698 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3697 3699 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3698 3700 </form>
3699 3701
3700 3702 <div class="description">
3701 3703 <p>
3702 3704 An error occurred while processing your request:
3703 3705 </p>
3704 3706 <p>
3705 3707 Not Found
3706 3708 </p>
3707 3709 </div>
3708 3710 </div>
3709 3711 </div>
3710 3712
3711 3713
3712 3714
3713 3715 </body>
3714 3716 </html>
3715 3717
3716 3718 [1]
3717 3719
3718 3720 $ killdaemons.py
3719 3721
3720 3722 #endif
General Comments 0
You need to be logged in to leave comments. Login now