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